Loading src/tool_cb_hdr.c +21 −25 Original line number Diff line number Diff line Loading @@ -41,10 +41,9 @@ static char *parse_filename(const char *ptr, size_t len); size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata) { HeaderData *hdrdata = userdata; struct getout *urlnode = hdrdata->urlnode; struct OutStruct *outs = hdrdata->outs; struct OutStruct *heads = hdrdata->heads; struct HdrCbData *hdrcbdata = userdata; struct OutStruct *outs = hdrcbdata->outs; struct OutStruct *heads = hdrcbdata->heads; const char *str = ptr; const size_t cb = size * nmemb; const char *end = (char*)ptr + cb; Loading @@ -57,39 +56,35 @@ size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata) */ size_t failure = (size * nmemb) ? 0 : 1; if(!outs->config) if(!heads->config) return failure; #ifdef DEBUGBUILD if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) { warnf(outs->config, "Header data exceeds single call write limit!\n"); warnf(heads->config, "Header data exceeds single call write limit!\n"); return failure; } #endif /* --dump-header option */ if(outs->config->headerfile) { fwrite(ptr, size, nmemb, heads->stream); } /* ** This callback callback MIGHT set the filename upon appropriate ** conditions and server specifying filename in Content-Disposition. * Write header data when curl option --dump-header (-D) is given. */ if(!outs->config->content_disposition) return cb; if(!urlnode) return failure; if(!checkprefix("http://", urlnode->url) && !checkprefix("https://", urlnode->url)) return cb; if(heads->config->headerfile && heads->stream) { size_t rc = fwrite(ptr, size, nmemb, heads->stream); if(rc != cb) return rc; } if(!(urlnode->flags & GETOUT_USEREMOTE)) return cb; /* * This callback sets the filename where output shall be written when * curl options --remote-name (-O) and --remote-header-name (-J) have * been simultaneously given and additionally server returns an HTTP * Content-Disposition header specifying a filename property. */ if((cb > 20) && checkprefix("Content-disposition:", str)) { if(hdrcbdata->honor_cd_filename && (cb > 20) && checkprefix("Content-disposition:", str)) { const char *p = str + 20; /* look for the 'filename=' parameter Loading Loading @@ -123,6 +118,7 @@ size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata) outs->s_isreg = TRUE; outs->fopened = FALSE; outs->stream = NULL; hdrcbdata->honor_cd_filename = FALSE; break; } else Loading src/tool_cb_hdr.h +18 −7 Original line number Diff line number Diff line Loading @@ -23,15 +23,26 @@ ***************************************************************************/ #include "tool_setup.h" /* Structure to pass as userdata in tool_header_cb */ typedef struct { /* getout object pointer currently processing */ struct getout *urlnode; /* output stream */ /* * curl operates using a single HdrCbData struct variable, a * pointer to this is passed as userdata pointer to tool_header_cb. * * 'outs' member is a pointer to the OutStruct variable used to keep * track of information relative to curl's output writing. * * 'heads' member is a pointer to the OutStruct variable used to keep * track of information relative to header response writing. * * 'honor_cd_filename' member is TRUE when tool_header_cb is allowed * to honor Content-Disposition filename property and accordingly * set 'outs' filename, otherwise FALSE; */ struct HdrCbData { struct OutStruct *outs; /* header output stream */ struct OutStruct *heads; } HeaderData; bool honor_cd_filename; }; /* ** callback for CURLOPT_HEADERFUNCTION Loading src/tool_operate.c +16 −5 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) struct ProgressData progressbar; struct getout *urlnode; struct HdrCbData hdrcbdata; struct OutStruct heads; metalinkfile *mlfile_last = NULL; Loading @@ -141,6 +142,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) errorbuffer[0] = '\0'; /* default headers output stream is stdout */ memset(&hdrcbdata, 0, sizeof(struct HdrCbData)); memset(&heads, 0, sizeof(struct OutStruct)); heads.stream = stdout; heads.config = config; Loading Loading @@ -531,7 +533,6 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) long retry_sleep_default; long retry_sleep; char *this_url; HeaderData hdrdata; int metalink_next_res = 0; outfile = NULL; Loading Loading @@ -1256,12 +1257,19 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) if(config->proto_redir_present) my_setopt_flags(curl, CURLOPT_REDIR_PROTOCOLS, config->proto_redir); hdrdata.urlnode = urlnode; hdrdata.outs = &outs; hdrdata.heads = &heads; if(config->content_disposition && (urlnode->flags & GETOUT_USEREMOTE) && (checkprefix("http://", this_url) || checkprefix("https://", this_url))) hdrcbdata.honor_cd_filename = TRUE; else hdrcbdata.honor_cd_filename = FALSE; hdrcbdata.outs = &outs; hdrcbdata.heads = &heads; my_setopt(curl, CURLOPT_HEADERFUNCTION, tool_header_cb); my_setopt(curl, CURLOPT_HEADERDATA, &hdrdata); my_setopt(curl, CURLOPT_HEADERDATA, &hdrcbdata); if(config->resolve) /* new in 7.21.3 */ Loading Loading @@ -1590,6 +1598,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) if(outs.alloc_filename) Curl_safefree(outs.filename); memset(&outs, 0, sizeof(struct OutStruct)); hdrcbdata.outs = NULL; /* Free loop-local allocated memory and close loop-local opened fd */ Loading Loading @@ -1696,6 +1705,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) easysrc_cleanup(); #endif hdrcbdata.heads = NULL; /* Close function-local opened file descriptors */ if(heads.fopened && heads.stream) Loading tests/data/DISABLED +0 −28 Original line number Diff line number Diff line Loading @@ -9,34 +9,6 @@ 1355 1363 # 1349 1350 1351 1352 1353 1354 1357 1358 1359 1360 1361 1362 # 1370 1371 1385 1393 # 1379 1380 1381 1382 1383 1384 1387 1388 1389 1390 1391 1392 # Loading
src/tool_cb_hdr.c +21 −25 Original line number Diff line number Diff line Loading @@ -41,10 +41,9 @@ static char *parse_filename(const char *ptr, size_t len); size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata) { HeaderData *hdrdata = userdata; struct getout *urlnode = hdrdata->urlnode; struct OutStruct *outs = hdrdata->outs; struct OutStruct *heads = hdrdata->heads; struct HdrCbData *hdrcbdata = userdata; struct OutStruct *outs = hdrcbdata->outs; struct OutStruct *heads = hdrcbdata->heads; const char *str = ptr; const size_t cb = size * nmemb; const char *end = (char*)ptr + cb; Loading @@ -57,39 +56,35 @@ size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata) */ size_t failure = (size * nmemb) ? 0 : 1; if(!outs->config) if(!heads->config) return failure; #ifdef DEBUGBUILD if(size * nmemb > (size_t)CURL_MAX_HTTP_HEADER) { warnf(outs->config, "Header data exceeds single call write limit!\n"); warnf(heads->config, "Header data exceeds single call write limit!\n"); return failure; } #endif /* --dump-header option */ if(outs->config->headerfile) { fwrite(ptr, size, nmemb, heads->stream); } /* ** This callback callback MIGHT set the filename upon appropriate ** conditions and server specifying filename in Content-Disposition. * Write header data when curl option --dump-header (-D) is given. */ if(!outs->config->content_disposition) return cb; if(!urlnode) return failure; if(!checkprefix("http://", urlnode->url) && !checkprefix("https://", urlnode->url)) return cb; if(heads->config->headerfile && heads->stream) { size_t rc = fwrite(ptr, size, nmemb, heads->stream); if(rc != cb) return rc; } if(!(urlnode->flags & GETOUT_USEREMOTE)) return cb; /* * This callback sets the filename where output shall be written when * curl options --remote-name (-O) and --remote-header-name (-J) have * been simultaneously given and additionally server returns an HTTP * Content-Disposition header specifying a filename property. */ if((cb > 20) && checkprefix("Content-disposition:", str)) { if(hdrcbdata->honor_cd_filename && (cb > 20) && checkprefix("Content-disposition:", str)) { const char *p = str + 20; /* look for the 'filename=' parameter Loading Loading @@ -123,6 +118,7 @@ size_t tool_header_cb(void *ptr, size_t size, size_t nmemb, void *userdata) outs->s_isreg = TRUE; outs->fopened = FALSE; outs->stream = NULL; hdrcbdata->honor_cd_filename = FALSE; break; } else Loading
src/tool_cb_hdr.h +18 −7 Original line number Diff line number Diff line Loading @@ -23,15 +23,26 @@ ***************************************************************************/ #include "tool_setup.h" /* Structure to pass as userdata in tool_header_cb */ typedef struct { /* getout object pointer currently processing */ struct getout *urlnode; /* output stream */ /* * curl operates using a single HdrCbData struct variable, a * pointer to this is passed as userdata pointer to tool_header_cb. * * 'outs' member is a pointer to the OutStruct variable used to keep * track of information relative to curl's output writing. * * 'heads' member is a pointer to the OutStruct variable used to keep * track of information relative to header response writing. * * 'honor_cd_filename' member is TRUE when tool_header_cb is allowed * to honor Content-Disposition filename property and accordingly * set 'outs' filename, otherwise FALSE; */ struct HdrCbData { struct OutStruct *outs; /* header output stream */ struct OutStruct *heads; } HeaderData; bool honor_cd_filename; }; /* ** callback for CURLOPT_HEADERFUNCTION Loading
src/tool_operate.c +16 −5 Original line number Diff line number Diff line Loading @@ -128,6 +128,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) struct ProgressData progressbar; struct getout *urlnode; struct HdrCbData hdrcbdata; struct OutStruct heads; metalinkfile *mlfile_last = NULL; Loading @@ -141,6 +142,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) errorbuffer[0] = '\0'; /* default headers output stream is stdout */ memset(&hdrcbdata, 0, sizeof(struct HdrCbData)); memset(&heads, 0, sizeof(struct OutStruct)); heads.stream = stdout; heads.config = config; Loading Loading @@ -531,7 +533,6 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) long retry_sleep_default; long retry_sleep; char *this_url; HeaderData hdrdata; int metalink_next_res = 0; outfile = NULL; Loading Loading @@ -1256,12 +1257,19 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) if(config->proto_redir_present) my_setopt_flags(curl, CURLOPT_REDIR_PROTOCOLS, config->proto_redir); hdrdata.urlnode = urlnode; hdrdata.outs = &outs; hdrdata.heads = &heads; if(config->content_disposition && (urlnode->flags & GETOUT_USEREMOTE) && (checkprefix("http://", this_url) || checkprefix("https://", this_url))) hdrcbdata.honor_cd_filename = TRUE; else hdrcbdata.honor_cd_filename = FALSE; hdrcbdata.outs = &outs; hdrcbdata.heads = &heads; my_setopt(curl, CURLOPT_HEADERFUNCTION, tool_header_cb); my_setopt(curl, CURLOPT_HEADERDATA, &hdrdata); my_setopt(curl, CURLOPT_HEADERDATA, &hdrcbdata); if(config->resolve) /* new in 7.21.3 */ Loading Loading @@ -1590,6 +1598,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) if(outs.alloc_filename) Curl_safefree(outs.filename); memset(&outs, 0, sizeof(struct OutStruct)); hdrcbdata.outs = NULL; /* Free loop-local allocated memory and close loop-local opened fd */ Loading Loading @@ -1696,6 +1705,8 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[]) easysrc_cleanup(); #endif hdrcbdata.heads = NULL; /* Close function-local opened file descriptors */ if(heads.fopened && heads.stream) Loading
tests/data/DISABLED +0 −28 Original line number Diff line number Diff line Loading @@ -9,34 +9,6 @@ 1355 1363 # 1349 1350 1351 1352 1353 1354 1357 1358 1359 1360 1361 1362 # 1370 1371 1385 1393 # 1379 1380 1381 1382 1383 1384 1387 1388 1389 1390 1391 1392 #