Skip to content

Idle time seems to count towards timeout configured in CURLOPT_TIMEOUT #3264

@jasal82

Description

@jasal82

In my application I'm using libcurl to perform FTP requests via the easy interface. I create a handle with curl_easy_init() and keep it open for as long as I need it. Most of the time the handle will be in idle state. Actual calls to curl_easy_perform() might occur, but sometimes there will be no request at all before the handle is destroyed via curl_easy_cleanup().

curl_easy_cleanup() sends a QUIT command to the FTP server. The server implementation I am using wants to respond to that command by sending Bye on the connection. What I observe now is that if CURLOPT_TIMEOUT is set to some value X and the time span between curl_easy_init() and curl_easy_cleanup() is greater than X (without any curl_easy_perform() in between), libcurl closes the connection immediately after sending the QUIT command, making the FTP server fail to send the Bye because the connection is already closed. I tested with multiple values of CURLOPT_TIMEOUT and I can confirm that the timeout is directly correlated to the observed behavior.

I skimmed through the libcurl sources and it seems that the current timestamp is stored inside the connection handle (conn->now). This is done in only one place and that is in the Curl_setup_conn() function in url.c. The stored timestamp is then used to evaluate the timeout by calculating the difference against the current timestamp in Curl_pp_state_timeout() in pingpong.c.

This tells me that idle time counts towards the timeout which seems unintuitive to me. I don't know where Curl_setup_conn() is called but obviously the stored time is updated whenever a curl_easy_perform() is executed, which is good. That way I can keep the connection open (and fix my problem) by sending periodic NOOPs on the control connection. But in my opinion it should not be necessary in the first place. The timeout should affect the runtime of curl_easy_perform() only.

Maybe I'm using libcurl the wrong way, but I think the behavior is wrong in an application context. It might make sense for command line calls of curl but when using the library functions I would expect that CURLOPT_TIMEOUT is equivalent to a transmit timeout and does not count idle time on the handle.

The issue can be reproduced on Linux and Windows with the latest version of libcurl.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions