tool: prepend output_dir in header callback

When Content-Disposition parsing is used and an output dir is prepended,
make sure to store that new file name correctly so that it can be used
for setting the file timestamp when --remote-time is used.

Extended test 3012 to verify.

Co-Authored-by: Jay Satiro
Reported-by: hgdagon on github
Fixes #12614
Closes #12617
This commit is contained in:
Daniel Stenberg 2024-01-02 13:32:18 +01:00
parent 1d8e8c9ad1
commit 941b56d790
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
3 changed files with 12 additions and 17 deletions

View File

@ -178,10 +178,18 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
return CURL_WRITEFUNC_ERROR; return CURL_WRITEFUNC_ERROR;
} }
if(per->config->output_dir) {
outs->filename = aprintf("%s/%s", per->config->output_dir, filename);
free(filename);
if(!outs->filename)
return CURL_WRITEFUNC_ERROR;
}
else
outs->filename = filename;
outs->is_cd_filename = TRUE; outs->is_cd_filename = TRUE;
outs->s_isreg = TRUE; outs->s_isreg = TRUE;
outs->fopened = FALSE; outs->fopened = FALSE;
outs->filename = filename;
outs->alloc_filename = TRUE; outs->alloc_filename = TRUE;
hdrcbdata->honor_cd_filename = FALSE; /* done now! */ hdrcbdata->honor_cd_filename = FALSE; /* done now! */
if(!tool_create_output_file(outs, per->config)) if(!tool_create_output_file(outs, per->config))

View File

@ -57,7 +57,6 @@ bool tool_create_output_file(struct OutStruct *outs,
struct GlobalConfig *global; struct GlobalConfig *global;
FILE *file = NULL; FILE *file = NULL;
char *fname = outs->filename; char *fname = outs->filename;
char *aname = NULL;
DEBUGASSERT(outs); DEBUGASSERT(outs);
DEBUGASSERT(config); DEBUGASSERT(config);
global = config->global; global = config->global;
@ -66,15 +65,6 @@ bool tool_create_output_file(struct OutStruct *outs,
return FALSE; return FALSE;
} }
if(config->output_dir && outs->is_cd_filename) {
aname = aprintf("%s/%s", config->output_dir, fname);
if(!aname) {
errorf(global, "out of memory");
return FALSE;
}
fname = aname;
}
if(config->file_clobber_mode == CLOBBER_ALWAYS || if(config->file_clobber_mode == CLOBBER_ALWAYS ||
(config->file_clobber_mode == CLOBBER_DEFAULT && (config->file_clobber_mode == CLOBBER_DEFAULT &&
!outs->is_cd_filename)) { !outs->is_cd_filename)) {
@ -94,14 +84,12 @@ bool tool_create_output_file(struct OutStruct *outs,
char *newname; char *newname;
/* Guard against wraparound in new filename */ /* Guard against wraparound in new filename */
if(newlen < len) { if(newlen < len) {
free(aname);
errorf(global, "overflow in filename generation"); errorf(global, "overflow in filename generation");
return FALSE; return FALSE;
} }
newname = malloc(newlen); newname = malloc(newlen);
if(!newname) { if(!newname) {
errorf(global, "out of memory"); errorf(global, "out of memory");
free(aname);
return FALSE; return FALSE;
} }
memcpy(newname, fname, len); memcpy(newname, fname, len);
@ -135,10 +123,8 @@ bool tool_create_output_file(struct OutStruct *outs,
if(!file) { if(!file) {
warnf(global, "Failed to open the file %s: %s", fname, warnf(global, "Failed to open the file %s: %s", fname,
strerror(errno)); strerror(errno));
free(aname);
return FALSE; return FALSE;
} }
free(aname);
outs->s_isreg = TRUE; outs->s_isreg = TRUE;
outs->fopened = TRUE; outs->fopened = TRUE;
outs->stream = file; outs->stream = file;

View File

@ -4,6 +4,7 @@
-O -O
-J -J
--output-dir --output-dir
--remote-time
</keywords> </keywords>
</info> </info>
# #
@ -36,10 +37,10 @@ http
http http
</features> </features>
<name> <name>
--output-dir with -J --output-dir with -J and -R
</name> </name>
<command option="no-output,no-include"> <command option="no-output,no-include">
http://%HOSTIP:%HTTPPORT/this/is/the/%TESTNUMBER -OJ --output-dir %PWD/%LOGDIR http://%HOSTIP:%HTTPPORT/this/is/the/%TESTNUMBER -OJR --output-dir %PWD/%LOGDIR
</command> </command>
</client> </client>