diff options
Diffstat (limited to 'stream/url.c')
-rw-r--r-- | stream/url.c | 119 |
1 files changed, 90 insertions, 29 deletions
diff --git a/stream/url.c b/stream/url.c index 2c241ee7ee..9114468388 100644 --- a/stream/url.c +++ b/stream/url.c @@ -24,6 +24,7 @@ #include <stdlib.h> #include <stdio.h> #include <ctype.h> +#include <stdarg.h> #include <inttypes.h> #include "url.h" @@ -33,56 +34,121 @@ #define SIZE_MAX ((size_t)-1) #endif +static char *mp_asprintf(const char *fmt, ...) +{ + char *p = NULL; + va_list va, va_bak; + int len; + + va_start(va, fmt); + va_copy(va_bak, va); + + len = vsnprintf(NULL, 0, fmt, va); + if (len < 0) + goto end; + + p = malloc(len + 1); + if (!p) + goto end; + + len = vsnprintf(p, len + 1, fmt, va_bak); + if (len < 0) + free(p), p = NULL; + +end: + va_end(va); + return p; +} + +static int is_proxy(const URL_t *url) { + return !strcasecmp(url->protocol, "http_proxy") && url->file && strstr(url->file, "://"); +} + +int url_is_protocol(const URL_t *url, const char *proto) { + int proxy = is_proxy(url); + if (proxy) { + URL_t *tmp = url_new(url->file + 1); + int res = !strcasecmp(tmp->protocol, proto); + url_free(tmp); + return res; + } + return !strcasecmp(url->protocol, proto); +} + +void url_set_protocol(URL_t *url, const char *proto) { + int proxy = is_proxy(url); + if (proxy) { + char *dst = url->file + 1; + int oldlen = strstr(dst, "://") - dst; + int newlen = strlen(proto); + if (newlen != oldlen) { + mp_msg(MSGT_NETWORK, MSGL_ERR, "Setting protocol not implemented!\n"); + return; + } + memcpy(dst, proto, newlen); + return; + } + free(url->protocol); + url->protocol = strdup(proto); +} + URL_t *url_redirect(URL_t **url, const char *redir) { URL_t *u = *url; + int proxy = is_proxy(u); + const char *oldurl = proxy ? u->file + 1 : u->url; + const char *newurl = redir; + char *buffer = NULL; URL_t *res; if (!strchr(redir, '/') || *redir == '/') { char *tmp; - char *newurl = malloc(strlen(u->url) + strlen(redir) + 1); - strcpy(newurl, u->url); + newurl = buffer = malloc(strlen(oldurl) + strlen(redir) + 1); + strcpy(buffer, oldurl); if (*redir == '/') { redir++; - tmp = strstr(newurl, "://"); + tmp = strstr(buffer, "://"); if (tmp) tmp = strchr(tmp + 3, '/'); } else - tmp = strrchr(newurl, '/'); + tmp = strrchr(buffer, '/'); if (tmp) tmp[1] = 0; - strcat(newurl, redir); - res = url_new(newurl); - free(newurl); - } else - res = url_new(redir); + strcat(buffer, redir); + } + if (proxy) { + char *tmp = get_http_proxy_url(u, newurl); + free(buffer); + newurl = buffer = tmp; + } + res = url_new(newurl); + free(buffer); url_free(u); *url = res; return res; } -static int make_noauth_url(URL_t *url, char *dst, int dst_size) +static char *get_noauth_url(const URL_t *url) { if (url->port) - return snprintf(dst, dst_size, "%s://%s:%d%s", url->protocol, - url->hostname, url->port, url->file); + return mp_asprintf("%s://%s:%d%s", + url->protocol, url->hostname, url->port, url->file); else - return snprintf(dst, dst_size, "%s://%s%s", url->protocol, - url->hostname, url->file); + return mp_asprintf("%s://%s%s", + url->protocol, url->hostname, url->file); } -int make_http_proxy_url(URL_t *proxy, const char *host_url, char *dst, - int dst_size) +char *get_http_proxy_url(const URL_t *proxy, const char *host_url) { if (proxy->username) - return snprintf(dst, dst_size, "http_proxy://%s:%s@%s:%d/%s", - proxy->username, - proxy->password ? proxy->password : "", - proxy->hostname, proxy->port, host_url); + return mp_asprintf("http_proxy://%s:%s@%s:%d/%s", + proxy->username, + proxy->password ? proxy->password : "", + proxy->hostname, proxy->port, host_url); else - return snprintf(dst, dst_size, "http_proxy://%s:%d/%s", - proxy->hostname, proxy->port, host_url); + return mp_asprintf("http_proxy://%s:%d/%s", + proxy->hostname, proxy->port, host_url); } URL_t* url_new(const char* url) { - int pos1, pos2,v6addr = 0, noauth_len; + int pos1, pos2,v6addr = 0; URL_t* Curl = NULL; char *escfilename=NULL; char *ptr1=NULL, *ptr2=NULL, *ptr3=NULL, *ptr4=NULL; @@ -251,16 +317,11 @@ url_new(const char* url) { strcpy(Curl->file, "/"); } - noauth_len = make_noauth_url(Curl, NULL, 0); - if (noauth_len > 0) { - noauth_len++; - Curl->noauth_url = malloc(noauth_len); + Curl->noauth_url = get_noauth_url(Curl); if (!Curl->noauth_url) { mp_msg(MSGT_NETWORK, MSGL_FATAL, "Memory allocation failed.\n"); goto err_out; } - make_noauth_url(Curl, Curl->noauth_url, noauth_len); - } free(escfilename); return Curl; |