Commit b373e9a6ba11b3b82ad6c74996488176d22920a0

Carlos Martín Nieto 2015-09-21T22:38:50

net: use proxy options struct in the stream config

diff --git a/include/git2/sys/stream.h b/include/git2/sys/stream.h
index 2b4ff7f..eeeb68d 100644
--- a/include/git2/sys/stream.h
+++ b/include/git2/sys/stream.h
@@ -9,6 +9,7 @@
 
 #include "git2/common.h"
 #include "git2/types.h"
+#include "git2/proxy.h"
 
 GIT_BEGIN_DECL
 
@@ -32,7 +33,7 @@ typedef struct git_stream {
 	int proxy_support;
 	int (*connect)(struct git_stream *);
 	int (*certificate)(git_cert **, struct git_stream *);
-	int (*set_proxy)(struct git_stream *, const char *proxy_url);
+	int (*set_proxy)(struct git_stream *, const git_proxy_options *proxy_opts);
 	ssize_t (*read)(struct git_stream *, void *, size_t);
 	ssize_t (*write)(struct git_stream *, const char *, size_t, int);
 	int (*close)(struct git_stream *);
diff --git a/src/curl_stream.c b/src/curl_stream.c
index 9963d94..f48dd22 100644
--- a/src/curl_stream.c
+++ b/src/curl_stream.c
@@ -13,6 +13,7 @@
 #include "git2/transport.h"
 #include "buffer.h"
 #include "vector.h"
+#include "proxy.h"
 
 typedef struct {
 	git_stream parent;
@@ -21,6 +22,7 @@ typedef struct {
 	char curl_error[CURL_ERROR_SIZE + 1];
 	git_cert_x509 cert_info;
 	git_strarray cert_info_strings;
+	git_proxy_options proxy;
 } curl_stream;
 
 static int seterr_curl(curl_stream *s)
@@ -95,12 +97,16 @@ static int curls_certificate(git_cert **out, git_stream *stream)
 	return 0;
 }
 
-static int curls_set_proxy(git_stream *stream, const char *proxy_url)
+static int curls_set_proxy(git_stream *stream, const git_proxy_options *proxy_opts)
 {
+	int error;
 	CURLcode res;
 	curl_stream *s = (curl_stream *) stream;
 
-	if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, proxy_url)) != CURLE_OK)
+	if ((error = git_proxy_options_dup(&s->proxy, proxy_opts)) < 0)
+		return error;
+
+	if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, s->proxy.url)) != CURLE_OK)
 		return seterr_curl(s);
 
 	return 0;
diff --git a/src/openssl_stream.c b/src/openssl_stream.c
index a65f558..edea8fe 100644
--- a/src/openssl_stream.c
+++ b/src/openssl_stream.c
@@ -496,11 +496,11 @@ int openssl_certificate(git_cert **out, git_stream *stream)
 	return 0;
 }
 
-static int openssl_set_proxy(git_stream *stream, const char *proxy_url)
+static int openssl_set_proxy(git_stream *stream, const git_proxy_options *proxy_opts)
 {
 	openssl_stream *st = (openssl_stream *) stream;
 
-	return git_stream_set_proxy(st->io, proxy_url);
+	return git_stream_set_proxy(st->io, proxy_opts);
 }
 
 ssize_t openssl_write(git_stream *stream, const char *data, size_t len, int flags)
diff --git a/src/stream.h b/src/stream.h
index 4692c71..d354775 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -35,14 +35,14 @@ GIT_INLINE(int) git_stream_supports_proxy(git_stream *st)
 	return st->proxy_support;
 }
 
-GIT_INLINE(int) git_stream_set_proxy(git_stream *st, const char *proxy_url)
+GIT_INLINE(int) git_stream_set_proxy(git_stream *st, const git_proxy_options *proxy_opts)
 {
 	if (!st->proxy_support) {
 		giterr_set(GITERR_INVALID, "proxy not supported on this stream");
 		return -1;
 	}
 
-	return st->set_proxy(st, proxy_url);
+	return st->set_proxy(st, proxy_opts);
 }
 
 GIT_INLINE(ssize_t) git_stream_read(git_stream *st, void *data, size_t len)
diff --git a/src/transports/http.c b/src/transports/http.c
index 88b124b..03a16da 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -555,10 +555,40 @@ static int write_chunk(git_stream *io, const char *buffer, size_t len)
 	return 0;
 }
 
+static int apply_proxy_config(http_subtransport *t)
+{
+	int error;
+	git_proxy_t proxy_type;
+
+	if (!git_stream_supports_proxy(t->io))
+		return 0;
+
+	proxy_type = t->owner->proxy.type;
+
+	if (proxy_type == GIT_PROXY_NONE)
+		return 0;
+
+	if (proxy_type == GIT_PROXY_AUTO) {
+		char *url;
+		git_proxy_options opts = GIT_PROXY_OPTIONS_INIT;
+
+		if ((error = git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &url)) < 0)
+			return error;
+
+		opts.type = GIT_PROXY_HTTP;
+		opts.url = url;
+		error = git_stream_set_proxy(t->io, &opts);
+		git__free(url);
+
+		return error;
+	}
+
+	return git_stream_set_proxy(t->io, &t->owner->proxy);
+}
+
 static int http_connect(http_subtransport *t)
 {
 	int error;
-	char *proxy_url;
 
 	if (t->connected &&
 		http_should_keep_alive(&t->parser) &&
@@ -586,14 +616,7 @@ static int http_connect(http_subtransport *t)
 
 	GITERR_CHECK_VERSION(t->io, GIT_STREAM_VERSION, "git_stream");
 
-	if (git_stream_supports_proxy(t->io) &&
-	    !git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url)) {
-		error = git_stream_set_proxy(t->io, proxy_url);
-		git__free(proxy_url);
-
-		if (error < 0)
-			return error;
-	}
+	apply_proxy_config(t);
 
 	error = git_stream_connect(t->io);