urlapi: cleanup the redirect logic somewhat

Closes #15877
This commit is contained in:
Daniel Stenberg 2024-12-31 13:27:12 +01:00
parent 07a084f539
commit 150b0d808b
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2

View File

@ -86,6 +86,9 @@ struct Curl_URL {
#define DEFAULT_SCHEME "https" #define DEFAULT_SCHEME "https"
static CURLUcode parseurl_and_replace(const char *url, CURLU *u,
unsigned int flags);
static void free_urlhandle(struct Curl_URL *u) static void free_urlhandle(struct Curl_URL *u)
{ {
free(u->scheme); free(u->scheme);
@ -244,20 +247,13 @@ size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen,
/* /*
* Concatenate a relative URL to a base URL making it absolute. * Concatenate a relative URL to a base URL making it absolute.
* URL-encodes any spaces.
* The returned pointer must be freed by the caller unless NULL
* (returns NULL on out of memory).
* *
* Note that this function destroys the 'base' string. * Note that this function destroys the 'base' string.
*/ */
static CURLcode concat_url(char *base, const char *relurl, char **newurl) static CURLUcode redirect_url(char *base, const char *relurl,
CURLU *u, unsigned int flags)
{ {
/*** struct dynbuf urlbuf;
TRY to append this new path to the old URL
to the right of the host part. Oh crap, this is doomed to cause
problems in the future...
*/
struct dynbuf newest;
bool host_changed = FALSE; bool host_changed = FALSE;
const char *useurl = relurl; const char *useurl = relurl;
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
@ -270,7 +266,6 @@ static CURLcode concat_url(char *base, const char *relurl, char **newurl)
else else
protsep += 2; /* pass the slashes */ protsep += 2; /* pass the slashes */
*newurl = NULL;
if(('/' != relurl[0]) && ('#' != relurl[0])) { if(('/' != relurl[0]) && ('#' != relurl[0])) {
/* First we need to find out if there is a ?-letter in the original URL, /* First we need to find out if there is a ?-letter in the original URL,
and cut it and the right-side of that off */ and cut it and the right-side of that off */
@ -319,21 +314,21 @@ static CURLcode concat_url(char *base, const char *relurl, char **newurl)
*pathsep = 0; *pathsep = 0;
} }
Curl_dyn_init(&newest, CURL_MAX_INPUT_LENGTH); Curl_dyn_init(&urlbuf, CURL_MAX_INPUT_LENGTH);
/* copy over the root URL part */ /* copy over the root URL part */
result = Curl_dyn_add(&newest, base); result = Curl_dyn_add(&urlbuf, base);
if(result) if(result)
return result; return cc2cu(result);
/* then append the new piece on the right side */ /* then append the new piece on the right side */
uc = urlencode_str(&newest, useurl, strlen(useurl), !host_changed, uc = urlencode_str(&urlbuf, useurl, strlen(useurl), !host_changed,
FALSE); FALSE);
if(uc) if(!uc)
return (uc == CURLUE_TOO_LARGE) ? CURLE_TOO_LARGE : CURLE_OUT_OF_MEMORY; uc = parseurl_and_replace(Curl_dyn_ptr(&urlbuf), u,
flags&~CURLU_PATH_AS_IS);
*newurl = Curl_dyn_ptr(&newest); Curl_dyn_free(&urlbuf);
return CURLE_OK; return uc;
} }
/* scan for byte values <= 31, 127 and sometimes space */ /* scan for byte values <= 31, 127 and sometimes space */
@ -1801,34 +1796,24 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
* If the existing contents is enough for a URL, allow a relative URL to * If the existing contents is enough for a URL, allow a relative URL to
* replace it. * replace it.
*/ */
CURLcode result;
CURLUcode uc; CURLUcode uc;
char *oldurl; char *oldurl;
char *redired_url;
if(!nalloc) if(!nalloc)
/* a blank URL is not a valid URL */ /* a blank URL is not a valid URL */
return CURLUE_MALFORMED_INPUT; return CURLUE_MALFORMED_INPUT;
/* if the new thing is absolute or the old one is not /* if the new thing is absolute or the old one is not (we could not get an
* (we could not get an absolute URL in 'oldurl'), * absolute URL in 'oldurl'), then replace the existing with the new. */
* then replace the existing with the new. */
if(Curl_is_absolute_url(part, NULL, 0, if(Curl_is_absolute_url(part, NULL, 0,
flags & (CURLU_GUESS_SCHEME| flags & (CURLU_GUESS_SCHEME|CURLU_DEFAULT_SCHEME))
CURLU_DEFAULT_SCHEME))
|| curl_url_get(u, CURLUPART_URL, &oldurl, flags)) { || curl_url_get(u, CURLUPART_URL, &oldurl, flags)) {
return parseurl_and_replace(part, u, 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. */ uc = redirect_url(oldurl, part, u, flags);
result = concat_url(oldurl, part, &redired_url);
free(oldurl); free(oldurl);
if(result)
return cc2cu(result);
uc = parseurl_and_replace(redired_url, u, flags&~CURLU_PATH_AS_IS);
free(redired_url);
return uc; return uc;
} }
default: default: