Remove members of `struct urlpieces` that now live in peers/creds.
Change all remaining uses of those urlpieces.
When comparing schemes, use the protocol constants.
Closes #22171
return CURLE_OUT_OF_MEMORY;
}
- if(curl_strequal("http", data->state.up.scheme)) {
+ if(data->state.origin->scheme == &Curl_scheme_http) {
/* when getting HTTP, we do not want the userinfo the URL */
uc = curl_url_set(h, CURLUPART_USER, NULL, 0);
if(uc) {
if(result)
return result;
- if(curl_strequal("ftp", data->state.up.scheme) &&
+ if((data->state.origin->scheme == &Curl_scheme_ftp) &&
data->set.proxy_transfer_mode) {
/* when doing ftp, append ;type=<a|i> if not present */
size_t len = strlen(path);
return result;
if(udp_tunnel)
- infof(data, "Establishing %s proxy UDP tunnel to %s:%s",
+ infof(data, "Establishing %s proxy UDP tunnel to %s:%u",
(ver == PROXY_HTTP_V2) ? "HTTP/2" :
(ver == PROXY_HTTP_V3) ? "HTTP/3" : "HTTP",
- data->state.up.hostname, data->state.up.port);
+ dest->user_hostname, dest->port);
else
infof(data, "Establishing %s proxy tunnel to %s",
(ver == PROXY_HTTP_V2) ? "HTTP/2" :
if(!data ||
!data->state.up.path ||
data->state.up.path[0] != '/' ||
- !curl_strnequal("LDAP", data->state.up.scheme, 4))
+ ((data->state.origin->scheme != &Curl_scheme_ldap) &&
+ (data->state.origin->scheme != &Curl_scheme_ldaps)))
return LDAP_INVALID_SYNTAX;
ludp->lud_scope = LDAP_SCOPE_BASE;
static CURLcode oldap_url_parse(struct Curl_easy *data, LDAPURLDesc **ludp)
{
CURLcode result = CURLE_OK;
- int rc = LDAP_URL_ERR_BADURL;
+ int rc;
static const char * const url_errs[] = {
"success",
"out of memory",
};
*ludp = NULL;
- if(!data->state.up.user && !data->state.up.password &&
- !data->state.up.options)
+ /* `ldap_url_parse() seems to be terrible with urls
+ * that have user/pass/options in it. So when we have options or
+ * creds from the url, fail without calling the function.
+ * Yes, this is super-weird code and I do not like it. */
+ if((data->state.creds && (data->state.creds->source == CREDS_URL)) ||
+ data->state.up.options)
+ rc = LDAP_URL_ERR_BADURL;
+ else
rc = ldap_url_parse(Curl_bufref_ptr(&data->state.url), ludp);
+
if(rc != LDAP_URL_SUCCESS) {
const char *msg = "url parsing problem";
if(result)
goto out;
- li->proto = ldap_pvt_url_scheme2proto(data->state.up.scheme);
+ li->proto = ldap_pvt_url_scheme2proto(data->state.origin->scheme->name);
/* Initialize the SASL storage */
Curl_sasl_init(&li->sasl, data, &saslldap);
if(result)
goto out;
- hosturl = curl_maprintf("%s://%s:%d",
+ hosturl = curl_maprintf("%s://%s:%u",
conn->scheme->name,
- (data->state.up.hostname[0] == '[') ?
- data->state.up.hostname : conn->origin->hostname,
+ conn->origin->ipv6 ?
+ conn->origin->user_hostname :
+ conn->origin->hostname,
conn->origin->port);
if(!hosturl) {
result = CURLE_OUT_OF_MEMORY;
#include "peer.h"
#include "urldata.h"
#include "url.h"
+#include "urlapi-int.h"
#include "vtls/vtls.h"
struct peer_parse {
CURLcode Curl_peer_from_url(CURLU *uh, struct Curl_easy *data,
uint16_t port_override,
uint32_t scopeid_override,
- struct urlpieces *up,
struct Curl_peer **ppeer)
{
struct peer_parse pp;
- char *zoneid = NULL;
+ char *zoneid = NULL, *scheme = NULL, *hostname = NULL;
CURLUcode uc;
CURLcode result;
Curl_peer_unlink(ppeer);
memset(&pp, 0, sizeof(pp));
- curlx_safefree(up->scheme);
- uc = curl_url_get(uh, CURLUPART_SCHEME, &up->scheme, 0);
+ uc = curl_url_get(uh, CURLUPART_SCHEME, &scheme, 0);
if(uc)
return Curl_uc_to_curlcode(uc);
- pp.scheme = Curl_get_scheme(up->scheme);
+ pp.scheme = Curl_get_scheme(scheme);
if(!pp.scheme) {
- failf(data, "Protocol \"%s\" not supported%s", up->scheme,
+ failf(data, "Protocol \"%s\" not supported%s", scheme,
data->state.this_is_a_follow ? " (in redirect)" : "");
result = CURLE_UNSUPPORTED_PROTOCOL;
goto out;
}
- curlx_safefree(up->hostname);
- uc = curl_url_get(uh, CURLUPART_HOST, &up->hostname, 0);
+ uc = curl_url_get(uh, CURLUPART_HOST, &hostname, 0);
if(uc) {
if((uc == CURLUE_NO_HOST) && (pp.scheme->flags & PROTOPT_NONETWORK))
; /* acceptable */
goto out;
}
}
- else if(strlen(up->hostname) > MAX_URL_LEN) {
+ else if(strlen(hostname) > MAX_URL_LEN) {
failf(data, "Too long hostname (maximum is %d)", MAX_URL_LEN);
result = CURLE_URL_MALFORMAT;
goto out;
}
- pp.host_user.str = up->hostname ? up->hostname : "";
+ pp.host_user.str = hostname ? hostname : "";
pp.host_user.len = strlen(pp.host_user.str);
if(pp.host_user.len) {
result = peer_parse_host(data, &pp, FALSE);
else
pp.host = pp.host_user;
- curlx_safefree(up->port);
if(port_override) {
/* if set, we use this instead of the port possibly given in the URL */
char portbuf[16];
pp.port = port_override;
}
else {
- uc = curl_url_get(uh, CURLUPART_PORT, &up->port, CURLU_DEFAULT_PORT);
+ uc = Curl_url_get_port(uh, &pp.port);
if(uc) {
if(uc == CURLUE_OUT_OF_MEMORY) {
result = CURLE_OUT_OF_MEMORY;
}
/* no port ok when not a network scheme */
}
- else {
- const char *p = up->port;
- curl_off_t offt;
- if(curlx_str_number(&p, &offt, 0xffff))
- return CURLE_URL_MALFORMAT;
- pp.port = (uint16_t)offt;
- }
}
if(scopeid_override)
out:
peer_parse_clear(&pp);
+ curlx_free(scheme);
+ curlx_free(hostname);
curlx_free(zoneid);
return result;
}
***************************************************************************/
struct Curl_scheme;
-struct urlpieces;
/* if peer hostname starts with this, the peer is a unix domain socket
* path, e.g. the remainder after 'localhost'. */
CURLcode Curl_peer_from_url(CURLU *uh, struct Curl_easy *data,
uint16_t port_override,
uint32_t scopeid_override,
- struct urlpieces *up,
struct Curl_peer **ppeer);
CURLcode Curl_peer_from_connect_to(struct Curl_easy *data,
static void up_free(struct Curl_easy *data)
{
struct urlpieces *up = &data->state.up;
- curlx_safefree(up->scheme);
- curlx_safefree(up->hostname);
- curlx_safefree(up->port);
- curlx_safefree(up->user);
- curlx_safefree(up->password);
curlx_safefree(up->options);
curlx_safefree(up->path);
curlx_safefree(up->query);
CURLUcode uc;
CURLcode result;
- curlx_safefree(data->state.up.scheme);
uc = curl_url_set(uh, CURLUPART_SCHEME, "https", 0);
if(uc)
return Curl_uc_to_curlcode(uc);
Curl_bufref_set(&data->state.url, url, 0, curl_free);
result = Curl_peer_from_url(uh, data, port_override, scope_id,
- &data->state.up, &data->state.origin);
+ &data->state.origin);
if(result)
return result;
infof(data, "Switched from HTTP to HTTPS due to HSTS => %s", url);
/* Extract credentials from the URL only if there are none OR
* if no CURLOPT_USER was set. */
if(!newcreds || !Curl_creds_has_user(newcreds)) {
+ char *user = NULL;
+ char *passwd = NULL;
char *udecoded = NULL;
char *pdecoded = NULL;
CURLUcode uc;
- uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0);
+ uc = curl_url_get(uh, CURLUPART_USER, &user, 0);
if(uc && (uc != CURLUE_NO_USER))
result = Curl_uc_to_curlcode(uc);
if(!result) {
- uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
+ uc = curl_url_get(uh, CURLUPART_PASSWORD, &passwd, 0);
if(uc && (uc != CURLUE_NO_PASSWORD))
result = Curl_uc_to_curlcode(uc);
}
- if(!result && data->state.up.user) {
- result = Curl_urldecode(data->state.up.user, 0, &udecoded, NULL,
+ if(!result && user) {
+ result = Curl_urldecode(user, 0, &udecoded, NULL,
(data->state.origin->scheme->flags &
PROTOPT_USERPWDCTRL) ?
REJECT_ZERO : REJECT_CTRL);
}
- if(!result && data->state.up.password) {
- result = Curl_urldecode(data->state.up.password, 0, &pdecoded, NULL,
+ if(!result && passwd) {
+ result = Curl_urldecode(passwd, 0, &pdecoded, NULL,
(data->state.origin->scheme->flags &
PROTOPT_USERPWDCTRL) ?
REJECT_ZERO : REJECT_CTRL);
curlx_free(udecoded);
curlx_free(pdecoded);
+ curlx_free(passwd);
+ curlx_free(user);
if(result) {
failf(data, "error extracting credentials from URL");
goto out;
/* `uh` is now as the connection should use it, probably. */
result = Curl_peer_from_url(uh, data, port_override, scope_id,
- &data->state.up, &data->state.origin);
+ &data->state.origin);
if(result)
goto out;
/* The origin might get changed when HSTS applies */
bool Curl_url_same_origin(CURLU *base, CURLU *href);
+CURLUcode Curl_url_get_port(CURLU *u, uint16_t *pport);
+
#endif /* HEADER_CURL_URLAPI_INT_H */
return FALSE;
return TRUE;
}
+
+CURLUcode Curl_url_get_port(CURLU *u, uint16_t *pport)
+{
+ if(u->port_present) {
+ *pport = u->portnum;
+ return CURLUE_OK;
+ }
+ else if(u->scheme) {
+ const struct Curl_scheme *s = Curl_get_scheme(u->scheme);
+ if(s && s->defport) {
+ *pport = s->defport;
+ return CURLUE_OK;
+ }
+ }
+ *pport = 0;
+ return CURLUE_NO_PORT;
+}
/* individual pieces of the URL */
struct urlpieces {
- char *scheme;
- char *hostname;
- char *port;
- char *user;
- char *password;
char *options;
char *path;
char *query;
}
rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_HOST,
- (data->state.up.hostname[0] == '[') ?
- data->state.up.hostname : conn->origin->hostname);
+ conn->origin->ipv6 ?
+ conn->origin->user_hostname : conn->origin->hostname);
if(rc != SSH_OK) {
failf(data, "Could not set remote host");