]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
curl: add %{header_json} support in -w handling
authorDaniel Stenberg <daniel@haxx.se>
Thu, 17 Mar 2022 16:55:06 +0000 (17:55 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Tue, 22 Mar 2022 07:24:25 +0000 (08:24 +0100)
Outputs all response headers as a JSON object.

docs/cmdline-opts/write-out.d
lib/headers.c
src/tool_writeout.c
src/tool_writeout.h
src/tool_writeout_json.c
src/tool_writeout_json.h

index 6d8ed44925ffb3a5ae458da18d55f2fb5249c4f6..11f01b87a24c914457886dce49557b384158266c 100644 (file)
@@ -52,6 +52,9 @@ option. (Added in 7.26.0)
 The initial path curl ended up in when logging on to the remote FTP
 server. (Added in 7.15.4)
 .TP
+.B header_json
+A JSON object with all HTTP response headers from the recent transfer.
+.TP
 .B http_code
 The numerical response code that was found in the last retrieved HTTP(S) or
 FTP(s) transfer.
index 67ae00fb4267feabe074cab1ff9756b524eeb808..add23b786e9988803a2e6307dfe9b27b4eda22bb 100644 (file)
@@ -155,7 +155,8 @@ struct curl_header *curl_easy_nextheader(CURL *easy,
       hs = pick->ptr;
       if((hs->type & type) && (hs->request == request))
         break;
-    } while((pick = pick->next));
+      pick = pick->next;
+    } while(pick);
   }
 
   if(!pick)
index c2e4095530aaee9f501b12b24be797a5b823ca1f..c2239efde1da77fe732e1e633a8d2a105f381676 100644 (file)
@@ -75,6 +75,7 @@ static const struct writeoutvar variables[] = {
   {"exitcode", VAR_EXITCODE, 0, writeLong},
   {"filename_effective", VAR_EFFECTIVE_FILENAME, 0, writeString},
   {"ftp_entry_path", VAR_FTP_ENTRY_PATH, CURLINFO_FTP_ENTRY_PATH, writeString},
+  {"header_json", VAR_HEADER_JSON, 0, NULL},
   {"http_code", VAR_HTTP_CODE, CURLINFO_RESPONSE_CODE, writeLong},
   {"http_connect", VAR_HTTP_CODE_PROXY, CURLINFO_HTTP_CONNECTCODE, writeLong},
   {"http_version", VAR_HTTP_VERSION, CURLINFO_HTTP_VERSION, writeString},
@@ -218,9 +219,8 @@ static int writeString(FILE *stream, const struct writeoutvar *wovar,
   if(valid) {
     DEBUGASSERT(strinfo);
     if(use_json) {
-      fprintf(stream, "\"%s\":\"", wovar->name);
+      fprintf(stream, "\"%s\":", wovar->name);
       jsonWriteString(stream, strinfo);
-      fputs("\"", stream);
     }
     else
       fputs(strinfo, stream);
@@ -366,6 +366,9 @@ void ourWriteOut(const char *writeinfo, struct per_transfer *per,
               case VAR_JSON:
                 ourWriteOutJSON(stream, variables, per, per_result);
                 break;
+              case VAR_HEADER_JSON:
+                headerJSON(stream, per);
+                break;
               default:
                 (void)variables[i].writefunc(stream, &variables[i],
                                              per, per_result, false);
index b8f51ffaa3bbedad44146198757dad5e4232f223..abf14e30b1c0ffbbfa76d258f9634a6b39b1374e 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, 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
@@ -35,6 +35,7 @@ typedef enum {
   VAR_ERRORMSG,
   VAR_EXITCODE,
   VAR_FTP_ENTRY_PATH,
+  VAR_HEADER_JSON,
   VAR_HEADER_SIZE,
   VAR_HTTP_CODE,
   VAR_HTTP_CODE_PROXY,
index caa1ea6f3d1947f7697e7dce66d41ca6e2491686..2ccc9942efa073e7ffe629a2cce1fb385f8edb81 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, 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
 #include "tool_writeout_json.h"
 #include "tool_writeout.h"
 
-
 void jsonWriteString(FILE *stream, const char *in)
 {
   const char *i = in;
   const char *in_end = in + strlen(in);
 
+  fputc('\"', stream);
   for(; i < in_end; i++) {
     switch(*i) {
     case '\\':
@@ -68,6 +68,7 @@ void jsonWriteString(FILE *stream, const char *in)
       break;
     }
   }
+  fputc('\"', stream);
 }
 
 void ourWriteOutJSON(FILE *stream, const struct writeoutvar mappings[],
@@ -85,7 +86,54 @@ void ourWriteOutJSON(FILE *stream, const struct writeoutvar mappings[],
 
   /* The variables are sorted in alphabetical order but as a special case
      curl_version (which is not actually a --write-out variable) is last. */
-  fprintf(stream, "\"curl_version\":\"");
+  fprintf(stream, "\"curl_version\":");
   jsonWriteString(stream, curl_version());
-  fprintf(stream, "\"}");
+  fprintf(stream, "}");
+}
+
+#ifdef _MSC_VER
+/* warning C4706: assignment within conditional expression */
+#pragma warning(disable:4706)
+#endif
+
+void headerJSON(FILE *stream, struct per_transfer *per)
+{
+  struct curl_header *header;
+  struct curl_header *prev = NULL;
+
+  fputc('{', stream);
+  while((header = curl_easy_nextheader(per->curl, CURLH_HEADER, -1,
+                                       prev))) {
+    if(prev)
+      fputs(",\n", stream);
+    jsonWriteString(stream, header->name);
+    fputc(':', stream);
+    prev = header;
+    if(header->amount > 1) {
+      if(!header->index) {
+        /* act on the 0-index entry and pull the others in, then output in a
+           JSON list */
+        size_t a = header->amount;
+        size_t i = 0;
+        char *name = header->name;
+        fputc('[', stream);
+        do {
+          jsonWriteString(stream, header->value);
+          if(++i >= a)
+            break;
+          fputc(',', stream);
+          if(curl_easy_header(per->curl, name, i, CURLH_HEADER,
+                              -1, &header))
+            break;
+        } while(1);
+      }
+      fputc(']', stream);
+    }
+    else {
+      fputc('[', stream);
+      jsonWriteString(stream, header->value);
+      fputc(']', stream);
+    }
+  }
+  fputs("\n}", stream);
 }
index f6b3a86afefb525fd31ae6b2e3f69be771e578ae..f10e260b52f3188a0ff52b28e9e3064fef40401d 100644 (file)
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2022, 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
@@ -26,7 +26,7 @@
 
 void ourWriteOutJSON(FILE *stream, const struct writeoutvar mappings[],
                      struct per_transfer *per, CURLcode per_result);
-
+void headerJSON(FILE *stream, struct per_transfer *per);
 void jsonWriteString(FILE *stream, const char *in);
 
 #endif /* HEADER_CURL_TOOL_WRITEOUT_H */