]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
lib: xfer_setup simplify
authorStefan Eissing <stefan@eissing.org>
Wed, 6 Aug 2025 09:56:08 +0000 (11:56 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 6 Aug 2025 12:12:46 +0000 (14:12 +0200)
Make variants for transfers that send/receive or do both with just the
parameters they need. Split out the shutdown setting into a separate
function. Only FTP bothers with that.

Closes #18203

15 files changed:
lib/curl_rtmp.c
lib/dict.c
lib/ftp.c
lib/gopher.c
lib/http.c
lib/imap.c
lib/openldap.c
lib/pop3.c
lib/rtsp.c
lib/smtp.c
lib/transfer.c
lib/transfer.h
lib/vssh/libssh.c
lib/vssh/libssh2.c
lib/vssh/wolfssh.c

index 584c8a9df6b69d3d155cfe3644e22bc50482b21d..07e0eeba2652a25afffae9e657fc092da8dc64a6 100644 (file)
@@ -296,10 +296,10 @@ static CURLcode rtmp_do(struct Curl_easy *data, bool *done)
 
   if(data->state.upload) {
     Curl_pgrsSetUploadSize(data, data->state.infilesize);
-    Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
+    Curl_xfer_setup_send(data, FIRSTSOCKET);
   }
   else
-    Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE);
+    Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, FALSE);
   *done = TRUE;
   return CURLE_OK;
 }
index 30e13b45479ec7375dc79bd28689869c16e35ab5..b8ede7848d49e88e6d69fa1d69a50c41b1578aa0 100644 (file)
@@ -242,7 +242,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
       failf(data, "Failed sending DICT request");
       goto error;
     }
-    Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE); /* no upload */
+    Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, FALSE);
   }
   else if(curl_strnequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
           curl_strnequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
@@ -283,7 +283,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
       failf(data, "Failed sending DICT request");
       goto error;
     }
-    Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE);
+    Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, FALSE);
   }
   else {
 
@@ -305,7 +305,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done)
         goto error;
       }
 
-      Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE);
+      Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, FALSE);
     }
   }
 
index 3eec2f14eeb34119a1880015a9a094508ea5ae11..d9539c7fd4d3b29107b2465884bf0d1a95a92e97 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -546,12 +546,14 @@ static CURLcode ftp_initiate_transfer(struct Curl_easy *data,
 
     /* FTP upload, shutdown DATA, ignore shutdown errors, as we rely
      * on the server response on the CONTROL connection. */
-    Curl_xfer_setup2(data, CURL_XFER_SEND, -1, TRUE, TRUE);
+    Curl_xfer_setup_send(data, SECONDARYSOCKET);
+    Curl_xfer_set_shutdown(data, TRUE, TRUE);
   }
   else {
     /* FTP download, shutdown, do not ignore errors */
-    Curl_xfer_setup2(data, CURL_XFER_RECV,
-                     ftpc->retr_size_saved, TRUE, FALSE);
+    Curl_xfer_setup_recv(data, SECONDARYSOCKET,
+                         ftpc->retr_size_saved, FALSE);
+    Curl_xfer_set_shutdown(data, TRUE, FALSE);
   }
 
   ftpc->pp.pending_resp = TRUE; /* expect server response */
index 82e02ed17034d4b634e0dc6c8bb3020ac1b95cf1..9ac3cca3e1911f15ee00adb2f484b6b1bdf877cb 100644 (file)
@@ -240,7 +240,7 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done)
   if(result)
     return result;
 
-  Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE);
+  Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, FALSE);
   return CURLE_OK;
 }
 #endif /* CURL_DISABLE_GOPHER */
index d41aefdfaa37d6850ec3530580fd33fdb17bbb8b..5e2a8c260f4df442dd65f723d560e0edb9eb697a 100644 (file)
@@ -2415,7 +2415,7 @@ static CURLcode http_req_complete(struct Curl_easy *data,
 out:
   if(!result) {
     /* setup variables for the upcoming transfer */
-    Curl_xfer_setup1(data, CURL_XFER_SENDRECV, -1, TRUE);
+    Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1, TRUE);
   }
   return result;
 }
