summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-02-28 13:12:04 +0100
committerMichael Niedermayer <michaelni@gmx.at>2013-02-28 13:13:04 +0100
commit03678a32bcb8e1ae5c213e02faf62df166cca05d (patch)
tree035a1b8ab38470337cf066aae3ab1cc60a03c48b
parent085bd039bb095cdf35ef41932eebbc428c5caa76 (diff)
parent5c8696555abd30a200d0d882e2913f66619fba68 (diff)
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>
-rw-r--r--libavformat/Makefile3
-rw-r--r--libavformat/http.c8
-rw-r--r--libavformat/internal.h2
-rw-r--r--libavformat/noproxy-test.c43
-rw-r--r--libavformat/tls.c8
-rw-r--r--libavformat/utils.c54
-rw-r--r--libavformat/version.h2
-rw-r--r--tests/fate/libavformat.mak4
-rw-r--r--tests/ref/fate/noproxy9
9 files changed, 123 insertions, 10 deletions
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 44456eab64..03d7e2357b 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -441,7 +441,8 @@ OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o
SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h
-TESTPROGS = seek \
+TESTPROGS = noproxy \
+ seek \
srtp \
url \
diff --git a/libavformat/http.c b/libavformat/http.c
index 0700eac815..59460005d3 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -120,10 +120,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 */
@@ -132,6 +128,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 d1bbf33603..4d56388312 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -390,4 +390,6 @@ AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precissi
*/
void ff_generate_avci_extradata(AVStream *st);
+int ff_http_match_no_proxy(const char *no_proxy, const char *hostname);
+
#endif /* AVFORMAT_INTERNAL_H */
diff --git a/libavformat/noproxy-test.c b/libavformat/noproxy-test.c
new file mode 100644
index 0000000000..a156620271
--- /dev/null
+++ b/libavformat/noproxy-test.c
@@ -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;
+}
diff --git a/libavformat/tls.c b/libavformat/tls.c
index 38dd70c9df..2c85d1dedc 100644
--- a/libavformat/tls.c
+++ b/libavformat/tls.c
@@ -172,10 +172,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, path, sizeof(path), uri);
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);
}
+ 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 9bd2d0c34b..3df8c51ddd 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -4379,3 +4379,57 @@ void ff_generate_avci_extradata(AVStream *st)
memcpy(st->codec->extradata, data, 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;
+}
diff --git a/libavformat/version.h b/libavformat/version.h
index 2136e3f415..082ab9911f 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -31,7 +31,7 @@
#define LIBAVFORMAT_VERSION_MAJOR 54
#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, \
LIBAVFORMAT_VERSION_MINOR, \
diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak
index 20bc31999f..8332246949 100644
--- a/tests/fate/libavformat.mak
+++ b/tests/fate/libavformat.mak
@@ -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-srtp: libavformat/srtp-test$(EXESUF)
fate-srtp: CMD = run libavformat/srtp-test
diff --git a/tests/ref/fate/noproxy b/tests/ref/fate/noproxy
new file mode 100644
index 0000000000..7707609d0f
--- /dev/null
+++ b/tests/ref/fate/noproxy
@@ -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