net: use proxy options struct in the stream config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
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);