diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/asyn-ares.c | 40 | ||||
-rw-r--r-- | lib/cfilters.c | 13 | ||||
-rw-r--r-- | lib/cfilters.h | 5 | ||||
-rw-r--r-- | lib/curl_rtmp.c | 2 | ||||
-rw-r--r-- | lib/dict.c | 6 | ||||
-rw-r--r-- | lib/ftp.c | 3 | ||||
-rw-r--r-- | lib/gopher.c | 2 | ||||
-rw-r--r-- | lib/http.c | 7 | ||||
-rw-r--r-- | lib/imap.c | 2 | ||||
-rw-r--r-- | lib/multi.c | 4 | ||||
-rw-r--r-- | lib/openldap.c | 2 | ||||
-rw-r--r-- | lib/pop3.c | 2 | ||||
-rw-r--r-- | lib/request.c | 4 | ||||
-rw-r--r-- | lib/request.h | 1 | ||||
-rw-r--r-- | lib/rtsp.c | 18 | ||||
-rw-r--r-- | lib/transfer.c | 28 | ||||
-rw-r--r-- | lib/transfer.h | 11 | ||||
-rw-r--r-- | lib/vquic/curl_quiche.c | 1 | ||||
-rw-r--r-- | lib/vssh/libssh.c | 4 | ||||
-rw-r--r-- | lib/vssh/libssh2.c | 4 | ||||
-rw-r--r-- | lib/vssh/wolfssh.c | 2 |
21 files changed, 83 insertions, 78 deletions
diff --git a/lib/asyn-ares.c b/lib/asyn-ares.c index 375f1a6eb..815d7ab57 100644 --- a/lib/asyn-ares.c +++ b/lib/asyn-ares.c @@ -237,26 +237,6 @@ CURLcode Curl_async_get_impl(struct Curl_easy *data, void **impl) return result; } -static void async_ares_cleanup(struct Curl_easy *data); - -void Curl_async_ares_shutdown(struct Curl_easy *data) -{ - struct async_ares_ctx *ares = &data->state.async.ares; - if(ares->channel) - ares_cancel(ares->channel); - async_ares_cleanup(data); -} - -void Curl_async_ares_destroy(struct Curl_easy *data) -{ - struct async_ares_ctx *ares = &data->state.async.ares; - Curl_async_ares_shutdown(data); - if(ares->channel) { - ares_destroy(ares->channel); - ares->channel = NULL; - } -} - /* * async_ares_cleanup() cleans up async resolver data. */ @@ -272,6 +252,26 @@ static void async_ares_cleanup(struct Curl_easy *data) #endif } +void Curl_async_ares_shutdown(struct Curl_easy *data) +{ + /* c-ares has a method to "cancel" operations on a channel, but + * as reported in #18216, this does not totally reset the channel + * and ares may get stuck. + * We need to destroy the channel and on demand create a new + * one to avoid that. */ + Curl_async_ares_destroy(data); +} + +void Curl_async_ares_destroy(struct Curl_easy *data) +{ + struct async_ares_ctx *ares = &data->state.async.ares; + if(ares->channel) { + ares_destroy(ares->channel); + ares->channel = NULL; + } + async_ares_cleanup(data); +} + /* * Curl_async_pollset() is called when someone from the outside world * (using curl_multi_fdset()) wants to get our fd_set setup. diff --git a/lib/cfilters.c b/lib/cfilters.c index c3b40b0bc..efd2ac6f6 100644 --- a/lib/cfilters.c +++ b/lib/cfilters.c @@ -910,18 +910,19 @@ CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf, return result; } -curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex) +curl_socket_t Curl_conn_get_first_socket(struct Curl_easy *data) { struct Curl_cfilter *cf; - cf = (data->conn && CONN_SOCK_IDX_VALID(sockindex)) ? - data->conn->cfilter[sockindex] : NULL; + if(!data->conn) + return CURL_SOCKET_BAD; + + cf = data->conn->cfilter[FIRSTSOCKET]; /* if the top filter has not connected, ask it (and its sub-filters) - * for the socket. Otherwise conn->sock[sockindex] should have it. - */ + * for the socket. Otherwise conn->sock[sockindex] should have it. */ if(cf && !cf->connected) return Curl_conn_cf_get_socket(cf, data); - return data->conn ? data->conn->sock[sockindex] : CURL_SOCKET_BAD; + return data->conn->sock[FIRSTSOCKET]; } const struct Curl_sockaddr_ex * diff --git a/lib/cfilters.h b/lib/cfilters.h index 458ce5893..815b72a6e 100644 --- a/lib/cfilters.h +++ b/lib/cfilters.h @@ -460,10 +460,11 @@ bool Curl_conn_needs_flush(struct Curl_easy *data, int sockindex); CURLcode Curl_conn_flush(struct Curl_easy *data, int sockindex); /** - * Return the socket used on data's connection for the index. + * Return the socket used on data's connection for FIRSTSOCKET, + * querying filters if the whole chain has not connected yet. * Returns CURL_SOCKET_BAD if not available. */ -curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex); +curl_socket_t Curl_conn_get_first_socket(struct Curl_easy *data); /* Return a pointer to the connected socket address or NULL. */ const struct Curl_sockaddr_ex * diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c index 07e0eeba2..b178dff84 100644 --- a/lib/curl_rtmp.c +++ b/lib/curl_rtmp.c @@ -299,7 +299,7 @@ static CURLcode rtmp_do(struct Curl_easy *data, bool *done) Curl_xfer_setup_send(data, FIRSTSOCKET); } else - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); *done = TRUE; return CURLE_OK; } diff --git a/lib/dict.c b/lib/dict.c index b8ede7848..819584f28 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_setup_recv(data, FIRSTSOCKET, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); } 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_setup_recv(data, FIRSTSOCKET, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); } else { @@ -305,7 +305,7 @@ static CURLcode dict_do(struct Curl_easy *data, bool *done) goto error; } - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); } } @@ -551,8 +551,7 @@ static CURLcode ftp_initiate_transfer(struct Curl_easy *data, } else { /* FTP download, shutdown, do not ignore errors */ - Curl_xfer_setup_recv(data, SECONDARYSOCKET, - ftpc->retr_size_saved, FALSE); + Curl_xfer_setup_recv(data, SECONDARYSOCKET, ftpc->retr_size_saved); Curl_xfer_set_shutdown(data, TRUE, FALSE); } diff --git a/lib/gopher.c b/lib/gopher.c index 9ac3cca3e..93db85e9d 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_setup_recv(data, FIRSTSOCKET, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); return CURLE_OK; } #endif /* CURL_DISABLE_GOPHER */ diff --git a/lib/http.c b/lib/http.c index 5e2a8c260..758ee50de 100644 --- a/lib/http.c +++ b/lib/http.c @@ -1528,8 +1528,7 @@ CURLcode Curl_http_do_pollset(struct Curl_easy *data, struct easy_pollset *ps) { /* write mode */ - curl_socket_t sock = Curl_conn_get_socket(data, FIRSTSOCKET); - return Curl_pollset_add_out(data, ps, sock); + return Curl_pollset_add_out(data, ps, data->conn->sock[FIRSTSOCKET]); } /* @@ -2415,7 +2414,7 @@ static CURLcode http_req_complete(struct Curl_easy *data, out: if(!result) { /* setup variables for the upcoming transfer */ - Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1, TRUE); + Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1); } return result; } @@ -2704,6 +2703,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) if(result) goto fail; info_version = "HTTP/2"; + /* There is no ALPN here, but the connection is now definitely h2 */ + conn->httpversion_seen = 20; } else info_version = "HTTP/1.x"; diff --git a/lib/imap.c b/lib/imap.c index d8f46a034..7e6b132ba 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_setup_recv(data, FIRSTSOCKET, size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, size); } } else { diff --git a/lib/multi.c b/lib/multi.c index cbecd6a7d..d38155cd9 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -912,7 +912,7 @@ static CURLcode mstate_connecting_pollset(struct Curl_easy *data, struct easy_pollset *ps) { if(data->conn) { - curl_socket_t sockfd = Curl_conn_get_socket(data, FIRSTSOCKET); + curl_socket_t sockfd = Curl_conn_get_first_socket(data); if(sockfd != CURL_SOCKET_BAD) { /* Default is to wait to something from the server */ return Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0); @@ -928,7 +928,7 @@ static CURLcode mstate_protocol_pollset(struct Curl_easy *data, curl_socket_t sockfd; if(data->conn->handler->proto_pollset) return data->conn->handler->proto_pollset(data, ps); - sockfd = Curl_conn_get_socket(data, FIRSTSOCKET); + sockfd = data->conn->sock[FIRSTSOCKET]; if(sockfd != CURL_SOCKET_BAD) { /* Default is to wait to something from the server */ return Curl_pollset_change(data, ps, sockfd, CURL_POLL_IN, 0); diff --git a/lib/openldap.c b/lib/openldap.c index c10f07220..1b32e12b6 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_setup_recv(data, FIRSTSOCKET, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); *done = TRUE; out: diff --git a/lib/pop3.c b/lib/pop3.c index 9417bb5fe..508f8faed 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_setup_recv(data, FIRSTSOCKET, -1, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); if(pp->overflow) { /* The recv buffer contains data that is actually body content so send diff --git a/lib/request.c b/lib/request.c index 9fc9ab4d6..733e3e929 100644 --- a/lib/request.c +++ b/lib/request.c @@ -62,7 +62,7 @@ CURLcode Curl_req_soft_reset(struct SingleRequest *req, req->shutdown = FALSE; req->bytecount = 0; req->writebytecount = 0; - req->header = TRUE; /* assume header */ + req->header = FALSE; req->headerline = 0; req->headerbytecount = 0; req->allheadercount = 0; @@ -153,6 +153,7 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data) req->eos_written = FALSE; req->eos_read = FALSE; req->eos_sent = FALSE; + req->rewind_read = FALSE; req->upload_done = FALSE; req->upload_aborted = FALSE; req->ignorebody = FALSE; @@ -160,7 +161,6 @@ void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data) req->chunk = FALSE; req->ignore_cl = FALSE; req->upload_chunky = FALSE; - req->getheader = FALSE; req->no_body = data->set.opt_no_body; req->authneg = FALSE; req->shutdown = FALSE; diff --git a/lib/request.h b/lib/request.h index 74d9f5343..bce34de8b 100644 --- a/lib/request.h +++ b/lib/request.h @@ -123,7 +123,6 @@ struct SingleRequest { BIT(ignore_cl); /* ignore content-length */ BIT(upload_chunky); /* set TRUE if we are doing chunked transfer-encoding on upload */ - BIT(getheader); /* TRUE if header parsing is wanted */ BIT(no_body); /* the response has no body */ BIT(authneg); /* TRUE when the auth phase has started, which means that we are creating a request with an auth header, diff --git a/lib/rtsp.c b/lib/rtsp.c index 153b98ea3..dbe3e63cf 100644 --- a/lib/rtsp.c +++ b/lib/rtsp.c @@ -100,6 +100,10 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data, const char *buf, size_t blen, bool is_eos); +static CURLcode rtsp_rtp_write_resp_hd(struct Curl_easy *data, + const char *buf, + size_t blen, + bool is_eos); static CURLcode rtsp_setup_connection(struct Curl_easy *data, struct connectdata *conn); @@ -141,7 +145,7 @@ const struct Curl_handler Curl_handler_rtsp = { ZERO_NULL, /* perform_pollset */ ZERO_NULL, /* disconnect */ rtsp_rtp_write_resp, /* write_resp */ - ZERO_NULL, /* write_resp_hd */ + rtsp_rtp_write_resp_hd, /* write_resp_hd */ rtsp_conncheck, /* connection_check */ ZERO_NULL, /* attach connection */ Curl_http_follow, /* follow */ @@ -370,7 +374,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) } if(rtspreq == RTSPREQ_RECEIVE) { - Curl_xfer_setup_recv(data, FIRSTSOCKET, -1, TRUE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, -1); goto out; } @@ -636,7 +640,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) if(result) goto out; - Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1, TRUE); + Curl_xfer_setup_sendrecv(data, FIRSTSOCKET, -1); /* issue the request */ result = Curl_req_send(data, &req_buffer, httpversion); @@ -935,6 +939,14 @@ out: return result; } +static CURLcode rtsp_rtp_write_resp_hd(struct Curl_easy *data, + const char *buf, + size_t blen, + bool is_eos) +{ + return rtsp_rtp_write_resp(data, buf, blen, is_eos); +} + static CURLcode rtp_client_write(struct Curl_easy *data, const char *ptr, size_t len) { diff --git a/lib/transfer.c b/lib/transfer.c index 76b7a8964..50f621056 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -721,8 +721,7 @@ static void xfer_setup( struct Curl_easy *data, /* 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 */ + curl_off_t recv_size /* how much to receive, -1 if unknown */ ) { struct SingleRequest *k = &data->req; @@ -738,10 +737,10 @@ static void xfer_setup( conn->send_idx = send_idx; conn->recv_idx = recv_idx; - k->getheader = getheader; /* without receiving, there should be not recv_size */ DEBUGASSERT((conn->recv_idx >= 0) || (recv_size == -1)); k->size = recv_size; + k->header = !!conn->handler->write_resp_hd; /* by default, we do not shutdown at the end of the transfer */ k->shutdown = FALSE; k->shutdown_err_ignore = FALSE; @@ -749,14 +748,11 @@ static void xfer_setup( /* 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(recv_size > 0) - Curl_pgrsSetDownloadSize(data, recv_size); - } + if(!k->header && (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(conn->handler->write_resp_hd || !data->req.no_body) { if(conn->recv_idx != -1) k->keepon |= KEEP_RECV; @@ -771,29 +767,27 @@ static void xfer_setup( void Curl_xfer_setup_nop(struct Curl_easy *data) { - xfer_setup(data, -1, -1, -1, FALSE); + xfer_setup(data, -1, -1, -1); } void Curl_xfer_setup_sendrecv(struct Curl_easy *data, int sockindex, - curl_off_t recv_size, - bool getheader) + curl_off_t recv_size) { - xfer_setup(data, sockindex, sockindex, recv_size, getheader); + xfer_setup(data, sockindex, sockindex, recv_size); } void Curl_xfer_setup_send(struct Curl_easy *data, int sockindex) { - xfer_setup(data, sockindex, -1, -1, FALSE); + xfer_setup(data, sockindex, -1, -1); } void Curl_xfer_setup_recv(struct Curl_easy *data, int sockindex, - curl_off_t recv_size, - bool getheader) + curl_off_t recv_size) { - xfer_setup(data, -1, sockindex, recv_size, getheader); + xfer_setup(data, -1, sockindex, recv_size); } void Curl_xfer_set_shutdown(struct Curl_easy *data, diff --git a/lib/transfer.h b/lib/transfer.h index 095c94fe2..91a81e52e 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -72,11 +72,10 @@ 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 */ + * amount to receive (or -1 if unknown). */ void Curl_xfer_setup_recv(struct Curl_easy *data, int sockindex, - curl_off_t recv_size, - bool getheader); + curl_off_t recv_size); /* *After* Curl_xfer_setup_xxx(), tell the transfer to shutdown the * connection at the end. Let the transfer either fail or ignore any @@ -87,13 +86,11 @@ void Curl_xfer_set_shutdown(struct Curl_easy *data, /** * 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. + * the amount to receive or -1 if unknown. */ void Curl_xfer_setup_sendrecv(struct Curl_easy *data, int sockindex, - curl_off_t recv_size, - bool getheader); + curl_off_t recv_size); /** * Multi has set transfer to DONE. Last chance to trigger diff --git a/lib/vquic/curl_quiche.c b/lib/vquic/curl_quiche.c index f22566781..179ccf8aa 100644 --- a/lib/vquic/curl_quiche.c +++ b/lib/vquic/curl_quiche.c @@ -40,6 +40,7 @@ #include "../connect.h" #include "../progress.h" #include "../strerror.h" +#include "../select.h" #include "../http1.h" #include "vquic.h" #include "vquic_int.h" diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index f04d5fe32..8c366aafa 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -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_setup_recv(data, FIRSTSOCKET, data->req.size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); /* not set by Curl_xfer_setup to preserve keepon bits */ data->conn->send_idx = 0; @@ -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_setup_recv(data, FIRSTSOCKET, bytecount, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount); /* 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 089a7af02..f6985ed25 100644 --- a/lib/vssh/libssh2.c +++ b/lib/vssh/libssh2.c @@ -1540,7 +1540,7 @@ sftp_download_stat(struct Curl_easy *data, myssh_state(data, sshc, SSH_STOP); return CURLE_OK; } - Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); /* 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_setup_recv(data, FIRSTSOCKET, bytecount, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, bytecount); /* not set by Curl_xfer_setup to preserve keepon bits */ data->conn->send_idx = 0; diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c index 7696545a0..556eda0cb 100644 --- a/lib/vssh/wolfssh.c +++ b/lib/vssh/wolfssh.c @@ -816,7 +816,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, wssh_state(data, sshc, SSH_STOP); break; } - Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size, FALSE); + Curl_xfer_setup_recv(data, FIRSTSOCKET, data->req.size); /* not set by Curl_xfer_setup to preserve keepon bits */ conn->send_idx = 0; |