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:
parent
b82eb72d80
commit
d24a2ffefe
@ -1131,12 +1131,10 @@ static CURLcode single_transfer(struct GlobalConfig *global,
|
||||
/*
|
||||
* We have specified a file to upload and it isn't "-".
|
||||
*/
|
||||
char *nurl = add_file_name_to_url(per->this_url, per->uploadfile);
|
||||
if(!nurl) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
result = add_file_name_to_url(per->curl, &per->this_url,
|
||||
per->uploadfile);
|
||||
if(result)
|
||||
break;
|
||||
}
|
||||
per->this_url = nurl;
|
||||
}
|
||||
else if(per->uploadfile && stdin_upload(per->uploadfile)) {
|
||||
/* count to see if there are more than one auth bit set
|
||||
|
||||
@ -73,61 +73,73 @@ bool stdin_upload(const char *uploadfile)
|
||||
* 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
|
||||
*/
|
||||
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 */
|
||||
char *ptr = strstr(url, "://");
|
||||
CURL *curl = curl_easy_init(); /* for url escaping */
|
||||
if(!curl)
|
||||
return NULL; /* error! */
|
||||
if(ptr)
|
||||
ptr += 3;
|
||||
else
|
||||
ptr = url;
|
||||
ptr = strrchr(ptr, '/');
|
||||
if(!ptr || !*++ptr) {
|
||||
/* The URL 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
|
||||
buffer.*/
|
||||
CURLcode result = CURLE_OUT_OF_MEMORY;
|
||||
CURLU *uh = curl_url();
|
||||
char *path = NULL;
|
||||
if(uh) {
|
||||
char *ptr;
|
||||
if(curl_url_set(uh, CURLUPART_URL, *inurlp,
|
||||
CURLU_GUESS_SCHEME|CURLU_NON_SUPPORT_SCHEME))
|
||||
goto fail;
|
||||
if(curl_url_get(uh, CURLUPART_PATH, &path, 0))
|
||||
goto fail;
|
||||
|
||||
/* We only want the part of the local path that is on the right
|
||||
side of the rightmost slash and backslash. */
|
||||
const char *filep = strrchr(filename, '/');
|
||||
char *file2 = strrchr(filep?filep:filename, '\\');
|
||||
char *encfile;
|
||||
ptr = strrchr(path, '/');
|
||||
if(!ptr || !*++ptr) {
|
||||
/* 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 buffer.*/
|
||||
|
||||
if(file2)
|
||||
filep = file2 + 1;
|
||||
else if(filep)
|
||||
filep++;
|
||||
else
|
||||
filep = filename;
|
||||
/* We only want the part of the local path that is on the right
|
||||
side of the rightmost slash and backslash. */
|
||||
const char *filep = strrchr(filename, '/');
|
||||
char *file2 = strrchr(filep?filep:filename, '\\');
|
||||
char *encfile;
|
||||
|
||||
/* URL encode the file name */
|
||||
encfile = curl_easy_escape(curl, filep, 0 /* use strlen */);
|
||||
if(encfile) {
|
||||
char *urlbuffer;
|
||||
if(ptr)
|
||||
/* there is a trailing slash on the URL */
|
||||
urlbuffer = aprintf("%s%s", url, encfile);
|
||||
if(file2)
|
||||
filep = file2 + 1;
|
||||
else if(filep)
|
||||
filep++;
|
||||
else
|
||||
/* there is no trailing slash on the URL */
|
||||
urlbuffer = aprintf("%s/%s", url, encfile);
|
||||
filep = filename;
|
||||
|
||||
curl_free(encfile);
|
||||
/* URL encode the file name */
|
||||
encfile = curl_easy_escape(curl, filep, 0 /* use strlen */);
|
||||
if(encfile) {
|
||||
char *newpath;
|
||||
char *newurl;
|
||||
CURLUcode uerr;
|
||||
if(ptr)
|
||||
/* there is a trailing slash on the path */
|
||||
newpath = aprintf("%s%s", path, encfile);
|
||||
else
|
||||
/* there is no trailing slash on the path */
|
||||
newpath = aprintf("%s/%s", path, encfile);
|
||||
|
||||
if(!urlbuffer) {
|
||||
url = NULL;
|
||||
goto end;
|
||||
curl_free(encfile);
|
||||
|
||||
if(!newpath)
|
||||
goto fail;
|
||||
uerr = curl_url_set(uh, CURLUPART_PATH, newpath, 0);
|
||||
free(newpath);
|
||||
if(uerr)
|
||||
goto fail;
|
||||
if(curl_url_get(uh, CURLUPART_URL, &newurl, CURLU_DEFAULT_SCHEME))
|
||||
goto fail;
|
||||
free(*inurlp);
|
||||
*inurlp = newurl;
|
||||
result = CURLE_OK;
|
||||
}
|
||||
|
||||
Curl_safefree(url);
|
||||
url = urlbuffer; /* use our new URL instead! */
|
||||
}
|
||||
else
|
||||
/* nothing to do */
|
||||
result = CURLE_OK;
|
||||
}
|
||||
end:
|
||||
curl_easy_cleanup(curl);
|
||||
return url;
|
||||
fail:
|
||||
curl_url_cleanup(uh);
|
||||
curl_free(path);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Extracts the name portion of the URL.
|
||||
|
||||
@ -33,7 +33,7 @@ bool output_expected(const char *url, 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);
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ a few bytes
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
PUT /we/want/%TESTNUMBERte%5B%5Dst.txt HTTP/1.1
|
||||
PUT /we/want/%TESTNUMBERte%5b%5dst.txt HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
Loading…
Reference in New Issue
Block a user