summaryrefslogtreecommitdiff
path: root/lib/url.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/url.c')
-rw-r--r--lib/url.c190
1 files changed, 106 insertions, 84 deletions
diff --git a/lib/url.c b/lib/url.c
index d21e4ad4f..3e3355d6b 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -449,6 +449,10 @@ CURLcode Curl_close(struct Curl_easy **datap)
Curl_safefree(data->state.aptr.host);
Curl_safefree(data->state.aptr.cookiehost);
Curl_safefree(data->state.aptr.rtsp_transport);
+ Curl_safefree(data->state.aptr.user);
+ Curl_safefree(data->state.aptr.passwd);
+ Curl_safefree(data->state.aptr.proxyuser);
+ Curl_safefree(data->state.aptr.proxypasswd);
#ifndef CURL_DISABLE_DOH
if(data->req.doh) {
@@ -1699,11 +1703,11 @@ static struct connectdata *allocate_conn(struct Curl_easy *data)
}
conn->bits.proxy_user_passwd =
- (data->set.str[STRING_PROXYUSERNAME]) ? TRUE : FALSE;
+ (data->state.aptr.proxyuser) ? TRUE : FALSE;
conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
#endif /* CURL_DISABLE_PROXY */
- conn->bits.user_passwd = (data->set.str[STRING_USERNAME]) ? TRUE : FALSE;
+ conn->bits.user_passwd = (data->state.aptr.user) ? TRUE : FALSE;
#ifndef CURL_DISABLE_FTP
conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
@@ -1970,36 +1974,50 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
if(result)
return result;
- /* we don't use the URL API's URL decoder option here since it rejects
- control codes and we want to allow them for some schemes in the user and
- password fields */
- uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0);
- if(!uc) {
- char *decoded;
- result = Curl_urldecode(NULL, data->state.up.user, 0, &decoded, NULL,
- conn->handler->flags&PROTOPT_USERPWDCTRL ?
- REJECT_ZERO : REJECT_CTRL);
- if(result)
- return result;
- conn->user = decoded;
- conn->bits.user_passwd = TRUE;
+ /*
+ * User name and password set with their own options override the
+ * credentials possibly set in the URL.
+ */
+ if(!data->state.aptr.user) {
+ /* we don't use the URL API's URL decoder option here since it rejects
+ control codes and we want to allow them for some schemes in the user
+ and password fields */
+ uc = curl_url_get(uh, CURLUPART_USER, &data->state.up.user, 0);
+ if(!uc) {
+ char *decoded;
+ result = Curl_urldecode(NULL, data->state.up.user, 0, &decoded, NULL,
+ conn->handler->flags&PROTOPT_USERPWDCTRL ?
+ REJECT_ZERO : REJECT_CTRL);
+ if(result)
+ return result;
+ conn->user = decoded;
+ conn->bits.user_passwd = TRUE;
+ result = Curl_setstropt(&data->state.aptr.user, decoded);
+ if(result)
+ return result;
+ }
+ else if(uc != CURLUE_NO_USER)
+ return Curl_uc_to_curlcode(uc);
}
- else if(uc != CURLUE_NO_USER)
- return Curl_uc_to_curlcode(uc);
- uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
- if(!uc) {
- char *decoded;
- result = Curl_urldecode(NULL, data->state.up.password, 0, &decoded, NULL,
- conn->handler->flags&PROTOPT_USERPWDCTRL ?
- REJECT_ZERO : REJECT_CTRL);
- if(result)
- return result;
- conn->passwd = decoded;
- conn->bits.user_passwd = TRUE;
+ if(!data->state.aptr.passwd) {
+ uc = curl_url_get(uh, CURLUPART_PASSWORD, &data->state.up.password, 0);
+ if(!uc) {
+ char *decoded;
+ result = Curl_urldecode(NULL, data->state.up.password, 0, &decoded, NULL,
+ conn->handler->flags&PROTOPT_USERPWDCTRL ?
+ REJECT_ZERO : REJECT_CTRL);
+ if(result)
+ return result;
+ conn->passwd = decoded;
+ conn->bits.user_passwd = TRUE;
+ result = Curl_setstropt(&data->state.aptr.passwd, decoded);
+ if(result)
+ return result;
+ }
+ else if(uc != CURLUE_NO_PASSWORD)
+ return Curl_uc_to_curlcode(uc);
}
- else if(uc != CURLUE_NO_PASSWORD)
- return Curl_uc_to_curlcode(uc);
uc = curl_url_get(uh, CURLUPART_OPTIONS, &data->state.up.options,
CURLU_URLDECODE);
@@ -2390,6 +2408,10 @@ static CURLcode parse_proxy(struct Curl_easy *data,
if(proxyuser || proxypasswd) {
Curl_safefree(proxyinfo->user);
proxyinfo->user = proxyuser;
+ result = Curl_setstropt(&data->state.aptr.proxyuser,
+ proxyuser);
+ if(result)
+ goto error;
Curl_safefree(proxyinfo->passwd);
if(!proxypasswd) {
proxypasswd = strdup("");
@@ -2399,6 +2421,10 @@ static CURLcode parse_proxy(struct Curl_easy *data,
}
}
proxyinfo->passwd = proxypasswd;
+ result = Curl_setstropt(&data->state.aptr.proxypasswd,
+ proxypasswd);
+ if(result)
+ goto error;
conn->bits.proxy_user_passwd = TRUE; /* enable it */
}
@@ -2455,18 +2481,26 @@ static CURLcode parse_proxy(struct Curl_easy *data,
static CURLcode parse_proxy_auth(struct Curl_easy *data,
struct connectdata *conn)
{
- const char *proxyuser = data->set.str[STRING_PROXYUSERNAME] ?
- data->set.str[STRING_PROXYUSERNAME] : "";
- const char *proxypasswd = data->set.str[STRING_PROXYPASSWORD] ?
- data->set.str[STRING_PROXYPASSWORD] : "";
+ const char *proxyuser = data->state.aptr.proxyuser ?
+ data->state.aptr.proxyuser : "";
+ const char *proxypasswd = data->state.aptr.proxypasswd ?
+ data->state.aptr.proxypasswd : "";
CURLcode result = CURLE_OK;
- if(proxyuser)
+ if(proxyuser) {
result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL,
REJECT_ZERO);
- if(!result && proxypasswd)
+ if(!result)
+ result = Curl_setstropt(&data->state.aptr.proxyuser,
+ conn->http_proxy.user);
+ }
+ if(!result && proxypasswd) {
result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd,
NULL, REJECT_ZERO);
+ if(!result)
+ result = Curl_setstropt(&data->state.aptr.proxypasswd,
+ conn->http_proxy.passwd);
+ }
return result;
}
@@ -2808,44 +2842,19 @@ static CURLcode parse_remote_port(struct Curl_easy *data,
* option or a .netrc file, if applicable.
*/
static CURLcode override_login(struct Curl_easy *data,
- struct connectdata *conn,
- char **userp, char **passwdp, char **optionsp)
+ struct connectdata *conn)
{
- bool user_changed = FALSE;
- bool passwd_changed = FALSE;
CURLUcode uc;
+ char **userp = &conn->user;
+ char **passwdp = &conn->passwd;
+ char **optionsp = &conn->options;
if(data->set.use_netrc == CURL_NETRC_REQUIRED && conn->bits.user_passwd) {
- /* ignore user+password in the URL */
- if(*userp) {
- Curl_safefree(*userp);
- user_changed = TRUE;
- }
- if(*passwdp) {
- Curl_safefree(*passwdp);
- passwd_changed = TRUE;
- }
+ Curl_safefree(*userp);
+ Curl_safefree(*passwdp);
conn->bits.user_passwd = FALSE; /* disable user+password */
}
- if(data->set.str[STRING_USERNAME]) {
- free(*userp);
- *userp = strdup(data->set.str[STRING_USERNAME]);
- if(!*userp)
- return CURLE_OUT_OF_MEMORY;
- conn->bits.user_passwd = TRUE; /* enable user+password */
- user_changed = TRUE;
- }
-
- if(data->set.str[STRING_PASSWORD]) {
- free(*passwdp);
- *passwdp = strdup(data->set.str[STRING_PASSWORD]);
- if(!*passwdp)
- return CURLE_OUT_OF_MEMORY;
- conn->bits.user_passwd = TRUE; /* enable user+password */
- passwd_changed = TRUE;
- }
-
if(data->set.str[STRING_OPTIONS]) {
free(*optionsp);
*optionsp = strdup(data->set.str[STRING_OPTIONS]);
@@ -2854,8 +2863,7 @@ static CURLcode override_login(struct Curl_easy *data,
}
conn->bits.netrc = FALSE;
- if(data->set.use_netrc != CURL_NETRC_IGNORED &&
- (!*userp || !**userp || !*passwdp || !**passwdp)) {
+ if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) {
bool netrc_user_changed = FALSE;
bool netrc_passwd_changed = FALSE;
int ret;
@@ -2865,8 +2873,8 @@ static CURLcode override_login(struct Curl_easy *data,
&netrc_user_changed, &netrc_passwd_changed,
data->set.str[STRING_NETRC_FILE]);
if(ret > 0) {
- infof(data, "Couldn't find host %s in the .netrc file; using defaults\n",
- conn->host.name);
+ infof(data, "Couldn't find host %s in the %s file; using defaults\n",
+ conn->host.name, data->set.str[STRING_NETRC_FILE]);
}
else if(ret < 0) {
return CURLE_OUT_OF_MEMORY;
@@ -2877,29 +2885,44 @@ static CURLcode override_login(struct Curl_easy *data,
different host or similar. */
conn->bits.netrc = TRUE;
conn->bits.user_passwd = TRUE; /* enable user+password */
-
- if(netrc_user_changed) {
- user_changed = TRUE;
- }
- if(netrc_passwd_changed) {
- passwd_changed = TRUE;
- }
}
}
/* for updated strings, we update them in the URL */
- if(user_changed) {
- uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp,
+ if(*userp) {
+ CURLcode result = Curl_setstropt(&data->state.aptr.user, *userp);
+ if(result)
+ return result;
+ }
+ if(data->state.aptr.user) {
+ uc = curl_url_set(data->state.uh, CURLUPART_USER, data->state.aptr.user,
CURLU_URLENCODE);
if(uc)
return Curl_uc_to_curlcode(uc);
+ if(!*userp) {
+ *userp = strdup(data->state.aptr.user);
+ if(!*userp)
+ return CURLE_OUT_OF_MEMORY;
+ }
}
- if(passwd_changed) {
- uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp,
- CURLU_URLENCODE);
+
+ if(*passwdp) {
+ CURLcode result = Curl_setstropt(&data->state.aptr.passwd, *passwdp);
+ if(result)
+ return result;
+ }
+ if(data->state.aptr.passwd) {
+ uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD,
+ data->state.aptr.passwd, CURLU_URLENCODE);
if(uc)
return Curl_uc_to_curlcode(uc);
+ if(!*passwdp) {
+ *passwdp = strdup(data->state.aptr.passwd);
+ if(!*passwdp)
+ return CURLE_OUT_OF_MEMORY;
+ }
}
+
return CURLE_OK;
}
@@ -3560,8 +3583,7 @@ static CURLcode create_conn(struct Curl_easy *data,
/* Check for overridden login details and set them accordingly so they
they are known when protocol->setup_connection is called! */
- result = override_login(data, conn, &conn->user, &conn->passwd,
- &conn->options);
+ result = override_login(data, conn);
if(result)
goto out;