setopt: add CURLOPT_CURLU

Allows an application to pass in a pre-parsed URL via a URL handle.

Closes #3227
This commit is contained in:
Jim Fuller 2018-11-01 19:16:15 +01:00 committed by Daniel Stenberg
parent 073332b525
commit 5c4fe0d826
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
16 changed files with 310 additions and 9 deletions

View file

@ -1204,6 +1204,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option,
return CURLE_BAD_FUNCTION_ARGUMENT;
data->set.low_speed_time = arg;
break;
case CURLOPT_CURLU:
/*
* pass CURLU to set URL
*/
data->set.uh = va_arg(param, CURLU *);
break;
case CURLOPT_URL:
/*
* The URL to fetch.

View file

@ -1353,17 +1353,30 @@ void Curl_init_CONNECT(struct Curl_easy *data)
CURLcode Curl_pretransfer(struct Curl_easy *data)
{
CURLcode result;
if(!data->change.url) {
if(!data->change.url && !data->set.uh) {
/* we can't do anything without URL */
failf(data, "No URL set!");
return CURLE_URL_MALFORMAT;
}
/* since the URL may have been redirected in a previous use of this handle */
if(data->change.url_alloc) {
/* the already set URL is allocated, free it first! */
Curl_safefree(data->change.url);
data->change.url_alloc = FALSE;
}
if(!data->change.url && data->set.uh) {
CURLUcode uc;
uc = curl_url_get(data->set.uh,
CURLUPART_URL, &data->set.str[STRING_SET_URL], 0);
if(uc) {
failf(data, "No URL set!");
return CURLE_URL_MALFORMAT;
}
}
data->change.url = data->set.str[STRING_SET_URL];
/* Init the SSL session ID cache here. We do it here since we want to do it

View file

@ -2026,7 +2026,13 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
Curl_up_free(data); /* cleanup previous leftovers first */
/* parse the URL */
uh = data->state.uh = curl_url();
if(data->set.uh) {
uh = data->set.uh;
}
else {
uh = data->state.uh = curl_url();
}
if(!uh)
return CURLE_OUT_OF_MEMORY;
@ -2043,15 +2049,17 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
data->change.url_alloc = TRUE;
}
uc = curl_url_set(uh, CURLUPART_URL, data->change.url,
if(!data->set.uh) {
uc = curl_url_set(uh, CURLUPART_URL, data->change.url,
CURLU_GUESS_SCHEME |
CURLU_NON_SUPPORT_SCHEME |
(data->set.disallow_username_in_url ?
CURLU_DISALLOW_USER : 0) |
(data->set.path_as_is ? CURLU_PATH_AS_IS : 0));
if(uc) {
DEBUGF(infof(data, "curl_url_set rejected %s\n", data->change.url));
return Curl_uc_to_curlcode(uc);
if(uc) {
DEBUGF(infof(data, "curl_url_set rejected %s\n", data->change.url));
return Curl_uc_to_curlcode(uc);
}
}
uc = curl_url_get(uh, CURLUPART_SCHEME, &data->state.up.scheme, 0);
@ -2193,6 +2201,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
return CURLE_OK;
}
/*
* If we're doing a resumed transfer, we need to setup our stuff
* properly.

View file

@ -1728,6 +1728,7 @@ struct UserDefined {
bool doh_get; /* use GET for DoH requests, instead of POST */
multidone_func fmultidone;
struct Curl_easy *dohfor; /* this is a DoH request for that transfer */
CURLU *uh; /* URL handle for the current parsed URL */
};
struct Names {