mirror of
https://github.com/curl/curl.git
synced 2026-07-28 05:53:11 +03:00
writeout: support to generate JSON output
This commit adds support to generate JSON via the writeout feature:
-w "%{json}"
It leverages the existing infrastructure as much as possible. Thus,
generating the JSON on STDERR is possible by:
-w "%{stderr}%{json}"
This implements a variant of
https://github.com/curl/curl/wiki/JSON#--write-out-json.
Closes #4870
This commit is contained in:
parent
d83402813b
commit
04c03416e6
8 changed files with 361 additions and 83 deletions
|
|
@ -5,7 +5,7 @@
|
|||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2020, 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
|
||||
|
|
@ -25,87 +25,81 @@
|
|||
#include "curlx.h"
|
||||
#include "tool_cfgable.h"
|
||||
#include "tool_writeout.h"
|
||||
#include "tool_writeout_json.h"
|
||||
|
||||
#include "memdebug.h" /* keep this as LAST include */
|
||||
|
||||
typedef enum {
|
||||
VAR_NONE, /* must be the first */
|
||||
VAR_TOTAL_TIME,
|
||||
VAR_NAMELOOKUP_TIME,
|
||||
VAR_CONNECT_TIME,
|
||||
VAR_APPCONNECT_TIME,
|
||||
VAR_PRETRANSFER_TIME,
|
||||
VAR_STARTTRANSFER_TIME,
|
||||
VAR_SIZE_DOWNLOAD,
|
||||
VAR_SIZE_UPLOAD,
|
||||
VAR_SPEED_DOWNLOAD,
|
||||
VAR_SPEED_UPLOAD,
|
||||
VAR_HTTP_CODE,
|
||||
VAR_HTTP_CODE_PROXY,
|
||||
VAR_HEADER_SIZE,
|
||||
VAR_REQUEST_SIZE,
|
||||
VAR_EFFECTIVE_URL,
|
||||
VAR_CONTENT_TYPE,
|
||||
VAR_NUM_CONNECTS,
|
||||
VAR_REDIRECT_TIME,
|
||||
VAR_REDIRECT_COUNT,
|
||||
VAR_FTP_ENTRY_PATH,
|
||||
VAR_REDIRECT_URL,
|
||||
VAR_SSL_VERIFY_RESULT,
|
||||
VAR_PROXY_SSL_VERIFY_RESULT,
|
||||
VAR_EFFECTIVE_FILENAME,
|
||||
VAR_PRIMARY_IP,
|
||||
VAR_PRIMARY_PORT,
|
||||
VAR_LOCAL_IP,
|
||||
VAR_LOCAL_PORT,
|
||||
VAR_HTTP_VERSION,
|
||||
VAR_SCHEME,
|
||||
VAR_STDOUT,
|
||||
VAR_STDERR,
|
||||
VAR_NUM_OF_VARS /* must be the last */
|
||||
} replaceid;
|
||||
|
||||
struct variable {
|
||||
const char *name;
|
||||
replaceid id;
|
||||
};
|
||||
|
||||
|
||||
static const struct variable replacements[]={
|
||||
{"url_effective", VAR_EFFECTIVE_URL},
|
||||
{"http_code", VAR_HTTP_CODE},
|
||||
{"response_code", VAR_HTTP_CODE},
|
||||
{"http_connect", VAR_HTTP_CODE_PROXY},
|
||||
{"time_total", VAR_TOTAL_TIME},
|
||||
{"time_namelookup", VAR_NAMELOOKUP_TIME},
|
||||
{"time_connect", VAR_CONNECT_TIME},
|
||||
{"time_appconnect", VAR_APPCONNECT_TIME},
|
||||
{"time_pretransfer", VAR_PRETRANSFER_TIME},
|
||||
{"time_starttransfer", VAR_STARTTRANSFER_TIME},
|
||||
{"size_header", VAR_HEADER_SIZE},
|
||||
{"size_request", VAR_REQUEST_SIZE},
|
||||
{"size_download", VAR_SIZE_DOWNLOAD},
|
||||
{"size_upload", VAR_SIZE_UPLOAD},
|
||||
{"speed_download", VAR_SPEED_DOWNLOAD},
|
||||
{"speed_upload", VAR_SPEED_UPLOAD},
|
||||
{"content_type", VAR_CONTENT_TYPE},
|
||||
{"num_connects", VAR_NUM_CONNECTS},
|
||||
{"time_redirect", VAR_REDIRECT_TIME},
|
||||
{"num_redirects", VAR_REDIRECT_COUNT},
|
||||
{"ftp_entry_path", VAR_FTP_ENTRY_PATH},
|
||||
{"redirect_url", VAR_REDIRECT_URL},
|
||||
{"ssl_verify_result", VAR_SSL_VERIFY_RESULT},
|
||||
{"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT},
|
||||
{"filename_effective", VAR_EFFECTIVE_FILENAME},
|
||||
{"remote_ip", VAR_PRIMARY_IP},
|
||||
{"remote_port", VAR_PRIMARY_PORT},
|
||||
{"local_ip", VAR_LOCAL_IP},
|
||||
{"local_port", VAR_LOCAL_PORT},
|
||||
{"http_version", VAR_HTTP_VERSION},
|
||||
{"scheme", VAR_SCHEME},
|
||||
{"stdout", VAR_STDOUT},
|
||||
{"stderr", VAR_STDERR},
|
||||
{NULL, VAR_NONE}
|
||||
static const struct writeoutvar variables[] = {
|
||||
{"url_effective", VAR_EFFECTIVE_URL, 0,
|
||||
CURLINFO_EFFECTIVE_URL, JSON_STRING},
|
||||
{"http_code", VAR_HTTP_CODE, 0,
|
||||
CURLINFO_RESPONSE_CODE, JSON_LONG},
|
||||
{"response_code", VAR_HTTP_CODE, 0,
|
||||
CURLINFO_RESPONSE_CODE, JSON_LONG},
|
||||
{"http_connect", VAR_HTTP_CODE_PROXY, 0,
|
||||
CURLINFO_HTTP_CONNECTCODE, JSON_LONG},
|
||||
{"time_total", VAR_TOTAL_TIME, 0,
|
||||
CURLINFO_TOTAL_TIME_T, JSON_TIME},
|
||||
{"time_namelookup", VAR_NAMELOOKUP_TIME, 0,
|
||||
CURLINFO_NAMELOOKUP_TIME_T, JSON_TIME},
|
||||
{"time_connect", VAR_CONNECT_TIME, 0,
|
||||
CURLINFO_CONNECT_TIME_T, JSON_TIME},
|
||||
{"time_appconnect", VAR_APPCONNECT_TIME, 0,
|
||||
CURLINFO_APPCONNECT_TIME_T, JSON_TIME},
|
||||
{"time_pretransfer", VAR_PRETRANSFER_TIME, 0,
|
||||
CURLINFO_PRETRANSFER_TIME_T, JSON_TIME},
|
||||
{"time_starttransfer", VAR_STARTTRANSFER_TIME, 0,
|
||||
CURLINFO_STARTTRANSFER_TIME_T, JSON_TIME},
|
||||
{"size_header", VAR_HEADER_SIZE, 0,
|
||||
CURLINFO_HEADER_SIZE, JSON_LONG},
|
||||
{"size_request", VAR_REQUEST_SIZE, 0,
|
||||
CURLINFO_REQUEST_SIZE, JSON_LONG},
|
||||
{"size_download", VAR_SIZE_DOWNLOAD, 0,
|
||||
CURLINFO_SIZE_DOWNLOAD_T, JSON_LONG},
|
||||
{"size_upload", VAR_SIZE_UPLOAD, 0,
|
||||
CURLINFO_SIZE_UPLOAD_T, JSON_LONG},
|
||||
{"speed_download", VAR_SPEED_DOWNLOAD, 0,
|
||||
CURLINFO_SPEED_DOWNLOAD_T, JSON_TIME},
|
||||
{"speed_upload", VAR_SPEED_UPLOAD, 0,
|
||||
CURLINFO_SPEED_UPLOAD_T, JSON_TIME},
|
||||
{"content_type", VAR_CONTENT_TYPE, 0,
|
||||
CURLINFO_CONTENT_TYPE, JSON_STRING},
|
||||
{"num_connects", VAR_NUM_CONNECTS, 0,
|
||||
CURLINFO_NUM_CONNECTS, JSON_LONG},
|
||||
{"time_redirect", VAR_REDIRECT_TIME, 0,
|
||||
CURLINFO_REDIRECT_TIME_T, JSON_TIME},
|
||||
{"num_redirects", VAR_REDIRECT_COUNT, 0,
|
||||
CURLINFO_REDIRECT_COUNT, JSON_LONG},
|
||||
{"ftp_entry_path", VAR_FTP_ENTRY_PATH, 0,
|
||||
CURLINFO_FTP_ENTRY_PATH, JSON_STRING},
|
||||
{"redirect_url", VAR_REDIRECT_URL, 0,
|
||||
CURLINFO_REDIRECT_URL, JSON_STRING},
|
||||
{"ssl_verify_result", VAR_SSL_VERIFY_RESULT, 0,
|
||||
CURLINFO_SSL_VERIFYRESULT, JSON_LONG},
|
||||
{"proxy_ssl_verify_result", VAR_PROXY_SSL_VERIFY_RESULT, 0,
|
||||
CURLINFO_PROXY_SSL_VERIFYRESULT, JSON_LONG},
|
||||
{"filename_effective", VAR_EFFECTIVE_FILENAME, 0,
|
||||
0, JSON_FILENAME},
|
||||
{"remote_ip", VAR_PRIMARY_IP, 0,
|
||||
CURLINFO_PRIMARY_IP, JSON_STRING},
|
||||
{"remote_port", VAR_PRIMARY_PORT, 0,
|
||||
CURLINFO_PRIMARY_PORT, JSON_LONG},
|
||||
{"local_ip", VAR_LOCAL_IP, 0,
|
||||
CURLINFO_LOCAL_IP, JSON_STRING},
|
||||
{"local_port", VAR_LOCAL_PORT, 0,
|
||||
CURLINFO_LOCAL_PORT, JSON_LONG},
|
||||
{"http_version", VAR_HTTP_VERSION, 0,
|
||||
CURLINFO_HTTP_VERSION, JSON_VERSION},
|
||||
{"scheme", VAR_SCHEME, 0,
|
||||
CURLINFO_SCHEME, JSON_STRING},
|
||||
{"stdout", VAR_STDOUT, 1,
|
||||
0, JSON_NONE},
|
||||
{"stderr", VAR_STDERR, 1,
|
||||
0, JSON_NONE},
|
||||
{"json", VAR_JSON, 1,
|
||||
0, JSON_NONE},
|
||||
{NULL, VAR_NONE, 1,
|
||||
0, JSON_NONE}
|
||||
};
|
||||
|
||||
void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
|
||||
|
|
@ -138,10 +132,10 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
|
|||
}
|
||||
keepit = *end;
|
||||
*end = 0; /* zero terminate */
|
||||
for(i = 0; replacements[i].name; i++) {
|
||||
if(curl_strequal(ptr, replacements[i].name)) {
|
||||
for(i = 0; variables[i].name; i++) {
|
||||
if(curl_strequal(ptr, variables[i].name)) {
|
||||
match = TRUE;
|
||||
switch(replacements[i].id) {
|
||||
switch(variables[i].id) {
|
||||
case VAR_EFFECTIVE_URL:
|
||||
if((CURLE_OK ==
|
||||
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &stringp))
|
||||
|
|
@ -334,6 +328,8 @@ void ourWriteOut(CURL *curl, struct OutStruct *outs, const char *writeinfo)
|
|||
case VAR_STDERR:
|
||||
stream = stderr;
|
||||
break;
|
||||
case VAR_JSON:
|
||||
ourWriteOutJSON(variables, curl, outs, stream);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue