From: Stefan Eissing Date: Mon, 14 Feb 2022 10:43:04 +0000 (+0100) Subject: urlapi: handle "redirects" smarter X-Git-Tag: curl-7_82_0~70 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=70ac27604a2abfa809a7b2736506af0da8c3c8a9;p=thirdparty%2Fcurl.git 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 --- diff --git a/lib/urlapi.c b/lib/urlapi.c index ebbc37f282..ff00ee4243 100644 --- a/lib/urlapi.c +++ b/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: