urlapi: handle "redirects" smarter
- avoid one malloc when setting a new url via curl_url_set() and CURLUPART_URL. - extract common pattern into a new static function. Closes #8450
This commit is contained in:
Родитель
663296c6b5
Коммит
70ac27604a
75
lib/urlapi.c
75
lib/urlapi.c
|
@ -90,16 +90,6 @@ static void free_urlhandle(struct Curl_URL *u)
|
|||
free(u->temppath);
|
||||
}
|
||||
|
||||
/* move the full contents of one handle onto another and
|
||||
free the original */
|
||||
static void mv_urlhandle(struct Curl_URL *from,
|
||||
struct Curl_URL *to)
|
||||
{
|
||||
free_urlhandle(to);
|
||||
*to = *from;
|
||||
free(from);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the separator at the end of the host name, or the '?' in cases like
|
||||
* http://www.url.com?id=2380
|
||||
|
@ -1153,6 +1143,25 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the URL and, if successful, replace everyting in the Curl_URL struct.
|
||||
*/
|
||||
static CURLUcode parseurl_and_replace(const char *url, CURLU *u,
|
||||
unsigned int flags)
|
||||
{
|
||||
CURLUcode result;
|
||||
CURLU tmpurl;
|
||||
memset(&tmpurl, 0, sizeof(tmpurl));
|
||||
result = parseurl(url, &tmpurl, flags);
|
||||
if(!result) {
|
||||
free_urlhandle(u);
|
||||
*u = tmpurl;
|
||||
}
|
||||
else
|
||||
free_urlhandle(&tmpurl);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
CURLU *curl_url(void)
|
||||
|
@ -1560,52 +1569,24 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
|
|||
CURLUcode result;
|
||||
char *oldurl;
|
||||
char *redired_url;
|
||||
CURLU *handle2;
|
||||
|
||||
if(Curl_is_absolute_url(part, NULL, 0)) {
|
||||
handle2 = curl_url();
|
||||
if(!handle2)
|
||||
return CURLUE_OUT_OF_MEMORY;
|
||||
result = parseurl(part, handle2, flags);
|
||||
if(!result)
|
||||
mv_urlhandle(handle2, u);
|
||||
else
|
||||
curl_url_cleanup(handle2);
|
||||
return result;
|
||||
}
|
||||
/* extract the full "old" URL to do the redirect on */
|
||||
result = curl_url_get(u, CURLUPART_URL, &oldurl, flags);
|
||||
if(result) {
|
||||
/* couldn't get the old URL, just use the new! */
|
||||
handle2 = curl_url();
|
||||
if(!handle2)
|
||||
return CURLUE_OUT_OF_MEMORY;
|
||||
result = parseurl(part, handle2, flags);
|
||||
if(!result)
|
||||
mv_urlhandle(handle2, u);
|
||||
else
|
||||
curl_url_cleanup(handle2);
|
||||
return result;
|
||||
/* if the new thing is absolute or the old one is not
|
||||
* (we could not get an absolute url in 'oldurl'),
|
||||
* then replace the existing with the new. */
|
||||
if(Curl_is_absolute_url(part, NULL, 0)
|
||||
|| curl_url_get(u, CURLUPART_URL, &oldurl, flags)) {
|
||||
return parseurl_and_replace(part, u, flags);
|
||||
}
|
||||
|
||||
/* apply the relative part to create a new URL */
|
||||
/* apply the relative part to create a new URL
|
||||
* and replace the existing one with it. */
|
||||
redired_url = concat_url(oldurl, part);
|
||||
free(oldurl);
|
||||
if(!redired_url)
|
||||
return CURLUE_OUT_OF_MEMORY;
|
||||
|
||||
/* now parse the new URL */
|
||||
handle2 = curl_url();
|
||||
if(!handle2) {
|
||||
free(redired_url);
|
||||
return CURLUE_OUT_OF_MEMORY;
|
||||
}
|
||||
result = parseurl(redired_url, handle2, flags);
|
||||
result = parseurl_and_replace(redired_url, u, flags);
|
||||
free(redired_url);
|
||||
if(!result)
|
||||
mv_urlhandle(handle2, u);
|
||||
else
|
||||
curl_url_cleanup(handle2);
|
||||
return result;
|
||||
}
|
||||
default:
|
||||
|
|
Загрузка…
Ссылка в новой задаче