aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/setopt.c6
-rw-r--r--lib/transfer.c15
-rw-r--r--lib/url.c19
-rw-r--r--lib/urldata.h1
4 files changed, 35 insertions, 6 deletions
diff --git a/lib/setopt.c b/lib/setopt.c
index 22956a20f..1627aba6d 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -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.
diff --git a/lib/transfer.c b/lib/transfer.c
index de6043d7d..32ca5a496 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -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
diff --git a/lib/url.c b/lib/url.c
index dd9fa2617..6118177d6 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -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.
diff --git a/lib/urldata.h b/lib/urldata.h
index 11a6a22c6..eae73a19f 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -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 {