Browse code

Merge remote-tracking branch 'qatar/master'

* qatar/master:
lavf: Add a fate test for the noproxy pattern matching
lavf: Handle the environment variable no_proxy more properly

Conflicts:
libavformat/Makefile
libavformat/internal.h
libavformat/tls.c
libavformat/utils.c
libavformat/version.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2013/02/28 21:12:04
Showing 9 changed files
... ...
@@ -441,7 +441,8 @@ OBJS-$(CONFIG_UDP_PROTOCOL)              += udp.o
441 441
 
442 442
 SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
443 443
 SKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.h
444
-TESTPROGS = seek                                                        \
444
+TESTPROGS = noproxy                                                     \
445
+            seek                                                        \
445 446
             srtp                                                        \
446 447
             url                                                         \
447 448
 
... ...
@@ -120,10 +120,6 @@ static int http_open_cnx(URLContext *h)
120 120
     HTTPAuthType cur_auth_type, cur_proxy_auth_type;
121 121
     HTTPContext *s = h->priv_data;
122 122
 
123
-    proxy_path = getenv("http_proxy");
124
-    use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
125
-        av_strstart(proxy_path, "http://", NULL);
126
-
127 123
     /* fill the dest addr */
128 124
  redo:
129 125
     /* needed in any case to build the host string */
... ...
@@ -132,6 +128,10 @@ static int http_open_cnx(URLContext *h)
132 132
                  path1, sizeof(path1), s->location);
133 133
     ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
134 134
 
135
+    proxy_path = getenv("http_proxy");
136
+    use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) &&
137
+                proxy_path != NULL && av_strstart(proxy_path, "http://", NULL);
138
+
135 139
     if (!strcmp(proto, "https")) {
136 140
         lower_proto = "tls";
137 141
         use_proxy = 0;
... ...
@@ -390,4 +390,6 @@ AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precissi
390 390
  */
391 391
 void ff_generate_avci_extradata(AVStream *st);
392 392
 
393
+int ff_http_match_no_proxy(const char *no_proxy, const char *hostname);
394
+
393 395
 #endif /* AVFORMAT_INTERNAL_H */
394 396
new file mode 100644
... ...
@@ -0,0 +1,43 @@
0
+/*
1
+ * Copyright (c) 2013 Martin Storsjo
2
+ *
3
+ * This file is part of FFmpeg.
4
+ *
5
+ * FFmpeg is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * FFmpeg is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with FFmpeg; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ */
19
+
20
+#include "internal.h"
21
+
22
+static void test(const char *pattern, const char *host)
23
+{
24
+    int res = ff_http_match_no_proxy(pattern, host);
25
+    printf("The pattern \"%s\" %s the hostname %s\n",
26
+           pattern ? pattern : "(null)", res ? "matches" : "does not match",
27
+           host);
28
+}
29
+
30
+int main(void)
31
+{
32
+    test(NULL, "domain.com");
33
+    test("example.com domain.com", "domain.com");
34
+    test("example.com other.com", "domain.com");
35
+    test("example.com,domain.com", "domain.com");
36
+    test("example.com,domain.com", "otherdomain.com");
37
+    test("example.com, *.domain.com", "sub.domain.com");
38
+    test("example.com, *.domain.com", "domain.com");
39
+    test("example.com, .domain.com", "domain.com");
40
+    test("*", "domain.com");
41
+    return 0;
42
+}
... ...
@@ -172,10 +172,6 @@ static int tls_open(URLContext *h, const char *uri, int flags)
172 172
 
173 173
     ff_tls_init();
174 174
 
175
-    proxy_path = getenv("http_proxy");
176
-    use_proxy = (proxy_path != NULL) && !getenv("no_proxy") &&
177
-        av_strstart(proxy_path, "http://", NULL);
178
-
179 175
     av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, path, sizeof(path), uri);
180 176
     ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, "%s", path);
181 177
 
... ...
@@ -185,6 +181,10 @@ static int tls_open(URLContext *h, const char *uri, int flags)
185 185
         freeaddrinfo(ai);
186 186
     }
187 187
 
