/* set the SO_SNDBUF for the secondary socket for those who need it */
Curl_sndbuf_init(conn->sock[SECONDARYSOCKET]);
- Curl_xfer_setup2(data, CURL_XFER_SEND, -1, TRUE);
+ /* 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);
}
else {
- /* FTP download: */
+ /* FTP download, shutdown, do not ignore errors */
Curl_xfer_setup2(data, CURL_XFER_RECV,
- conn->proto.ftpc.retr_size_saved, TRUE);
+ conn->proto.ftpc.retr_size_saved, TRUE, FALSE);
}
conn->proto.ftpc.pp.pending_resp = TRUE; /* expect server response */
bool getheader, /* TRUE if header parsing is wanted */
int writesockindex, /* socket index to write to, it may very well be
the same we read from. -1 disables */
- bool shutdown /* shutdown connection at transfer end. Only
+ 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 */
)
{
struct SingleRequest *k = &data->req;
k->getheader = getheader;
k->size = size;
k->shutdown = shutdown;
+ k->shutdown_err_ignore = shutdown_err_ignore;
/* 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
void Curl_xfer_setup_nop(struct Curl_easy *data)
{
- xfer_setup(data, -1, -1, FALSE, -1, FALSE);
+ xfer_setup(data, -1, -1, FALSE, -1, FALSE, FALSE);
}
void Curl_xfer_setup1(struct Curl_easy *data,
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);
+ xfer_setup(data, recv_index, recv_size, getheader, send_index, FALSE, FALSE);
}
void Curl_xfer_setup2(struct Curl_easy *data,
int send_recv,
curl_off_t recv_size,
- bool shutdown)
+ bool shutdown,
+ bool shutdown_err_ignore)
{
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);
+ xfer_setup(data, recv_index, recv_size, FALSE, send_index,
+ shutdown, shutdown_err_ignore);
}
CURLcode Curl_xfer_write_resp(struct Curl_easy *data,
* 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.
+ * 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, bool shutdown_err_ignore);
/**
* Multi has set transfer to DONE. Last chance to trigger