Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SFTP (libssh2) postquotes are executed despite operation will be retried #2939

tomaszewskip opened this issue Sep 4, 2018 · 1 comment


Copy link

I did this

  1. Setup cURL easy interface to do some operations on the sftp server (let's call it sftp://server),
  2. call curl_easy_perform to execute operation from previous step,
  3. call curl_easy_reset to clear structures, but leave handle to reuse existing connection,
  4. setup CURLOPT_URL to download file from sftp://server (sftp://server/file1),
  5. setup CURLOPT_POSTQUOTE to remove sftp://server/file1 when download is successful,
  6. call curl_easy_perform

Following code shows this approach

CURL *handle = curl_easy_init();
// setup some operation here, which is done on sftp://server
curl_easy_setopt(handle, CUROPT_URL, "sftp://server/file");
curl_easy_setopt(handle, CURLOPT_POSTQUOTE, "*rm sftp://server/file");
// setup write functions

What may happen:

  • first curl_easy_perform is successful,
  • during second curl_easy_perform, it is decided to retry operation, as existing connection cannot be reused,
  • sftp_done is called to cleanup connection,
  • post quote commands are executed and sftp://server/file is removed,
  • new connection is established and it fails as sftp://server/file does not exist.

I expected the following

Postquote commands are not executed when retry operation is going to be executed, as explained here:

[...]  The commands will only be run if no error occurred [...]

Following patch does the thing:

Index: curl-7.61.0/lib/ssh.c
--- curl-7.61.0.orig/lib/ssh.c
+++ curl-7.61.0/lib/ssh.c
@@ -3218,8 +3218,10 @@ static CURLcode sftp_done(struct connect
   if(!status) {
     /* Post quote commands are executed after the SFTP_CLOSE state to avoid
        errors that could happen due to open file handles during POSTQUOTE
-       operation */
-    if(!status && !premature && conn->data->set.postquote) {
+       operation. This step is skipped if this is retry operation, to avoid
+       executing postquotes when operation is not successful.*/
+    if(!status && !premature && conn->data->set.postquote
+               && !conn->bits.retry) {
       sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
       state(conn, SSH_SFTP_CLOSE);

curl/libcurl version


operating system

Ubuntu 16.04 (libssh2 1.8.0)

Copy link

bagder commented Sep 4, 2018

Thanks! I noticed the libssh backend has the exact same logic so I copied your fix into that function as well and made a PR out of your patch: #2940

@bagder bagder closed this as completed in daa3c45 Sep 4, 2018
falconindy pushed a commit to falconindy/curl that referenced this issue Sep 10, 2018
@lock lock bot locked as resolved and limited conversation to collaborators Dec 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

No branches or pull requests

2 participants