From 77444b84f3299786f956ed0f7a4a6ddf039a0962 Mon Sep 17 00:00:00 2001 From: Joel Depooter Date: Fri, 14 May 2021 14:44:07 -0700 Subject: [PATCH] data_pending: check only SECONDARY socket for FTP(S) transfers Check the FIRST for all other protocols. This fixes a timeout in an ftps download. The server sends a TLS close_notify message in the same packet as the file data. The close_notify seems to not be handled in the schannel_recv function, so libcurl is not aware that the server has closed the connection. Thus libcurl ends up waiting for action on the socket until a timeout is reached. With the secondary socket check added to the data_pending function, the close_notify is properly handled, and the ftps transfer terminates as expected. Fixes #7068 Closes #7069 --- lib/transfer.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/transfer.c b/lib/transfer.c index 3ed321dd4..bca4e548f 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -497,11 +497,13 @@ static int data_pending(const struct Curl_easy *data) return Curl_quic_data_pending(data); #endif + if(conn->handler->protocol&PROTO_FAMILY_FTP) + return Curl_ssl_data_pending(conn, SECONDARYSOCKET); + /* in the case of libssh2, we can never be really sure that we have emptied its internal buffers so we MUST always try until we get EAGAIN back */ return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) || #if defined(USE_NGHTTP2) - Curl_ssl_data_pending(conn, FIRSTSOCKET) || /* For HTTP/2, we may read up everything including response body with header fields in Curl_http_readwrite_headers. If no content-length is provided, curl waits for the connection @@ -509,10 +511,9 @@ static int data_pending(const struct Curl_easy *data) TRUE. The thing is if we read everything, then http2_recv won't be called and we cannot signal the HTTP/2 stream has closed. As a workaround, we return nonzero here to call http2_recv. */ - ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20); -#else - Curl_ssl_data_pending(conn, FIRSTSOCKET); + ((conn->handler->protocol&PROTO_FAMILY_HTTP) && conn->httpversion >= 20) || #endif + Curl_ssl_data_pending(conn, FIRSTSOCKET); } /*