From 0cfc7fcca18ff21a5664b5d1552a31dcae2fd3c7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 17 Sep 2024 07:41:59 +0200 Subject: [PATCH] tool_cb_wrt: use "curl_response" if no file name in URL Use the same fallback for content-disposition cases as for regular -O Add test692: verify -JO with URL without a file name Reported-by: Brian Inglis Fixes #14939 Closes #14940 --- src/tool_cb_wrt.c | 7 ++---- src/tool_operate.c | 16 +++--------- src/tool_operhlp.c | 12 ++++++--- src/tool_operhlp.h | 3 ++- tests/data/Makefile.am | 2 +- tests/data/test692 | 56 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 73 insertions(+), 23 deletions(-) create mode 100644 tests/data/test692 diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c index 660000b69..e35489a39 100644 --- a/src/tool_cb_wrt.c +++ b/src/tool_cb_wrt.c @@ -54,14 +54,11 @@ bool tool_create_output_file(struct OutStruct *outs, { struct GlobalConfig *global; FILE *file = NULL; - char *fname = outs->filename; + const char *fname = outs->filename; DEBUGASSERT(outs); DEBUGASSERT(config); global = config->global; - if(!fname || !*fname) { - warnf(global, "Remote filename has no length"); - return FALSE; - } + DEBUGASSERT(fname && *fname); if(config->file_clobber_mode == CLOBBER_ALWAYS || (config->file_clobber_mode == CLOBBER_DEFAULT && diff --git a/src/tool_operate.c b/src/tool_operate.c index 41fd6718c..75b9ec9fd 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -1158,21 +1158,12 @@ static CURLcode single_transfer(struct GlobalConfig *global, if(!per->outfile) { /* extract the filename from the URL */ - result = get_url_file_name(&per->outfile, per->this_url); + result = get_url_file_name(global, &per->outfile, per->this_url); if(result) { - errorf(global, "Failed to extract a sensible filename" + errorf(global, "Failed to extract a filename" " from the URL to use for storage"); break; } - if(!*per->outfile && !config->content_disposition) { - free(per->outfile); - per->outfile = strdup("curl_response"); - if(!per->outfile) { - result = CURLE_OUT_OF_MEMORY; - break; - } - warnf(global, "No remote file name, uses \"%s\"", per->outfile); - } } else if(state->urls) { /* fill '#1' ... '#9' terms from URL pattern */ @@ -1190,6 +1181,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, break; } } + DEBUGASSERT(per->outfile); if(config->output_dir && *config->output_dir) { char *d = aprintf("%s/%s", config->output_dir, per->outfile); @@ -1210,7 +1202,7 @@ static CURLcode single_transfer(struct GlobalConfig *global, break; } - if(per->outfile && config->skip_existing) { + if(config->skip_existing) { struct_stat fileinfo; if(!stat(per->outfile, &fileinfo)) { /* file is present */ diff --git a/src/tool_operhlp.c b/src/tool_operhlp.c index 7dce5ff0c..0ed441c3f 100644 --- a/src/tool_operhlp.c +++ b/src/tool_operhlp.c @@ -31,6 +31,7 @@ #include "tool_cfgable.h" #include "tool_doswin.h" #include "tool_operhlp.h" +#include "tool_msgs.h" #include "memdebug.h" /* keep this as LAST include */ @@ -178,7 +179,8 @@ fail: * Returns a pointer to a heap-allocated string or NULL if * no name part, at location indicated by first argument. */ -CURLcode get_url_file_name(char **filename, const char *url) +CURLcode get_url_file_name(struct GlobalConfig *global, + char **filename, const char *url) { CURLU *uh = curl_url(); char *path = NULL; @@ -212,9 +214,11 @@ CURLcode get_url_file_name(char **filename, const char *url) if(pc) /* duplicate the string beyond the slash */ pc++; - else - /* no slash => empty string */ - pc = (char *)""; + else { + /* no slash => empty string, use default */ + pc = (char *)"curl_response"; + warnf(global, "No remote file name, uses \"%s\"", pc); + } *filename = strdup(pc); curl_free(path); diff --git a/src/tool_operhlp.h b/src/tool_operhlp.h index 1d56fa040..19daa8e43 100644 --- a/src/tool_operhlp.h +++ b/src/tool_operhlp.h @@ -35,7 +35,8 @@ bool stdin_upload(const char *uploadfile); 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(struct GlobalConfig *global, + char **filename, const char *url); CURLcode urlerr_cvt(CURLUcode ucode); diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 9e6fb7bb8..d6bd237c2 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -101,7 +101,7 @@ test652 test653 test654 test655 test656 test658 test659 test660 test661 \ test662 test663 test664 test665 test666 test667 test668 test669 test670 \ test671 test672 test673 test674 test675 test676 test677 test678 test679 \ test680 test681 test682 test683 test684 test685 test686 test687 test688 \ -test689 test690 test691 \ +test689 test690 test691 test692 \ \ test700 test701 test702 test703 test704 test705 test706 test707 test708 \ test709 test710 test711 test712 test713 test714 test715 test716 test717 \ diff --git a/tests/data/test692 b/tests/data/test692 new file mode 100644 index 000000000..e3e49a018 --- /dev/null +++ b/tests/data/test692 @@ -0,0 +1,56 @@ + + + +HTTP +HTTP GET + + + +# +# Server-side + + +HTTP/1.1 200 OK +Date: Tue, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT +ETag: "21025-dc7-39462498" +Accept-Ranges: bytes +Content-Length: 6 +Connection: close +Content-Type: text/html +Funny-head: yesyes + +-foo- + + + +# +# Client-side + + +http + + +-JO with URL without path using trailing slash + + +http://%HOSTIP:%HTTPPORT/ -JO --output-dir %LOGDIR + + + +# +# Verify data after the test has been "shot" + + +GET / HTTP/1.1 +Host: %HOSTIP:%HTTPPORT +User-Agent: curl/%VERSION +Accept: */* + + + +-foo- + + +