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