lib: remove bad set.opt_no_body assignments

This struct field MUST remain what the application set it to, so that
handle reuse and handle duplication work.

Instead, the request state bit 'no_body' is introduced for code flows
that need to change this in run-time.

Closes #9888
This commit is contained in:
Daniel Stenberg 2022-11-11 10:57:04 +01:00
parent dafdb20a26
commit bf12c2bed6
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
13 changed files with 30 additions and 28 deletions

View File

@ -482,13 +482,13 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
tm->tm_hour, tm->tm_hour,
tm->tm_min, tm->tm_min,
tm->tm_sec, tm->tm_sec,
data->set.opt_no_body ? "": "\r\n"); data->req.no_body ? "": "\r\n");
result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen); result = Curl_client_write(data, CLIENTWRITE_HEADER, header, headerlen);
if(result) if(result)
return result; return result;
/* set the file size to make it available post transfer */ /* set the file size to make it available post transfer */
Curl_pgrsSetDownloadSize(data, expected_size); Curl_pgrsSetDownloadSize(data, expected_size);
if(data->set.opt_no_body) if(data->req.no_body)
return result; return result;
} }

View File

@ -1510,7 +1510,7 @@ static CURLcode ftp_state_type(struct Curl_easy *data)
/* If we have selected NOBODY and HEADER, it means that we only want file /* If we have selected NOBODY and HEADER, it means that we only want file
information. Which in FTP can't be much more than the file size and information. Which in FTP can't be much more than the file size and
date. */ date. */
if(data->set.opt_no_body && ftpc->file && if(data->req.no_body && ftpc->file &&
ftp_need_type(conn, data->state.prefer_ascii)) { ftp_need_type(conn, data->state.prefer_ascii)) {
/* The SIZE command is _not_ RFC 959 specified, and therefore many servers /* The SIZE command is _not_ RFC 959 specified, and therefore many servers
may not support it! It is however the only way we have to get a file's may not support it! It is however the only way we have to get a file's
@ -2082,7 +2082,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data,
/* If we asked for a time of the file and we actually got one as well, /* If we asked for a time of the file and we actually got one as well,
we "emulate" an HTTP-style header in our output. */ we "emulate" an HTTP-style header in our output. */
if(data->set.opt_no_body && if(data->req.no_body &&
ftpc->file && ftpc->file &&
data->set.get_filetime && data->set.get_filetime &&
(data->info.filetime >= 0) ) { (data->info.filetime >= 0) ) {
@ -3699,7 +3699,7 @@ CURLcode ftp_perform(struct Curl_easy *data,
DEBUGF(infof(data, "DO phase starts")); DEBUGF(infof(data, "DO phase starts"));
if(data->set.opt_no_body) { if(data->req.no_body) {
/* requested no body means no transfer... */ /* requested no body means no transfer... */
struct FTP *ftp = data->req.p.ftp; struct FTP *ftp = data->req.p.ftp;
ftp->transfer = PPTRANSFER_INFO; ftp->transfer = PPTRANSFER_INFO;

View File

@ -2047,7 +2047,7 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
if(data->set.str[STRING_CUSTOMREQUEST]) if(data->set.str[STRING_CUSTOMREQUEST])
request = data->set.str[STRING_CUSTOMREQUEST]; request = data->set.str[STRING_CUSTOMREQUEST];
else { else {
if(data->set.opt_no_body) if(data->req.no_body)
request = "HEAD"; request = "HEAD";
else { else {
DEBUGASSERT((httpreq >= HTTPREQ_GET) && (httpreq <= HTTPREQ_HEAD)); DEBUGASSERT((httpreq >= HTTPREQ_GET) && (httpreq <= HTTPREQ_HEAD));
@ -4201,7 +4201,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
* If we requested a "no body", this is a good time to get * If we requested a "no body", this is a good time to get
* out and return home. * out and return home.
*/ */
if(data->set.opt_no_body) if(data->req.no_body)
*stop_reading = TRUE; *stop_reading = TRUE;
#ifndef CURL_DISABLE_RTSP #ifndef CURL_DISABLE_RTSP
else if((conn->handler->protocol & CURLPROTO_RTSP) && else if((conn->handler->protocol & CURLPROTO_RTSP) &&

View File

@ -1568,7 +1568,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected,
DEBUGF(infof(data, "DO phase starts")); DEBUGF(infof(data, "DO phase starts"));
if(data->set.opt_no_body) { if(data->req.no_body) {
/* Requested no body means no transfer */ /* Requested no body means no transfer */
imap->transfer = PPTRANSFER_INFO; imap->transfer = PPTRANSFER_INFO;
} }

View File

@ -956,7 +956,7 @@ static CURLcode pop3_state_command_resp(struct Curl_easy *data,
content so send it as such. Note that there may even be additional content so send it as such. Note that there may even be additional
"headers" after the body */ "headers" after the body */
if(!data->set.opt_no_body) { if(!data->req.no_body) {
result = Curl_pop3_write(data, pp->cache, pp->cache_size); result = Curl_pop3_write(data, pp->cache, pp->cache_size);
if(result) if(result)
return result; return result;
@ -1204,7 +1204,7 @@ static CURLcode pop3_perform(struct Curl_easy *data, bool *connected,
DEBUGF(infof(data, "DO phase starts")); DEBUGF(infof(data, "DO phase starts"));
if(data->set.opt_no_body) { if(data->req.no_body) {
/* Requested no body means no transfer */ /* Requested no body means no transfer */
pop3->transfer = PPTRANSFER_INFO; pop3->transfer = PPTRANSFER_INFO;
} }

View File

@ -283,7 +283,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
* Since all RTSP requests are included here, there is no need to * Since all RTSP requests are included here, there is no need to
* support custom requests like HTTP. * support custom requests like HTTP.
**/ **/
data->set.opt_no_body = TRUE; /* most requests don't contain a body */ data->req.no_body = TRUE; /* most requests don't contain a body */
switch(rtspreq) { switch(rtspreq) {
default: default:
failf(data, "Got invalid RTSP request"); failf(data, "Got invalid RTSP request");
@ -293,7 +293,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
break; break;
case RTSPREQ_DESCRIBE: case RTSPREQ_DESCRIBE:
p_request = "DESCRIBE"; p_request = "DESCRIBE";
data->set.opt_no_body = FALSE; data->req.no_body = FALSE;
break; break;
case RTSPREQ_ANNOUNCE: case RTSPREQ_ANNOUNCE:
p_request = "ANNOUNCE"; p_request = "ANNOUNCE";
@ -313,7 +313,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
case RTSPREQ_GET_PARAMETER: case RTSPREQ_GET_PARAMETER:
/* GET_PARAMETER's no_body status is determined later */ /* GET_PARAMETER's no_body status is determined later */
p_request = "GET_PARAMETER"; p_request = "GET_PARAMETER";
data->set.opt_no_body = FALSE; data->req.no_body = FALSE;
break; break;
case RTSPREQ_SET_PARAMETER: case RTSPREQ_SET_PARAMETER:
p_request = "SET_PARAMETER"; p_request = "SET_PARAMETER";
@ -324,7 +324,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
case RTSPREQ_RECEIVE: case RTSPREQ_RECEIVE:
p_request = ""; p_request = "";
/* Treat interleaved RTP as body */ /* Treat interleaved RTP as body */
data->set.opt_no_body = FALSE; data->req.no_body = FALSE;
break; break;
case RTSPREQ_LAST: case RTSPREQ_LAST:
failf(data, "Got invalid RTSP request: RTSPREQ_LAST"); failf(data, "Got invalid RTSP request: RTSPREQ_LAST");
@ -573,7 +573,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
else if(rtspreq == RTSPREQ_GET_PARAMETER) { else if(rtspreq == RTSPREQ_GET_PARAMETER) {
/* Check for an empty GET_PARAMETER (heartbeat) request */ /* Check for an empty GET_PARAMETER (heartbeat) request */
data->state.httpreq = HTTPREQ_HEAD; data->state.httpreq = HTTPREQ_HEAD;
data->set.opt_no_body = TRUE; data->req.no_body = TRUE;
} }
} }

View File

@ -1050,7 +1050,7 @@ static CURLcode smtp_state_command_resp(struct Curl_easy *data, int smtpcode,
} }
else { else {
/* Temporarily add the LF character back and send as body to the client */ /* Temporarily add the LF character back and send as body to the client */
if(!data->set.opt_no_body) { if(!data->req.no_body) {
line[len] = '\n'; line[len] = '\n';
result = Curl_client_write(data, CLIENTWRITE_BODY, line, len + 1); result = Curl_client_write(data, CLIENTWRITE_BODY, line, len + 1);
line[len] = '\0'; line[len] = '\0';
@ -1490,7 +1490,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected,
DEBUGF(infof(data, "DO phase starts")); DEBUGF(infof(data, "DO phase starts"));
if(data->set.opt_no_body) { if(data->req.no_body) {
/* Requested no body means no transfer */ /* Requested no body means no transfer */
smtp->transfer = PPTRANSFER_INFO; smtp->transfer = PPTRANSFER_INFO;
} }

View File

@ -668,7 +668,7 @@ static CURLcode readwrite_data(struct Curl_easy *data,
is non-headers. */ is non-headers. */
if(!k->header && (nread > 0 || is_empty_data)) { if(!k->header && (nread > 0 || is_empty_data)) {
if(data->set.opt_no_body) { if(data->req.no_body) {
/* data arrives although we want none, bail out */ /* data arrives although we want none, bail out */
streamclose(conn, "ignoring body"); streamclose(conn, "ignoring body");
*done = TRUE; *done = TRUE;
@ -1310,7 +1310,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
* returning. * returning.
*/ */
if(!(data->set.opt_no_body) && (k->size != -1) && if(!(data->req.no_body) && (k->size != -1) &&
(k->bytecount != k->size) && (k->bytecount != k->size) &&
#ifdef CURL_DO_LINEEND_CONV #ifdef CURL_DO_LINEEND_CONV
/* Most FTP servers don't adjust their file SIZE response for CRLFs, /* Most FTP servers don't adjust their file SIZE response for CRLFs,
@ -1325,7 +1325,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
result = CURLE_PARTIAL_FILE; result = CURLE_PARTIAL_FILE;
goto out; goto out;
} }
if(!(data->set.opt_no_body) && k->chunk && if(!(data->req.no_body) && k->chunk &&
(conn->chunk.state != CHUNK_STOP)) { (conn->chunk.state != CHUNK_STOP)) {
/* /*
* In chunked mode, return an error if the connection is closed prior to * In chunked mode, return an error if the connection is closed prior to
@ -1839,7 +1839,7 @@ CURLcode Curl_follow(struct Curl_easy *data,
data->state.httpreq = HTTPREQ_GET; data->state.httpreq = HTTPREQ_GET;
data->set.upload = false; data->set.upload = false;
infof(data, "Switch to %s", infof(data, "Switch to %s",
data->set.opt_no_body?"HEAD":"GET"); data->req.no_body?"HEAD":"GET");
} }
break; break;
case 304: /* Not Modified */ case 304: /* Not Modified */
@ -1881,7 +1881,7 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
if((data->req.bytecount + data->req.headerbytecount == 0) && if((data->req.bytecount + data->req.headerbytecount == 0) &&
conn->bits.reuse && conn->bits.reuse &&
(!data->set.opt_no_body || (conn->handler->protocol & PROTO_FAMILY_HTTP)) (!data->req.no_body || (conn->handler->protocol & PROTO_FAMILY_HTTP))
#ifndef CURL_DISABLE_RTSP #ifndef CURL_DISABLE_RTSP
&& (data->set.rtspreq != RTSPREQ_RECEIVE) && (data->set.rtspreq != RTSPREQ_RECEIVE)
#endif #endif
@ -1995,7 +1995,7 @@ Curl_setup_transfer(
Curl_pgrsSetDownloadSize(data, size); Curl_pgrsSetDownloadSize(data, size);
} }
/* we want header and/or body, if neither then don't do this! */ /* we want header and/or body, if neither then don't do this! */
if(k->getheader || !data->set.opt_no_body) { if(k->getheader || !data->req.no_body) {
if(sockindex != -1) if(sockindex != -1)
k->keepon |= KEEP_RECV; k->keepon |= KEEP_RECV;
@ -2031,6 +2031,6 @@ Curl_setup_transfer(
k->keepon |= KEEP_SEND; k->keepon |= KEEP_SEND;
} }
} /* if(writesockindex != -1) */ } /* if(writesockindex != -1) */
} /* if(k->getheader || !data->set.opt_no_body) */ } /* if(k->getheader || !data->req.no_body) */
} }

View File

@ -4115,6 +4115,7 @@ CURLcode Curl_connect(struct Curl_easy *data,
Curl_free_request_state(data); Curl_free_request_state(data);
memset(&data->req, 0, sizeof(struct SingleRequest)); memset(&data->req, 0, sizeof(struct SingleRequest));
data->req.size = data->req.maxdownload = -1; data->req.size = data->req.maxdownload = -1;
data->req.no_body = data->set.opt_no_body;
/* call the stuff that needs to be called */ /* call the stuff that needs to be called */
result = create_conn(data, &conn, asyncp); result = create_conn(data, &conn, asyncp);
@ -4176,7 +4177,7 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn)
data->state.done = FALSE; /* *_done() is not called yet */ data->state.done = FALSE; /* *_done() is not called yet */
data->state.expect100header = FALSE; data->state.expect100header = FALSE;
if(data->set.opt_no_body) if(data->req.no_body)
/* in HTTP lingo, no body means using the HEAD request... */ /* in HTTP lingo, no body means using the HEAD request... */
data->state.httpreq = HTTPREQ_HEAD; data->state.httpreq = HTTPREQ_HEAD;

View File

@ -723,6 +723,7 @@ struct SingleRequest {
BIT(forbidchunk); /* used only to explicitly forbid chunk-upload for BIT(forbidchunk); /* used only to explicitly forbid chunk-upload for
specific upload buffers. See readmoredata() in http.c specific upload buffers. See readmoredata() in http.c
for details. */ for details. */
BIT(no_body); /* the response has no body */
}; };
/* /*

View File

@ -1416,7 +1416,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_SFTP_READDIR_INIT: case SSH_SFTP_READDIR_INIT:
Curl_pgrsSetDownloadSize(data, -1); Curl_pgrsSetDownloadSize(data, -1);
if(data->set.opt_no_body) { if(data->req.no_body) {
state(data, SSH_STOP); state(data, SSH_STOP);
break; break;
} }

View File

@ -2251,7 +2251,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_SFTP_READDIR_INIT: case SSH_SFTP_READDIR_INIT:
Curl_pgrsSetDownloadSize(data, -1); Curl_pgrsSetDownloadSize(data, -1);
if(data->set.opt_no_body) { if(data->req.no_body) {
state(data, SSH_STOP); state(data, SSH_STOP);
break; break;
} }

View File

@ -837,7 +837,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block)
case SSH_SFTP_READDIR_INIT: case SSH_SFTP_READDIR_INIT:
Curl_pgrsSetDownloadSize(data, -1); Curl_pgrsSetDownloadSize(data, -1);
if(data->set.opt_no_body) { if(data->req.no_body) {
state(data, SSH_STOP); state(data, SSH_STOP);
break; break;
} }