Yes: "http_version": "1.1"
No: "http_version": 1.1
- Variable names should be in alphabetical order.
+ Variable names MUST 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},
+ {"content_type", VAR_CONTENT_TYPE, CURLINFO_CONTENT_TYPE, writeString},
{"errormsg", VAR_ERRORMSG, CURLINFO_NONE, writeString},
{"exitcode", VAR_EXITCODE, CURLINFO_NONE, writeLong},
{"filename_effective", VAR_EFFECTIVE_FILENAME, CURLINFO_NONE, writeString},
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.fragment", VAR_INPUT_URLFRAGMENT, CURLINFO_NONE, writeString},
{"url.host", VAR_INPUT_URLHOST, CURLINFO_NONE, writeString},
- {"url.port", VAR_INPUT_URLPORT, CURLINFO_NONE, writeString},
+ {"url.options", VAR_INPUT_URLOPTIONS, CURLINFO_NONE, writeString},
+ {"url.password", VAR_INPUT_URLPASSWORD, CURLINFO_NONE, writeString},
{"url.path", VAR_INPUT_URLPATH, CURLINFO_NONE, writeString},
+ {"url.port", VAR_INPUT_URLPORT, CURLINFO_NONE, writeString},
{"url.query", VAR_INPUT_URLQUERY, CURLINFO_NONE, writeString},
- {"url.fragment", VAR_INPUT_URLFRAGMENT, CURLINFO_NONE, writeString},
+ {"url.scheme", VAR_INPUT_URLSCHEME, CURLINFO_NONE, writeString},
+ {"url.user", VAR_INPUT_URLUSER, 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},
+ {"url_effective", VAR_EFFECTIVE_URL, CURLINFO_EFFECTIVE_URL, writeString},
+ {"urle.fragment", VAR_INPUT_URLEFRAGMENT, CURLINFO_NONE, writeString},
{"urle.host", VAR_INPUT_URLEHOST, CURLINFO_NONE, writeString},
- {"urle.port", VAR_INPUT_URLEPORT, CURLINFO_NONE, writeString},
+ {"urle.options", VAR_INPUT_URLEOPTIONS, CURLINFO_NONE, writeString},
+ {"urle.password", VAR_INPUT_URLEPASSWORD, CURLINFO_NONE, writeString},
{"urle.path", VAR_INPUT_URLEPATH, CURLINFO_NONE, writeString},
+ {"urle.port", VAR_INPUT_URLEPORT, CURLINFO_NONE, writeString},
{"urle.query", VAR_INPUT_URLEQUERY, CURLINFO_NONE, writeString},
- {"urle.fragment", VAR_INPUT_URLEFRAGMENT, CURLINFO_NONE, writeString},
+ {"urle.scheme", VAR_INPUT_URLESCHEME, CURLINFO_NONE, writeString},
+ {"urle.user", VAR_INPUT_URLEUSER, 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}
+ {"xfer_id", VAR_EASY_ID, CURLINFO_XFER_ID, writeOffset}
};
static int writeTime(FILE *stream, const struct writeoutvar *wovar,
return 1; /* return 1 if anything was written */
}
+static int
+matchvar(const void *m1, const void *m2)
+{
+ const struct writeoutvar *v1 = m1;
+ const struct writeoutvar *v2 = m2;
+
+ return strcmp(v1->name, v2->name);
+}
+
+#define MAX_WRITEOUT_NAME_LENGTH 24
+
void ourWriteOut(struct OperationConfig *config, struct per_transfer *per,
CURLcode per_result)
{
struct curl_certinfo *certinfo;
CURLcode res = curl_easy_getinfo(per->curl, CURLINFO_CERTINFO, &certinfo);
bool fclose_stream = FALSE;
+ struct dynbuf name;
if(!writeinfo)
return;
if(!res && certinfo)
per->certinfo = certinfo;
+ curlx_dyn_init(&name, MAX_WRITEOUT_NAME_LENGTH);
while(ptr && *ptr && !done) {
if('%' == *ptr && ptr[1]) {
if('%' == ptr[1]) {
char *end;
size_t vlen;
if('{' == ptr[1]) {
- int i;
- bool match = FALSE;
+ struct writeoutvar *wv = NULL;
+ struct writeoutvar find = { 0 };
end = strchr(ptr, '}');
ptr += 2; /* pass the % and the { */
if(!end) {
continue;
}
vlen = end - ptr;
- for(i = 0; variables[i].name; i++) {
- if((strlen(variables[i].name) == vlen) &&
- curl_strnequal(ptr, variables[i].name, vlen)) {
- match = TRUE;
- switch(variables[i].id) {
- case VAR_ONERROR:
- if(per_result == CURLE_OK)
- /* this isn't error so skip the rest */
- done = TRUE;
- break;
- case VAR_STDOUT:
- if(fclose_stream)
- fclose(stream);
- fclose_stream = FALSE;
- stream = stdout;
- break;
- case VAR_STDERR:
- if(fclose_stream)
- fclose(stream);
- fclose_stream = FALSE;
- stream = tool_stderr;
- break;
- 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);
- break;
- }
+
+ curlx_dyn_reset(&name);
+ if(!curlx_dyn_addn(&name, ptr, vlen)) {
+ find.name = curlx_dyn_ptr(&name);
+ wv = bsearch(&find,
+ variables, sizeof(variables)/sizeof(variables[0]),
+ sizeof(variables[0]), matchvar);
+ }
+ if(wv) {
+ switch(wv->id) {
+ case VAR_ONERROR:
+ if(per_result == CURLE_OK)
+ /* this isn't error so skip the rest */
+ done = TRUE;
+ break;
+ case VAR_STDOUT:
+ if(fclose_stream)
+ fclose(stream);
+ fclose_stream = FALSE;
+ stream = stdout;
+ break;
+ case VAR_STDERR:
+ if(fclose_stream)
+ fclose(stream);
+ fclose_stream = FALSE;
+ stream = tool_stderr;
+ break;
+ case VAR_JSON:
+ ourWriteOutJSON(stream, variables,
+ sizeof(variables)/sizeof(variables[0]),
+ per, per_result);
+ break;
+ case VAR_HEADER_JSON:
+ headerJSON(stream, per);
+ break;
+ default:
+ (void)wv->writefunc(stream, wv, per, per_result, false);
break;
}
}
- if(!match) {
+ else {
fprintf(tool_stderr,
"curl: unknown --write-out variable: '%.*s'\n",
(int)vlen, ptr);
}
if(fclose_stream)
fclose(stream);
+ curlx_dyn_free(&name);
}
\r
</protocol>
<stdout nonewline="yes">
-{"certs":"","content_type":"text/html","conn_id":0,"errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.scheme":"http","url.user":null,"url.password":null,"url.options":null,"url.host":"%HOSTIP","url.port":"%HTTPPORT","url.path":"/%TESTNUMBER","url.query":null,"url.fragment":null,"url.zoneid":null,"urle.scheme":"http","urle.user":null,"urle.password":null,"urle.options":null,"urle.host":"%HOSTIP","urle.port":"%HTTPPORT","urle.path":"/%TESTNUMBER","urle.query":null,"urle.fragment":null,"urle.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"}
+{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"}
</stdout>
</verify>
</testcase>
\r
</protocol>
<stdout mode="text">
-{"certs":"","content_type":"text/html","conn_id":0,"errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out972","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"%HOSTIP","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.scheme":"http","url.user":null,"url.password":null,"url.options":null,"url.host":"%HOSTIP","url.port":"%HTTPPORT","url.path":"/%TESTNUMBER","url.query":null,"url.fragment":null,"url.zoneid":null,"urle.scheme":"http","urle.user":null,"urle.password":null,"urle.options":null,"urle.host":"%HOSTIP","urle.port":"%HTTPPORT","urle.path":"/%TESTNUMBER","urle.query":null,"urle.fragment":null,"urle.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"}
+{"certs":"","conn_id":0,"content_type":"text/html","errormsg":null,"exitcode":0,"filename_effective":"%LOGDIR/out%TESTNUMBER","ftp_entry_path":null,"http_code":200,"http_connect":0,"http_version":"1.1","local_ip":"127.0.0.1","local_port":13,"method":"GET","num_certs":0,"num_connects":1,"num_headers":9,"num_redirects":0,"proxy_ssl_verify_result":0,"proxy_used":0,"redirect_url":null,"referer":null,"remote_ip":"%HOSTIP","remote_port":%HTTPPORT,"response_code":200,"scheme":"http","size_download":445,"size_header":4019,"size_request":4019,"size_upload":0,"speed_download":13,"speed_upload":13,"ssl_verify_result":0,"time_appconnect":0.000013,"time_connect":0.000013,"time_namelookup":0.000013,"time_pretransfer":0.000013,"time_redirect":0.000013,"time_starttransfer":0.000013,"time_total":0.000013,"url":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","url.fragment":null,"url.host":"127.0.0.1","url.options":null,"url.password":null,"url.path":"/%TESTNUMBER","url.port":"%HTTPPORT","url.query":null,"url.scheme":"http","url.user":null,"url.zoneid":null,"url_effective":"http://%HOSTIP:%HTTPPORT/%TESTNUMBER","urle.fragment":null,"urle.host":"127.0.0.1","urle.options":null,"urle.password":null,"urle.path":"/%TESTNUMBER","urle.port":"%HTTPPORT","urle.query":null,"urle.scheme":"http","urle.user":null,"urle.zoneid":null,"urlnum":0,"xfer_id":0,"curl_version":"curl-unit-test-fake-version"}
</stdout>
</verify>
</testcase>