curl: add %{header_json} support in -w handling

Outputs all response headers as a JSON object.
This commit is contained in:
Daniel Stenberg 2022-03-17 17:55:06 +01:00
parent 2d45137e1e
commit 4133a69f2d
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
6 changed files with 66 additions and 10 deletions

View 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.

View 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)

View 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);

View 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,

View 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
@ -29,12 +29,12 @@
#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);
}

View 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 */