188
+    proxy_path = getenv("http_proxy");
189
+    use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), host) &&
190
+                proxy_path != NULL && av_strstart(proxy_path, "http://", NULL);
191
+
188 192
     if (use_proxy) {
189 193
         char proxy_host[200], proxy_auth[200], dest[200];
190 194
         int proxy_port;
... ...
@@ -4379,3 +4379,57 @@ void ff_generate_avci_extradata(AVStream *st)
4379 4379
     memcpy(st->codec->extradata, data, size);
4380 4380
     st->codec->extradata_size = size;
4381 4381
 }
4382
+
4383
+static int match_host_pattern(const char *pattern, const char *hostname)
4384
+{
4385
+    int len_p, len_h;
4386
+    if (!strcmp(pattern, "*"))
4387
+        return 1;
4388
+    // Skip a possible *. at the start of the pattern
4389
+    if (pattern[0] == '*')
4390
+        pattern++;
4391
+    if (pattern[0] == '.')
4392
+        pattern++;
4393
+    len_p = strlen(pattern);
4394
+    len_h = strlen(hostname);
4395
+    if (len_p > len_h)
4396
+        return 0;
4397
+    // Simply check if the end of hostname is equal to 'pattern'
4398
+    if (!strcmp(pattern, &hostname[len_h - len_p])) {
4399
+        if (len_h == len_p)
4400
+            return 1; // Exact match
4401
+        if (hostname[len_h - len_p - 1] == '.')
4402
+            return 1; // The matched substring is a domain and not just a substring of a domain
4403
+    }
4404
+    return 0;
4405
+}
4406
+
4407
+int ff_http_match_no_proxy(const char *no_proxy, const char *hostname)
4408
+{
4409
+    char *buf, *start;
4410
+    int ret = 0;
4411
+    if (!no_proxy)
4412
+        return 0;
4413
+    if (!hostname)
4414
+        return 0;
4415
+    buf = av_strdup(no_proxy);
4416
+    if (!buf)
4417
+        return 0;
4418
+    start = buf;
4419
+    while (start) {
4420
+        char *sep, *next = NULL;
4421
+        start += strspn(start, " ,");
4422
+        sep = start + strcspn(start, " ,");
4423
+        if (*sep) {
4424
+            next = sep + 1;
4425
+            *sep = '\0';
4426
+        }
4427
+        if (match_host_pattern(start, hostname)) {
4428
+            ret = 1;
4429
+            break;
4430
+        }
4431
+        start = next;
4432
+    }
4433
+    av_free(buf);
4434
+    return ret;
4435
+}
... ...
@@ -31,7 +31,7 @@
31 31
 
32 32
 #define LIBAVFORMAT_VERSION_MAJOR 54
33 33
 #define LIBAVFORMAT_VERSION_MINOR 63
34
-#define LIBAVFORMAT_VERSION_MICRO 101
34
+#define LIBAVFORMAT_VERSION_MICRO 102
35 35
 
36 36
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
37 37
                                                LIBAVFORMAT_VERSION_MINOR, \
... ...
@@ -1,3 +1,7 @@
1
+FATE_LIBAVFORMAT += fate-noproxy
2
+fate-noproxy: libavformat/noproxy-test$(EXESUF)
3
+fate-noproxy: CMD = run libavformat/noproxy-test
4
+
1 5
 FATE_LIBAVFORMAT += fate-srtp
2 6
 fate-srtp: libavformat/srtp-test$(EXESUF)
3 7
 fate-srtp: CMD = run libavformat/srtp-test
4 8
new file mode 100644
... ...
@@ -0,0 +1,9 @@
0
+The pattern "(null)" does not match the hostname domain.com
1
+The pattern "example.com domain.com" matches the hostname domain.com
2
+The pattern "example.com other.com" does not match the hostname domain.com
3
+The pattern "example.com,domain.com" matches the hostname domain.com
4
+The pattern "example.com,domain.com" does not match the hostname otherdomain.com
5
+The pattern "example.com, *.domain.com" matches the hostname sub.domain.com
6
+The pattern "example.com, *.domain.com" matches the hostname domain.com
7
+The pattern "example.com, .domain.com" matches the hostname domain.com
8
+The pattern "*" matches the hostname domain.com