Buy commercial curl support. We
help you work out your issues, debug your libcurl applications, use the API,
port to new platforms, add new features and more. With a team lead by the
curl founder Daniel himself.
libcurl and nginx persistent auth behavior
- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]
From: Luke Palmer via curl-library <curl-library_at_lists.haxx.se>
Date: Sat, 31 May 2025 10:34:08 -0400
Hi all,
I've been working on understanding how libcurl and nginx implement HTTP/2
(and 3) with SPNEGO. I've reached a point that I don't think is covered by
specifications and where libcurl and nginx have incompatible opinions about
what should happen, and I wanted to see if anyone else has experience or
insight.
The connection and first request all work as I'd expect. libcurl either
makes a first request without auth then responds to a 401 requesting
negotiation (CURLAUTH_ANYSAFE), or proactively sends authorization along
with the first request (CURLAUTH_NEGOTIATE).
Things get interesting when multiplexing additional requests onto the same
connection (CURLPIPE_MULTIPLEX). libcurl appears to believe that because
authentication has already occurred on the *connection*, nothing else needs
to be done. Nginx appears to believe that authentication is a property of
the *stream*, and expects the client to behave just as if the stream was a
new connection.
To put this another way, libcurl assumes persistent authentication is
present when multiplexing, and nginx does not natively implement persistent
authentication at all.
What ends up happening is that libcurl will not proactively send auth
headers for the additional stream, nor will it respond to a 401 requesting
negotiation for that stream. The additional stream terminates in a 401.
This can be avoided with CURLPIPE_NOTHING, but then there's not much point
to HTTP/2 or 3.
I believe the relevant section of code is here. If there are multiple
requests then libcurl assume authentication is persistent:
https://github.com/curl/curl/blob/4977747f0da325f5ba4e7f346ce1db8eb6899885/lib/http_negotiate.c#L177
I think this has been an issue for a while. Reference:
https://curl.se/mail/lib-2020-02/0073.html
This seems tricky to get right, but it's also a shame to have the most
popular client not be compatible with the most popular server.
Your thoughts appreciated!
Thanks
Luke
Date: Sat, 31 May 2025 10:34:08 -0400
Hi all,
I've been working on understanding how libcurl and nginx implement HTTP/2
(and 3) with SPNEGO. I've reached a point that I don't think is covered by
specifications and where libcurl and nginx have incompatible opinions about
what should happen, and I wanted to see if anyone else has experience or
insight.
The connection and first request all work as I'd expect. libcurl either
makes a first request without auth then responds to a 401 requesting
negotiation (CURLAUTH_ANYSAFE), or proactively sends authorization along
with the first request (CURLAUTH_NEGOTIATE).
Things get interesting when multiplexing additional requests onto the same
connection (CURLPIPE_MULTIPLEX). libcurl appears to believe that because
authentication has already occurred on the *connection*, nothing else needs
to be done. Nginx appears to believe that authentication is a property of
the *stream*, and expects the client to behave just as if the stream was a
new connection.
To put this another way, libcurl assumes persistent authentication is
present when multiplexing, and nginx does not natively implement persistent
authentication at all.
What ends up happening is that libcurl will not proactively send auth
headers for the additional stream, nor will it respond to a 401 requesting
negotiation for that stream. The additional stream terminates in a 401.
This can be avoided with CURLPIPE_NOTHING, but then there's not much point
to HTTP/2 or 3.
I believe the relevant section of code is here. If there are multiple
requests then libcurl assume authentication is persistent:
https://github.com/curl/curl/blob/4977747f0da325f5ba4e7f346ce1db8eb6899885/lib/http_negotiate.c#L177
I think this has been an issue for a while. Reference:
https://curl.se/mail/lib-2020-02/0073.html
This seems tricky to get right, but it's also a shame to have the most
popular client not be compatible with the most popular server.
Your thoughts appreciated!
Thanks
Luke
-- Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.htmlReceived on 2025-05-31