curl/add_file_name_to_url: use the libcurl URL parser

instead of the custom error-prone parser, to extract and update the path
of the given URL

Closes #9683
This commit is contained in:
Daniel Stenberg 2022-10-10 10:55:05 +02:00
parent b82eb72d80
commit d24a2ffefe
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
4 changed files with 62 additions and 52 deletions

View File

@ -1131,13 +1131,11 @@ static CURLcode single_transfer(struct GlobalConfig *global,
/* /*
* We have specified a file to upload and it isn't "-". * We have specified a file to upload and it isn't "-".
*/ */
char *nurl = add_file_name_to_url(per->this_url, per->uploadfile); result = add_file_name_to_url(per->curl, &per->this_url,
if(!nurl) { per->uploadfile);
result = CURLE_OUT_OF_MEMORY; if(result)
break; break;
} }
per->this_url = nurl;
}
else if(per->uploadfile && stdin_upload(per->uploadfile)) { else if(per->uploadfile && stdin_upload(per->uploadfile)) {
/* count to see if there are more than one auth bit set /* count to see if there are more than one auth bit set
in the authtype field */ in the authtype field */

View File

@ -73,22 +73,23 @@ bool stdin_upload(const char *uploadfile)
* Adds the file name to the URL if it doesn't already have one. * Adds the file name to the URL if it doesn't already have one.
* url will be freed before return if the returned pointer is different * url will be freed before return if the returned pointer is different
*/ */
char *add_file_name_to_url(char *url, const char *filename) CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename)
{ {
/* If no file name part is given in the URL, we add this file name */ CURLcode result = CURLE_OUT_OF_MEMORY;
char *ptr = strstr(url, "://"); CURLU *uh = curl_url();
CURL *curl = curl_easy_init(); /* for url escaping */ char *path = NULL;
if(!curl) if(uh) {
return NULL; /* error! */ char *ptr;
if(ptr) if(curl_url_set(uh, CURLUPART_URL, *inurlp,
ptr += 3; CURLU_GUESS_SCHEME|CURLU_NON_SUPPORT_SCHEME))
else goto fail;
ptr = url; if(curl_url_get(uh, CURLUPART_PATH, &path, 0))
ptr = strrchr(ptr, '/'); goto fail;
ptr = strrchr(path, '/');
if(!ptr || !*++ptr) { if(!ptr || !*++ptr) {
/* The URL has no file name part, add the local file name. In order /* The URL path has no file name part, add the local file name. In order
to be able to do so, we have to create a new URL in another to be able to do so, we have to create a new URL in another buffer.*/
buffer.*/
/* We only want the part of the local path that is on the right /* We only want the part of the local path that is on the right
side of the rightmost slash and backslash. */ side of the rightmost slash and backslash. */
@ -106,28 +107,39 @@ char *add_file_name_to_url(char *url, const char *filename)
/* URL encode the file name */ /* URL encode the file name */
encfile = curl_easy_escape(curl, filep, 0 /* use strlen */); encfile = curl_easy_escape(curl, filep, 0 /* use strlen */);
if(encfile) { if(encfile) {
char *urlbuffer; char *newpath;
char *newurl;
CURLUcode uerr;
if(ptr) if(ptr)
/* there is a trailing slash on the URL */ /* there is a trailing slash on the path */
urlbuffer = aprintf("%s%s", url, encfile); newpath = aprintf("%s%s", path, encfile);
else else
/* there is no trailing slash on the URL */ /* there is no trailing slash on the path */
urlbuffer = aprintf("%s/%s", url, encfile); newpath = aprintf("%s/%s", path, encfile);
curl_free(encfile); curl_free(encfile);
if(!urlbuffer) { if(!newpath)
url = NULL; goto fail;
goto end; uerr = curl_url_set(uh, CURLUPART_PATH, newpath, 0);
} free(newpath);
if(uerr)
Curl_safefree(url); goto fail;
url = urlbuffer; /* use our new URL instead! */ if(curl_url_get(uh, CURLUPART_URL, &newurl, CURLU_DEFAULT_SCHEME))
goto fail;
free(*inurlp);
*inurlp = newurl;
result = CURLE_OK;
} }
} }
end: else
curl_easy_cleanup(curl); /* nothing to do */
return url; result = CURLE_OK;
}
fail:
curl_url_cleanup(uh);
curl_free(path);
return result;
} }
/* Extracts the name portion of the URL. /* Extracts the name portion of the URL.

View File

@ -33,7 +33,7 @@ bool output_expected(const char *url, const char *uploadfile);
bool stdin_upload(const char *uploadfile); bool stdin_upload(const char *uploadfile);
char *add_file_name_to_url(char *url, const char *filename); CURLcode add_file_name_to_url(CURL *curl, char **inurlp, const char *filename);
CURLcode get_url_file_name(char **filename, const char *url); CURLcode get_url_file_name(char **filename, const char *url);

View File

@ -36,7 +36,7 @@ a few bytes
# Verify data after the test has been "shot" # Verify data after the test has been "shot"
<verify> <verify>
<protocol> <protocol>
PUT /we/want/%TESTNUMBERte%5B%5Dst.txt HTTP/1.1 PUT /we/want/%TESTNUMBERte%5b%5dst.txt HTTP/1.1
Host: %HOSTIP:%HTTPPORT Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION User-Agent: curl/%VERSION
Accept: */* Accept: */*