Unverified Commit fe41e582 by Edward Thomson Committed by GitHub

Merge pull request #5741 from libgit2/ethomson/ipv6

Handle ipv6 addresses
parents 1c3f29a9 27301cd0
......@@ -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(
......
......@@ -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)
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment