diff options
author | AlexSm <alex@ydb.tech> | 2024-01-18 11:28:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-18 11:28:56 +0100 |
commit | 9d0a3761b3201e0d9db879a7adf91876ebdb0564 (patch) | |
tree | 541d11ac878c18efd7ebca81e35112aa0fef995b /contrib/libs/curl/src/tool_writeout.c | |
parent | 404ef8886ecc9736bc58ade6da2fbd83b486a408 (diff) | |
download | ydb-9d0a3761b3201e0d9db879a7adf91876ebdb0564.tar.gz |
Library import 8 (#1074)
* Library import 8
* Add contrib/libs/cxxsupp/libcxx/include/__verbose_abort
Diffstat (limited to 'contrib/libs/curl/src/tool_writeout.c')
-rw-r--r-- | contrib/libs/curl/src/tool_writeout.c | 244 |
1 files changed, 240 insertions, 4 deletions
diff --git a/contrib/libs/curl/src/tool_writeout.c b/contrib/libs/curl/src/tool_writeout.c index 2789ee20bf..981065c9ef 100644 --- a/contrib/libs/curl/src/tool_writeout.c +++ b/contrib/libs/curl/src/tool_writeout.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 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 @@ -28,6 +28,7 @@ #include "tool_cfgable.h" #include "tool_writeout.h" #include "tool_writeout_json.h" +#include "dynbuf.h" #include "memdebug.h" /* keep this as LAST include */ @@ -72,7 +73,9 @@ static const struct httpmap http_version[] = { Variable names should be in alphabetical order. */ static const struct writeoutvar variables[] = { + {"certs", VAR_CERT, CURLINFO_NONE, writeString}, {"content_type", VAR_CONTENT_TYPE, CURLINFO_CONTENT_TYPE, writeString}, + {"conn_id", VAR_CONN_ID, CURLINFO_CONN_ID, writeOffset}, {"errormsg", VAR_ERRORMSG, CURLINFO_NONE, writeString}, {"exitcode", VAR_EXITCODE, CURLINFO_NONE, writeLong}, {"filename_effective", VAR_EFFECTIVE_FILENAME, CURLINFO_NONE, writeString}, @@ -85,6 +88,7 @@ static const struct writeoutvar variables[] = { {"local_ip", VAR_LOCAL_IP, CURLINFO_LOCAL_IP, writeString}, {"local_port", VAR_LOCAL_PORT, CURLINFO_LOCAL_PORT, writeLong}, {"method", VAR_EFFECTIVE_METHOD, CURLINFO_EFFECTIVE_METHOD, writeString}, + {"num_certs", VAR_NUM_CERTS, CURLINFO_NONE, writeLong}, {"num_connects", VAR_NUM_CONNECTS, CURLINFO_NUM_CONNECTS, writeLong}, {"num_headers", VAR_NUM_HEADERS, CURLINFO_NONE, writeLong}, {"num_redirects", VAR_REDIRECT_COUNT, CURLINFO_REDIRECT_COUNT, writeLong}, @@ -120,8 +124,29 @@ static const struct writeoutvar variables[] = { writeTime}, {"time_total", VAR_TOTAL_TIME, CURLINFO_TOTAL_TIME_T, writeTime}, {"url", VAR_INPUT_URL, CURLINFO_NONE, writeString}, + {"url.scheme", VAR_INPUT_URLSCHEME, CURLINFO_NONE, writeString}, + {"url.user", VAR_INPUT_URLUSER, CURLINFO_NONE, writeString}, + {"url.password", VAR_INPUT_URLPASSWORD, CURLINFO_NONE, writeString}, + {"url.options", VAR_INPUT_URLOPTIONS, CURLINFO_NONE, writeString}, + {"url.host", VAR_INPUT_URLHOST, CURLINFO_NONE, writeString}, + {"url.port", VAR_INPUT_URLPORT, CURLINFO_NONE, writeString}, + {"url.path", VAR_INPUT_URLPATH, CURLINFO_NONE, writeString}, + {"url.query", VAR_INPUT_URLQUERY, CURLINFO_NONE, writeString}, + {"url.fragment", VAR_INPUT_URLFRAGMENT, CURLINFO_NONE, writeString}, + {"url.zoneid", VAR_INPUT_URLZONEID, CURLINFO_NONE, writeString}, + {"urle.scheme", VAR_INPUT_URLESCHEME, CURLINFO_NONE, writeString}, + {"urle.user", VAR_INPUT_URLEUSER, CURLINFO_NONE, writeString}, + {"urle.password", VAR_INPUT_URLEPASSWORD, CURLINFO_NONE, writeString}, + {"urle.options", VAR_INPUT_URLEOPTIONS, CURLINFO_NONE, writeString}, + {"urle.host", VAR_INPUT_URLEHOST, CURLINFO_NONE, writeString}, + {"urle.port", VAR_INPUT_URLEPORT, CURLINFO_NONE, writeString}, + {"urle.path", VAR_INPUT_URLEPATH, CURLINFO_NONE, writeString}, + {"urle.query", VAR_INPUT_URLEQUERY, CURLINFO_NONE, writeString}, + {"urle.fragment", VAR_INPUT_URLEFRAGMENT, CURLINFO_NONE, writeString}, + {"urle.zoneid", VAR_INPUT_URLEZONEID, CURLINFO_NONE, writeString}, {"url_effective", VAR_EFFECTIVE_URL, CURLINFO_EFFECTIVE_URL, writeString}, {"urlnum", VAR_URLNUM, CURLINFO_NONE, writeLong}, + {"xfer_id", VAR_EASY_ID, CURLINFO_XFER_ID, writeOffset}, {NULL, VAR_NONE, CURLINFO_NONE, NULL} }; @@ -162,12 +187,96 @@ static int writeTime(FILE *stream, const struct writeoutvar *wovar, return 1; /* return 1 if anything was written */ } +static int urlpart(struct per_transfer *per, writeoutid vid, + const char **contentp) +{ + CURLU *uh = curl_url(); + int rc = 0; + if(uh) { + CURLUPart cpart = CURLUPART_HOST; + char *part = NULL; + const char *url = NULL; + + if(vid >= VAR_INPUT_URLEHOST) { + if(curl_easy_getinfo(per->curl, CURLINFO_EFFECTIVE_URL, &url)) + rc = 5; + } + else + url = per->this_url; + + if(!rc) { + switch(vid) { + case VAR_INPUT_URLSCHEME: + case VAR_INPUT_URLESCHEME: + cpart = CURLUPART_SCHEME; + break; + case VAR_INPUT_URLUSER: + case VAR_INPUT_URLEUSER: + cpart = CURLUPART_USER; + break; + case VAR_INPUT_URLPASSWORD: + case VAR_INPUT_URLEPASSWORD: + cpart = CURLUPART_PASSWORD; + break; + case VAR_INPUT_URLOPTIONS: + case VAR_INPUT_URLEOPTIONS: + cpart = CURLUPART_OPTIONS; + break; + case VAR_INPUT_URLHOST: + case VAR_INPUT_URLEHOST: + cpart = CURLUPART_HOST; + break; + case VAR_INPUT_URLPORT: + case VAR_INPUT_URLEPORT: + cpart = CURLUPART_PORT; + break; + case VAR_INPUT_URLPATH: + case VAR_INPUT_URLEPATH: + cpart = CURLUPART_PATH; + break; + case VAR_INPUT_URLQUERY: + case VAR_INPUT_URLEQUERY: + cpart = CURLUPART_QUERY; + break; + case VAR_INPUT_URLFRAGMENT: + case VAR_INPUT_URLEFRAGMENT: + cpart = CURLUPART_FRAGMENT; + break; + case VAR_INPUT_URLZONEID: + case VAR_INPUT_URLEZONEID: + cpart = CURLUPART_ZONEID; + break; + default: + /* not implemented */ + rc = 4; + break; + } + } + if(!rc && curl_url_set(uh, CURLUPART_URL, url, + CURLU_GUESS_SCHEME|CURLU_NON_SUPPORT_SCHEME)) + rc = 2; + + if(!rc && curl_url_get(uh, cpart, &part, CURLU_DEFAULT_PORT)) + rc = 3; + + if(!rc && part) + *contentp = part; + curl_url_cleanup(uh); + } + else + return 1; + return rc; +} + static int writeString(FILE *stream, const struct writeoutvar *wovar, struct per_transfer *per, CURLcode per_result, bool use_json) { bool valid = false; const char *strinfo = NULL; + const char *freestr = NULL; + struct dynbuf buf; + curlx_dyn_init(&buf, 256*1024); DEBUGASSERT(wovar->writefunc == writeString); @@ -193,6 +302,51 @@ static int writeString(FILE *stream, const struct writeoutvar *wovar, } else { switch(wovar->id) { + case VAR_CERT: + if(per->certinfo) { + int i; + bool error = FALSE; + for(i = 0; (i < per->certinfo->num_of_certs) && !error; i++) { + struct curl_slist *slist; + + for(slist = per->certinfo->certinfo[i]; slist; slist = slist->next) { + size_t len; + if(curl_strnequal(slist->data, "cert:", 5)) { + if(curlx_dyn_add(&buf, &slist->data[5])) { + error = TRUE; + break; + } + } + else { + if(curlx_dyn_add(&buf, slist->data)) { + error = TRUE; + break; + } + } + len = curlx_dyn_len(&buf); + if(len) { + char *ptr = curlx_dyn_ptr(&buf); + if(ptr[len -1] != '\n') { + /* add a newline to make things look better */ + if(curlx_dyn_addn(&buf, "\n", 1)) { + error = TRUE; + break; + } + } + } + } + } + if(!error) { + strinfo = curlx_dyn_ptr(&buf); + if(!strinfo) + /* maybe not a TLS protocol */ + strinfo = ""; + valid = true; + } + } + else + strinfo = ""; /* no cert info */ + break; case VAR_ERRORMSG: if(per_result) { strinfo = (per->errorbuffer && per->errorbuffer[0]) ? @@ -212,6 +366,33 @@ static int writeString(FILE *stream, const struct writeoutvar *wovar, valid = true; } break; + case VAR_INPUT_URLSCHEME: + case VAR_INPUT_URLUSER: + case VAR_INPUT_URLPASSWORD: + case VAR_INPUT_URLOPTIONS: + case VAR_INPUT_URLHOST: + case VAR_INPUT_URLPORT: + case VAR_INPUT_URLPATH: + case VAR_INPUT_URLQUERY: + case VAR_INPUT_URLFRAGMENT: + case VAR_INPUT_URLZONEID: + case VAR_INPUT_URLESCHEME: + case VAR_INPUT_URLEUSER: + case VAR_INPUT_URLEPASSWORD: + case VAR_INPUT_URLEOPTIONS: + case VAR_INPUT_URLEHOST: + case VAR_INPUT_URLEPORT: + case VAR_INPUT_URLEPATH: + case VAR_INPUT_URLEQUERY: + case VAR_INPUT_URLEFRAGMENT: + case VAR_INPUT_URLEZONEID: + if(per->this_url) { + if(!urlpart(per, wovar->id, &strinfo)) { + freestr = strinfo; + valid = true; + } + } + break; default: DEBUGASSERT(0); break; @@ -231,7 +412,9 @@ static int writeString(FILE *stream, const struct writeoutvar *wovar, if(use_json) fprintf(stream, "\"%s\":null", wovar->name); } + curl_free((char *)freestr); + curlx_dyn_free(&buf); return 1; /* return 1 if anything was written */ } @@ -250,6 +433,10 @@ static int writeLong(FILE *stream, const struct writeoutvar *wovar, } else { switch(wovar->id) { + case VAR_NUM_CERTS: + longinfo = per->certinfo ? per->certinfo->num_of_certs : 0; + valid = true; + break; case VAR_NUM_HEADERS: longinfo = per->num_headers; valid = true; @@ -321,12 +508,22 @@ static int writeOffset(FILE *stream, const struct writeoutvar *wovar, return 1; /* return 1 if anything was written */ } -void ourWriteOut(const char *writeinfo, struct per_transfer *per, +void ourWriteOut(struct OperationConfig *config, struct per_transfer *per, CURLcode per_result) { FILE *stream = stdout; + const char *writeinfo = config->writeout; const char *ptr = writeinfo; bool done = FALSE; + struct curl_certinfo *certinfo; + CURLcode res = curl_easy_getinfo(per->curl, CURLINFO_CERTINFO, &certinfo); + bool fclose_stream = FALSE; + + if(!writeinfo) + return; + + if(!res && certinfo) + per->certinfo = certinfo; while(ptr && *ptr && !done) { if('%' == *ptr && ptr[1]) { @@ -360,10 +557,16 @@ void ourWriteOut(const char *writeinfo, struct per_transfer *per, done = TRUE; break; case VAR_STDOUT: + if(fclose_stream) + fclose(stream); + fclose_stream = FALSE; stream = stdout; break; case VAR_STDERR: - stream = stderr; + if(fclose_stream) + fclose(stream); + fclose_stream = FALSE; + stream = tool_stderr; break; case VAR_JSON: ourWriteOutJSON(stream, variables, per, per_result); @@ -380,7 +583,8 @@ void ourWriteOut(const char *writeinfo, struct per_transfer *per, } } if(!match) { - fprintf(stderr, "curl: unknown --write-out variable: '%.*s'\n", + fprintf(tool_stderr, + "curl: unknown --write-out variable: '%.*s'\n", (int)vlen, ptr); } ptr = end + 1; /* pass the end */ @@ -404,6 +608,36 @@ void ourWriteOut(const char *writeinfo, struct per_transfer *per, else fputs("%header{", stream); } + else if(!strncmp("output{", &ptr[1], 7)) { + bool append = FALSE; + ptr += 8; + if((ptr[0] == '>') && (ptr[1] == '>')) { + append = TRUE; + ptr += 2; + } + end = strchr(ptr, '}'); + if(end) { + char fname[512]; /* holds the longest file name */ + size_t flen = end - ptr; + if(flen < sizeof(fname)) { + FILE *stream2; + memcpy(fname, ptr, flen); + fname[flen] = 0; + stream2 = fopen(fname, append? FOPEN_APPENDTEXT : + FOPEN_WRITETEXT); + if(stream2) { + /* only change if the open worked */ + if(fclose_stream) + fclose(stream); + stream = stream2; + fclose_stream = TRUE; + } + } + ptr = end + 1; + } + else + fputs("%output{", stream); + } else { /* illegal syntax, then just output the characters that are used */ fputc('%', stream); @@ -436,4 +670,6 @@ void ourWriteOut(const char *writeinfo, struct per_transfer *per, ptr++; } } + if(fclose_stream) + fclose(stream); } |