Buy commercial curl support from WolfSSL. 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
himself.
Re: Support HTTP2 Goaway Frame callback for curl multi
- Contemporary messages sorted: [ by date ] [ by thread ] [ by subject ] [ by author ] [ by messages with attachments ]
From: Ray Satiro via curl-library <curl-library_at_lists.haxx.se>
Date: Fri, 5 Jan 2024 15:35:16 -0500
On 1/5/2024 11:28 AM, Cao Duc Quan via curl-library wrote:
> 1. Open a new HTTP2 connection by creating an HTTP GET to an url path.
> I created a CURLM object and added the easy handle for HTTP GET
> Request to it.
> 2. Next HTTP request will be sent in the HTTP2 connection created by
> step 1. I created a new easy handle for this request and added it to
> CURLM object created in step 1.
> 3. After a few hours or less, the connection at step 1 will be closed
> by server side (due to idle timeout or TTL). The server will send a
> GOAWAY frame to start Graceful shutdown before explicitly closing it
> after 60s so that both Client and Server could finish their in-flight
> transferring.
> 4. My library needs to detect the connection is closed and reopen a
> new one (step 1).
>
> So I have a problem at step 2:
> - If the connection created by step 1 received a GOAWAY frame, cURL
> will open a new HTTP2 to send the next HTTP request. The new HTTP2
> request will fail because there is some logic check at server side to
> ensure only connection created by step 1 is allowed. I believe this is
> odd checking but that is the logic from the server side and I could
> not change it.
If the first connection has idled approximately 2 minutes (118 seconds)
[1] then curl should close it before before processing the next transfer
on the new connection. If a GOAWAY frame is received on the first
connection before then (either bundled with the previous request or due
to a timeout in the interim) it *should* do the same thing:
* received GOAWAY, error=0, last_stream=1
* Connection 0 seems to be dead
* The cache now contains 0 members
* Curl_disconnect(conn #0, dead=1)
* Closing connection
* TLSv1.2 (IN), TLS alert, close notify (256):
* TLSv1.2 (OUT), TLS alert, close notify (256):
The connection cache logic for that is in function extract_if_dead [2].
nginx test #1:
- set `http2_max_requests 1;`
- `sudo systemctl reload nginx.service` to reload the config
- first curl_easy_perform
- first transfer reply and curl receives GOAWAY
- second curl_easy_perform
- curl opens a new connection for the second transfer
- second transfer reply
nginx test #2:
- unset `http2_max_requests 1;`
- set `http2_idle_timeout 30s;`
- `sudo systemctl reload nginx.service` to reload the config
- first curl_easy_perform
- first transfer reply and curl does not receive GOAWAY
- wait 1 minute (GOAWAY packet sent by nginx during this time according
to wireshark)
- second curl_easy_perform
- curl receives GOAWAY before initiating the second transfer
- curl opens a new connection for the second transfer
- second transfer reply
If curl is working as intended then I do not understand why your
application needs to handle GOAWAY on its own. Are you using the latest
curl?
[1]: https://curl.se/libcurl/c/CURLOPT_MAXAGE_CONN.html
[2]: https://github.com/curl/curl/blob/curl-8_5_0/lib/url.c#L767-L777
Date: Fri, 5 Jan 2024 15:35:16 -0500
On 1/5/2024 11:28 AM, Cao Duc Quan via curl-library wrote:
> 1. Open a new HTTP2 connection by creating an HTTP GET to an url path.
> I created a CURLM object and added the easy handle for HTTP GET
> Request to it.
> 2. Next HTTP request will be sent in the HTTP2 connection created by
> step 1. I created a new easy handle for this request and added it to
> CURLM object created in step 1.
> 3. After a few hours or less, the connection at step 1 will be closed
> by server side (due to idle timeout or TTL). The server will send a
> GOAWAY frame to start Graceful shutdown before explicitly closing it
> after 60s so that both Client and Server could finish their in-flight
> transferring.
> 4. My library needs to detect the connection is closed and reopen a
> new one (step 1).
>
> So I have a problem at step 2:
> - If the connection created by step 1 received a GOAWAY frame, cURL
> will open a new HTTP2 to send the next HTTP request. The new HTTP2
> request will fail because there is some logic check at server side to
> ensure only connection created by step 1 is allowed. I believe this is
> odd checking but that is the logic from the server side and I could
> not change it.
If the first connection has idled approximately 2 minutes (118 seconds)
[1] then curl should close it before before processing the next transfer
on the new connection. If a GOAWAY frame is received on the first
connection before then (either bundled with the previous request or due
to a timeout in the interim) it *should* do the same thing:
* received GOAWAY, error=0, last_stream=1
* Connection 0 seems to be dead
* The cache now contains 0 members
* Curl_disconnect(conn #0, dead=1)
* Closing connection
* TLSv1.2 (IN), TLS alert, close notify (256):
* TLSv1.2 (OUT), TLS alert, close notify (256):
The connection cache logic for that is in function extract_if_dead [2].
nginx test #1:
- set `http2_max_requests 1;`
- `sudo systemctl reload nginx.service` to reload the config
- first curl_easy_perform
- first transfer reply and curl receives GOAWAY
- second curl_easy_perform
- curl opens a new connection for the second transfer
- second transfer reply
nginx test #2:
- unset `http2_max_requests 1;`
- set `http2_idle_timeout 30s;`
- `sudo systemctl reload nginx.service` to reload the config
- first curl_easy_perform
- first transfer reply and curl does not receive GOAWAY
- wait 1 minute (GOAWAY packet sent by nginx during this time according
to wireshark)
- second curl_easy_perform
- curl receives GOAWAY before initiating the second transfer
- curl opens a new connection for the second transfer
- second transfer reply
If curl is working as intended then I do not understand why your
application needs to handle GOAWAY on its own. Are you using the latest
curl?
[1]: https://curl.se/libcurl/c/CURLOPT_MAXAGE_CONN.html
[2]: https://github.com/curl/curl/blob/curl-8_5_0/lib/url.c#L767-L777
-- Unsubscribe: https://lists.haxx.se/mailman/listinfo/curl-library Etiquette: https://curl.se/mail/etiquette.htmlReceived on 2024-01-05