diff --git a/libavformat/http.c b/libavformat/http.c index 9666ca3206..9645bd1ffb 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -106,10 +106,6 @@ static int http_open_cnx(URLContext *h) HTTPAuthType cur_auth_type, cur_proxy_auth_type; HTTPContext *s = h->priv_data; - proxy_path = getenv("http_proxy"); - use_proxy = (proxy_path != NULL) && !getenv("no_proxy") && - av_strstart(proxy_path, "http://", NULL); - /* fill the dest addr */ redo: /* needed in any case to build the host string */ @@ -118,6 +114,10 @@ static int http_open_cnx(URLContext *h) path1, sizeof(path1), s->location); ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); + proxy_path = getenv("http_proxy"); + use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) && + proxy_path != NULL && av_strstart(proxy_path, "http://", NULL); + if (!strcmp(proto, "https")) { lower_proto = "tls"; use_proxy = 0; diff --git a/libavformat/internal.h b/libavformat/internal.h index 3ca2d8fb97..7367369647 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -375,4 +375,6 @@ enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag); */ enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags); +int ff_http_match_no_proxy(const char *no_proxy, const char *hostname); + #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/tls.c b/libavformat/tls.c index 866e55f2ba..fecf096b02 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -116,10 +116,6 @@ static int tls_open(URLContext *h, const char *uri, int flags) ff_tls_init(); - proxy_path = getenv("http_proxy"); - use_proxy = (proxy_path != NULL) && !getenv("no_proxy") && - av_strstart(proxy_path, "http://", NULL); - av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri); ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, NULL); @@ -129,6 +125,10 @@ static int tls_open(URLContext *h, const char *uri, int flags) freeaddrinfo(ai); } + proxy_path = getenv("http_proxy"); + use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), host) && + proxy_path != NULL && av_strstart(proxy_path, "http://", NULL); + if (use_proxy) { char proxy_host[200], proxy_auth[200], dest[200]; int proxy_port; diff --git a/libavformat/utils.c b/libavformat/utils.c index cd46caf3fd..be5a5caabf 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3589,3 +3589,57 @@ const struct AVCodecTag *avformat_get_riff_audio_tags(void) { return ff_codec_wav_tags; } + +static int match_host_pattern(const char *pattern, const char *hostname) +{ + int len_p, len_h; + if (!strcmp(pattern, "*")) + return 1; + // Skip a possible *. at the start of the pattern + if (pattern[0] == '*') + pattern++; + if (pattern[0] == '.') + pattern++; + len_p = strlen(pattern); + len_h = strlen(hostname); + if (len_p > len_h) + return 0; + // Simply check if the end of hostname is equal to 'pattern' + if (!strcmp(pattern, &hostname[len_h - len_p])) { + if (len_h == len_p) + return 1; // Exact match + if (hostname[len_h - len_p - 1] == '.') + return 1; // The matched substring is a domain and not just a substring of a domain + } + return 0; +} + +int ff_http_match_no_proxy(const char *no_proxy, const char *hostname) +{ + char *buf, *start; + int ret = 0; + if (!no_proxy) + return 0; + if (!hostname) + return 0; + buf = av_strdup(no_proxy); + if (!buf) + return 0; + start = buf; + while (start) { + char *sep, *next = NULL; + start += strspn(start, " ,"); + sep = start + strcspn(start, " ,"); + if (*sep) { + next = sep + 1; + *sep = '\0'; + } + if (match_host_pattern(start, hostname)) { + ret = 1; + break; + } + start = next; + } + av_free(buf); + return ret; +} diff --git a/libavformat/version.h b/libavformat/version.h index a9d542af2f..763c9df303 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 54 #define LIBAVFORMAT_VERSION_MINOR 21 -#define LIBAVFORMAT_VERSION_MICRO 2 +#define LIBAVFORMAT_VERSION_MICRO 3 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \