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
This commit is contained in:
Daniel Stenberg 2024-09-17 07:41:59 +02:00
Родитель 89de543204
Коммит 0cfc7fcca1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
6 изменённых файлов: 73 добавлений и 23 удалений

Просмотреть файл

@ -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 &&

Просмотреть файл

@ -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 */

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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 \

56
tests/data/test692 Normal file
Просмотреть файл

@ -0,0 +1,56 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
</keywords>
</info>
#
# Server-side
<reply>
<data crlf="yes" nocheck="yes">
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-
</data>
</reply>
#
# Client-side
<client>
<server>
http
</server>
<name>
-JO with URL without path using trailing slash
</name>
<command option="no-output/no-include">
http://%HOSTIP:%HTTPPORT/ -JO --output-dir %LOGDIR
</command>
</client>
#
# Verify data after the test has been "shot"
<verify>
<protocol crlf="yes">
GET / HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
</protocol>
<file crlf="yes" name="%LOGDIR/curl_response">
-foo-
</file>
</verify>
</testcase>