diff options
Diffstat (limited to 'Utilities/cmcurl/lib/transfer.c')
-rw-r--r-- | Utilities/cmcurl/lib/transfer.c | 114 |
1 files changed, 41 insertions, 73 deletions
diff --git a/Utilities/cmcurl/lib/transfer.c b/Utilities/cmcurl/lib/transfer.c index ba0410f..69df214 100644 --- a/Utilities/cmcurl/lib/transfer.c +++ b/Utilities/cmcurl/lib/transfer.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -73,6 +73,7 @@ #include "url.h" #include "getinfo.h" #include "vtls/vtls.h" +#include "vquic/vquic.h" #include "select.h" #include "multiif.h" #include "connect.h" @@ -367,27 +368,12 @@ static int data_pending(struct Curl_easy *data) { struct connectdata *conn = data->conn; -#ifdef ENABLE_QUIC - if(conn->transport == TRNSPRT_QUIC) - return Curl_quic_data_pending(data); -#endif - if(conn->handler->protocol&PROTO_FAMILY_FTP) return Curl_conn_data_pending(data, 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) || -#ifdef USE_NGHTTP2 - /* 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 - close, which we emulate it using conn->proto.httpc.closed = - 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) || -#endif Curl_conn_data_pending(data, FIRSTSOCKET); } @@ -454,29 +440,16 @@ static CURLcode readwrite_data(struct Curl_easy *data, bool is_empty_data = FALSE; size_t buffersize = data->set.buffer_size; size_t bytestoread = buffersize; -#ifdef USE_NGHTTP2 - bool is_http2 = ((conn->handler->protocol & PROTO_FAMILY_HTTP) && - (conn->httpversion == 20)); -#endif - bool is_http3 = -#ifdef ENABLE_QUIC - ((conn->handler->protocol & PROTO_FAMILY_HTTP) && - (conn->httpversion == 30)); -#else - FALSE; -#endif - - if( -#ifdef USE_NGHTTP2 - /* For HTTP/2, read data without caring about the content length. This - is safe because body in HTTP/2 is always segmented thanks to its - framing layer. Meanwhile, we have to call Curl_read to ensure that - http2_handle_stream_close is called when we read all incoming bytes - for a particular stream. */ - !is_http2 && -#endif - !is_http3 && /* Same reason mentioned above. */ - k->size != -1 && !k->header) { + /* For HTTP/2 and HTTP/3, read data without caring about the content + length. This is safe because body in HTTP/2 is always segmented + thanks to its framing layer. Meanwhile, we have to call Curl_read + to ensure that http2_handle_stream_close is called when we read all + incoming bytes for a particular stream. */ + bool is_http3 = Curl_conn_is_http3(data, conn, FIRSTSOCKET); + bool data_eof_handled = is_http3 + || Curl_conn_is_http2(data, conn, FIRSTSOCKET); + + if(!data_eof_handled && k->size != -1 && !k->header) { /* make sure we don't read too much */ curl_off_t totalleft = k->size - k->bytecount; if(totalleft < (curl_off_t)bytestoread) @@ -499,7 +472,7 @@ static CURLcode readwrite_data(struct Curl_easy *data, else { /* read nothing but since we wanted nothing we consider this an OK situation to proceed from */ - DEBUGF(infof(data, "readwrite_data: we're done")); + DEBUGF(infof(data, DMSG(data, "readwrite_data: we're done"))); nread = 0; } @@ -518,14 +491,9 @@ static CURLcode readwrite_data(struct Curl_easy *data, buf[nread] = 0; } else { - /* if we receive 0 or less here, either the http2 stream is closed or the + /* if we receive 0 or less here, either the data transfer is done or the server closed the connection and we bail out from this! */ -#ifdef USE_NGHTTP2 - if(is_http2 && !nread) - DEBUGF(infof(data, "nread == 0, stream closed, bailing")); - else -#endif - if(is_http3 && !nread) + if(data_eof_handled) DEBUGF(infof(data, "nread == 0, stream closed, bailing")); else DEBUGF(infof(data, "nread <= 0, server closed connection, bailing")); @@ -776,8 +744,8 @@ static CURLcode readwrite_data(struct Curl_easy *data, k->keepon &= ~KEEP_RECV; } - if(k->keepon & KEEP_RECV_PAUSE) { - /* this is a paused transfer */ + if((k->keepon & KEEP_RECV_PAUSE) || !(k->keepon & KEEP_RECV)) { + /* this is a paused or stopped transfer */ break; } @@ -799,19 +767,18 @@ static CURLcode readwrite_data(struct Curl_easy *data, } out: - DEBUGF(infof(data, "readwrite_data(handle=%p) -> %d", data, result)); + if(result) + DEBUGF(infof(data, DMSG(data, "readwrite_data() -> %d"), result)); return result; } CURLcode Curl_done_sending(struct Curl_easy *data, struct SingleRequest *k) { - struct connectdata *conn = data->conn; k->keepon &= ~KEEP_SEND; /* we're done writing */ /* These functions should be moved into the handler struct! */ - Curl_http2_done_sending(data, conn); - Curl_quic_done_sending(data); + Curl_conn_ev_data_done_send(data); return CURLE_OK; } @@ -1088,6 +1055,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, { struct SingleRequest *k = &data->req; CURLcode result; + struct curltime now; int didwhat = 0; curl_socket_t fd_read; @@ -1113,6 +1081,8 @@ CURLcode Curl_readwrite(struct connectdata *conn, if(data->state.drain) { select_res |= CURL_CSELECT_IN; DEBUGF(infof(data, "Curl_readwrite: forcibly told to drain data")); + if((k->keepon & KEEP_SENDBITS) == KEEP_SEND) + select_res |= CURL_CSELECT_OUT; } #endif @@ -1155,7 +1125,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, } #endif - k->now = Curl_now(); + now = Curl_now(); if(!didwhat) { /* no read no write, this is a timeout? */ if(k->exp100 == EXP100_AWAITING_CONTINUE) { @@ -1172,7 +1142,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, */ - timediff_t ms = Curl_timediff(k->now, k->start100); + timediff_t ms = Curl_timediff(now, k->start100); if(ms >= data->set.expect_100_timeout) { /* we've waited long enough, continue anyway */ k->exp100 = EXP100_SEND_DATA; @@ -1182,35 +1152,31 @@ CURLcode Curl_readwrite(struct connectdata *conn, } } -#ifdef ENABLE_QUIC - if(conn->transport == TRNSPRT_QUIC) { - result = Curl_quic_idle(data); - if(result) - goto out; - } -#endif + result = Curl_conn_ev_data_idle(data); + if(result) + goto out; } if(Curl_pgrsUpdate(data)) result = CURLE_ABORTED_BY_CALLBACK; else - result = Curl_speedcheck(data, k->now); + result = Curl_speedcheck(data, now); if(result) goto out; if(k->keepon) { - if(0 > Curl_timeleft(data, &k->now, FALSE)) { + if(0 > Curl_timeleft(data, &now, FALSE)) { if(k->size != -1) { failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_timediff(k->now, data->progress.t_startsingle), + Curl_timediff(now, data->progress.t_startsingle), k->bytecount, k->size); } else { failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received", - Curl_timediff(k->now, data->progress.t_startsingle), + Curl_timediff(now, data->progress.t_startsingle), k->bytecount); } result = CURLE_OPERATION_TIMEDOUT; @@ -1264,7 +1230,8 @@ CURLcode Curl_readwrite(struct connectdata *conn, KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE; result = CURLE_OK; out: - DEBUGF(infof(data, "Curl_readwrite(handle=%p) -> %d", data, result)); + if(result) + DEBUGF(infof(data, DMSG(data, "Curl_readwrite() -> %d"), result)); return result; } @@ -1377,6 +1344,7 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) data->state.authhost.want = data->set.httpauth; data->state.authproxy.want = data->set.proxyauth; Curl_safefree(data->info.wouldredirect); + Curl_data_priority_clear_state(data); if(data->state.httpreq == HTTPREQ_PUT) data->state.infilesize = data->set.filesize; @@ -1389,15 +1357,16 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) else data->state.infilesize = 0; -#ifndef CURL_DISABLE_COOKIES /* If there is a list of cookie files to read, do it now! */ - if(data->state.cookielist) - Curl_cookie_loadfiles(data); -#endif + Curl_cookie_loadfiles(data); + /* If there is a list of host pairs to deal with */ if(data->state.resolve) result = Curl_loadhostpairs(data); + /* If there is a list of hsts files to read */ + Curl_hsts_loadfiles(data); + if(!result) { /* Allow data->set.use_port to set which port to use. This needs to be * disabled for example when we follow Location: headers to URLs using @@ -1433,7 +1402,6 @@ CURLcode Curl_pretransfer(struct Curl_easy *data) } } #endif - Curl_http2_init_state(&data->state); result = Curl_hsts_loadcb(data, data->hsts); } @@ -1871,7 +1839,7 @@ Curl_setup_transfer( httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) && (http->sending == HTTPSEND_REQUEST)); - if(conn->bits.multiplex || conn->httpversion == 20 || httpsending) { + if(conn->bits.multiplex || conn->httpversion >= 20 || httpsending) { /* when multiplexing, the read/write sockets need to be the same! */ conn->sockfd = sockindex == -1 ? ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) : |