From: Stefan Eissing Date: Wed, 6 Aug 2025 09:56:08 +0000 (+0200) Subject: lib: xfer_setup simplify X-Git-Tag: curl-8_16_0~232 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=6cebd35b4cda026d6f4ad682a51561be10b7e915;p=thirdparty%2Fcurl.git lib: xfer_setup simplify 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 --- diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c index 584c8a9df6..07e0eeba26 100644 --- a/lib/curl_rtmp.c +++ b/lib/curl_rtmp.c @@ -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; } diff --git a/lib/dict.c b/lib/dict.c index 30e13b4547..b8ede7848d 100644 --- a/lib/dict.c +++ b/lib/dict.c @@ -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); } } diff --git a/lib/ftp.c b/lib/ftp.c index 3eec2f14ee..d9539c7fd4 100644 --- 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 */ diff --git a/lib/gopher.c b/lib/gopher.c index 82e02ed170..9ac3cca3e1 100644 --- a/lib/gopher.c +++ b/lib/gopher.c @@ -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 */ diff --git a/lib/http.c b/lib/http.c index d41aefdfaa..5e2a8c260f 100644 --- a/lib/http.c +++ b/lib/http.c @@ -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; } diff --git a/lib/imap.c b/lib/imap.c index 5949b667e9..d8f46a034c 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -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); diff --git a/lib/openldap.c b/lib/openldap.c index c532be3f32..c10f07220f 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -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: diff --git a/lib/pop3.c b/lib/pop3.c index 493b36f45f..9417bb5fe8 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -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 diff --git a/lib/rtsp.c b/lib/rtsp.c index 46ff660aed..153b98ea39 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -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); diff --git a/lib/smtp.c b/lib/smtp.c index 4bb3bde4af..97083e41f8 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -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); diff --git a/lib/transfer.c b/lib/transfer.c index 6ba5d0b309..76b7a8964b 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -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, diff --git a/lib/transfer.h b/lib/transfer.h index 157c6b991e..095c94fe27 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -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 diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index b1d8b7c591..f04d5fe320 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -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; diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c index b31e3ab6d3..089a7af020 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -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; diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c index 5b198d7568..7696545a07 100644 --- a/lib/vssh/wolfssh.c +++ b/lib/vssh/wolfssh.c @@ -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;