Unverified Commit c1c27625 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

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.
parent 6876ccf9
Loading
Loading
Loading
Loading
+52 −11
Original line number Diff line number Diff line
@@ -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;
        outs->filename = filename;
        outs->alloc_filename = TRUE;
        hdrcbdata->honor_cd_filename = FALSE; /* done now! */
        if(!tool_create_output_file(outs, TRUE))
          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;
}
+3 −1
Original line number Diff line number Diff line
@@ -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;
+7 −6
Original line number Diff line number Diff line
@@ -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) {
+2 −2
Original line number Diff line number Diff line
@@ -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 */
+1 −1
Original line number Diff line number Diff line
@@ -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 */
Loading