index 5949b667e98021df4f9c1424eed5bdca68c559b7..d8f46a034c69e04b78370345b547926aa8995fe0 100644 (file)
@@ -1347,7 +1347,7 @@ static CURLcode imap_state_fetch_resp(struct Curl_easy *data,
     else {
       /* IMAP download */
       data->req.maxdownload = size;
-      Curl_xfer_setup1(data, CURL_XFER_RECV, size, FALSE);
+      Curl_xfer_setup_recv(data, FIRSTSOCKET, size, FALSE);
     }
   }
   else {
@@ -1398,7 +1398,7 @@ static CURLcode imap_state_append_resp(struct Curl_easy *data,
     Curl_pgrsSetUploadSize(data, data->state.infilesize);
 
     /* IMAP upload */
-    Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
+    Curl_xfer_setup_send(data, FIRSTSOCKET);
 
     /* End of DO phase */
     imap_state(data, imapc, IMAP_STOP);
index c532be3f3243e7e5928ebec7835bf9582ee30a04..c10f07220fe96c7116dc52ffb2c81292c62d3b36 100644 (file)
@@ -993,7 +993,7 @@ static CURLcode oldap_do(struct Curl_easy *data, bool *done)
   }
 
   lr->msgid = msgid;
-  Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE);
+  Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, FALSE);
   *done = TRUE;
 
 out:
