diff options
author | Daniel Stenberg <daniel@haxx.se> | 2018-05-17 13:56:35 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2018-05-21 20:05:05 +0200 |
commit | c1c27625c797cfb7b21128484b4990446c1e92d9 (patch) | |
tree | 7a1e6b2597a10628f7787e16bb850adb09a87fc7 /src | |
parent | 6876ccf90b473480998af4619de5f316fbd63084 (diff) |
curl: show headers in bold
The feature is only enabled if the output is believed to be a tty.
-J: There's some minor differences and improvements in -J handling, as
now J should work with -i and it actually creates a file first using the
initial name and then *renames* that to the one found in
Content-Disposition (if any).
-i: only shows headers for HTTP transfers now (as documented).
Previously it would also show for pieces of the transfer that were HTTP
(for example when doing FTP over a HTTP proxy).
-i: now shows trailers as well. Previously they were not shown at all.
--libcurl: the CURLOPT_HEADER is no longer set, as the header output is
now done in the header callback.
Diffstat (limited to 'src')
-rw-r--r-- | src/tool_cb_hdr.c | 63 | ||||
-rw-r--r-- | src/tool_cb_hdr.h | 4 | ||||
-rw-r--r-- | src/tool_cb_wrt.c | 13 | ||||
-rw-r--r-- | src/tool_cb_wrt.h | 4 | ||||
-rw-r--r-- | src/tool_cfgable.h | 2 | ||||
-rw-r--r-- | src/tool_getparam.c | 12 | ||||
-rw-r--r-- | src/tool_operate.c | 15 |
7 files changed, 75 insertions, 38 deletions
diff --git a/src/tool_cb_hdr.c b/src/tool_cb_hdr.c index 7f2181f40..4e9e49a6d 100644 --- a/src/tool_cb_hdr.c +++ b/src/tool_cb_hdr.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -31,11 +31,20 @@ #include "tool_doswin.h" #include "tool_msgs.h" #include "tool_cb_hdr.h" +#include "tool_cb_wrt.h" #include "memdebug.h" /* keep this as LAST include */ static char *parse_filename(const char *ptr, size_t len); +#ifdef WIN32 +#define BOLD +#define BOLDOFF +#else +#define BOLD "\x1b[1m" +#define BOLDOFF "\x1b[21m" +#endif + /* ** callback for CURLOPT_HEADERFUNCTION */ @@ -48,7 +57,7 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) const char *str = ptr; const size_t cb = size * nmemb; const char *end = (char *)ptr + cb; - char *url = NULL; + long protocol = 0; /* * Once that libcurl has called back tool_header_cb() the returned value @@ -88,12 +97,15 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) * Content-Disposition header specifying a filename property. */ + curl_easy_getinfo(outs->config->easy, CURLINFO_PROTOCOL, &protocol); if(hdrcbdata->honor_cd_filename && (cb > 20) && checkprefix("Content-disposition:", str) && - !curl_easy_getinfo(outs->config->easy, CURLINFO_EFFECTIVE_URL, &url) && - url && (checkprefix("http://", url) || checkprefix("https://", url))) { + (protocol & (CURLPROTO_HTTPS|CURLPROTO_HTTP))) { const char *p = str + 20; + if(!outs->stream && !tool_create_output_file(outs, FALSE)) + return failure; + /* look for the 'filename=' parameter (encoded filenames (*=) are not supported) */ for(;;) { @@ -119,19 +131,49 @@ size_t tool_header_cb(char *ptr, size_t size, size_t nmemb, void *userdata) len = (ssize_t)cb - (p - str); filename = parse_filename(p, len); if(filename) { - outs->filename = filename; - outs->alloc_filename = TRUE; + if(outs->stream) { + /* already opened and possibly written to */ + if(outs->fopened) + fclose(outs->stream); + outs->stream = NULL; + + /* rename the initial file name to the new file name */ + rename(outs->filename, filename); + if(outs->alloc_filename) + free(outs->filename); + } outs->is_cd_filename = TRUE; outs->s_isreg = TRUE; outs->fopened = FALSE; - outs->stream = NULL; - hdrcbdata->honor_cd_filename = FALSE; - break; + outs->filename = filename; + outs->alloc_filename = TRUE; + hdrcbdata->honor_cd_filename = FALSE; /* done now! */ + if(!tool_create_output_file(outs, TRUE)) + return failure; } - return failure; + break; } } + if(hdrcbdata->config->show_headers && + (protocol & (CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_RTSP))) { + /* bold headers only happen for HTTP(S) and RTSP */ + char *value = NULL; + + if(!outs->stream && !tool_create_output_file(outs, FALSE)) + return failure; + + if(hdrcbdata->global->isatty) + value = memchr(ptr, ':', cb); + if(value) { + size_t namelen = value - ptr; + fprintf(outs->stream, BOLD "%.*s" BOLDOFF ":", namelen, ptr); + fwrite(&value[1], cb - namelen - 1, 1, outs->stream); + } + else + /* not "handled", just show it */ + fwrite(ptr, cb, 1, outs->stream); + } return cb; } @@ -233,4 +275,3 @@ static char *parse_filename(const char *ptr, size_t len) return copy; } - diff --git a/src/tool_cb_hdr.h b/src/tool_cb_hdr.h index 32032e980..e1b9a920e 100644 --- a/src/tool_cb_hdr.h +++ b/src/tool_cb_hdr.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -39,6 +39,8 @@ */ struct HdrCbData { + struct GlobalConfig *global; + struct OperationConfig *config; struct OutStruct *outs; struct OutStruct *heads; bool honor_cd_filename; diff --git a/src/tool_cb_wrt.c b/src/tool_cb_wrt.c index 6716ba5cd..476fef9a4 100644 --- a/src/tool_cb_wrt.c +++ b/src/tool_cb_wrt.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -32,7 +32,8 @@ #include "memdebug.h" /* keep this as LAST include */ /* create a local file for writing, return TRUE on success */ -bool tool_create_output_file(struct OutStruct *outs) +bool tool_create_output_file(struct OutStruct *outs, + bool append) { struct GlobalConfig *global = outs->config->global; FILE *file; @@ -42,7 +43,7 @@ bool tool_create_output_file(struct OutStruct *outs) return FALSE; } - if(outs->is_cd_filename) { + if(outs->is_cd_filename && !append) { /* don't overwrite existing files */ file = fopen(outs->filename, "rb"); if(file) { @@ -54,7 +55,7 @@ bool tool_create_output_file(struct OutStruct *outs) } /* open file for writing */ - file = fopen(outs->filename, "wb"); + file = fopen(outs->filename, append?"ab":"wb"); if(!file) { warnf(global, "Failed to create the file %s: %s\n", outs->filename, strerror(errno)); @@ -97,7 +98,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) } } - if(config->include_headers) { + if(config->show_headers) { if(bytes > (size_t)CURL_MAX_HTTP_HEADER) { warnf(config->global, "Header data size exceeds single call write " "limit!\n"); @@ -141,7 +142,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata) } #endif - if(!outs->stream && !tool_create_output_file(outs)) + if(!outs->stream && !tool_create_output_file(outs, FALSE)) return failure; if(is_tty && (outs->bytes < 2000) && !config->terminal_binary_ok) { diff --git a/src/tool_cb_wrt.h b/src/tool_cb_wrt.h index 4ccbf3a5f..2b6e98ae4 100644 --- a/src/tool_cb_wrt.h +++ b/src/tool_cb_wrt.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -30,7 +30,7 @@ size_t tool_write_cb(char *buffer, size_t sz, size_t nmemb, void *userdata); /* create a local file for writing, return TRUE on success */ -bool tool_create_output_file(struct OutStruct *outs); +bool tool_create_output_file(struct OutStruct *outs, bool append); #endif /* HEADER_CURL_TOOL_CB_WRT_H */ diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h index 96618f8b1..3bd908879 100644 --- a/src/tool_cfgable.h +++ b/src/tool_cfgable.h @@ -100,7 +100,7 @@ struct OperationConfig { bool use_ascii; /* select ascii or text transfer */ bool autoreferer; /* automatically set referer */ bool failonerror; /* fail on (HTTP) errors */ - bool include_headers; /* send headers to data output */ + bool show_headers; /* show headers to data output */ bool no_body; /* don't get the body */ bool dirlistonly; /* only get the FTP dir list */ bool followlocation; /* follow http redirects */ diff --git a/src/tool_getparam.c b/src/tool_getparam.c index 19454c84a..60a88e266 100644 --- a/src/tool_getparam.c +++ b/src/tool_getparam.c @@ -1722,24 +1722,22 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */ } break; case 'i': - config->include_headers = toggle; /* include the headers as well in the - general output stream */ + config->show_headers = toggle; /* show the headers as well in the + general output stream */ break; case 'j': config->cookiesession = toggle; break; - case 'I': - /* - * no_body will imply include_headers later on - */ + case 'I': /* --head */ config->no_body = toggle; + config->show_headers = toggle; if(SetHTTPrequest(config, (config->no_body)?HTTPREQ_HEAD:HTTPREQ_GET, &config->httpreq)) return PARAM_BAD_USE; break; case 'J': /* --remote-header-name */ - if(config->include_headers) { + if(config->show_headers) { warnf(global, "--include and --remote-header-name cannot be combined.\n"); return PARAM_BAD_USE; diff --git a/src/tool_operate.c b/src/tool_operate.c index 626c30888..5be862228 100644 --- a/src/tool_operate.c +++ b/src/tool_operate.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -851,15 +851,8 @@ static CURLcode operate_do(struct GlobalConfig *global, my_setopt(curl, CURLOPT_INFILESIZE_LARGE, uploadfilesize); my_setopt_str(curl, CURLOPT_URL, this_url); /* what to fetch */ my_setopt(curl, CURLOPT_NOPROGRESS, global->noprogress?1L:0L); - if(config->no_body) { + if(config->no_body) my_setopt(curl, CURLOPT_NOBODY, 1L); - my_setopt(curl, CURLOPT_HEADER, 1L); - } - /* If --metalink is used, we ignore --include (headers in - output) option because mixing headers to the body will - confuse XML parser and/or hash check will fail. */ - else if(!config->use_metalink) - my_setopt(curl, CURLOPT_HEADER, config->include_headers?1L:0L); if(config->oauth_bearer) my_setopt_str(curl, CURLOPT_XOAUTH2_BEARER, config->oauth_bearer); @@ -1373,6 +1366,8 @@ static CURLcode operate_do(struct GlobalConfig *global, hdrcbdata.outs = &outs; hdrcbdata.heads = &heads; + hdrcbdata.global = global; + hdrcbdata.config = config; my_setopt(curl, CURLOPT_HEADERFUNCTION, tool_header_cb); my_setopt(curl, CURLOPT_HEADERDATA, &hdrcbdata); @@ -1523,7 +1518,7 @@ static CURLcode operate_do(struct GlobalConfig *global, /* do not create (or even overwrite) the file in case we get no data because of unmet condition */ curl_easy_getinfo(curl, CURLINFO_CONDITION_UNMET, &cond_unmet); - if(!cond_unmet && !tool_create_output_file(&outs)) + if(!cond_unmet && !tool_create_output_file(&outs, FALSE)) result = CURLE_WRITE_ERROR; } |