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.html

Reply via email to