Why did that curl request take so long?

I’ve just discovered that you can get curl to report how long each part of a session took.

I set up a bash script

t=(--write-out "\n DNS Lookup:%{time_namelookup}s\n TCP Connect:%{time_connect}s\n TLS Handshake: %{time_appconnect}s\n Total Time: %{time_total}s\n")
...
curl -X PUT --header 'Content-Type: application/json' "${t[@]}" ....

and in the output it gives

 DNS Lookup:0.000033s
TCP Connect:0.003088s
TLS Handshake: 0.322826s
Total Time: 0.981765s

Note the \n in the text to give new lines.

For more details

see curl man page. –write-out.

You can specify an output file, stderr or stdout.

There are many parameters, the performance timing ones are

  • time_appconnect: The time, in seconds, it took from the start until the SSL/SSH/etc connect/handshake to the remote host was completed.
  • time_connect: The time, in seconds, it took from the start until the TCP connect to the remote host (or proxy) was completed.
  • time_namelookup: The time, in seconds, it took from the start until the name resolving was completed.
  • time_posttransfer:The time it took from the start until the last byte is sent by libcurl. In microseconds.
  • time_pretransfer: The time, in seconds, it took from the start until the file transfer was just about to begin. This includes all pre-transfer commands and negotiations that are specific to the particular protocol(s) involved.
  • time_queue: The time, in seconds, the transfer was queued during its run. This adds the queue time for each redirect step that may have happened. Transfers may be queued for significant amounts of time when connection or parallel limits are in place.
  • time_redirect: The time, in seconds, it took for all redirection steps including name lookup, connect, pretransfer and transfer before the final transaction was started. “time_redirect” shows the complete execution time for multiple redirections.
  • time_starttransfer: The time, in seconds, it took from the start until the first byte was received. This includes time_pretransfer and also the time the server needed to calculate the result.
  • time_total: The total time, in seconds, that the full operation lasted.
  • tls_earlydata: The amount of bytes that were sent as TLSv1.3 early data. This is 0 if this TLS feature was not used and negative if the data sent had been rejected by the server. The use of early data is enabled via the command line option “–tls-earlydata“.

z/OS curl headers not always working.

I had problems using cURL trying to get to a back end server (z/OSMF). Once it did work, I realised it should not have worked – because I had not defined a security profile!

My basic bash script was

set -x 
trace=" "
ca="--cacert /u/colin/ssl/zosmfca.pem"
key="--cert key.pem:12345678 "
insecure="--insecure"
cert=" "
header='-H "X-CSRF-ZOSMF-HEADER: Dummy "'
userid="--basic --user colin2:password"
url="https://127.0.0.1:10443/zosmf/rest/mvssubs"

If I hard coded the header statement it worked

curl -v  -H "X-CSRF-ZOSMF-HEADER: dummy" $trace $cert $key $insecure $userid $ca  $url 

If I used the bash variable in $header it did not work, even though it looked as if was identical to the case above.

curl  -v  -H  $header $trace $cert $key $insecure  $userid $ca  $url 

{ “errorID”:”IZUG846W”,”errorMsg”:”IZUG846W: An HTTP request for a z/OSMF REST service was received from a remote site. The request was rejected, however, because the remote site “” is not permitted to z/OSMF server “IZUSVR” on target system “127.0.0.1:10443″ .”}

If I put the parameter in a config file (curl.config below) it worked

-H "X-CSRF-ZOSMF-HEADER: Dummy" 

and I used

curl -v --config ./curl.config $trace $cert $key $insecure $userid $ca $url 

I think it is all to do with an interaction between curl, bash and double quotes.

It worked – when it should not have worked!

The documentation says you need a security profile set up see Enabling cross-origin resource sharing (CORS) for REST services.

On my system, there was no profile IZUDFLT.REST…. so I do not understand how it works, as the documentation implies I need an allow list!