1From 7815647d6582c0a4900be2e1de6c5e61272c496b Mon Sep 17 00:00:00 2001 2From: Daniel Stenberg <daniel@haxx.se> 3Date: Tue, 25 Apr 2023 08:28:01 +0200 4Subject: [PATCH] lib: unify the upload/method handling 5 6By making sure we set state.upload based on the set.method value and not 7independently as set.upload, we reduce confusion and mixup risks, both 8internally and externally. 9 10Closes #11017 11 12Conflict:Context adaptation and delete modifications for code which not exit 13Reference:https://github.com/curl/curl/commit/7815647d6582c0a4900be2e1de 14--- 15 lib/curl_rtmp.c | 4 ++-- 16 lib/file.c | 4 ++-- 17 lib/ftp.c | 8 ++++---- 18 lib/http.c | 4 ++-- 19 lib/imap.c | 6 +++--- 20 lib/rtsp.c | 4 ++-- 21 lib/setopt.c | 6 ++---- 22 lib/smb.c | 4 ++-- 23 lib/smtp.c | 4 ++-- 24 lib/tftp.c | 8 ++++---- 25 lib/transfer.c | 4 ++-- 26 lib/urldata.h | 2 +- 27 lib/vssh/libssh.c | 6 +++--- 28 lib/vssh/libssh2.c | 6 +++--- 29 lib/vssh/wolfssh.c | 2 +- 30 15 files changed, 35 insertions(+), 37 deletions(-) 31 32diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c 33index 2fa0267..c42c07e 100644 34--- a/lib/curl_rtmp.c 35+++ b/lib/curl_rtmp.c 36@@ -229,7 +229,7 @@ static CURLcode rtmp_connect(struct Curl_easy *data, bool *done) 37 /* We have to know if it's a write before we send the 38 * connect request packet 39 */ 40- if(data->set.upload) 41+ if(data->state.upload) 42 r->Link.protocol |= RTMP_FEATURE_WRITE; 43 44 /* For plain streams, use the buffer toggle trick to keep data flowing */ 45@@ -261,7 +261,7 @@ static CURLcode rtmp_do(struct Curl_easy *data, bool *done) 46 if(!RTMP_ConnectStream(r, 0)) 47 return CURLE_FAILED_INIT; 48 49- if(data->set.upload) { 50+ if(data->state.upload) { 51 Curl_pgrsSetUploadSize(data, data->state.infilesize); 52 Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET); 53 } 54diff --git a/lib/file.c b/lib/file.c 55index 0420db3..f15fe71 100644 56--- a/lib/file.c 57+++ b/lib/file.c 58@@ -200,7 +200,7 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done) 59 file->freepath = real_path; /* free this when done */ 60 61 file->fd = fd; 62- if(!data->set.upload && (fd == -1)) { 63+ if(!data->state.upload && (fd == -1)) { 64 failf(data, "Couldn't open file %s", data->state.up.path); 65 file_done(data, CURLE_FILE_COULDNT_READ_FILE, FALSE); 66 return CURLE_FILE_COULDNT_READ_FILE; 67@@ -382,7 +382,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done) 68 69 Curl_pgrsStartNow(data); 70 71- if(data->set.upload) 72+ if(data->state.upload) 73 return file_upload(data); 74 75 file = data->req.p.file; 76diff --git a/lib/ftp.c b/lib/ftp.c 77index f2f6852..6b9cd22 100644 78--- a/lib/ftp.c 79+++ b/lib/ftp.c 80@@ -1381,7 +1381,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data) 81 data->set.str[STRING_CUSTOMREQUEST]? 82 data->set.str[STRING_CUSTOMREQUEST]: 83 (data->state.list_only?"NLST":"LIST")); 84- else if(data->set.upload) 85+ else if(data->state.upload) 86 result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s", 87 conn->proto.ftpc.file); 88 else 89@@ -3371,7 +3371,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status, 90 /* the response code from the transfer showed an error already so no 91 use checking further */ 92 ; 93- else if(data->set.upload) { 94+ else if(data->state.upload) { 95 if((-1 != data->state.infilesize) && 96 (data->state.infilesize != data->req.writebytecount) && 97 !data->set.crlf && 98@@ -3643,7 +3643,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep) 99 connected back to us */ 100 } 101 } 102- else if(data->set.upload) { 103+ else if(data->state.upload) { 104 result = ftp_nb_type(data, conn, data->state.prefer_ascii, 105 FTP_STOR_TYPE); 106 if(result) 107@@ -4225,7 +4225,7 @@ CURLcode ftp_parse_url_path(struct Curl_easy *data) 108 ftpc->file = NULL; /* instead of point to a zero byte, 109 we make it a NULL pointer */ 110 111- if(data->set.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) { 112+ if(data->state.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) { 113 /* We need a file name when uploading. Return error! */ 114 failf(data, "Uploading to a URL without a file name!"); 115 free(rawPath); 116diff --git a/lib/http.c b/lib/http.c 117index 9ac77a0..e5a3eb0 100644 118--- a/lib/http.c 119+++ b/lib/http.c 120@@ -2037,7 +2037,7 @@ void Curl_http_method(struct Curl_easy *data, struct connectdata *conn, 121 Curl_HttpReq httpreq = data->state.httpreq; 122 const char *request; 123 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && 124- data->set.upload) 125+ data->state.upload) 126 httpreq = HTTPREQ_PUT; 127 128 /* Now set the 'request' pointer to the proper request string */ 129@@ -2353,7 +2353,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn, 130 if((conn->handler->protocol & PROTO_FAMILY_HTTP) && 131 (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) && 132 http->postsize < 0) || 133- ((data->set.upload || httpreq == HTTPREQ_POST) && 134+ ((data->state.upload || httpreq == HTTPREQ_POST) && 135 data->state.infilesize == -1))) { 136 if(conn->bits.authneg) 137 /* don't enable chunked during auth neg */ 138diff --git a/lib/imap.c b/lib/imap.c 139index 6163899..5e3bb14 100644 140--- a/lib/imap.c 141+++ b/lib/imap.c 142@@ -1490,11 +1490,11 @@ static CURLcode imap_done(struct Curl_easy *data, CURLcode status, 143 result = status; /* use the already set error code */ 144 } 145 else if(!data->set.connect_only && !imap->custom && 146- (imap->uid || imap->mindex || data->set.upload || 147+ (imap->uid || imap->mindex || data->state.upload || 148 data->set.mimepost.kind != MIMEKIND_NONE)) { 149 /* Handle responses after FETCH or APPEND transfer has finished */ 150 151- if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE) 152+ if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE) 153 state(data, IMAP_FETCH_FINAL); 154 else { 155 /* End the APPEND command first by sending an empty line */ 156@@ -1560,7 +1560,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected, 157 selected = TRUE; 158 159 /* Start the first command in the DO phase */ 160- if(data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE) 161+ if(data->state.upload || data->set.mimepost.kind != MIMEKIND_NONE) 162 /* APPEND can be executed directly */ 163 result = imap_perform_append(data); 164 else if(imap->custom && (selected || !imap->mailbox)) 165diff --git a/lib/rtsp.c b/lib/rtsp.c 166index 30fefb9..fd902bf 100644 167--- a/lib/rtsp.c 168+++ b/lib/rtsp.c 169@@ -508,7 +508,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) 170 rtspreq == RTSPREQ_SET_PARAMETER || 171 rtspreq == RTSPREQ_GET_PARAMETER) { 172 173- if(data->set.upload) { 174+ if(data->state.upload) { 175 putsize = data->state.infilesize; 176 data->state.httpreq = HTTPREQ_PUT; 177 178@@ -527,7 +527,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done) 179 result = 180 Curl_dyn_addf(&req_buffer, 181 "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n", 182- (data->set.upload ? putsize : postsize)); 183+ (data->state.upload ? putsize : postsize)); 184 if(result) 185 return result; 186 } 187diff --git a/lib/setopt.c b/lib/setopt.c 188index e47c415..ebfa539 100644 189--- a/lib/setopt.c 190+++ b/lib/setopt.c 191@@ -299,8 +299,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) 192 * We want to sent data to the remote host. If this is HTTP, that equals 193 * using the PUT request. 194 */ 195- data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE; 196- if(data->set.upload) { 197+ arg = va_arg(param, long); 198+ if(arg) { 199 /* If this is HTTP, PUT is what's needed to "upload" */ 200 data->set.method = HTTPREQ_PUT; 201 data->set.opt_no_body = FALSE; /* this is implied */ 202@@ -630,7 +630,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) 203 } 204 else 205 data->set.method = HTTPREQ_GET; 206- data->set.upload = FALSE; 207 break; 208 209 case CURLOPT_HTTPPOST: 210@@ -878,7 +877,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) 211 */ 212 if(va_arg(param, long)) { 213 data->set.method = HTTPREQ_GET; 214- data->set.upload = FALSE; /* switch off upload */ 215 data->set.opt_no_body = FALSE; /* this is implied */ 216 } 217 break; 218diff --git a/lib/smb.c b/lib/smb.c 219index 1c458a3..d3b6e7c 100644 220--- a/lib/smb.c 221+++ b/lib/smb.c 222@@ -534,7 +534,7 @@ static CURLcode smb_send_open(struct Curl_easy *data) 223 byte_count = strlen(req->path); 224 msg.name_length = smb_swap16((unsigned short)byte_count); 225 msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL); 226- if(data->set.upload) { 227+ if(data->state.upload) { 228 msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE); 229 msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF); 230 } 231@@ -813,7 +813,7 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done) 232 smb_m = (const struct smb_nt_create_response*) msg; 233 req->fid = smb_swap16(smb_m->fid); 234 data->req.offset = 0; 235- if(data->set.upload) { 236+ if(data->state.upload) { 237 data->req.size = data->state.infilesize; 238 Curl_pgrsSetUploadSize(data, data->req.size); 239 next_state = SMB_UPLOAD; 240diff --git a/lib/smtp.c b/lib/smtp.c 241index 02ddaca..1ea0ab5 100644 242--- a/lib/smtp.c 243+++ b/lib/smtp.c 244@@ -1390,7 +1390,7 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status, 245 result = status; /* use the already set error code */ 246 } 247 else if(!data->set.connect_only && data->set.mail_rcpt && 248- (data->set.upload || data->set.mimepost.kind)) { 249+ (data->state.upload || data->set.mimepost.kind)) { 250 /* Calculate the EOB taking into account any terminating CRLF from the 251 previous line of the email or the CRLF of the DATA command when there 252 is "no mail data". RFC-5321, sect. 4.1.1.4. 253@@ -1483,7 +1483,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected, 254 smtp->eob = 2; 255 256 /* Start the first command in the DO phase */ 257- if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt) 258+ if((data->state.upload || data->set.mimepost.kind) && data->set.mail_rcpt) 259 /* MAIL transfer */ 260 result = smtp_perform_mail(data); 261 else 262diff --git a/lib/tftp.c b/lib/tftp.c 263index aae997d..cf6189a 100644 264--- a/lib/tftp.c 265+++ b/lib/tftp.c 266@@ -367,7 +367,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state, 267 268 /* tsize should be ignored on upload: Who cares about the size of the 269 remote file? */ 270- if(!data->set.upload) { 271+ if(!data->state.upload) { 272 if(!tsize) { 273 failf(data, "invalid tsize -:%s:- value in OACK packet", value); 274 return CURLE_TFTP_ILLEGAL; 275@@ -448,7 +448,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, 276 return result; 277 } 278 279- if(data->set.upload) { 280+ if(data->state.upload) { 281 /* If we are uploading, send an WRQ */ 282 setpacketevent(&state->spacket, TFTP_EVENT_WRQ); 283 state->data->req.upload_fromhere = 284@@ -483,7 +483,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, 285 if(!data->set.tftp_no_options) { 286 char buf[64]; 287 /* add tsize option */ 288- if(data->set.upload && (data->state.infilesize != -1)) 289+ if(data->state.upload && (data->state.infilesize != -1)) 290 msnprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T, 291 data->state.infilesize); 292 else 293@@ -537,7 +537,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state, 294 break; 295 296 case TFTP_EVENT_OACK: 297- if(data->set.upload) { 298+ if(data->state.upload) { 299 result = tftp_connect_for_tx(state, event); 300 } 301 else { 302diff --git a/lib/transfer.c b/lib/transfer.c 303index 970ef35..9b5a7ed 100644 304--- a/lib/transfer.c 305+++ b/lib/transfer.c 306@@ -1391,6 +1391,7 @@ void Curl_init_CONNECT(struct Curl_easy *data) 307 { 308 data->state.fread_func = data->set.fread_func_set; 309 data->state.in = data->set.in_set; 310+ data->state.upload = (data->state.httpreq == HTTPREQ_PUT); 311 } 312 313 /* 314@@ -1814,7 +1815,6 @@ CURLcode Curl_follow(struct Curl_easy *data, 315 data->state.httpreq != HTTPREQ_POST_MIME) || 316 !(data->set.keep_post & CURL_REDIR_POST_303))) { 317 data->state.httpreq = HTTPREQ_GET; 318- data->set.upload = false; 319 infof(data, "Switch to %s", 320 data->set.opt_no_body?"HEAD":"GET"); 321 } 322@@ -1852,7 +1852,7 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url) 323 324 /* if we're talking upload, we can't do the checks below, unless the protocol 325 is HTTP as when uploading over HTTP we will still get a response */ 326- if(data->set.upload && 327+ if(data->state.upload && 328 !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP))) 329 return CURLE_OK; 330 331diff --git a/lib/urldata.h b/lib/urldata.h 332index 7852bd3..8b6e87b 100644 333--- a/lib/urldata.h 334+++ b/lib/urldata.h 335@@ -1485,6 +1485,7 @@ struct UrlState { 336 BIT(url_alloc); /* URL string is malloc()'ed */ 337 BIT(referer_alloc); /* referer string is malloc()ed */ 338 BIT(wildcard_resolve); /* Set to true if any resolve change is a wildcard */ 339+ BIT(upload); /* upload request */ 340 }; 341 342 /* 343@@ -1827,7 +1828,6 @@ struct UserDefined { 344 BIT(http_auto_referer); /* set "correct" referer when following 345 location: */ 346 BIT(opt_no_body); /* as set with CURLOPT_NOBODY */ 347- BIT(upload); /* upload request */ 348 BIT(verbose); /* output verbosity */ 349 BIT(krb); /* Kerberos connection requested */ 350 BIT(reuse_forbid); /* forbidden to be reused, close after use */ 351diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c 352index 3e317e8..a871134 100644 353--- a/lib/vssh/libssh.c 354+++ b/lib/vssh/libssh.c 355@@ -1198,7 +1198,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) 356 } 357 358 case SSH_SFTP_TRANS_INIT: 359- if(data->set.upload) 360+ if(data->state.upload) 361 state(data, SSH_SFTP_UPLOAD_INIT); 362 else { 363 if(protop->path[strlen(protop->path)-1] == '/') 364@@ -1811,7 +1811,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) 365 /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */ 366 ssh_set_blocking(sshc->ssh_session, 1); 367 368- if(data->set.upload) { 369+ if(data->state.upload) { 370 if(data->state.infilesize < 0) { 371 failf(data, "SCP requires a known file size for upload"); 372 sshc->actualcode = CURLE_UPLOAD_FAILED; 373@@ -1916,7 +1916,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block) 374 break; 375 } 376 case SSH_SCP_DONE: 377- if(data->set.upload) 378+ if(data->state.upload) 379 state(data, SSH_SCP_SEND_EOF); 380 else 381 state(data, SSH_SCP_CHANNEL_FREE); 382diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c 383index a772f1f..c5b1bc6 100644 384--- a/lib/vssh/libssh2.c 385+++ b/lib/vssh/libssh2.c 386@@ -1839,7 +1839,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) 387 } 388 389 case SSH_SFTP_TRANS_INIT: 390- if(data->set.upload) 391+ if(data->state.upload) 392 state(data, SSH_SFTP_UPLOAD_INIT); 393 else { 394 if(sshp->path[strlen(sshp->path)-1] == '/') 395@@ -2511,7 +2511,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) 396 break; 397 } 398 399- if(data->set.upload) { 400+ if(data->state.upload) { 401 if(data->state.infilesize < 0) { 402 failf(data, "SCP requires a known file size for upload"); 403 sshc->actualcode = CURLE_UPLOAD_FAILED; 404@@ -2651,7 +2651,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block) 405 break; 406 407 case SSH_SCP_DONE: 408- if(data->set.upload) 409+ if(data->state.upload) 410 state(data, SSH_SCP_SEND_EOF); 411 else 412 state(data, SSH_SCP_CHANNEL_FREE); 413diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c 414index 4b1e2ec..4ab21ae 100644 415--- a/lib/vssh/wolfssh.c 416+++ b/lib/vssh/wolfssh.c 417@@ -553,7 +553,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block) 418 } 419 break; 420 case SSH_SFTP_TRANS_INIT: 421- if(data->set.upload) 422+ if(data->state.upload) 423 state(data, SSH_SFTP_UPLOAD_INIT); 424 else { 425 if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/') 426-- 4272.33.0 428 429