* 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>
... | ... |
@@ -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, \ |
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 |