Commit ea59f659 by Ben Straub

Deploy gitno_connection_data into transport (winhttp)

...and have that call manage replaced memory in the output structure.
parent 83fbd368
...@@ -579,23 +579,29 @@ static const char *prefix_https = "https://"; ...@@ -579,23 +579,29 @@ static const char *prefix_https = "https://";
int gitno_connection_data_from_url( int gitno_connection_data_from_url(
gitno_connection_data *data, gitno_connection_data *data,
const char *url, const char *url,
const char *service_suffix, const char *service_suffix)
const char *original_host,
bool original_use_ssl)
{ {
int error = 0; int error = -1;
const char *default_port = NULL; const char *default_port = NULL;
char *original_host = NULL;
bool original_use_ssl;
/* service_suffix is optional */ /* service_suffix is optional */
assert(data && url); assert(data && url);
/* Save these for comparison later */
if (data->host)
original_host = git__strdup(data->host);
original_use_ssl = data->use_ssl;
gitno_connection_data_free_ptrs(data);
if (!git__prefixcmp(url, prefix_http)) { if (!git__prefixcmp(url, prefix_http)) {
url = url + strlen(prefix_http); url = url + strlen(prefix_http);
default_port = "80"; default_port = "80";
if (data->use_ssl) { if (data->use_ssl) {
giterr_set(GITERR_NET, "Redirect from HTTPS to HTTP is not allowed"); giterr_set(GITERR_NET, "Redirect from HTTPS to HTTP is not allowed");
return -1; goto cleanup;
} }
} }
...@@ -607,7 +613,7 @@ int gitno_connection_data_from_url( ...@@ -607,7 +613,7 @@ int gitno_connection_data_from_url(
if (!default_port) { if (!default_port) {
giterr_set(GITERR_NET, "Unrecognized URL prefix"); giterr_set(GITERR_NET, "Unrecognized URL prefix");
return -1; goto cleanup;
} }
error = gitno_extract_url_parts( error = gitno_extract_url_parts(
...@@ -620,7 +626,7 @@ int gitno_connection_data_from_url( ...@@ -620,7 +626,7 @@ int gitno_connection_data_from_url(
size_t suffixlen = service_suffix ? strlen(service_suffix) : 0; size_t suffixlen = service_suffix ? strlen(service_suffix) : 0;
if (suffixlen && if (suffixlen &&
!memcmp(path + pathlen - suffixlen, service_suffix, suffixlen)) !memcmp(path + pathlen - suffixlen, service_suffix, suffixlen))
data->path = git__strndup(path, pathlen - suffixlen); data->path = git__strndup(path, pathlen - suffixlen);
else else
data->path = git__strdup(path); data->path = git__strdup(path);
...@@ -636,6 +642,8 @@ int gitno_connection_data_from_url( ...@@ -636,6 +642,8 @@ int gitno_connection_data_from_url(
} }
} }
cleanup:
if (original_host) git__free(original_host);
return error; return error;
} }
......
...@@ -84,9 +84,7 @@ typedef struct gitno_connection_data { ...@@ -84,9 +84,7 @@ typedef struct gitno_connection_data {
int gitno_connection_data_from_url( int gitno_connection_data_from_url(
gitno_connection_data *data, gitno_connection_data *data,
const char *url, const char *url,
const char *service_suffix, const char *service_suffix);
const char *original_host,
bool original_use_ssl);
/* This frees all the pointers IN the struct, but not the struct itself. */ /* This frees all the pointers IN the struct, but not the struct itself. */
void gitno_connection_data_free_ptrs(gitno_connection_data *data); void gitno_connection_data_free_ptrs(gitno_connection_data *data);
......
...@@ -73,17 +73,12 @@ typedef struct { ...@@ -73,17 +73,12 @@ typedef struct {
typedef struct { typedef struct {
git_smart_subtransport parent; git_smart_subtransport parent;
transport_smart *owner; transport_smart *owner;
char *path; gitno_connection_data connection_data;
char *host;
char *port;
char *user_from_url;
char *pass_from_url;
git_cred *cred; git_cred *cred;
git_cred *url_cred; git_cred *url_cred;
int auth_mechanism; int auth_mechanism;
HINTERNET session; HINTERNET session;
HINTERNET connection; HINTERNET connection;
unsigned use_ssl : 1;
} winhttp_subtransport; } winhttp_subtransport;
static int apply_basic_credential(HINTERNET request, git_cred *cred) static int apply_basic_credential(HINTERNET request, git_cred *cred)
...@@ -155,7 +150,7 @@ static int winhttp_stream_connect(winhttp_stream *s) ...@@ -155,7 +150,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS; unsigned long disable_redirects = WINHTTP_DISABLE_REDIRECTS;
/* Prepare URL */ /* Prepare URL */
git_buf_printf(&buf, "%s%s", t->path, s->service_url); git_buf_printf(&buf, "%s%s", t->connection_data.path, s->service_url);
if (git_buf_oom(&buf)) if (git_buf_oom(&buf))
return -1; return -1;
...@@ -188,7 +183,7 @@ static int winhttp_stream_connect(winhttp_stream *s) ...@@ -188,7 +183,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
NULL, NULL,
WINHTTP_NO_REFERER, WINHTTP_NO_REFERER,
types, types,
t->use_ssl ? WINHTTP_FLAG_SECURE : 0); t->connection_data.use_ssl ? WINHTTP_FLAG_SECURE : 0);
if (!s->request) { if (!s->request) {
giterr_set(GITERR_OS, "Failed to open request"); giterr_set(GITERR_OS, "Failed to open request");
...@@ -196,7 +191,7 @@ static int winhttp_stream_connect(winhttp_stream *s) ...@@ -196,7 +191,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
} }
/* Set proxy if necessary */ /* Set proxy if necessary */
if (git_remote__get_http_proxy(t->owner->owner, !!t->use_ssl, &proxy_url) < 0) if (git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url) < 0)
goto on_error; goto on_error;
if (proxy_url) { if (proxy_url) {
...@@ -285,7 +280,7 @@ static int winhttp_stream_connect(winhttp_stream *s) ...@@ -285,7 +280,7 @@ static int winhttp_stream_connect(winhttp_stream *s)
} }
/* If requested, disable certificate validation */ /* If requested, disable certificate validation */
if (t->use_ssl) { if (t->connection_data.use_ssl) {
int flags; int flags;
if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0) if (t->owner->parent.read_flags(&t->owner->parent, &flags) < 0)
...@@ -308,9 +303,9 @@ static int winhttp_stream_connect(winhttp_stream *s) ...@@ -308,9 +303,9 @@ static int winhttp_stream_connect(winhttp_stream *s)
/* If no other credentials have been applied and the URL has username and /* If no other credentials have been applied and the URL has username and
* password, use those */ * password, use those */
if (!t->cred && t->user_from_url && t->pass_from_url) { if (!t->cred && t->connection_data.user && t->connection_data.pass) {
if (!t->url_cred && if (!t->url_cred &&
git_cred_userpass_plaintext_new(&t->url_cred, t->user_from_url, t->pass_from_url) < 0) git_cred_userpass_plaintext_new(&t->url_cred, t->connection_data.user, t->connection_data.pass) < 0)
goto on_error; goto on_error;
if (apply_basic_credential(s->request, t->url_cred) < 0) if (apply_basic_credential(s->request, t->url_cred) < 0)
goto on_error; goto on_error;
...@@ -392,34 +387,6 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len) ...@@ -392,34 +387,6 @@ static int write_chunk(HINTERNET request, const char *buffer, size_t len)
return 0; return 0;
} }
static void free_connection_data(winhttp_subtransport *t)
{
if (t->host) {
git__free(t->host);
t->host = NULL;
}
if (t->port) {
git__free(t->port);
t->port = NULL;
}
if (t->user_from_url) {
git__free(t->user_from_url);
t->user_from_url = NULL;
}
if (t->pass_from_url) {
git__free(t->pass_from_url);
t->pass_from_url = NULL;
}
if (t->path) {
git__free(t->path);
t->path = NULL;
}
}
static int winhttp_connect( static int winhttp_connect(
winhttp_subtransport *t, winhttp_subtransport *t,
const char *url) const char *url)
...@@ -430,11 +397,11 @@ static int winhttp_connect( ...@@ -430,11 +397,11 @@ static int winhttp_connect(
const char *default_port = "80"; const char *default_port = "80";
/* Prepare port */ /* Prepare port */
if (git__strtol32(&port, t->port, NULL, 10) < 0) if (git__strtol32(&port, t->connection_data.port, NULL, 10) < 0)
return -1; return -1;
/* Prepare host */ /* Prepare host */
git_win32_path_from_c(host, t->host); git_win32_path_from_c(host, t->connection_data.host);
/* Establish session */ /* Establish session */
t->session = WinHttpOpen( t->session = WinHttpOpen(
...@@ -636,17 +603,8 @@ replay: ...@@ -636,17 +603,8 @@ replay:
if (!git__prefixcmp_icase(location8, prefix_https)) { if (!git__prefixcmp_icase(location8, prefix_https)) {
/* Upgrade to secure connection; disconnect and start over */ /* Upgrade to secure connection; disconnect and start over */
gitno_connection_data data = { 0 }; gitno_connection_data data = { 0 };
if (gitno_connection_data_from_url(&data, location8, s->service_url, t->host, t->use_ssl) < 0) { if (gitno_connection_data_from_url(&data, location8, s->service_url) < 0)
gitno_connection_data_free_ptrs(&data);
return -1; return -1;
}
free_connection_data(t);
t->host = data.host;
t->port = data.port;
t->path = data.path;
t->user_from_url = data.user;
t->pass_from_url = data.pass;
t->use_ssl = data.use_ssl;
winhttp_connect(t, location8); winhttp_connect(t, location8);
} }
...@@ -665,7 +623,8 @@ replay: ...@@ -665,7 +623,8 @@ replay:
if (allowed_types && if (allowed_types &&
(!t->cred || 0 == (t->cred->credtype & allowed_types))) { (!t->cred || 0 == (t->cred->credtype & allowed_types))) {
if (t->owner->cred_acquire_cb(&t->cred, t->owner->url, t->user_from_url, allowed_types, t->owner->cred_acquire_payload) < 0) if (t->owner->cred_acquire_cb(&t->cred, t->owner->url, t->connection_data.user, allowed_types,
t->owner->cred_acquire_payload) < 0)
return -1; return -1;
assert(t->cred); assert(t->cred);
...@@ -1048,22 +1007,10 @@ static int winhttp_action( ...@@ -1048,22 +1007,10 @@ static int winhttp_action(
winhttp_stream *s; winhttp_stream *s;
int ret = -1; int ret = -1;
if (!t->connection) { if (!t->connection)
gitno_connection_data data = { 0 }; if (gitno_connection_data_from_url(&t->connection_data, url, NULL) < 0 ||
if (gitno_connection_data_from_url(&data, url, NULL, NULL, false) < 0) { winhttp_connect(t, url) < 0)
gitno_connection_data_free_ptrs(&data);
return -1;
}
free_connection_data(t);
t->host = data.host;
t->port = data.port;
t->path = data.path;
t->user_from_url = data.user;
t->pass_from_url = data.pass;
t->use_ssl = data.use_ssl;
if (winhttp_connect(t, url) < 0)
return -1; return -1;
}
if (winhttp_stream_alloc(t, &s) < 0) if (winhttp_stream_alloc(t, &s) < 0)
return -1; return -1;
...@@ -1104,7 +1051,7 @@ static int winhttp_close(git_smart_subtransport *subtransport) ...@@ -1104,7 +1051,7 @@ static int winhttp_close(git_smart_subtransport *subtransport)
winhttp_subtransport *t = (winhttp_subtransport *)subtransport; winhttp_subtransport *t = (winhttp_subtransport *)subtransport;
int ret = 0; int ret = 0;
free_connection_data(t); gitno_connection_data_free_ptrs(&t->connection_data);
if (t->cred) { if (t->cred) {
t->cred->free(t->cred); t->cred->free(t->cred);
......
...@@ -88,7 +88,7 @@ void test_network_urlparse__user_pass_port(void) ...@@ -88,7 +88,7 @@ void test_network_urlparse__user_pass_port(void)
void test_network_urlparse__connection_data_http(void) void test_network_urlparse__connection_data_http(void)
{ {
cl_git_pass(gitno_connection_data_from_url(&conndata, cl_git_pass(gitno_connection_data_from_url(&conndata,
"http://example.com/foo/bar/baz", "bar/baz", NULL, false)); "http://example.com/foo/bar/baz", "bar/baz"));
cl_assert_equal_s(conndata.host, "example.com"); cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "80"); cl_assert_equal_s(conndata.port, "80");
cl_assert_equal_s(conndata.path, "/foo/"); cl_assert_equal_s(conndata.path, "/foo/");
...@@ -100,7 +100,7 @@ void test_network_urlparse__connection_data_http(void) ...@@ -100,7 +100,7 @@ void test_network_urlparse__connection_data_http(void)
void test_network_urlparse__connection_data_ssl(void) void test_network_urlparse__connection_data_ssl(void)
{ {
cl_git_pass(gitno_connection_data_from_url(&conndata, cl_git_pass(gitno_connection_data_from_url(&conndata,
"https://example.com/foo/bar/baz", "bar/baz", NULL, false)); "https://example.com/foo/bar/baz", "bar/baz"));
cl_assert_equal_s(conndata.host, "example.com"); cl_assert_equal_s(conndata.host, "example.com");
cl_assert_equal_s(conndata.port, "443"); cl_assert_equal_s(conndata.port, "443");
cl_assert_equal_s(conndata.path, "/foo/"); cl_assert_equal_s(conndata.path, "/foo/");
...@@ -111,14 +111,16 @@ void test_network_urlparse__connection_data_ssl(void) ...@@ -111,14 +111,16 @@ void test_network_urlparse__connection_data_ssl(void)
void test_network_urlparse__connection_data_cross_host_redirect(void) void test_network_urlparse__connection_data_cross_host_redirect(void)
{ {
conndata.host = git__strdup("bar.com");
cl_git_fail_with(gitno_connection_data_from_url(&conndata, cl_git_fail_with(gitno_connection_data_from_url(&conndata,
"https://foo.com/bar/baz", NULL, "bar.com", true), "https://foo.com/bar/baz", NULL),
-1); -1);
} }
void test_network_urlparse__connection_data_http_downgrade(void) void test_network_urlparse__connection_data_http_downgrade(void)
{ {
conndata.use_ssl = true;
cl_git_fail_with(gitno_connection_data_from_url(&conndata, cl_git_fail_with(gitno_connection_data_from_url(&conndata,
"http://foo.com/bar/baz", NULL, NULL, true), "http://foo.com/bar/baz", NULL),
-1); -1);
} }
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