Hello!

I have been using curl to upload files with sftp, and I have encountered an
unexpected behaviour related to timeouts and disconnects. When setting
CURLOPT_TIMEOUT_MS to some value, and the network disconnects during a file
upload, libcurl does not timeout the operation.

I found a commit on Github that indicates that this behaviour is actually
intentional to address a problem that could leak to memory leaks for
libssh2 (
https://github.com/curl/curl/commit/f31760e63b4e9ef1eb25f8f211390f8239388515
).
I actually was relying on CURLOPT_TIMEOUT_MS to ensure that a task running
on a server ran for at most that time. Assuming this is intentional, is
there a
workaround or a way to mitigate this behavior, to ensure that
curl_easy_perform
ends within the specified timeout?

As an example, when running the sample code with CURLOPT_TIMEOUT_MS set to
20000ms, the task will time out and disconnect with the following output,
which
is expected, because it hits the timeout

$ time ./example
*   Trying 10.0.0.1:22...
* Connected to example.com (10.0.0.1) port 22 (#0)
* SSH MD5 fingerprint: fingerprint
* SSH authentication methods available: password
* Initialized password authentication
* Authentication complete
* Operation timed out after 20000 milliseconds with 0 bytes received
* Closing connection 0
Curl error [28]
real 0m20.475s
user 0m0.118s
sys 0m0.054s

However if I run this example and disconnect the network after
"Authentication
complete", the output I get is the following (and the command ends after I
reconnect the network). In which the connection seems to hang until it can
reconnect.

$ time ./example
*   Trying 10.0.0.1:22...
* Connected to example.com (10.0.0.1) port 22 (#0)
* SSH MD5 fingerprint: fingerprint
* SSH authentication methods available: password
* Initialized password authentication
* Authentication complete
* Operation timed out after 20000 milliseconds with 0 bytes received
* Closing connection 0
Curl error [28]
real 2m46.291s
user 0m0.038s
sys 0m0.033s

This is the example code I have used to isolate this specific issue. Also,
the
libcurl version is libcurl/7.71.0-DEV OpenSSL/1.1.1f zlib/1.2.11
libssh2/1.9.0,
on Ubuntu 20.04.

---
#include <stdlib.h>
#include <curl/curl.h>

int main() {
    curl_global_init(CURL_GLOBAL_ALL);

    CURL* handle = curl_easy_init();
    const char* url = "sftp://user:p...@example.com/path/filename";;
    FILE *file = fopen("filename", "rb");

    curl_easy_setopt(handle, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
    curl_easy_setopt(handle, CURLOPT_TIMEOUT_MS, 20000);
    curl_easy_setopt(handle, CURLOPT_USERPWD, "user:pwd");
    curl_easy_setopt(handle, CURLOPT_URL, url);
    curl_easy_setopt(handle, CURLOPT_UPLOAD, 1L);
    curl_easy_setopt(handle, CURLOPT_READDATA, file);
    curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0);
    curl_easy_setopt(handle, CURLOPT_VERBOSE, 1);

    CURLcode code = curl_easy_perform(handle);
    if (code != 0) {
        printf("Curl error [%d]", code);
    }

    curl_easy_cleanup(handle);
    fclose(file);
    curl_global_cleanup();

    return EXIT_SUCCESS;
}
---

Any thoughts or ideas on this would be much appreciated,

Thanks!
-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html

Reply via email to