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:
Stefan Eissing 2022-02-14 11:43:04 +01:00 коммит произвёл Daniel Stenberg
Родитель 663296c6b5
Коммит 70ac27604a
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
1 изменённых файлов: 28 добавлений и 47 удалений

Просмотреть файл

@ -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: