]> git.sesse.net Git - ffmpeg/commitdiff
lavf: Handle the environment variable no_proxy more properly
authorMartin Storsjö <martin@martin.st>
Wed, 27 Feb 2013 09:13:47 +0000 (11:13 +0200)
committerMartin Storsjö <martin@martin.st>
Wed, 27 Feb 2013 19:32:13 +0000 (21:32 +0200)
The handling of the environment variable no_proxy, present since
one of the initial commits (de6d9b6404), is inconsistent with
how many other applications and libraries interpret this
variable. Its bare presence does not indicate that the use of
proxies should be skipped, but it is some sort of pattern for
hosts that does not need using a proxy (e.g. for a local network).

As investigated by Rudolf Polzer, different libraries handle this
in different ways, some supporting IP address masks, some supporting
arbitrary globbing using *, some just checking that the pattern matches
the end of the hostname without regard for whether it actually is
the right domain or a domain that ends in the same string.

This simple logic should be pretty similar to the logic used by
lynx and curl.

Signed-off-by: Martin Storsjö <martin@martin.st>
libavformat/http.c
libavformat/internal.h
libavformat/tls.c
libavformat/utils.c
libavformat/version.h

index 9666ca320666297243650e3f49c1074254cc7922..9645bd1ffb69e2edf0360ab73e9064b9360ae82c 100644 (file)
@@ -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;
index 3ca2d8fb97c1991247fb1e680452ae27972ec824..73673696476f0e23ff3b67706b890b540a22a54e 100644 (file)
@@ -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 */
index 866e55f2baaf41e350ff5d91ced9ff65540682dc..fecf096b021ab2dd52b4dc65d97eff5157bb21a0 100644 (file)
@@ -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;
index cd46caf3fd5c1432fb506f6eb726cfa28067a9d4..be5a5caabfc7b4de607dd815aa8425866d4e5cfc 100644 (file)
@@ -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;
+}
index a9d542af2f294cf46368e9954caed8684baedf2c..763c9df30381e35494773539ccb28354e7405c48 100644 (file)
@@ -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, \