diff options
| author | Edward Thomson <ethomson@edwardthomson.com> | 2020-12-23 12:32:58 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-23 12:32:58 +0000 |
| commit | fe41e5823986aff01054b7db4b869b2896ea4c30 (patch) | |
| tree | a0e5ca132d68d0216a9f8de824a9f7a865127e9b /src | |
| parent | 1c3f29a9e21e494d19fbe6e5f965fce8bd2b7d48 (diff) | |
| parent | 27301cd02676e8e1247f36ff5bbd3ee9c2579ee1 (diff) | |
| download | libgit2-fe41e5823986aff01054b7db4b869b2896ea4c30.tar.gz | |
Merge pull request #5741 from libgit2/ethomson/ipv6
Handle ipv6 addresses
Diffstat (limited to 'src')
| -rw-r--r-- | src/net.c | 7 | ||||
| -rw-r--r-- | src/net.h | 7 | ||||
| -rw-r--r-- | src/transports/httpclient.c | 40 | ||||
| -rw-r--r-- | src/transports/winhttp.c | 42 |
4 files changed, 68 insertions, 28 deletions
@@ -335,7 +335,7 @@ bool git_net_url_valid(git_net_url *url) return (url->host && url->port && url->path); } -int git_net_url_is_default_port(git_net_url *url) +bool git_net_url_is_default_port(git_net_url *url) { const char *default_port; @@ -345,6 +345,11 @@ int git_net_url_is_default_port(git_net_url *url) return false; } +bool git_net_url_is_ipv6(git_net_url *url) +{ + return (strchr(url->host, ':') != NULL); +} + void git_net_url_swap(git_net_url *a, git_net_url *b) { git_net_url tmp = GIT_NET_URL_INIT; @@ -33,8 +33,11 @@ extern int git_net_url_joinpath( /** Ensures that a URL is minimally valid (contains a host, port and path) */ extern bool git_net_url_valid(git_net_url *url); -/** Returns nonzero if the URL is on the default port. */ -extern int git_net_url_is_default_port(git_net_url *url); +/** Returns true if the URL is on the default port. */ +extern bool git_net_url_is_default_port(git_net_url *url); + +/** Returns true if the host portion of the URL is an ipv6 address. */ +extern bool git_net_url_is_ipv6(git_net_url *url); /* Applies a redirect to the URL with a git-aware service suffix. */ extern int git_net_url_apply_redirect( diff --git a/src/transports/httpclient.c b/src/transports/httpclient.c index d9cbf1783..d3975746b 100644 --- a/src/transports/httpclient.c +++ b/src/transports/httpclient.c @@ -631,6 +631,26 @@ GIT_INLINE(int) apply_proxy_credentials( request->proxy_credentials); } +static int puts_host_and_port(git_buf *buf, git_net_url *url, bool force_port) +{ + bool ipv6 = git_net_url_is_ipv6(url); + + if (ipv6) + git_buf_putc(buf, '['); + + git_buf_puts(buf, url->host); + + if (ipv6) + git_buf_putc(buf, ']'); + + if (force_port || !git_net_url_is_default_port(url)) { + git_buf_putc(buf, ':'); + git_buf_puts(buf, url->port); + } + + return git_buf_oom(buf) ? -1 : 0; +} + static int generate_connect_request( git_http_client *client, git_http_request *request) @@ -641,14 +661,17 @@ static int generate_connect_request( git_buf_clear(&client->request_msg); buf = &client->request_msg; - git_buf_printf(buf, "CONNECT %s:%s HTTP/1.1\r\n", - client->server.url.host, client->server.url.port); + git_buf_puts(buf, "CONNECT "); + puts_host_and_port(buf, &client->server.url, true); + git_buf_puts(buf, " HTTP/1.1\r\n"); git_buf_puts(buf, "User-Agent: "); git_http__user_agent(buf); git_buf_puts(buf, "\r\n"); - git_buf_printf(buf, "Host: %s\r\n", client->proxy.url.host); + git_buf_puts(buf, "Host: "); + puts_host_and_port(buf, &client->proxy.url, false); + git_buf_puts(buf, "\r\n"); if ((error = apply_proxy_credentials(buf, client, request) < 0)) return -1; @@ -687,11 +710,8 @@ static int generate_request( git_http__user_agent(buf); git_buf_puts(buf, "\r\n"); - git_buf_printf(buf, "Host: %s", request->url->host); - - if (!git_net_url_is_default_port(request->url)) - git_buf_printf(buf, ":%s", request->url->port); - + git_buf_puts(buf, "Host: "); + puts_host_and_port(buf, request->url, false); git_buf_puts(buf, "\r\n"); if (request->accept) @@ -902,7 +922,7 @@ static int proxy_connect( int error; if (!client->proxy_connected || !client->keepalive) { - git_trace(GIT_TRACE_DEBUG, "Connecting to proxy %s:%s", + git_trace(GIT_TRACE_DEBUG, "Connecting to proxy %s port %s", client->proxy.url.host, client->proxy.url.port); if ((error = server_create_stream(&client->proxy)) < 0 || @@ -1023,7 +1043,7 @@ static int http_client_connect( goto on_error; } - git_trace(GIT_TRACE_DEBUG, "Connecting to remote %s:%s", + git_trace(GIT_TRACE_DEBUG, "Connecting to remote %s port %s", client->server.url.host, client->server.url.port); if ((error = server_connect(client)) < 0) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index c82c788ae..54aacdba3 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -451,8 +451,14 @@ static int winhttp_stream_connect(winhttp_stream *s) git_buf_puts(&processed_url, t->proxy.url.scheme); git_buf_PUTS(&processed_url, "://"); + if (git_net_url_is_ipv6(&t->proxy.url)) + git_buf_putc(&processed_url, '['); + git_buf_puts(&processed_url, t->proxy.url.host); + if (git_net_url_is_ipv6(&t->proxy.url)) + git_buf_putc(&processed_url, ']'); + if (!git_net_url_is_default_port(&t->proxy.url)) git_buf_printf(&processed_url, ":%s", t->proxy.url.port); @@ -736,10 +742,11 @@ static void CALLBACK winhttp_status( static int winhttp_connect( winhttp_subtransport *t) { - wchar_t *wide_host; + wchar_t *wide_host = NULL; int32_t port; - wchar_t *wide_ua; - git_buf ua = GIT_BUF_INIT; + wchar_t *wide_ua = NULL; + git_buf ipv6 = GIT_BUF_INIT, ua = GIT_BUF_INIT; + const char *host; int error = -1; int default_timeout = TIMEOUT_INFINITE; int default_connect_timeout = DEFAULT_CONNECT_TIMEOUT; @@ -755,29 +762,33 @@ static int winhttp_connect( /* Prepare port */ if (git__strntol32(&port, t->server.url.port, strlen(t->server.url.port), NULL, 10) < 0) - return -1; + goto on_error; + + /* IPv6? Add braces around the host. */ + if (git_net_url_is_ipv6(&t->server.url)) { + if (git_buf_printf(&ipv6, "[%s]", t->server.url.host) < 0) + goto on_error; + + host = ipv6.ptr; + } else { + host = t->server.url.host; + } /* Prepare host */ - if (git__utf8_to_16_alloc(&wide_host, t->server.url.host) < 0) { + if (git__utf8_to_16_alloc(&wide_host, host) < 0) { git_error_set(GIT_ERROR_OS, "unable to convert host to wide characters"); - return -1; + goto on_error; } - if ((error = git_http__user_agent(&ua)) < 0) { - git__free(wide_host); - return error; - } + if (git_http__user_agent(&ua) < 0) + goto on_error; if (git__utf8_to_16_alloc(&wide_ua, git_buf_cstr(&ua)) < 0) { git_error_set(GIT_ERROR_OS, "unable to convert host to wide characters"); - git__free(wide_host); - git_buf_dispose(&ua); - return -1; + goto on_error; } - git_buf_dispose(&ua); - /* Establish session */ t->session = WinHttpOpen( wide_ua, @@ -836,6 +847,7 @@ on_error: if (error < 0) winhttp_close_connection(t); + git_buf_dispose(&ipv6); git__free(wide_host); git__free(wide_ua); |
