curl 7.83.0 headers bonanza

Welcome to the third curl release of the year.

Release presentation

curl 7.83.0 release presentation


the 207th release
6 changes
53 days (total: 8,804)

125 bug-fixes (total: 7,816)
185 commits (total: 28,507)
2 new public libcurl function (total: 88)
0 new curl_easy_setopt() option (total: 295)

2 new curl command line option (total: 247)
60 contributors, 29 new (total: 2,626)
35 authors, 13 new (total: 1,027)
4 security fixes (total: 115)
0 USD paid in Bug Bounties (total: 16,900 USD)

Security fixes

The reason the Bug Bounty amount above is still at zero dollars for this cycle is that the rewards have not been set yet. There will be money handed out for all of them.

CVE-2022-22576– OAUTH2 bearer bypass in connection re-use

curl might reuse wrong connections when OAUTH2 bearer tokens are used.

CVE-2022-27774 – Credential leak on redirect

When curl follows a redirect to another protocol or to another port number, it could keep sending the credentials over the new connection and thus leak sensible information to the wrong party.

CVE-2022-27775 – Bad local IPv6 connection reuse

curl could reuse the wrong connection when asking to connect to an IPv6 address using zone id, as the zone id was not correctly checked when picking connection from the pool.

CVE-2022-27776 – Auth/cookie leak on redirect

curl’s system to avoid sending custom auth and cookies to other hosts after redirects did not take port number or protocol into account, and could leak sensible information to the wrong party.


While the number of changes can be counted to six, I will group them under four subtitles.

Cherry-pick headers

(These features are all landed as experimental to start with so you need to make sure to enable these in the build if you want to play with them.)

Two new functions have been introduced, curl_easy_header() and curl_easy_nextheader(). They allow applications to get the contents of specific HTTP headers or iterate over all of them after a transfer has been done. Applications have been able to get access to headers already before, but these functions bring a new level of ease and flexibility.

The command line tool was also extended to use these functions to allow easy header output to the --write-out option, both individual headers and also all headers as a JSON object. Read further.


Long time TODO listing was now made into reality. Using this option, you can ask curl to not overwrite a local file even if you have specified it as an output file name in curl a command line.


The second of the new command line options: tell curl to remove the possibly partial file that might have been downloaded when it detects and returns an error.


This is the third supported HTTP/3 backend.


curl: error out if -T and -d are used for the same URL

One of them implies PUT and the other implies POST, they cannot both be used for the same target URL and starting now curl will error out properly with a message saying so.

system.h: ifdefs for MCST-LCC compiler

Yet another compiler is now supported by default when you build curl.

curl: fix segmentation fault for empty output file names

Also now generally behave better as in telling the user why it errors out because of this situation.

http2: RST the stream if we stop it on our own will

When an application stops a transfer that is being done over HTTP/2, it was not properly shut down from curl’s side and therefore could end up wasting data that the server kept sending but that the client wouldn’t receive anymore!

http: close the stream (not connection) on time condition abort

For a special kind of transfer abort due to a failed time condition, curl would always close the connection to stop the transfer, instead of just closing the stream. This of course made no different on HTTP/1 but for later HTTP versions the connection should be kept alive even for this condition.

http: streamclose “already downloaded”

Another case of curl deciding the connection shouldn’t continue when it for in fact should be kept alive for HTTP/2 and HTTP/3.

http: reject header contents with nul bytes

HTTP headers cannot legally contain these bytes as per the protocol specification and as hyper already rejects these response it made sense to unify the implementation and refuse them in native code as well. It might also save us from future badness.

http: return error on colon-less HTTP headers

Similar to the change above, HTTP/1 headers must have colons so curl now will consider it a broken transfer if a header arrives without. This makes curl much pickier of course, but should not affect any “real” HTTP transfers.

mqtt: better handling of TCP disconnect mid-message

A nasty busy-loop occurred if the connection was cut off at the wrong time for an MQTT transfer.

ngtcp2: numerous improvements

HTTP/3 with ngtcp2 was greatly enhanced during this cycle in several ways. Check out the changelog for the specific details and do try it out!

tls: make mbedtls and NSS check for h2, not nghttp2

In leftovers from the past we still checked if HTTP/2 support is present by the wrong #ifdef in a few places in the code. nghttp2 is no longer the only HTTP/2 library we can use.

curl: escape ‘?’ in code generated with --libcurl

It turns out you could sneakily insert and get fooled by trigraphs otherwise:

curl --libcurl client.c --user-agent "??/\");char c[]={'i','d',' ','>','x',0},m[]={'r',0};fclose(popen(c,m));//" http://example.invalid