diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c
index 969acac1e4..1b0348d23c 100644
--- a/src/tool_cb_hdr.c
+++ b/src/tool_cb_hdr.c
@@ -62,6 +62,25 @@ static void write_linked_location(CURL *curl, const char *location,
size_t loclen, FILE *stream);
#endif
+int tool_write_headers(struct HdrCbData *hdrcbdata, FILE *stream)
+{
+ struct curl_slist *h = hdrcbdata->headlist;
+ int rc = 1;
+ while(h) {
+ /* not "handled", just show it */
+ size_t len = strlen(h->data);
+ if(len != fwrite(h->data, 1, len, stream))
+ goto fail;
+ h = h->next;
+ }
+ rc = 0; /* success */
+fail:
+ curl_slist_free_all(hdrcbdata->headlist);
+ hdrcbdata->headlist = NULL;
+ return rc;
+}
+
+
/*
** callback for CURLOPT_HEADERFUNCTION
*/
@@ -164,63 +183,90 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
* Content-Disposition header specifying a filename property.
*/
- else if(hdrcbdata->honor_cd_filename &&
- (cb > 20) && checkprefix("Content-disposition:", str)) {
- const char *p = str + 20;
+ else if(hdrcbdata->honor_cd_filename) {
+ if((cb > 20) && checkprefix("Content-disposition:", str)) {
+ const char *p = str + 20;
- /* look for the 'filename=' parameter
- (encoded filenames (*=) are not supported) */
- for(;;) {
- char *filename;
- size_t len;
+ /* look for the 'filename=' parameter
+ (encoded filenames (*=) are not supported) */
+ for(;;) {
+ char *filename;
+ size_t len;
- while((p < end) && *p && !ISALPHA(*p))
- p++;
- if(p > end - 9)
- break;
-
- if(memcmp(p, "filename=", 9)) {
- /* no match, find next parameter */
- while((p < end) && *p && (*p != ';'))
+ while((p < end) && *p && !ISALPHA(*p))
p++;
- if((p < end) && *p)
- continue;
- else
+ if(p > end - 9)
break;
- }
- p += 9;
- len = cb - (size_t)(p - str);
- filename = parse_filename(p, len);
- if(filename) {
- if(outs->stream) {
- /* indication of problem, get out! */
- free(filename);
- return CURL_WRITEFUNC_ERROR;
+ if(memcmp(p, "filename=", 9)) {
+ /* no match, find next parameter */
+ while((p < end) && *p && (*p != ';'))
+ p++;
+ if((p < end) && *p)
+ continue;
+ else
+ break;
}
+ p += 9;
- if(per->config->output_dir) {
- outs->filename = aprintf("%s/%s", per->config->output_dir,
- filename);
- free(filename);
- if(!outs->filename)
+ len = cb - (size_t)(p - str);
+ filename = parse_filename(p, len);
+ if(filename) {
+ if(outs->stream) {
+ /* indication of problem, get out! */
+ free(filename);
+ 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->s_isreg = TRUE;
+ outs->fopened = FALSE;
+ outs->alloc_filename = TRUE;
+ hdrcbdata->honor_cd_filename = FALSE; /* done now! */
+ if(!tool_create_output_file(outs, per->config))
+ return CURL_WRITEFUNC_ERROR;
+ if(tool_write_headers(&per->hdrcbdata, outs->stream))
return CURL_WRITEFUNC_ERROR;
}
- else
- outs->filename = filename;
-
- outs->is_cd_filename = TRUE;
- outs->s_isreg = TRUE;
- outs->fopened = FALSE;
- outs->alloc_filename = TRUE;
- hdrcbdata->honor_cd_filename = FALSE; /* done now! */
- if(!tool_create_output_file(outs, per->config))
- return CURL_WRITEFUNC_ERROR;
+ break;
}
- break;
+ if(!outs->stream && !tool_create_output_file(outs, per->config))
+ return CURL_WRITEFUNC_ERROR;
+ if(tool_write_headers(&per->hdrcbdata, outs->stream))
+ return CURL_WRITEFUNC_ERROR;
+ } /* content-disposition handling */
+
+ if(hdrcbdata->honor_cd_filename &&
+ hdrcbdata->config->show_headers) {
+ /* still awaiting the Content-Disposition header, store the header in
+ memory. Since it is not zero terminated, we need an extra dance. */
+ char *clone = aprintf("%.*s", (int)cb, (char *)str);
+ if(clone) {
+ struct curl_slist *old = hdrcbdata->headlist;
+ hdrcbdata->headlist = curl_slist_append(old, clone);
+ free(clone);
+ if(!hdrcbdata->headlist) {
+ curl_slist_free_all(old);
+ return CURL_WRITEFUNC_ERROR;
+ }
+ }
+ else {
+ curl_slist_free_all(hdrcbdata->headlist);
+ hdrcbdata->headlist = NULL;
+ return CURL_WRITEFUNC_ERROR;
+ }
+ return cb; /* done for now */
}
- if(!outs->stream && !tool_create_output_file(outs, per->config))
- return CURL_WRITEFUNC_ERROR;
}
}
if(hdrcbdata->config->writeout) {
diff --git a/src/tool_cb_hdr.h b/src/tool_cb_hdr.h
index a855052d0d..7402c12a9b 100644
--- a/src/tool_cb_hdr.h
+++ b/src/tool_cb_hdr.h
@@ -46,9 +46,12 @@ struct HdrCbData {
struct OutStruct *outs;
struct OutStruct *heads;
struct OutStruct *etag_save;
+ struct curl_slist *headlist;
bool honor_cd_filename;
};
+int tool_write_headers(struct HdrCbData *hdrcbdata, FILE *stream);
+
/*
** callback for CURLOPT_HEADERFUNCTION
*/
diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c
index e35489a39f..f25a481503 100644
--- a/src/tool_cb_wrt.c
+++ b/src/tool_cb_wrt.c
@@ -345,7 +345,13 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata)
}
else
#endif
+ {
+ if(per->hdrcbdata.headlist) {
+ if(tool_write_headers(&per->hdrcbdata, outs->stream))
+ return CURL_WRITEFUNC_ERROR;
+ }
rc = fwrite(buffer, sz, nmemb, outs->stream);
+ }
if(bytes == rc)
/* we added this amount of data to the output */
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 7a38992a9e..9a5de1e731 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -2763,9 +2763,7 @@ ParameterError parse_args(struct GlobalConfig *global, int argc,
}
if(!result && config->content_disposition) {
- if(config->show_headers)
- result = PARAM_CONTDISP_SHOW_HEADER;
- else if(config->resume_from_current)
+ if(config->resume_from_current)
result = PARAM_CONTDISP_RESUME_FROM;
}
diff --git a/src/tool_getparam.h b/src/tool_getparam.h
index 9d6c72ef82..b22e60b7b3 100644
--- a/src/tool_getparam.h
+++ b/src/tool_getparam.h
@@ -342,7 +342,6 @@ typedef enum {
PARAM_NO_PREFIX,
PARAM_NUMBER_TOO_LARGE,
PARAM_NO_NOT_BOOLEAN,
- PARAM_CONTDISP_SHOW_HEADER, /* --include and --remote-header-name */
PARAM_CONTDISP_RESUME_FROM, /* --continue-at and --remote-header-name */
PARAM_READ_ERROR,
PARAM_EXPAND_ERROR, /* --expand problem */
diff --git a/src/tool_helpers.c b/src/tool_helpers.c
index 2e15144b7b..02193c3e51 100644
--- a/src/tool_helpers.c
+++ b/src/tool_helpers.c
@@ -67,8 +67,6 @@ const char *param2text(ParameterError error)
return "too large number";
case PARAM_NO_NOT_BOOLEAN:
return "used '--no-' for option that is not a boolean";
- case PARAM_CONTDISP_SHOW_HEADER:
- return "showing headers and --remote-header-name cannot be combined";
case PARAM_CONTDISP_RESUME_FROM:
return "--continue-at and --remote-header-name cannot be combined";
case PARAM_READ_ERROR:
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 5b51243374..0a959a8bcd 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -770,7 +770,8 @@ skip:
free(per->uploadfile);
if(global->parallel)
free(per->errorbuffer);
-
+ curl_slist_free_all(per->hdrcbdata.headlist);
+ per->hdrcbdata.headlist = NULL;
return result;
}
diff --git a/tests/data/DISABLED b/tests/data/DISABLED
index 80f835d4b7..45b0753658 100644
--- a/tests/data/DISABLED
+++ b/tests/data/DISABLED
@@ -75,6 +75,7 @@
# 1021 re-added here due to flakiness
1021
1417
+1460
1533
1540
1591
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 90442d80e3..5b028a05b2 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -170,7 +170,7 @@ test1271 test1272 test1273 test1274 test1275 test1276 test1277 test1278 \
test1279 test1280 test1281 test1282 test1283 test1284 test1285 test1286 \
test1287 test1288 test1289 test1290 test1291 test1292 test1293 test1294 \
test1295 test1296 test1297 test1298 test1299 test1300 test1301 test1302 \
-test1303 test1304 test1305 test1306 test1307 test1308 test1309 \
+test1303 test1304 test1305 test1306 test1307 test1308 test1309 test1310 \
test1311 test1312 test1313 test1314 test1315 test1316 test1317 test1318 \
test1319 test1320 test1321 test1322 test1323 test1324 test1325 test1326 \
test1327 test1328 test1329 test1330 test1331 test1332 test1333 test1334 \
@@ -193,7 +193,7 @@ test1455 test1456 test1457 test1458 test1459 test1460 test1461 test1462 \
test1463 test1464 test1465 test1466 test1467 test1468 test1469 test1470 \
test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 \
test1479 test1480 test1481 test1482 test1483 test1484 test1485 test1486 \
-test1487 test1488 test1489 test1490 test1491 \
+test1487 test1488 test1489 test1490 test1491 test1492 \
\
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \
diff --git a/tests/data/test1310 b/tests/data/test1310
new file mode 100644
index 0000000000..49bb0d36df
--- /dev/null
+++ b/tests/data/test1310
@@ -0,0 +1,63 @@
+
+
+
+HTTP
+HTTP GET
+-J
+--show-headers
+
+
+
+#
+
+
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 6
+Connection: close
+Content-Disposition: inline; filename="name%TESTNUMBER"
+Content-Type: text/html
+
+12345
+
+
+
+#
+# Client-side
+
+
+http
+
+
+HTTP GET with -J + --show-headers
+
+
+http://%HOSTIP:%HTTPPORT/junk -J -O --show-headers --output-dir %LOGDIR
+
+
+
+#
+# Verify data after the test has been "shot"
+
+
+GET /junk HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+
+
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 6
+Connection: close
+Content-Disposition: inline; filename="name%TESTNUMBER"
+Content-Type: text/html
+
+12345
+
+
+
+
diff --git a/tests/data/test1460 b/tests/data/test1460
index 4e85082e38..7422d4b99b 100644
--- a/tests/data/test1460
+++ b/tests/data/test1460
@@ -11,33 +11,26 @@ HTTP GET
HTTP/1.1 200 swsclose
- 12345
-fooo
-54 3 2 1
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
Content-Disposition: filename=name%TESTNUMBER; charset=funny; option=strange
+Content-Length: 4
+hej
#
# Client-side
-# this relies on the debug feature to allow us to set directory to store the
-# -J output in
-
-Debug
-
http
HTTP GET with -Ji and Content-Disposition with existing file
-
-CURL_TESTDIR=%LOGDIR
-
-http://%HOSTIP:%HTTPPORT/%TESTNUMBER -Ji -O
+http://%HOSTIP:%HTTPPORT/%TESTNUMBER -Ji -O --output-dir %LOGDIR
initial content
@@ -47,9 +40,9 @@ initial content
#
# Verify data after the test has been "shot"
-# Warning: --include and --remote-header-name cannot be combined.
+# Warning: Failed to open the file log/name1460: File exists
-2
+23
initial content
diff --git a/tests/data/test1492 b/tests/data/test1492
new file mode 100644
index 0000000000..2e7e1f32ae
--- /dev/null
+++ b/tests/data/test1492
@@ -0,0 +1,63 @@
+
+
+
+HTTP
+HTTP GET
+-J
+--show-headers
+
+
+
+#
+
+
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 6
+Connection: close
+Content-Jisposition: inline; filename="name%TESTNUMBER"
+Content-Type: text/html
+
+12345
+
+
+
+#
+# Client-side
+
+
+http
+
+
+HTTP GET with -J + --show-headers but no Content-Disposition:
+
+
+http://%HOSTIP:%HTTPPORT/junk%TESTNUMBER -J -O --show-headers --output-dir %LOGDIR
+
+
+
+#
+# Verify data after the test has been "shot"
+
+
+GET /junk%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+
+
+HTTP/1.1 200 OK
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 6
+Connection: close
+Content-Jisposition: inline; filename="name%TESTNUMBER"
+Content-Type: text/html
+
+12345
+
+
+
+