summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/asyn-ares.c40
-rw-r--r--lib/cfilters.c13
-rw-r--r--lib/cfilters.h5
-rw-r--r--lib/curl_rtmp.c2
-rw-r--r--lib/dict.c6
-rw-r--r--lib/ftp.c3
-rw-r--r--lib/gopher.c2
-rw-r--r--lib/http.c7
-rw-r--r--lib/imap.c2
-rw-r--r--lib/multi.c4
-rw-r--r--lib/openldap.c2
-rw-r--r--lib/pop3.c2
-rw-r--r--lib/request.c4
-rw-r--r--lib/request.h1
-rw-r--r--lib/rtsp.c18
-rw-r--r--lib/transfer.c28
-rw-r--r--lib/transfer.h11
-rw-r--r--lib/vquic/curl_quiche.c1
-rw-r--r--lib/vssh/libssh.c4
-rw-r--r--lib/vssh/libssh2.c4
-rw-r--r--lib/vssh/wolfssh.c2
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);
}
}
diff --git a/lib/ftp.c b/lib/ftp.c
index d9539c7fd..f088054b2 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -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;