summaryrefslogtreecommitdiff
path: root/lib/urlapi.c
diff options
context:
space:
mode:
authorStefan Eissing <stefan@eissing.org>2023-04-26 12:38:22 +0200
committerDaniel Stenberg <daniel@haxx.se>2023-04-26 23:24:46 +0200
commitacd82c8bfd743d0f743a1c1296890738832ac83e (patch)
treefc4da775326efd7562f6217f41929b703902431c /lib/urlapi.c
parent21575b26fe33099e087b8beaac9bc43fa8597874 (diff)
downloadcurl-acd82c8bfd743d0f743a1c1296890738832ac83e.tar.gz
tests/http: more tests with specific clients
- Makefile support for building test specific clients in tests/http/clients - auto-make of clients when invoking pytest - added test_09_02 for server PUSH_PROMISEs using clients/h2-serverpush - added test_02_21 for lib based downloads and pausing/unpausing transfers curl url parser: - added internal method `curl_url_set_authority()` for setting the authority part of a url (used for PUSH_PROMISE) http2: - made logging of PUSH_PROMISE handling nicer Placing python test requirements in requirements.txt files - separate files to base test suite and http tests since use and module lists differ - using the files in the gh workflows websocket test cases, fixes for we and bufq - bufq: account for spare chunks in space calculation - bufq: reset chunks that are skipped empty - ws: correctly encode frames with 126 bytes payload - ws: update frame meta information on first call of collect callback that fills user buffer - test client ws-data: some test/reporting improvements Closes #11006
Diffstat (limited to 'lib/urlapi.c')
-rw-r--r--lib/urlapi.c116
1 files changed, 75 insertions, 41 deletions
diff --git a/lib/urlapi.c b/lib/urlapi.c
index 15e31ec6d..bdbe6c8a7 100644
--- a/lib/urlapi.c
+++ b/lib/urlapi.c
@@ -432,6 +432,7 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
DEBUGASSERT(login);
+ *offset = 0;
ptr = memchr(login, '@', len);
if(!ptr)
goto out;
@@ -462,14 +463,17 @@ static CURLUcode parse_hostname_login(struct Curl_URL *u,
result = CURLUE_USER_NOT_ALLOWED;
goto out;
}
+ free(u->user);
u->user = userp;
}
if(passwdp) {
+ free(u->password);
u->password = passwdp;
}
if(optionsp) {
+ free(u->options);
u->options = optionsp;
}
@@ -543,6 +547,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
u->portnum = port;
/* generate a new port number string to get rid of leading zeroes etc */
+ free(u->port);
u->port = aprintf("%ld", port);
if(!u->port)
return CURLUE_OUT_OF_MEMORY;
@@ -763,6 +768,75 @@ static CURLUcode urldecode_host(struct dynbuf *host)
return CURLUE_OK;
}
+static CURLUcode parse_authority(struct Curl_URL *u,
+ const char *auth, size_t authlen,
+ unsigned int flags,
+ struct dynbuf *host,
+ bool has_scheme)
+{
+ size_t offset;
+ CURLUcode result;
+
+ /*
+ * Parse the login details and strip them out of the host name.
+ */
+ result = parse_hostname_login(u, auth, authlen, flags, &offset);
+ if(result)
+ goto out;
+
+ if(Curl_dyn_addn(host, auth + offset, authlen - offset)) {
+ result = CURLUE_OUT_OF_MEMORY;
+ goto out;
+ }
+
+ result = Curl_parse_port(u, host, has_scheme);
+ if(result)
+ goto out;
+
+ switch(ipv4_normalize(host)) {
+ case HOST_IPV4:
+ break;
+ case HOST_IPV6:
+ result = ipv6_parse(u, Curl_dyn_ptr(host), Curl_dyn_len(host));
+ break;
+ case HOST_NAME:
+ result = urldecode_host(host);
+ if(!result)
+ result = hostname_check(u, Curl_dyn_ptr(host), Curl_dyn_len(host));
+ break;
+ case HOST_ERROR:
+ result = CURLUE_OUT_OF_MEMORY;
+ break;
+ case HOST_BAD:
+ default:
+ result = CURLUE_BAD_HOSTNAME; /* Bad IPv4 address even */
+ break;
+ }
+
+out:
+ return result;
+}
+
+CURLUcode curl_url_set_authority(CURLU *u, const char *authority,
+ unsigned int flags)
+{
+ CURLUcode result;
+ struct dynbuf host;
+
+ DEBUGASSERT(authority);
+ Curl_dyn_init(&host, CURL_MAX_INPUT_LENGTH);
+
+ result = parse_authority(u, authority, strlen(authority), flags,
+ &host, !!u->scheme);
+ if(result)
+ Curl_dyn_free(&host);
+ else {
+ free(u->host);
+ u->host = Curl_dyn_ptr(&host);
+ }
+ return result;
+}
+
/*
* "Remove Dot Segments"
* https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4
@@ -1091,48 +1165,8 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
/* this pathlen also contains the query and the fragment */
pathlen = urllen - (path - url);
if(hostlen) {
- /* number of bytes into the string the host name starts: */
- size_t offset = 0;
- /*
- * Parse the login details and strip them out of the host name.
- */
- result = parse_hostname_login(u, hostp, hostlen, flags, &offset);
- if(!result) {
- hostp += offset;
- hostlen -= offset;
- if(Curl_dyn_addn(&host, hostp, hostlen))
- result = CURLUE_OUT_OF_MEMORY;
- else
- result = Curl_parse_port(u, &host, schemelen);
- }
- if(!result) {
- int norm = ipv4_normalize(&host);
- switch(norm) {
- case HOST_IPV4:
- break;
-
- case HOST_IPV6:
- result = ipv6_parse(u, Curl_dyn_ptr(&host), Curl_dyn_len(&host));
- break;
-
- case HOST_NAME:
- result = urldecode_host(&host);
- if(!result)
- result = hostname_check(u, Curl_dyn_ptr(&host),
- Curl_dyn_len(&host));
- break;
-
- case HOST_ERROR:
- result = CURLUE_OUT_OF_MEMORY;
- break;
-
- case HOST_BAD:
- default:
- result = CURLUE_BAD_HOSTNAME; /* Bad IPv4 address even */
- break;
- }
- }
+ result = parse_authority(u, hostp, hostlen, flags, &host, schemelen);
if(result)
goto fail;