index 493b36f45fdede608f63375fdce28da4636a402a..9417bb5fe822ca0a32e2a6baa6d980dbd20eded5 100644 (file)
@@ -1116,7 +1116,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data,
 
   if(pop3->transfer == PPTRANSFER_BODY) {
     /* POP3 download */
-    Curl_xfer_setup1(data, CURL_XFER_RECV, -1, FALSE);
+    Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, FALSE);
 
     if(pp->overflow) {
       /* The recv buffer contains data that is actually body content so send
index 46ff660aed852640152742a2cf8a0ada408e108a..153b98ea39f7871d5d2a48ec9222722157556561 100644 (file)
@@ -370,7 +370,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
   }
 
   if(rtspreq == RTSPREQ_RECEIVE) {
-    Curl_xfer_setup1(data, CURL_XFER_RECV, -1, TRUE);
+    Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, TRUE);
     goto out;
   }
 
@@ -636,7 +636,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
   if(result)
     goto out;
 
-  Curl_xfer_setup1(data, CURL_XFER_SENDRECV, -1, TRUE);
+  Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1, TRUE);
 
   /* issue the request */
   result = Curl_req_send(data, &req_buffer, httpversion);
index 4bb3bde4afa4d882e28ed92482a1cc88ccd4de85..97083e41f8bf182f64e09ef47edae68c81a91db5 100644 (file)
@@ -1257,7 +1257,7 @@ static CURLcode smtp_state_data_resp(struct Curl_easy *data,
     Curl_pgrsSetUploadSize(data, data->state.infilesize);
 
     /* SMTP upload */
-    Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
+    Curl_xfer_setup_send(data, FIRSTSOCKET);
 
     /* End of DO phase */
     smtp_state(data, smtpc, SMTP_STOP);
index 6ba5d0b30919f1d0dcae8f7daceae01c269a195e..76b7a8964bd712658d5fb76cba52168d6c759be7 100644 (file)
@@ -717,99 +717,94 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
   return CURLE_OK;
 }
 
-/*
- * xfer_setup() is called to setup basic properties for the transfer.
- */
 static void xfer_setup(
   struct Curl_easy *data,   /* transfer */
-  int sockindex,            /* socket index to read from or -1 */
-  curl_off_t size,          /* -1 if unknown at this point */
-  bool getheader,           /* TRUE if header parsing is wanted */
-  int writesockindex,       /* socket index to write to, it may be the same we
-                               read from. -1 disables */
-  bool shutdown,            /* shutdown connection at transfer end. Only
-                             * supported when sending OR receiving. */
-  bool shutdown_err_ignore  /* errors during shutdown do not fail the
-                             * transfer */
+  int send_idx,             /* sockindex to send on or -1 */
+  int recv_idx,             /* sockindex to receive on or -1 */
+  curl_off_t recv_size,     /* how much to receive, -1 if unknown */
+  bool getheader            /* TRUE if header parsing is wanted */
   )
 {
   struct SingleRequest *k = &data->req;
   struct connectdata *conn = data->conn;
-  bool want_send = Curl_req_want_send(data);
 
   DEBUGASSERT(conn != NULL);
-  DEBUGASSERT((sockindex <= 1) && (sockindex >= -1));
-  DEBUGASSERT((writesockindex <= 1) && (writesockindex >= -1));
-  DEBUGASSERT(!shutdown || (sockindex == -1) || (writesockindex == -1));
-
-  if(Curl_conn_is_multiplex(conn, FIRSTSOCKET) || want_send) {
-    /* when multiplexing, the read/write sockets need to be the same! */
-    if(want_send)
-      /* special and HTTP-specific */
-      writesockindex = FIRSTSOCKET;
-    conn->recv_idx = sockindex;
-    conn->send_idx = writesockindex;
-  }
-  else {
-    conn->recv_idx = sockindex;
-    conn->send_idx = writesockindex;
-  }
+  /* indexes are in range */
+  DEBUGASSERT((send_idx <= 1) && (send_idx >= -1));
+  DEBUGASSERT((recv_idx <= 1) && (recv_idx >= -1));
+  /* if request wants to send, switching off the send direction is wrong */
+  DEBUGASSERT((send_idx >= 0) || !Curl_req_want_send(data));
+
+  conn->send_idx = send_idx;
+  conn->recv_idx = recv_idx;
 
   k->getheader = getheader;
-  k->size = size;
-  k->shutdown = shutdown;
-  k->shutdown_err_ignore = shutdown_err_ignore;
+  /* without receiving, there should be not recv_size */
+  DEBUGASSERT((conn->recv_idx >= 0) || (recv_size == -1));
+  k->size = recv_size;
+  /* by default, we do not shutdown at the end of the transfer */
+  k->shutdown = FALSE;
+  k->shutdown_err_ignore = FALSE;
 
   /* The code sequence below is placed in this function just because all
      necessary input is not always known in do_complete() as this function may
      be called after that */
-
   if(!k->getheader) {
     k->header = FALSE;
-    if(size > 0)
-      Curl_pgrsSetDownloadSize(data, size);
+    if(recv_size > 0)
+      Curl_pgrsSetDownloadSize(data, recv_size);
   }
+
   /* we want header and/or body, if neither then do not do this! */
   if(k->getheader || !data->req.no_body) {
 
-    if(sockindex != -1)
+    if(conn->recv_idx != -1)
       k->keepon |= KEEP_RECV;
 
-    if(writesockindex != -1)
+    if(conn->send_idx != -1)
       k->keepon |= KEEP_SEND;
-  } /* if(k->getheader || !data->req.no_body) */
+  }
 
-  CURL_TRC_M(data, "transfer setup: recv_idx=%d, send_idx=%d",
+  CURL_TRC_M(data, "xfer_setup: recv_idx=%d, send_idx=%d",
              conn->recv_idx, conn->send_idx);
 }
 
 void Curl_xfer_setup_nop(struct Curl_easy *data)
 {
-  xfer_setup(data, -1, -1, FALSE, -1, FALSE, FALSE);
+  xfer_setup(data, -1, -1, -1, FALSE);
+}
+
+void Curl_xfer_setup_sendrecv(struct Curl_easy *data,
+                              int sockindex,
+                              curl_off_t recv_size,
+                              bool getheader)
+{
+  xfer_setup(data, sockindex, sockindex, recv_size, getheader);
+}
+
+void Curl_xfer_setup_send(struct Curl_easy *data,
+                          int sockindex)
+{
+  xfer_setup(data, sockindex, -1, -1, FALSE);
 }
 
-void Curl_xfer_setup1(struct Curl_easy *data,
-                      int send_recv,
-                      curl_off_t recv_size,
-                      bool getheader)
+void Curl_xfer_setup_recv(struct Curl_easy *data,
+                          int sockindex,
+                          curl_off_t recv_size,
+                          bool getheader)
 {
-  int recv_index = (send_recv & CURL_XFER_RECV) ? FIRSTSOCKET : -1;
-  int send_index = (send_recv & CURL_XFER_SEND) ? FIRSTSOCKET : -1;
-  DEBUGASSERT((recv_index >= 0) || (recv_size == -1));
-  xfer_setup(data, recv_index, recv_size, getheader, send_index, FALSE, FALSE);
+  xfer_setup(data, -1, sockindex, recv_size, getheader);
 }
 
-void Curl_xfer_setup2(struct Curl_easy *data,
-                      int send_recv,
-                      curl_off_t recv_size,
-                      bool shutdown,
-                      bool shutdown_err_ignore)
+void Curl_xfer_set_shutdown(struct Curl_easy *data,
+                            bool shutdown,
+                            bool ignore_errors)
 {
-  int recv_index = (send_recv & CURL_XFER_RECV) ? SECONDARYSOCKET : -1;
-  int send_index = (send_recv & CURL_XFER_SEND) ? SECONDARYSOCKET : -1;
-  DEBUGASSERT((recv_index >= 0) || (recv_size == -1));
-  xfer_setup(data, recv_index, recv_size, FALSE, send_index,
-             shutdown, shutdown_err_ignore);
+  /* Shutdown should only be set when the transfer only sends or receives. */
+  DEBUGASSERT(!shutdown ||
+              (data->conn->send_idx < 0) || (data->conn->recv_idx < 0));
+  data->req.shutdown = shutdown;
+  data->req.shutdown_err_ignore = ignore_errors;
 }
 
 CURLcode Curl_xfer_write_resp(struct Curl_easy *data,
index 157c6b991ea5baeec1220ffa867061496f4c3eee..095c94fe27b57f4edfcca8d4f346d0beebbe8f49 100644 (file)
@@ -64,38 +64,36 @@ bool Curl_xfer_write_is_paused(struct Curl_easy *data);
 CURLcode Curl_xfer_write_resp_hd(struct Curl_easy *data,
                                  const char *hd0, size_t hdlen, bool is_eos);
 
-#define CURL_XFER_NOP     (0)
-#define CURL_XFER_RECV    (1<<(0))
-#define CURL_XFER_SEND    (1<<(1))
-#define CURL_XFER_SENDRECV (CURL_XFER_RECV|CURL_XFER_SEND)
-
-/**
- * The transfer is neither receiving nor sending now.
- */
+/* The transfer is neither receiving nor sending. */
 void Curl_xfer_setup_nop(struct Curl_easy *data);
 
+/* The transfer sends data on the given socket index */
+void Curl_xfer_setup_send(struct Curl_easy *data,
+                          int sockindex);
+
+/* The transfer receives data on the given socket index, the
+ * amount to receive (or -1 if unknown) and if headers are expected */
+void Curl_xfer_setup_recv(struct Curl_easy *data,
+                          int sockindex,
+                          curl_off_t recv_size,
+                          bool getheader);
+
+/* *After* Curl_xfer_setup_xxx(), tell the transfer to shutdown the
+ * connection at the end. Let the transfer either fail or ignore any
+ * errors during shutdown. */
+void Curl_xfer_set_shutdown(struct Curl_easy *data,
+                            bool shutdown,
+                            bool ignore_errors);
+
 /**
  * The transfer will use socket 1 to send/recv. `recv_size` is
  * the amount to receive or -1 if unknown. `getheader` indicates
  * response header processing is expected.
  */
-void Curl_xfer_setup1(struct Curl_easy *data,
-                      int send_recv,
-                      curl_off_t recv_size,
-                      bool getheader);
-
-/**
- * The transfer will use socket 2 to send/recv. `recv_size` is
- * the amount to receive or -1 if unknown. With `shutdown` being
- * set, the transfer is only allowed to either send OR receive
- * and the socket 2 connection will be shutdown at the end of
- * the transfer. An unclean shutdown will fail the transfer
- * unless `shutdown_err_ignore` is TRUE.
- */
-void Curl_xfer_setup2(struct Curl_easy *data,
-                      int send_recv,
-                      curl_off_t recv_size,
-                      bool shutdown, bool shutdown_err_ignore);
+void Curl_xfer_setup_sendrecv(struct Curl_easy *data,
+                              int sockindex,
+                              curl_off_t recv_size,
+                              bool getheader);
 
 /**
  * Multi has set transfer to DONE. Last chance to trigger
index b1d8b7c5913e1523d01c5228afb3887d1ab175c5..f04d5fe320c6948a7f8af1ea6fa5d58b6c6b399b 100644 (file)
@@ -1251,7 +1251,7 @@ static int myssh_in_UPLOAD_INIT(struct Curl_easy *data,
     Curl_pgrsSetUploadSize(data, data->state.infilesize);
   }
   /* upload data */
-  Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
+  Curl_xfer_setup_send(data, FIRSTSOCKET);
 
   /* not set by Curl_xfer_setup to preserve keepon bits */
   data->conn->recv_idx = FIRSTSOCKET;
@@ -1423,7 +1423,7 @@ static int myssh_in_SFTP_DOWNLOAD_STAT(struct Curl_easy *data,
     myssh_to(data, sshc, SSH_STOP);
     return rc;
   }
-  Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE);
+  Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size, FALSE);
 
   /* not set by Curl_xfer_setup to preserve keepon bits */
   data->conn->send_idx = 0;
