diff --git a/include/git2/sys/stream.h b/include/git2/sys/stream.h index c22179fab..55a714bbb 100644 --- a/include/git2/sys/stream.h +++ b/include/git2/sys/stream.h @@ -29,8 +29,10 @@ typedef struct git_stream { int version; int encrypted; + 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); 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 fb7a61341..51b7fa7a4 100644 --- a/src/curl_stream.c +++ b/src/curl_stream.c @@ -64,6 +64,17 @@ static int curls_certificate(git_cert **out, git_stream *stream) return 0; } +static int curls_set_proxy(git_stream *stream, const char *proxy_url) +{ + CURLcode res; + curl_stream *s = (curl_stream *) stream; + + if ((res = curl_easy_setopt(s->handle, CURLOPT_PROXY, proxy_url)) != CURLE_OK) + return seterr_curl(s); + + return 0; +} + static int wait_for(curl_socket_t fd, bool reading) { int ret; @@ -185,12 +196,16 @@ int git_curl_stream_new(git_stream **out, const char *host, const char *port, in curl_easy_setopt(handle, CURLOPT_CONNECT_ONLY, 1); curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 1); curl_easy_setopt(handle, CURLOPT_CERTINFO, 1); + curl_easy_setopt(handle, CURLOPT_HTTPPROXYTUNNEL, 1); + /* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); */ st->parent.version = GIT_STREAM_VERSION; st->parent.encrypted = encrypted; + st->parent.proxy_support = 1; st->parent.connect = curls_connect; st->parent.certificate = curls_certificate; + st->parent.set_proxy = curls_set_proxy; st->parent.read = curls_read; st->parent.write = curls_write; st->parent.close = curls_close; diff --git a/src/stream.h b/src/stream.h index d810e704d..43fcc3045 100644 --- a/src/stream.h +++ b/src/stream.h @@ -30,6 +30,21 @@ GIT_INLINE(int) git_stream_certificate(git_cert **out, git_stream *st) return st->certificate(out, st); } +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) +{ + if (!st->proxy_support) { + giterr_set(GITERR_INVALID, "proxy not supported on this stream"); + return -1; + } + + return st->set_proxy(st, proxy_url); +} + GIT_INLINE(ssize_t) git_stream_read(git_stream *st, void *data, size_t len) { return st->read(st, data, len);