* 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>tags/n1.2
| @@ -441,7 +441,8 @@ OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o | |||||
| SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h | SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h | ||||
| SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h | SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h | ||||
| TESTPROGS = seek \ | |||||
| TESTPROGS = noproxy \ | |||||
| seek \ | |||||
| srtp \ | srtp \ | ||||
| url \ | url \ | ||||
| @@ -120,10 +120,6 @@ static int http_open_cnx(URLContext *h) | |||||
| HTTPAuthType cur_auth_type, cur_proxy_auth_type; | HTTPAuthType cur_auth_type, cur_proxy_auth_type; | ||||
| HTTPContext *s = h->priv_data; | 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 */ | /* fill the dest addr */ | ||||
| redo: | redo: | ||||
| /* needed in any case to build the host string */ | /* needed in any case to build the host string */ | ||||
| @@ -132,6 +128,10 @@ static int http_open_cnx(URLContext *h) | |||||
| path1, sizeof(path1), s->location); | path1, sizeof(path1), s->location); | ||||
| ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); | 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")) { | if (!strcmp(proto, "https")) { | ||||
| lower_proto = "tls"; | lower_proto = "tls"; | ||||
| use_proxy = 0; | use_proxy = 0; | ||||
| @@ -390,4 +390,6 @@ AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precissi | |||||
| */ | */ | ||||
| void ff_generate_avci_extradata(AVStream *st); | void ff_generate_avci_extradata(AVStream *st); | ||||
| int ff_http_match_no_proxy(const char *no_proxy, const char *hostname); | |||||
| #endif /* AVFORMAT_INTERNAL_H */ | #endif /* AVFORMAT_INTERNAL_H */ | ||||
| @@ -0,0 +1,43 @@ | |||||
| /* | |||||
| * Copyright (c) 2013 Martin Storsjo | |||||
| * | |||||
| * This file is part of FFmpeg. | |||||
| * | |||||
| * FFmpeg is free software; you can redistribute it and/or | |||||
| * modify it under the terms of the GNU Lesser General Public | |||||
| * License as published by the Free Software Foundation; either | |||||
| * version 2.1 of the License, or (at your option) any later version. | |||||
| * | |||||
| * FFmpeg is distributed in the hope that it will be useful, | |||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||||
| * Lesser General Public License for more details. | |||||
| * | |||||
| * You should have received a copy of the GNU Lesser General Public | |||||
| * License along with FFmpeg; if not, write to the Free Software | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||||
| */ | |||||
| #include "internal.h" | |||||
| static void test(const char *pattern, const char *host) | |||||
| { | |||||
| int res = ff_http_match_no_proxy(pattern, host); | |||||
| printf("The pattern \"%s\" %s the hostname %s\n", | |||||
| pattern ? pattern : "(null)", res ? "matches" : "does not match", | |||||
| host); | |||||
| } | |||||
| int main(void) | |||||
| { | |||||
| test(NULL, "domain.com"); | |||||
| test("example.com domain.com", "domain.com"); | |||||
| test("example.com other.com", "domain.com"); | |||||
| test("example.com,domain.com", "domain.com"); | |||||
| test("example.com,domain.com", "otherdomain.com"); | |||||
| test("example.com, *.domain.com", "sub.domain.com"); | |||||
| test("example.com, *.domain.com", "domain.com"); | |||||
| test("example.com, .domain.com", "domain.com"); | |||||
| test("*", "domain.com"); | |||||
| return 0; | |||||
| } | |||||
| @@ -172,10 +172,6 @@ static int tls_open(URLContext *h, const char *uri, int flags) | |||||
| ff_tls_init(); | 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, path, sizeof(path), uri); | av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, path, sizeof(path), uri); | ||||
| ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, "%s", path); | ff_url_join(buf, sizeof(buf), "tcp", NULL, host, port, "%s", path); | ||||
| @@ -185,6 +181,10 @@ static int tls_open(URLContext *h, const char *uri, int flags) | |||||
| freeaddrinfo(ai); | 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) { | if (use_proxy) { | ||||
| char proxy_host[200], proxy_auth[200], dest[200]; | char proxy_host[200], proxy_auth[200], dest[200]; | ||||
| int proxy_port; | int proxy_port; | ||||
| @@ -4379,3 +4379,57 @@ void ff_generate_avci_extradata(AVStream *st) | |||||
| memcpy(st->codec->extradata, data, size); | memcpy(st->codec->extradata, data, size); | ||||
| st->codec->extradata_size = size; | st->codec->extradata_size = size; | ||||
| } | } | ||||
| 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; | |||||
| } | |||||
| @@ -31,7 +31,7 @@ | |||||
| #define LIBAVFORMAT_VERSION_MAJOR 54 | #define LIBAVFORMAT_VERSION_MAJOR 54 | ||||
| #define LIBAVFORMAT_VERSION_MINOR 63 | #define LIBAVFORMAT_VERSION_MINOR 63 | ||||
| #define LIBAVFORMAT_VERSION_MICRO 101 | |||||
| #define LIBAVFORMAT_VERSION_MICRO 102 | |||||
| #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ | ||||
| LIBAVFORMAT_VERSION_MINOR, \ | LIBAVFORMAT_VERSION_MINOR, \ | ||||
| @@ -1,3 +1,7 @@ | |||||
| FATE_LIBAVFORMAT += fate-noproxy | |||||
| fate-noproxy: libavformat/noproxy-test$(EXESUF) | |||||
| fate-noproxy: CMD = run libavformat/noproxy-test | |||||
| FATE_LIBAVFORMAT += fate-srtp | FATE_LIBAVFORMAT += fate-srtp | ||||
| fate-srtp: libavformat/srtp-test$(EXESUF) | fate-srtp: libavformat/srtp-test$(EXESUF) | ||||
| fate-srtp: CMD = run libavformat/srtp-test | fate-srtp: CMD = run libavformat/srtp-test | ||||
| @@ -0,0 +1,9 @@ | |||||
| The pattern "(null)" does not match the hostname domain.com | |||||
| The pattern "example.com domain.com" matches the hostname domain.com | |||||
| The pattern "example.com other.com" does not match the hostname domain.com | |||||
| The pattern "example.com,domain.com" matches the hostname domain.com | |||||
| The pattern "example.com,domain.com" does not match the hostname otherdomain.com | |||||
| The pattern "example.com, *.domain.com" matches the hostname sub.domain.com | |||||
| The pattern "example.com, *.domain.com" matches the hostname domain.com | |||||
| The pattern "example.com, .domain.com" matches the hostname domain.com | |||||
| The pattern "*" matches the hostname domain.com | |||||