@@ -2240,7 +2240,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
       }
 
       /* upload data */
-      Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
+      Curl_xfer_setup_send(data, FIRSTSOCKET);
 
       /* not set by Curl_xfer_setup to preserve keepon bits */
       data->conn->recv_idx = FIRSTSOCKET;
@@ -2279,7 +2279,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data,
         /* download data */
         bytecount = ssh_scp_request_get_size(sshc->scp_session);
         data->req.maxdownload = (curl_off_t) bytecount;
-        Curl_xfer_setup1(data, CURL_XFER_RECV, bytecount, FALSE);
+        Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount, FALSE);
 
         /* not set by Curl_xfer_setup to preserve keepon bits */
         conn->send_idx = 0;
index b31e3ab6d3e65e6f63aa0b9e5d3f008c782a6115..089a7af02039133edcc62b685cb51e326844c530 100644 (file)
@@ -1199,7 +1199,7 @@ sftp_upload_init(struct Curl_easy *data,
     Curl_pgrsSetUploadSize(data, data->state.infilesize);
   }
   /* upload data */
-  Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
+  Curl_xfer_setup_send(data, FIRSTSOCKET);
 
   /* not set by Curl_xfer_setup to preserve keepon bits */
   data->conn->recv_idx = FIRSTSOCKET;
