lib: move 'done' parameter to SingleRequests
A transfer may do several `SingleRequest`s for its success. This happens regularly for authentication, follows and retries on failed connections. The "readwrite()" calls and functions connected to those carried a `bool *done` parameter to indicate that the current `SingleRequest` is over. This may happen before `upload_done` or `download_done` bits of `SingleRequest` are set. The problem with that is now `write_resp()` protocol handlers are invoked in places where the `bool *done` cannot be passed up to the caller. Instead of being a bool in the call chain, it needs to become a member of `SingleRequest`, reflecting its state. This removes the `bool *done` parameter and adds the `done` bit to `SingleRequest` instead. It adds `Curl_req_soft_reset()` for using a `SingleRequest` in a follow up, clearing `done` and other flags/counters. Closes #13096
This commit is contained in:
Родитель
6aeb729b5c
Коммит
4e4e8af1f6
|
@ -207,7 +207,6 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk)
|
|||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(0 == k->bodywrites) {
|
||||
bool done = FALSE;
|
||||
#if defined(USE_NTLM)
|
||||
struct connectdata *conn = data->conn;
|
||||
if(conn->bits.close &&
|
||||
|
@ -235,12 +234,12 @@ static int hyper_body_chunk(void *userdata, const hyper_buf *chunk)
|
|||
}
|
||||
if(data->state.hconnect && (data->req.httpcode/100 != 2) &&
|
||||
data->state.authproxy.done) {
|
||||
done = TRUE;
|
||||
data->req.done = TRUE;
|
||||
result = CURLE_OK;
|
||||
}
|
||||
else
|
||||
result = Curl_http_firstwrite(data, data->conn, &done);
|
||||
if(result || done) {
|
||||
result = Curl_http_firstwrite(data);
|
||||
if(result || data->req.done) {
|
||||
infof(data, "Return early from hyper_body_chunk");
|
||||
data->state.hresult = result;
|
||||
return HYPER_ITER_BREAK;
|
||||
|
@ -338,7 +337,6 @@ static CURLcode empty_header(struct Curl_easy *data)
|
|||
CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int *didwhat,
|
||||
bool *done,
|
||||
int select_res)
|
||||
{
|
||||
hyper_response *resp = NULL;
|
||||
|
@ -382,7 +380,6 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
|||
h->write_waker = NULL;
|
||||
}
|
||||
|
||||
*done = FALSE;
|
||||
do {
|
||||
hyper_task_return_type t;
|
||||
task = hyper_executor_poll(h->exec);
|
||||
|
@ -425,7 +422,7 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
|||
break;
|
||||
}
|
||||
}
|
||||
*done = TRUE;
|
||||
data->req.done = TRUE;
|
||||
hyper_error_free(hypererr);
|
||||
break;
|
||||
}
|
||||
|
@ -434,12 +431,11 @@ CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
|||
hyper_task_free(task);
|
||||
if((userdata_t)userdata == USERDATA_RESP_BODY) {
|
||||
/* end of transfer */
|
||||
*done = TRUE;
|
||||
data->req.done = TRUE;
|
||||
infof(data, "hyperstream is done");
|
||||
if(!k->bodywrites) {
|
||||
/* hyper doesn't always call the body write callback */
|
||||
bool stilldone;
|
||||
result = Curl_http_firstwrite(data, data->conn, &stilldone);
|
||||
result = Curl_http_firstwrite(data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ size_t Curl_hyper_send(void *userp, hyper_context *ctx,
|
|||
CURLcode Curl_hyper_stream(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int *didwhat,
|
||||
bool *done,
|
||||
int select_res);
|
||||
|
||||
CURLcode Curl_hyper_header(struct Curl_easy *data, hyper_headers *headers,
|
||||
|
|
|
@ -832,9 +832,9 @@ static CURLcode recv_CONNECT_resp(struct Curl_cfilter *cf,
|
|||
int didwhat;
|
||||
|
||||
(void)ts;
|
||||
*done = FALSE;
|
||||
result = Curl_hyper_stream(data, cf->conn, &didwhat, done,
|
||||
result = Curl_hyper_stream(data, cf->conn, &didwhat,
|
||||
CURL_CSELECT_IN | CURL_CSELECT_OUT);
|
||||
*done = data->req.done;
|
||||
if(result || !*done)
|
||||
return result;
|
||||
if(h->exec) {
|
||||
|
@ -918,6 +918,7 @@ static CURLcode H1_CONNECT(struct Curl_cfilter *cf,
|
|||
* If the other side indicated a connection close, or if someone
|
||||
* else told us to close this connection, do so now.
|
||||
*/
|
||||
Curl_req_soft_reset(&data->req, data);
|
||||
if(ts->close_connection || conn->bits.close) {
|
||||
/* Close this filter and the sub-chain, re-connect the
|
||||
* sub-chain and continue. Closing this filter will
|
||||
|
@ -1003,10 +1004,8 @@ out:
|
|||
*done = (result == CURLE_OK) && tunnel_is_established(cf->ctx);
|
||||
if(*done) {
|
||||
cf->connected = TRUE;
|
||||
/* Restore `data->req` fields that may habe been touched */
|
||||
data->req.header = TRUE; /* assume header */
|
||||
data->req.bytecount = 0;
|
||||
data->req.ignorebody = FALSE;
|
||||
/* The real request will follow the CONNECT, reset request partially */
|
||||
Curl_req_soft_reset(&data->req, data);
|
||||
Curl_client_reset(data);
|
||||
Curl_pgrsSetUploadCounter(data, 0);
|
||||
Curl_pgrsSetDownloadCounter(data, 0);
|
||||
|
|
|
@ -1040,7 +1040,7 @@ fail:
|
|||
*/
|
||||
void curl_easy_reset(struct Curl_easy *data)
|
||||
{
|
||||
Curl_req_reset(&data->req, data);
|
||||
Curl_req_hard_reset(&data->req, data);
|
||||
|
||||
/* zero out UserDefined data: */
|
||||
Curl_freeset(data);
|
||||
|
|
26
lib/http.c
26
lib/http.c
|
@ -2446,19 +2446,17 @@ CURLcode Curl_http_range(struct Curl_easy *data,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool *done)
|
||||
CURLcode Curl_http_firstwrite(struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct SingleRequest *k = &data->req;
|
||||
|
||||
*done = FALSE;
|
||||
if(data->req.newurl) {
|
||||
if(conn->bits.close) {
|
||||
/* Abort after the headers if "follow Location" is set
|
||||
and we're set to close anyway. */
|
||||
k->keepon &= ~KEEP_RECV;
|
||||
*done = TRUE;
|
||||
k->done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
/* We have a new url to load, but since we want to be able to reuse this
|
||||
|
@ -2477,7 +2475,7 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
|||
streamclose(conn, "already downloaded");
|
||||
/* Abort download */
|
||||
k->keepon &= ~KEEP_RECV;
|
||||
*done = TRUE;
|
||||
k->done = TRUE;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
@ -2495,7 +2493,7 @@ CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
|||
action for an HTTP/1.1 client */
|
||||
|
||||
if(!Curl_meets_timecondition(data, k->timeofdoc)) {
|
||||
*done = TRUE;
|
||||
k->done = TRUE;
|
||||
/* We're simulating an HTTP 304 from server so we return
|
||||
what should have been returned from the server */
|
||||
data->info.httpcode = 304;
|
||||
|
@ -3951,10 +3949,8 @@ out:
|
|||
*/
|
||||
CURLcode Curl_http_write_resp_hds(struct Curl_easy *data,
|
||||
const char *buf, size_t blen,
|
||||
size_t *pconsumed,
|
||||
bool *done)
|
||||
size_t *pconsumed)
|
||||
{
|
||||
*done = FALSE;
|
||||
if(!data->req.header) {
|
||||
*pconsumed = 0;
|
||||
return CURLE_OK;
|
||||
|
@ -3965,7 +3961,7 @@ CURLcode Curl_http_write_resp_hds(struct Curl_easy *data,
|
|||
result = http_rw_headers(data, buf, blen, pconsumed);
|
||||
if(!result && !data->req.header) {
|
||||
/* we have successfully finished parsing the HEADERs */
|
||||
result = Curl_http_firstwrite(data, data->conn, done);
|
||||
result = Curl_http_firstwrite(data);
|
||||
|
||||
if(!data->req.no_body && Curl_dyn_len(&data->state.headerb)) {
|
||||
/* leftover from parsing something that turned out not
|
||||
|
@ -3983,16 +3979,14 @@ CURLcode Curl_http_write_resp_hds(struct Curl_easy *data,
|
|||
|
||||
CURLcode Curl_http_write_resp(struct Curl_easy *data,
|
||||
const char *buf, size_t blen,
|
||||
bool is_eos,
|
||||
bool *done)
|
||||
bool is_eos)
|
||||
{
|
||||
CURLcode result;
|
||||
size_t consumed;
|
||||
int flags;
|
||||
|
||||
*done = FALSE;
|
||||
result = Curl_http_write_resp_hds(data, buf, blen, &consumed, done);
|
||||
if(result || *done)
|
||||
result = Curl_http_write_resp_hds(data, buf, blen, &consumed);
|
||||
if(result || data->req.done)
|
||||
goto out;
|
||||
|
||||
DEBUGASSERT(consumed <= blen);
|
||||
|
|
10
lib/http.h
10
lib/http.h
|
@ -121,9 +121,7 @@ CURLcode Curl_http_cookies(struct Curl_easy *data,
|
|||
#endif
|
||||
CURLcode Curl_http_range(struct Curl_easy *data,
|
||||
Curl_HttpReq httpreq);
|
||||
CURLcode Curl_http_firstwrite(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool *done);
|
||||
CURLcode Curl_http_firstwrite(struct Curl_easy *data);
|
||||
|
||||
/* protocol-specific functions set up to be called by the main engine */
|
||||
CURLcode Curl_http_setup_conn(struct Curl_easy *data,
|
||||
|
@ -135,8 +133,7 @@ int Curl_http_getsock_do(struct Curl_easy *data, struct connectdata *conn,
|
|||
curl_socket_t *socks);
|
||||
CURLcode Curl_http_write_resp(struct Curl_easy *data,
|
||||
const char *buf, size_t blen,
|
||||
bool is_eos,
|
||||
bool *done);
|
||||
bool is_eos);
|
||||
|
||||
/* These functions are in http.c */
|
||||
CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
|
||||
|
@ -197,8 +194,7 @@ CURLcode Curl_http_size(struct Curl_easy *data);
|
|||
|
||||
CURLcode Curl_http_write_resp_hds(struct Curl_easy *data,
|
||||
const char *buf, size_t blen,
|
||||
size_t *pconsumed,
|
||||
bool *done);
|
||||
size_t *pconsumed);
|
||||
|
||||
/**
|
||||
* Curl_http_output_auth() setups the authentication headers for the
|
||||
|
|
|
@ -951,10 +951,8 @@ static CURLcode recvbuf_write_hds(struct Curl_cfilter *cf,
|
|||
struct Curl_easy *data,
|
||||
const char *buf, size_t blen)
|
||||
{
|
||||
bool done;
|
||||
|
||||
(void)cf;
|
||||
return Curl_xfer_write_resp(data, (char *)buf, blen, FALSE, &done);
|
||||
return Curl_xfer_write_resp(data, (char *)buf, blen, FALSE);
|
||||
}
|
||||
|
||||
static CURLcode on_stream_frame(struct Curl_cfilter *cf,
|
||||
|
@ -1234,7 +1232,6 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
|||
struct h2_stream_ctx *stream;
|
||||
struct Curl_easy *data_s;
|
||||
CURLcode result;
|
||||
bool done;
|
||||
(void)flags;
|
||||
|
||||
DEBUGASSERT(stream_id); /* should never be a zero stream ID here */
|
||||
|
@ -1257,7 +1254,7 @@ static int on_data_chunk_recv(nghttp2_session *session, uint8_t flags,
|
|||
if(!stream)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
result = Curl_xfer_write_resp(data_s, (char *)mem, len, FALSE, &done);
|
||||
result = Curl_xfer_write_resp(data_s, (char *)mem, len, FALSE);
|
||||
if(result && result != CURLE_AGAIN)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
|
||||
|
|
11
lib/multi.c
11
lib/multi.c
|
@ -1843,7 +1843,6 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
bool async;
|
||||
bool protocol_connected = FALSE;
|
||||
bool dophase_done = FALSE;
|
||||
bool done = FALSE;
|
||||
CURLMcode rc;
|
||||
CURLcode result = CURLE_OK;
|
||||
timediff_t recv_timeout_ms;
|
||||
|
@ -2405,9 +2404,9 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
}
|
||||
|
||||
/* read/write data if it is ready to do so */
|
||||
result = Curl_readwrite(data, &done);
|
||||
result = Curl_readwrite(data);
|
||||
|
||||
if(done || (result == CURLE_RECV_ERROR)) {
|
||||
if(data->req.done || (result == CURLE_RECV_ERROR)) {
|
||||
/* If CURLE_RECV_ERROR happens early enough, we assume it was a race
|
||||
* condition and the server closed the reused connection exactly when
|
||||
* we wanted to use it, so figure out if that is indeed the case.
|
||||
|
@ -2422,7 +2421,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
/* if we are to retry, set the result to OK and consider the
|
||||
request as done */
|
||||
result = CURLE_OK;
|
||||
done = TRUE;
|
||||
data->req.done = TRUE;
|
||||
}
|
||||
}
|
||||
else if((CURLE_HTTP2_STREAM == result) &&
|
||||
|
@ -2442,7 +2441,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
as done */
|
||||
retry = TRUE;
|
||||
result = CURLE_OK;
|
||||
done = TRUE;
|
||||
data->req.done = TRUE;
|
||||
}
|
||||
else
|
||||
result = ret;
|
||||
|
@ -2464,7 +2463,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||
Curl_posttransfer(data);
|
||||
multi_done(data, result, TRUE);
|
||||
}
|
||||
else if(done) {
|
||||
else if(data->req.done) {
|
||||
|
||||
/* call this even if the readwrite function returned error */
|
||||
Curl_posttransfer(data);
|
||||
|
|
|
@ -46,12 +46,23 @@ CURLcode Curl_req_init(struct SingleRequest *req)
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_req_start(struct SingleRequest *req,
|
||||
struct Curl_easy *data)
|
||||
CURLcode Curl_req_soft_reset(struct SingleRequest *req,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
req->start = Curl_now();
|
||||
req->done = FALSE;
|
||||
req->upload_done = FALSE;
|
||||
req->download_done = FALSE;
|
||||
req->ignorebody = FALSE;
|
||||
req->bytecount = 0;
|
||||
req->writebytecount = 0;
|
||||
req->header = TRUE; /* assume header */
|
||||
req->headerline = 0;
|
||||
req->headerbytecount = 0;
|
||||
req->allheadercount = 0;
|
||||
req->deductheadercount = 0;
|
||||
|
||||
result = Curl_client_start(data);
|
||||
if(result)
|
||||
return result;
|
||||
|
@ -73,6 +84,13 @@ CURLcode Curl_req_start(struct SingleRequest *req,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_req_start(struct SingleRequest *req,
|
||||
struct Curl_easy *data)
|
||||
{
|
||||
req->start = Curl_now();
|
||||
return Curl_req_soft_reset(req, data);
|
||||
}
|
||||
|
||||
static CURLcode req_flush(struct Curl_easy *data);
|
||||
|
||||
CURLcode Curl_req_done(struct SingleRequest *req,
|
||||
|
@ -85,7 +103,7 @@ CURLcode Curl_req_done(struct SingleRequest *req,
|
|||
return CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_req_reset(struct SingleRequest *req, struct Curl_easy *data)
|
||||
void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data)
|
||||
{
|
||||
struct curltime t0 = {0, 0};
|
||||
|
||||
|
|
|
@ -123,6 +123,9 @@ struct SingleRequest {
|
|||
unsigned char setcookies;
|
||||
#endif
|
||||
BIT(header); /* incoming data has HTTP header */
|
||||
BIT(done); /* request is done, e.g. no more send/recv should
|
||||
* happen. This can be TRUE before `upload_done` or
|
||||
* `download_done` is TRUE. */
|
||||
BIT(content_range); /* set TRUE if Content-Range: was found */
|
||||
BIT(download_done); /* set to TRUE when download is complete */
|
||||
BIT(eos_written); /* iff EOS has been written to client */
|
||||
|
@ -153,11 +156,18 @@ struct SingleRequest {
|
|||
CURLcode Curl_req_init(struct SingleRequest *req);
|
||||
|
||||
/**
|
||||
* The request is about to start.
|
||||
* The request is about to start. Record time and do a soft reset.
|
||||
*/
|
||||
CURLcode Curl_req_start(struct SingleRequest *req,
|
||||
struct Curl_easy *data);
|
||||
|
||||
/**
|
||||
* The request may continue with a follow up. Reset
|
||||
* members, but keep start time for overall duration calc.
|
||||
*/
|
||||
CURLcode Curl_req_soft_reset(struct SingleRequest *req,
|
||||
struct Curl_easy *data);
|
||||
|
||||
/**
|
||||
* The request is done. If not aborted, make sure that buffers are
|
||||
* flushed to the client.
|
||||
|
@ -174,10 +184,10 @@ CURLcode Curl_req_done(struct SingleRequest *req,
|
|||
void Curl_req_free(struct SingleRequest *req, struct Curl_easy *data);
|
||||
|
||||
/**
|
||||
* Reset the state of the request for new use, given the
|
||||
* settings.
|
||||
* Hard reset the state of the request to virgin state base on
|
||||
* transfer settings.
|
||||
*/
|
||||
void Curl_req_reset(struct SingleRequest *req, struct Curl_easy *data);
|
||||
void Curl_req_hard_reset(struct SingleRequest *req, struct Curl_easy *data);
|
||||
|
||||
#ifndef USE_HYPER
|
||||
/**
|
||||
|
|
14
lib/rtsp.c
14
lib/rtsp.c
|
@ -70,8 +70,7 @@ static int rtsp_getsock_do(struct Curl_easy *data,
|
|||
static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data,
|
||||
const char *buf,
|
||||
size_t blen,
|
||||
bool is_eos,
|
||||
bool *done);
|
||||
bool is_eos);
|
||||
|
||||
static CURLcode rtsp_setup_connection(struct Curl_easy *data,
|
||||
struct connectdata *conn);
|
||||
|
@ -790,8 +789,7 @@ out:
|
|||
static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data,
|
||||
const char *buf,
|
||||
size_t blen,
|
||||
bool is_eos,
|
||||
bool *done)
|
||||
bool is_eos)
|
||||
{
|
||||
struct rtsp_conn *rtspc = &(data->conn->proto.rtspc);
|
||||
CURLcode result = CURLE_OK;
|
||||
|
@ -799,7 +797,6 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data,
|
|||
|
||||
if(!data->req.header)
|
||||
rtspc->in_header = FALSE;
|
||||
*done = FALSE;
|
||||
if(!blen) {
|
||||
goto out;
|
||||
}
|
||||
|
@ -823,7 +820,7 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data,
|
|||
/* we want to parse headers, do so */
|
||||
if(data->req.header && blen) {
|
||||
rtspc->in_header = TRUE;
|
||||
result = Curl_http_write_resp_hds(data, buf, blen, &consumed, done);
|
||||
result = Curl_http_write_resp_hds(data, buf, blen, &consumed);
|
||||
if(result)
|
||||
goto out;
|
||||
|
||||
|
@ -849,13 +846,14 @@ static CURLcode rtsp_rtp_write_resp(struct Curl_easy *data,
|
|||
}
|
||||
|
||||
if(rtspc->state != RTP_PARSE_SKIP)
|
||||
*done = FALSE;
|
||||
data->req.done = FALSE;
|
||||
/* we SHOULD have consumed all bytes, unless the response is borked.
|
||||
* In which case we write out the left over bytes, letting the client
|
||||
* writer deal with it (it will report EXCESS and fail the transfer). */
|
||||
DEBUGF(infof(data, "rtsp_rtp_write_resp(len=%zu, in_header=%d, done=%d "
|
||||
" rtspc->state=%d, req.size=%" CURL_FORMAT_CURL_OFF_T ")",
|
||||
blen, rtspc->in_header, *done, rtspc->state, data->req.size));
|
||||
blen, rtspc->in_header, data->req.done, rtspc->state,
|
||||
data->req.size));
|
||||
if(!result && (is_eos || blen)) {
|
||||
result = Curl_client_write(data, CLIENTWRITE_BODY|
|
||||
(is_eos? CLIENTWRITE_EOS:0),
|
||||
|
|
|
@ -209,7 +209,7 @@ static ssize_t Curl_xfer_recv_resp(struct Curl_easy *data,
|
|||
*/
|
||||
static CURLcode readwrite_data(struct Curl_easy *data,
|
||||
struct SingleRequest *k,
|
||||
int *didwhat, bool *done)
|
||||
int *didwhat)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
@ -219,8 +219,6 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
|||
curl_off_t total_received = 0;
|
||||
bool is_multiplex = FALSE;
|
||||
|
||||
*done = FALSE;
|
||||
|
||||
result = Curl_multi_xfer_buf_borrow(data, &xfer_buf, &xfer_blen);
|
||||
if(result)
|
||||
goto out;
|
||||
|
@ -281,8 +279,8 @@ static CURLcode readwrite_data(struct Curl_easy *data,
|
|||
}
|
||||
total_received += blen;
|
||||
|
||||
result = Curl_xfer_write_resp(data, buf, blen, is_eos, done);
|
||||
if(result || *done)
|
||||
result = Curl_xfer_write_resp(data, buf, blen, is_eos);
|
||||
if(result || data->req.done)
|
||||
goto out;
|
||||
|
||||
/* if we are done, we stop receiving. On multiplexed connections,
|
||||
|
@ -403,8 +401,7 @@ static int select_bits_paused(struct Curl_easy *data, int select_bits)
|
|||
* Curl_readwrite() is the low-level function to be called when data is to
|
||||
* be read and written to/from the connection.
|
||||
*/
|
||||
CURLcode Curl_readwrite(struct Curl_easy *data,
|
||||
bool *done)
|
||||
CURLcode Curl_readwrite(struct Curl_easy *data)
|
||||
{
|
||||
struct connectdata *conn = data->conn;
|
||||
struct SingleRequest *k = &data->req;
|
||||
|
@ -450,8 +447,8 @@ CURLcode Curl_readwrite(struct Curl_easy *data,
|
|||
|
||||
#ifdef USE_HYPER
|
||||
if(conn->datastream) {
|
||||
result = conn->datastream(data, conn, &didwhat, done, select_bits);
|
||||
if(result || *done)
|
||||
result = conn->datastream(data, conn, &didwhat, select_bits);
|
||||
if(result || data->req.done)
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
|
@ -460,8 +457,8 @@ CURLcode Curl_readwrite(struct Curl_easy *data,
|
|||
the stream was rewound (in which case we have data in a
|
||||
buffer) */
|
||||
if((k->keepon & KEEP_RECV) && (select_bits & CURL_CSELECT_IN)) {
|
||||
result = readwrite_data(data, k, &didwhat, done);
|
||||
if(result || *done)
|
||||
result = readwrite_data(data, k, &didwhat);
|
||||
if(result || data->req.done)
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -561,8 +558,10 @@ CURLcode Curl_readwrite(struct Curl_easy *data,
|
|||
}
|
||||
}
|
||||
|
||||
/* Now update the "done" boolean we return */
|
||||
*done = (0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS))) ? TRUE : FALSE;
|
||||
/* If there is nothing more to send/recv, the request is done */
|
||||
if(0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS)))
|
||||
data->req.done = TRUE;
|
||||
|
||||
out:
|
||||
if(result)
|
||||
DEBUGF(infof(data, "Curl_readwrite() -> %d", result));
|
||||
|
@ -937,7 +936,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
|
|||
|
||||
data->state.url = newurl;
|
||||
data->state.url_alloc = TRUE;
|
||||
|
||||
Curl_req_soft_reset(&data->req, data);
|
||||
infof(data, "Issue another request to this URL: '%s'", data->state.url);
|
||||
|
||||
/*
|
||||
|
@ -1209,14 +1208,14 @@ void Curl_xfer_setup(
|
|||
|
||||
CURLcode Curl_xfer_write_resp(struct Curl_easy *data,
|
||||
char *buf, size_t blen,
|
||||
bool is_eos, bool *done)
|
||||
bool is_eos)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
if(data->conn->handler->write_resp) {
|
||||
/* protocol handlers offering this function take full responsibility
|
||||
* for writing all received download data to the client. */
|
||||
result = data->conn->handler->write_resp(data, buf, blen, is_eos, done);
|
||||
result = data->conn->handler->write_resp(data, buf, blen, is_eos);
|
||||
}
|
||||
else {
|
||||
/* No special handling by protocol handler, write all received data
|
||||
|
|
|
@ -45,7 +45,7 @@ typedef enum {
|
|||
|
||||
CURLcode Curl_follow(struct Curl_easy *data, char *newurl,
|
||||
followtype type);
|
||||
CURLcode Curl_readwrite(struct Curl_easy *data, bool *done);
|
||||
CURLcode Curl_readwrite(struct Curl_easy *data);
|
||||
int Curl_single_getsock(struct Curl_easy *data,
|
||||
struct connectdata *conn, curl_socket_t *socks);
|
||||
CURLcode Curl_retry_request(struct Curl_easy *data, char **url);
|
||||
|
@ -66,7 +66,7 @@ bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc);
|
|||
*/
|
||||
CURLcode Curl_xfer_write_resp(struct Curl_easy *data,
|
||||
char *buf, size_t blen,
|
||||
bool is_eos, bool *done);
|
||||
bool is_eos);
|
||||
|
||||
/* This sets up a forthcoming transfer */
|
||||
void Curl_xfer_setup(struct Curl_easy *data,
|
||||
|
|
10
lib/url.c
10
lib/url.c
|
@ -3839,8 +3839,8 @@ CURLcode Curl_connect(struct Curl_easy *data,
|
|||
|
||||
*asyncp = FALSE; /* assume synchronous resolves by default */
|
||||
|
||||
/* init the single-transfer specific data */
|
||||
Curl_req_reset(&data->req, data);
|
||||
/* Set the request to virgin state based on transfer settings */
|
||||
Curl_req_hard_reset(&data->req, data);
|
||||
|
||||
/* call the stuff that needs to be called */
|
||||
result = create_conn(data, &conn, asyncp);
|
||||
|
@ -3883,8 +3883,6 @@ CURLcode Curl_connect(struct Curl_easy *data,
|
|||
|
||||
CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
|
||||
{
|
||||
struct SingleRequest *k = &data->req;
|
||||
|
||||
/* if this is a pushed stream, we need this: */
|
||||
CURLcode result = Curl_preconnect(data);
|
||||
if(result)
|
||||
|
@ -3910,10 +3908,6 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
|
|||
if(result)
|
||||
return result;
|
||||
|
||||
k->header = TRUE; /* assume header */
|
||||
k->bytecount = 0;
|
||||
k->ignorebody = FALSE;
|
||||
|
||||
Curl_speedinit(data);
|
||||
Curl_pgrsSetUploadCounter(data, 0);
|
||||
Curl_pgrsSetDownloadCounter(data, 0);
|
||||
|
|
|
@ -163,7 +163,6 @@ typedef ssize_t (Curl_recv)(struct Curl_easy *data, /* transfer */
|
|||
typedef CURLcode (*Curl_datastream)(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
int *didwhat,
|
||||
bool *done,
|
||||
int select_res);
|
||||
#endif
|
||||
|
||||
|
@ -703,7 +702,7 @@ struct Curl_handler {
|
|||
allow the protocol to do extra handling in writing response to
|
||||
the client. */
|
||||
CURLcode (*write_resp)(struct Curl_easy *data, const char *buf, size_t blen,
|
||||
bool is_eos, bool *done);
|
||||
bool is_eos);
|
||||
|
||||
/* This function can perform various checks on the connection. See
|
||||
CONNCHECK_* for more information about the checks that can be performed,
|
||||
|
|
|
@ -762,8 +762,7 @@ static int cb_h3_stream_close(nghttp3_conn *conn, int64_t stream_id,
|
|||
static CURLcode write_resp_hds(struct Curl_easy *data,
|
||||
const char *buf, size_t blen)
|
||||
{
|
||||
bool done;
|
||||
return Curl_xfer_write_resp(data, (char *)buf, blen, FALSE, &done);
|
||||
return Curl_xfer_write_resp(data, (char *)buf, blen, FALSE);
|
||||
}
|
||||
|
||||
static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
|
||||
|
@ -775,7 +774,6 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
|
|||
struct Curl_easy *data = stream_user_data;
|
||||
struct h3_stream_ctx *stream = H3_STREAM_CTX(data);
|
||||
CURLcode result;
|
||||
bool done;
|
||||
|
||||
(void)conn;
|
||||
(void)stream3_id;
|
||||
|
@ -783,7 +781,7 @@ static int cb_h3_recv_data(nghttp3_conn *conn, int64_t stream3_id,
|
|||
if(!stream)
|
||||
return NGHTTP3_ERR_CALLBACK_FAILURE;
|
||||
|
||||
result = Curl_xfer_write_resp(data, (char *)buf, blen, FALSE, &done);
|
||||
result = Curl_xfer_write_resp(data, (char *)buf, blen, FALSE);
|
||||
if(result) {
|
||||
CURL_TRC_CF(data, cf, "[%" PRId64 "] DATA len=%zu, ERROR receiving %d",
|
||||
stream->id, blen, result);
|
||||
|
|
Загрузка…
Ссылка в новой задаче