@@ -1540,7 +1540,7 @@ sftp_download_stat(struct Curl_easy *data,
     myssh_state(data, sshc, SSH_STOP);
     return CURLE_OK;
   }
-  Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE);
+  Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size, FALSE);
 
   /* not set by Curl_xfer_setup to preserve keepon bits */
   data->conn->send_idx = 0;
@@ -2460,7 +2460,7 @@ static CURLcode ssh_state_scp_download_init(struct Curl_easy *data,
   /* download data */
   bytecount = (curl_off_t)sb.st_size;
   data->req.maxdownload = (curl_off_t)sb.st_size;
-  Curl_xfer_setup1(data, CURL_XFER_RECV, bytecount, FALSE);
+  Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount, FALSE);
 
   /* not set by Curl_xfer_setup to preserve keepon bits */
   data->conn->send_idx = 0;
@@ -2609,7 +2609,7 @@ static CURLcode ssh_state_scp_upload_init(struct Curl_easy *data,
   /* upload data */
   data->req.size = data->state.infilesize;
   Curl_pgrsSetUploadSize(data, data->state.infilesize);
-  Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
+  Curl_xfer_setup_send(data, FIRSTSOCKET);
 
   /* not set by Curl_xfer_setup to preserve keepon bits */
   data->conn->recv_idx = FIRSTSOCKET;
index 5b198d7568981fd31cf74d3b194f85151820e8ef..7696545a07fee98d5912676673e623d8d84f9cb5 100644 (file)
@@ -717,7 +717,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data,
         Curl_pgrsSetUploadSize(data, data->state.infilesize);
       }
       /* upload data */
-      Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
+      Curl_xfer_setup_send(data, FIRSTSOCKET);
 
       /* not set by Curl_xfer_setup to preserve keepon bits */
       data->conn->recv_idx = FIRSTSOCKET;
@@ -816,7 +816,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data,
         wssh_state(data, sshc, SSH_STOP);
         break;
       }
-      Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE);
+      Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size, FALSE);
 
       /* not set by Curl_xfer_setup to preserve keepon bits */
       conn->send_idx = 0;