transfer.c (31548B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25 #include "curl_setup.h" 26 27 #ifdef HAVE_NETINET_IN_H 28 #include <netinet/in.h> 29 #endif 30 #ifdef HAVE_NETDB_H 31 #include <netdb.h> 32 #endif 33 #ifdef HAVE_ARPA_INET_H 34 #include <arpa/inet.h> 35 #endif 36 #ifdef HAVE_NET_IF_H 37 #include <net/if.h> 38 #endif 39 #ifdef HAVE_SYS_IOCTL_H 40 #include <sys/ioctl.h> 41 #endif 42 #ifndef UNDER_CE 43 #include <signal.h> 44 #endif 45 46 #ifdef HAVE_SYS_PARAM_H 47 #include <sys/param.h> 48 #endif 49 50 #ifdef HAVE_SYS_SELECT_H 51 #include <sys/select.h> 52 #elif defined(HAVE_UNISTD_H) 53 #include <unistd.h> 54 #endif 55 56 #ifndef HAVE_SOCKET 57 #error "We cannot compile without socket() support!" 58 #endif 59 60 #include "urldata.h" 61 #include <curl/curl.h> 62 #include "netrc.h" 63 64 #include "content_encoding.h" 65 #include "hostip.h" 66 #include "cfilters.h" 67 #include "cw-out.h" 68 #include "transfer.h" 69 #include "sendf.h" 70 #include "speedcheck.h" 71 #include "progress.h" 72 #include "http.h" 73 #include "url.h" 74 #include "getinfo.h" 75 #include "vtls/vtls.h" 76 #include "vquic/vquic.h" 77 #include "select.h" 78 #include "multiif.h" 79 #include "connect.h" 80 #include "http2.h" 81 #include "mime.h" 82 #include "hsts.h" 83 #include "setopt.h" 84 #include "headers.h" 85 86 /* The last 3 #include files should be in this order */ 87 #include "curl_printf.h" 88 #include "curl_memory.h" 89 #include "memdebug.h" 90 91 #if !defined(CURL_DISABLE_HTTP) || !defined(CURL_DISABLE_SMTP) || \ 92 !defined(CURL_DISABLE_IMAP) 93 /* 94 * checkheaders() checks the linked list of custom headers for a 95 * particular header (prefix). Provide the prefix without colon! 96 * 97 * Returns a pointer to the first matching header or NULL if none matched. 98 */ 99 char *Curl_checkheaders(const struct Curl_easy *data, 100 const char *thisheader, 101 const size_t thislen) 102 { 103 struct curl_slist *head; 104 DEBUGASSERT(thislen); 105 DEBUGASSERT(thisheader[thislen-1] != ':'); 106 107 for(head = data->set.headers; head; head = head->next) { 108 if(curl_strnequal(head->data, thisheader, thislen) && 109 Curl_headersep(head->data[thislen]) ) 110 return head->data; 111 } 112 113 return NULL; 114 } 115 #endif 116 117 static int data_pending(struct Curl_easy *data, bool rcvd_eagain) 118 { 119 struct connectdata *conn = data->conn; 120 121 if(conn->handler->protocol&PROTO_FAMILY_FTP) 122 return Curl_conn_data_pending(data, SECONDARYSOCKET); 123 124 /* in the case of libssh2, we can never be really sure that we have emptied 125 its internal buffers so we MUST always try until we get EAGAIN back */ 126 return (!rcvd_eagain && 127 conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP)) || 128 Curl_conn_data_pending(data, FIRSTSOCKET); 129 } 130 131 /* 132 * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the 133 * remote document with the time provided by CURLOPT_TIMEVAL 134 */ 135 bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) 136 { 137 if((timeofdoc == 0) || (data->set.timevalue == 0)) 138 return TRUE; 139 140 switch(data->set.timecondition) { 141 case CURL_TIMECOND_IFMODSINCE: 142 default: 143 if(timeofdoc <= data->set.timevalue) { 144 infof(data, 145 "The requested document is not new enough"); 146 data->info.timecond = TRUE; 147 return FALSE; 148 } 149 break; 150 case CURL_TIMECOND_IFUNMODSINCE: 151 if(timeofdoc >= data->set.timevalue) { 152 infof(data, 153 "The requested document is not old enough"); 154 data->info.timecond = TRUE; 155 return FALSE; 156 } 157 break; 158 } 159 160 return TRUE; 161 } 162 163 static CURLcode xfer_recv_shutdown(struct Curl_easy *data, bool *done) 164 { 165 int sockindex; 166 167 if(!data || !data->conn) 168 return CURLE_FAILED_INIT; 169 if(data->conn->sockfd == CURL_SOCKET_BAD) 170 return CURLE_FAILED_INIT; 171 sockindex = (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET]); 172 return Curl_conn_shutdown(data, sockindex, done); 173 } 174 175 static bool xfer_recv_shutdown_started(struct Curl_easy *data) 176 { 177 int sockindex; 178 179 if(!data || !data->conn) 180 return FALSE; 181 if(data->conn->sockfd == CURL_SOCKET_BAD) 182 return FALSE; 183 sockindex = (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET]); 184 return Curl_shutdown_started(data, sockindex); 185 } 186 187 CURLcode Curl_xfer_send_shutdown(struct Curl_easy *data, bool *done) 188 { 189 int sockindex; 190 191 if(!data || !data->conn) 192 return CURLE_FAILED_INIT; 193 if(data->conn->writesockfd == CURL_SOCKET_BAD) 194 return CURLE_FAILED_INIT; 195 sockindex = (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET]); 196 return Curl_conn_shutdown(data, sockindex, done); 197 } 198 199 /** 200 * Receive raw response data for the transfer. 201 * @param data the transfer 202 * @param buf buffer to keep response data received 203 * @param blen length of `buf` 204 * @param eos_reliable if EOS detection in underlying connection is reliable 205 * @param err error code in case of -1 return 206 * @return number of bytes read or -1 for error 207 */ 208 static ssize_t xfer_recv_resp(struct Curl_easy *data, 209 char *buf, size_t blen, 210 bool eos_reliable, 211 CURLcode *err) 212 { 213 size_t nread; 214 215 DEBUGASSERT(blen > 0); 216 /* If we are reading BODY data and the connection does NOT handle EOF 217 * and we know the size of the BODY data, limit the read amount */ 218 if(!eos_reliable && !data->req.header && data->req.size != -1) { 219 curl_off_t totalleft = data->req.size - data->req.bytecount; 220 if(totalleft <= 0) 221 blen = 0; 222 else if(totalleft < (curl_off_t)blen) 223 blen = (size_t)totalleft; 224 } 225 else if(xfer_recv_shutdown_started(data)) { 226 /* we already received everything. Do not try more. */ 227 blen = 0; 228 } 229 230 if(!blen) { 231 /* want nothing more */ 232 *err = CURLE_OK; 233 nread = 0; 234 } 235 else { 236 *err = Curl_xfer_recv(data, buf, blen, &nread); 237 } 238 239 if(*err) 240 return -1; 241 if(nread == 0) { 242 if(data->req.shutdown) { 243 bool done; 244 *err = xfer_recv_shutdown(data, &done); 245 if(*err) 246 return -1; 247 if(!done) { 248 *err = CURLE_AGAIN; 249 return -1; 250 } 251 } 252 DEBUGF(infof(data, "sendrecv_dl: we are done")); 253 } 254 return (ssize_t)nread; 255 } 256 257 /* 258 * Go ahead and do a read if we have a readable socket or if 259 * the stream was rewound (in which case we have data in a 260 * buffer) 261 */ 262 static CURLcode sendrecv_dl(struct Curl_easy *data, 263 struct SingleRequest *k, 264 int *didwhat) 265 { 266 struct connectdata *conn = data->conn; 267 CURLcode result = CURLE_OK; 268 char *buf, *xfer_buf; 269 size_t blen, xfer_blen; 270 int maxloops = 10; 271 curl_off_t total_received = 0; 272 bool is_multiplex = FALSE; 273 bool rcvd_eagain = FALSE; 274 275 result = Curl_multi_xfer_buf_borrow(data, &xfer_buf, &xfer_blen); 276 if(result) 277 goto out; 278 279 /* This is where we loop until we have read everything there is to 280 read or we get a CURLE_AGAIN */ 281 do { 282 bool is_eos = FALSE; 283 size_t bytestoread; 284 ssize_t nread; 285 286 if(!is_multiplex) { 287 /* Multiplexed connection have inherent handling of EOF and we do not 288 * have to carefully restrict the amount we try to read. 289 * Multiplexed changes only in one direction. */ 290 is_multiplex = Curl_conn_is_multiplex(conn, FIRSTSOCKET); 291 } 292 293 buf = xfer_buf; 294 bytestoread = xfer_blen; 295 296 if(bytestoread && data->set.max_recv_speed > 0) { 297 /* In case of speed limit on receiving: if this loop already got 298 * data, break out. If not, limit the amount of bytes to receive. 299 * The overall, timed, speed limiting is done in multi.c */ 300 if(total_received) 301 break; 302 if(data->set.max_recv_speed < (curl_off_t)bytestoread) 303 bytestoread = (size_t)data->set.max_recv_speed; 304 } 305 306 rcvd_eagain = FALSE; 307 nread = xfer_recv_resp(data, buf, bytestoread, is_multiplex, &result); 308 if(nread < 0) { 309 if(CURLE_AGAIN != result) 310 goto out; /* real error */ 311 rcvd_eagain = TRUE; 312 result = CURLE_OK; 313 if(data->req.download_done && data->req.no_body && 314 !data->req.resp_trailer) { 315 DEBUGF(infof(data, "EAGAIN, download done, no trailer announced, " 316 "not waiting for EOS")); 317 nread = 0; 318 /* continue as if we received the EOS */ 319 } 320 else 321 break; /* get out of loop */ 322 } 323 324 /* We only get a 0-length receive at the end of the response */ 325 blen = (size_t)nread; 326 is_eos = (blen == 0); 327 *didwhat |= KEEP_RECV; 328 329 if(!blen) { 330 /* if we receive 0 or less here, either the data transfer is done or the 331 server closed the connection and we bail out from this! */ 332 if(is_multiplex) 333 DEBUGF(infof(data, "nread == 0, stream closed, bailing")); 334 else 335 DEBUGF(infof(data, "nread <= 0, server closed connection, bailing")); 336 result = Curl_req_stop_send_recv(data); 337 if(result) 338 goto out; 339 if(k->eos_written) /* already did write this to client, leave */ 340 break; 341 } 342 total_received += blen; 343 344 result = Curl_xfer_write_resp(data, buf, blen, is_eos); 345 if(result || data->req.done) 346 goto out; 347 348 /* if we are done, we stop receiving. On multiplexed connections, 349 * we should read the EOS. Which may arrive as meta data after 350 * the bytes. Not taking it in might lead to RST of streams. */ 351 if((!is_multiplex && data->req.download_done) || is_eos) { 352 data->req.keepon &= ~KEEP_RECV; 353 } 354 /* if we are PAUSEd or stopped receiving, leave the loop */ 355 if((k->keepon & KEEP_RECV_PAUSE) || !(k->keepon & KEEP_RECV)) 356 break; 357 358 } while(maxloops--); 359 360 if(!Curl_xfer_is_blocked(data) && 361 (!rcvd_eagain || data_pending(data, rcvd_eagain))) { 362 /* Did not read until EAGAIN or there is still data pending 363 * in buffers. Mark as read-again via simulated SELECT results. */ 364 Curl_multi_mark_dirty(data); 365 CURL_TRC_M(data, "sendrecv_dl() no EAGAIN/pending data, mark as dirty"); 366 } 367 368 if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) && 369 (conn->bits.close || is_multiplex)) { 370 /* When we have read the entire thing and the close bit is set, the server 371 may now close the connection. If there is now any kind of sending going 372 on from our side, we need to stop that immediately. */ 373 infof(data, "we are done reading and this is set to close, stop send"); 374 Curl_req_abort_sending(data); 375 } 376 377 out: 378 Curl_multi_xfer_buf_release(data, xfer_buf); 379 if(result) 380 DEBUGF(infof(data, "sendrecv_dl() -> %d", result)); 381 return result; 382 } 383 384 /* 385 * Send data to upload to the server, when the socket is writable. 386 */ 387 static CURLcode sendrecv_ul(struct Curl_easy *data, int *didwhat) 388 { 389 /* We should not get here when the sending is already done. It 390 * probably means that someone set `data-req.keepon |= KEEP_SEND` 391 * when it should not. */ 392 DEBUGASSERT(!Curl_req_done_sending(data)); 393 394 if(!Curl_req_done_sending(data)) { 395 *didwhat |= KEEP_SEND; 396 return Curl_req_send_more(data); 397 } 398 return CURLE_OK; 399 } 400 401 /* 402 * Curl_sendrecv() is the low-level function to be called when data is to 403 * be read and written to/from the connection. 404 */ 405 CURLcode Curl_sendrecv(struct Curl_easy *data, struct curltime *nowp) 406 { 407 struct SingleRequest *k = &data->req; 408 CURLcode result = CURLE_OK; 409 int didwhat = 0; 410 411 DEBUGASSERT(nowp); 412 if(Curl_xfer_is_blocked(data)) { 413 result = CURLE_OK; 414 goto out; 415 } 416 417 /* We go ahead and do a read if we have a readable socket or if the stream 418 was rewound (in which case we have data in a buffer) */ 419 if(k->keepon & KEEP_RECV) { 420 result = sendrecv_dl(data, k, &didwhat); 421 if(result || data->req.done) 422 goto out; 423 } 424 425 /* If we still have writing to do, we check if we have a writable socket. */ 426 if(Curl_req_want_send(data) || (data->req.keepon & KEEP_SEND_TIMED)) { 427 result = sendrecv_ul(data, &didwhat); 428 if(result) 429 goto out; 430 } 431 432 if(!didwhat) { 433 /* Transfer wanted to send/recv, but nothing was possible. */ 434 result = Curl_conn_ev_data_idle(data); 435 if(result) 436 goto out; 437 } 438 439 if(Curl_pgrsUpdate(data)) 440 result = CURLE_ABORTED_BY_CALLBACK; 441 else 442 result = Curl_speedcheck(data, *nowp); 443 if(result) 444 goto out; 445 446 if(k->keepon) { 447 if(0 > Curl_timeleft(data, nowp, FALSE)) { 448 if(k->size != -1) { 449 failf(data, "Operation timed out after %" FMT_TIMEDIFF_T 450 " milliseconds with %" FMT_OFF_T " out of %" 451 FMT_OFF_T " bytes received", 452 curlx_timediff(*nowp, data->progress.t_startsingle), 453 k->bytecount, k->size); 454 } 455 else { 456 failf(data, "Operation timed out after %" FMT_TIMEDIFF_T 457 " milliseconds with %" FMT_OFF_T " bytes received", 458 curlx_timediff(*nowp, data->progress.t_startsingle), 459 k->bytecount); 460 } 461 result = CURLE_OPERATION_TIMEDOUT; 462 goto out; 463 } 464 } 465 else { 466 /* 467 * The transfer has been performed. Just make some general checks before 468 * returning. 469 */ 470 if(!(data->req.no_body) && (k->size != -1) && 471 (k->bytecount != k->size) && !k->newurl) { 472 failf(data, "transfer closed with %" FMT_OFF_T 473 " bytes remaining to read", k->size - k->bytecount); 474 result = CURLE_PARTIAL_FILE; 475 goto out; 476 } 477 if(Curl_pgrsUpdate(data)) { 478 result = CURLE_ABORTED_BY_CALLBACK; 479 goto out; 480 } 481 } 482 483 /* If there is nothing more to send/recv, the request is done */ 484 if(0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS))) 485 data->req.done = TRUE; 486 487 out: 488 if(result) 489 DEBUGF(infof(data, "Curl_sendrecv() -> %d", result)); 490 return result; 491 } 492 493 /* Curl_init_CONNECT() gets called each time the handle switches to CONNECT 494 which means this gets called once for each subsequent redirect etc */ 495 void Curl_init_CONNECT(struct Curl_easy *data) 496 { 497 data->state.fread_func = data->set.fread_func_set; 498 data->state.in = data->set.in_set; 499 data->state.upload = (data->state.httpreq == HTTPREQ_PUT); 500 } 501 502 /* 503 * Curl_pretransfer() is called immediately before a transfer starts, and only 504 * once for one transfer no matter if it has redirects or do multi-pass 505 * authentication etc. 506 */ 507 CURLcode Curl_pretransfer(struct Curl_easy *data) 508 { 509 CURLcode result = CURLE_OK; 510 511 if(!data->set.str[STRING_SET_URL] && !data->set.uh) { 512 /* we cannot do anything without URL */ 513 failf(data, "No URL set"); 514 return CURLE_URL_MALFORMAT; 515 } 516 517 /* CURLOPT_CURLU overrides CURLOPT_URL and the contents of the CURLU handle 518 is allowed to be changed by the user between transfers */ 519 if(data->set.uh) { 520 CURLUcode uc; 521 free(data->set.str[STRING_SET_URL]); 522 uc = curl_url_get(data->set.uh, 523 CURLUPART_URL, &data->set.str[STRING_SET_URL], 0); 524 if(uc) { 525 failf(data, "No URL set"); 526 return CURLE_URL_MALFORMAT; 527 } 528 } 529 530 /* since the URL may have been redirected in a previous use of this handle */ 531 if(data->state.url_alloc) { 532 Curl_safefree(data->state.url); 533 data->state.url_alloc = FALSE; 534 } 535 536 data->state.url = data->set.str[STRING_SET_URL]; 537 538 if(data->set.postfields && data->set.set_resume_from) { 539 /* we cannot */ 540 failf(data, "cannot mix POSTFIELDS with RESUME_FROM"); 541 return CURLE_BAD_FUNCTION_ARGUMENT; 542 } 543 544 data->state.prefer_ascii = data->set.prefer_ascii; 545 #ifdef CURL_LIST_ONLY_PROTOCOL 546 data->state.list_only = data->set.list_only; 547 #endif 548 data->state.httpreq = data->set.method; 549 550 data->state.requests = 0; 551 data->state.followlocation = 0; /* reset the location-follow counter */ 552 data->state.this_is_a_follow = FALSE; /* reset this */ 553 data->state.errorbuf = FALSE; /* no error has occurred */ 554 #ifndef CURL_DISABLE_HTTP 555 Curl_http_neg_init(data, &data->state.http_neg); 556 #endif 557 data->state.authproblem = FALSE; 558 data->state.authhost.want = data->set.httpauth; 559 data->state.authproxy.want = data->set.proxyauth; 560 Curl_safefree(data->info.wouldredirect); 561 Curl_data_priority_clear_state(data); 562 563 if(data->state.httpreq == HTTPREQ_PUT) 564 data->state.infilesize = data->set.filesize; 565 else if((data->state.httpreq != HTTPREQ_GET) && 566 (data->state.httpreq != HTTPREQ_HEAD)) { 567 data->state.infilesize = data->set.postfieldsize; 568 if(data->set.postfields && (data->state.infilesize == -1)) 569 data->state.infilesize = (curl_off_t)strlen(data->set.postfields); 570 } 571 else 572 data->state.infilesize = 0; 573 574 /* If there is a list of cookie files to read, do it now! */ 575 Curl_cookie_loadfiles(data); 576 577 /* If there is a list of host pairs to deal with */ 578 if(data->state.resolve) 579 result = Curl_loadhostpairs(data); 580 581 /* If there is a list of hsts files to read */ 582 Curl_hsts_loadfiles(data); 583 584 if(!result) { 585 /* Allow data->set.use_port to set which port to use. This needs to be 586 * disabled for example when we follow Location: headers to URLs using 587 * different ports! */ 588 data->state.allow_port = TRUE; 589 590 #if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) 591 /************************************************************* 592 * Tell signal handler to ignore SIGPIPE 593 *************************************************************/ 594 if(!data->set.no_signal) 595 data->state.prev_signal = signal(SIGPIPE, SIG_IGN); 596 #endif 597 598 Curl_initinfo(data); /* reset session-specific information "variables" */ 599 Curl_pgrsResetTransferSizes(data); 600 Curl_pgrsStartNow(data); 601 602 /* In case the handle is reused and an authentication method was picked 603 in the session we need to make sure we only use the one(s) we now 604 consider to be fine */ 605 data->state.authhost.picked &= data->state.authhost.want; 606 data->state.authproxy.picked &= data->state.authproxy.want; 607 608 #ifndef CURL_DISABLE_FTP 609 data->state.wildcardmatch = data->set.wildcard_enabled; 610 if(data->state.wildcardmatch) { 611 struct WildcardData *wc; 612 if(!data->wildcard) { 613 data->wildcard = calloc(1, sizeof(struct WildcardData)); 614 if(!data->wildcard) 615 return CURLE_OUT_OF_MEMORY; 616 } 617 wc = data->wildcard; 618 if(wc->state < CURLWC_INIT) { 619 if(wc->ftpwc) 620 wc->dtor(wc->ftpwc); 621 Curl_safefree(wc->pattern); 622 Curl_safefree(wc->path); 623 result = Curl_wildcard_init(wc); /* init wildcard structures */ 624 if(result) 625 return CURLE_OUT_OF_MEMORY; 626 } 627 } 628 #endif 629 result = Curl_hsts_loadcb(data, data->hsts); 630 } 631 632 /* 633 * Set user-agent. Used for HTTP, but since we can attempt to tunnel 634 * basically anything through an HTTP proxy we cannot limit this based on 635 * protocol. 636 */ 637 if(data->set.str[STRING_USERAGENT]) { 638 free(data->state.aptr.uagent); 639 data->state.aptr.uagent = 640 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]); 641 if(!data->state.aptr.uagent) 642 return CURLE_OUT_OF_MEMORY; 643 } 644 645 if(data->set.str[STRING_USERNAME] || 646 data->set.str[STRING_PASSWORD]) 647 data->state.creds_from = CREDS_OPTION; 648 if(!result) 649 result = Curl_setstropt(&data->state.aptr.user, 650 data->set.str[STRING_USERNAME]); 651 if(!result) 652 result = Curl_setstropt(&data->state.aptr.passwd, 653 data->set.str[STRING_PASSWORD]); 654 #ifndef CURL_DISABLE_PROXY 655 if(!result) 656 result = Curl_setstropt(&data->state.aptr.proxyuser, 657 data->set.str[STRING_PROXYUSERNAME]); 658 if(!result) 659 result = Curl_setstropt(&data->state.aptr.proxypasswd, 660 data->set.str[STRING_PROXYPASSWORD]); 661 #endif 662 663 data->req.headerbytecount = 0; 664 Curl_headers_cleanup(data); 665 return result; 666 } 667 668 /* Returns CURLE_OK *and* sets '*url' if a request retry is wanted. 669 670 NOTE: that the *url is malloc()ed. */ 671 CURLcode Curl_retry_request(struct Curl_easy *data, char **url) 672 { 673 struct connectdata *conn = data->conn; 674 bool retry = FALSE; 675 *url = NULL; 676 677 /* if we are talking upload, we cannot do the checks below, unless the 678 protocol is HTTP as when uploading over HTTP we will still get a 679 response */ 680 if(data->state.upload && 681 !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP))) 682 return CURLE_OK; 683 684 if((data->req.bytecount + data->req.headerbytecount == 0) && 685 conn->bits.reuse && 686 (!data->req.no_body || (conn->handler->protocol & PROTO_FAMILY_HTTP)) 687 #ifndef CURL_DISABLE_RTSP 688 && (data->set.rtspreq != RTSPREQ_RECEIVE) 689 #endif 690 ) 691 /* We got no data, we attempted to reuse a connection. For HTTP this 692 can be a retry so we try again regardless if we expected a body. 693 For other protocols we only try again only if we expected a body. 694 695 This might happen if the connection was left alive when we were 696 done using it before, but that was closed when we wanted to read from 697 it again. Bad luck. Retry the same request on a fresh connect! */ 698 retry = TRUE; 699 else if(data->state.refused_stream && 700 (data->req.bytecount + data->req.headerbytecount == 0) ) { 701 /* This was sent on a refused stream, safe to rerun. A refused stream 702 error can typically only happen on HTTP/2 level if the stream is safe 703 to issue again, but the nghttp2 API can deliver the message to other 704 streams as well, which is why this adds the check the data counters 705 too. */ 706 infof(data, "REFUSED_STREAM, retrying a fresh connect"); 707 data->state.refused_stream = FALSE; /* clear again */ 708 retry = TRUE; 709 } 710 if(retry) { 711 #define CONN_MAX_RETRIES 5 712 if(data->state.retrycount++ >= CONN_MAX_RETRIES) { 713 failf(data, "Connection died, tried %d times before giving up", 714 CONN_MAX_RETRIES); 715 data->state.retrycount = 0; 716 return CURLE_SEND_ERROR; 717 } 718 infof(data, "Connection died, retrying a fresh connect (retry count: %d)", 719 data->state.retrycount); 720 *url = strdup(data->state.url); 721 if(!*url) 722 return CURLE_OUT_OF_MEMORY; 723 724 connclose(conn, "retry"); /* close this connection */ 725 conn->bits.retry = TRUE; /* mark this as a connection we are about 726 to retry. Marking it this way should 727 prevent i.e HTTP transfers to return 728 error just because nothing has been 729 transferred! */ 730 Curl_creader_set_rewind(data, TRUE); 731 } 732 return CURLE_OK; 733 } 734 735 /* 736 * xfer_setup() is called to setup basic properties for the transfer. 737 */ 738 static void xfer_setup( 739 struct Curl_easy *data, /* transfer */ 740 int sockindex, /* socket index to read from or -1 */ 741 curl_off_t size, /* -1 if unknown at this point */ 742 bool getheader, /* TRUE if header parsing is wanted */ 743 int writesockindex, /* socket index to write to, it may be the same we 744 read from. -1 disables */ 745 bool shutdown, /* shutdown connection at transfer end. Only 746 * supported when sending OR receiving. */ 747 bool shutdown_err_ignore /* errors during shutdown do not fail the 748 * transfer */ 749 ) 750 { 751 struct SingleRequest *k = &data->req; 752 struct connectdata *conn = data->conn; 753 bool want_send = Curl_req_want_send(data); 754 755 DEBUGASSERT(conn != NULL); 756 DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); 757 DEBUGASSERT((writesockindex <= 1) && (writesockindex >= -1)); 758 DEBUGASSERT(!shutdown || (sockindex == -1) || (writesockindex == -1)); 759 760 if(Curl_conn_is_multiplex(conn, FIRSTSOCKET) || want_send) { 761 /* when multiplexing, the read/write sockets need to be the same! */ 762 conn->sockfd = sockindex == -1 ? 763 ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) : 764 conn->sock[sockindex]; 765 conn->writesockfd = conn->sockfd; 766 if(want_send) 767 /* special and HTTP-specific */ 768 writesockindex = FIRSTSOCKET; 769 } 770 else { 771 conn->sockfd = sockindex == -1 ? 772 CURL_SOCKET_BAD : conn->sock[sockindex]; 773 conn->writesockfd = writesockindex == -1 ? 774 CURL_SOCKET_BAD : conn->sock[writesockindex]; 775 } 776 777 k->getheader = getheader; 778 k->size = size; 779 k->shutdown = shutdown; 780 k->shutdown_err_ignore = shutdown_err_ignore; 781 782 /* The code sequence below is placed in this function just because all 783 necessary input is not always known in do_complete() as this function may 784 be called after that */ 785 786 if(!k->getheader) { 787 k->header = FALSE; 788 if(size > 0) 789 Curl_pgrsSetDownloadSize(data, size); 790 } 791 /* we want header and/or body, if neither then do not do this! */ 792 if(k->getheader || !data->req.no_body) { 793 794 if(sockindex != -1) 795 k->keepon |= KEEP_RECV; 796 797 if(writesockindex != -1) 798 k->keepon |= KEEP_SEND; 799 } /* if(k->getheader || !data->req.no_body) */ 800 801 } 802 803 void Curl_xfer_setup_nop(struct Curl_easy *data) 804 { 805 xfer_setup(data, -1, -1, FALSE, -1, FALSE, FALSE); 806 } 807 808 void Curl_xfer_setup1(struct Curl_easy *data, 809 int send_recv, 810 curl_off_t recv_size, 811 bool getheader) 812 { 813 int recv_index = (send_recv & CURL_XFER_RECV) ? FIRSTSOCKET : -1; 814 int send_index = (send_recv & CURL_XFER_SEND) ? FIRSTSOCKET : -1; 815 DEBUGASSERT((recv_index >= 0) || (recv_size == -1)); 816 xfer_setup(data, recv_index, recv_size, getheader, send_index, FALSE, FALSE); 817 } 818 819 void Curl_xfer_setup2(struct Curl_easy *data, 820 int send_recv, 821 curl_off_t recv_size, 822 bool shutdown, 823 bool shutdown_err_ignore) 824 { 825 int recv_index = (send_recv & CURL_XFER_RECV) ? SECONDARYSOCKET : -1; 826 int send_index = (send_recv & CURL_XFER_SEND) ? SECONDARYSOCKET : -1; 827 DEBUGASSERT((recv_index >= 0) || (recv_size == -1)); 828 xfer_setup(data, recv_index, recv_size, FALSE, send_index, 829 shutdown, shutdown_err_ignore); 830 } 831 832 CURLcode Curl_xfer_write_resp(struct Curl_easy *data, 833 const char *buf, size_t blen, 834 bool is_eos) 835 { 836 CURLcode result = CURLE_OK; 837 838 if(data->conn->handler->write_resp) { 839 /* protocol handlers offering this function take full responsibility 840 * for writing all received download data to the client. */ 841 result = data->conn->handler->write_resp(data, buf, blen, is_eos); 842 } 843 else { 844 /* No special handling by protocol handler, write all received data 845 * as BODY to the client. */ 846 if(blen || is_eos) { 847 int cwtype = CLIENTWRITE_BODY; 848 if(is_eos) 849 cwtype |= CLIENTWRITE_EOS; 850 result = Curl_client_write(data, cwtype, buf, blen); 851 } 852 } 853 854 if(!result && is_eos) { 855 /* If we wrote the EOS, we are definitely done */ 856 data->req.eos_written = TRUE; 857 data->req.download_done = TRUE; 858 } 859 CURL_TRC_WRITE(data, "xfer_write_resp(len=%zu, eos=%d) -> %d", 860 blen, is_eos, result); 861 return result; 862 } 863 864 bool Curl_xfer_write_is_paused(struct Curl_easy *data) 865 { 866 return Curl_cwriter_is_paused(data); 867 } 868 869 CURLcode Curl_xfer_write_resp_hd(struct Curl_easy *data, 870 const char *hd0, size_t hdlen, bool is_eos) 871 { 872 if(data->conn->handler->write_resp_hd) { 873 /* protocol handlers offering this function take full responsibility 874 * for writing all received download data to the client. */ 875 return data->conn->handler->write_resp_hd(data, hd0, hdlen, is_eos); 876 } 877 /* No special handling by protocol handler, write as response bytes */ 878 return Curl_xfer_write_resp(data, hd0, hdlen, is_eos); 879 } 880 881 CURLcode Curl_xfer_write_done(struct Curl_easy *data, bool premature) 882 { 883 (void)premature; 884 return Curl_cw_out_done(data); 885 } 886 887 bool Curl_xfer_needs_flush(struct Curl_easy *data) 888 { 889 int sockindex; 890 sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && 891 (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); 892 return Curl_conn_needs_flush(data, sockindex); 893 } 894 895 CURLcode Curl_xfer_flush(struct Curl_easy *data) 896 { 897 int sockindex; 898 sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && 899 (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); 900 return Curl_conn_flush(data, sockindex); 901 } 902 903 CURLcode Curl_xfer_send(struct Curl_easy *data, 904 const void *buf, size_t blen, bool eos, 905 size_t *pnwritten) 906 { 907 CURLcode result; 908 int sockindex; 909 910 DEBUGASSERT(data); 911 DEBUGASSERT(data->conn); 912 913 sockindex = ((data->conn->writesockfd != CURL_SOCKET_BAD) && 914 (data->conn->writesockfd == data->conn->sock[SECONDARYSOCKET])); 915 result = Curl_conn_send(data, sockindex, buf, blen, eos, pnwritten); 916 if(result == CURLE_AGAIN) { 917 result = CURLE_OK; 918 *pnwritten = 0; 919 } 920 else if(!result && *pnwritten) 921 data->info.request_size += *pnwritten; 922 923 DEBUGF(infof(data, "Curl_xfer_send(len=%zu, eos=%d) -> %d, %zu", 924 blen, eos, result, *pnwritten)); 925 return result; 926 } 927 928 CURLcode Curl_xfer_recv(struct Curl_easy *data, 929 char *buf, size_t blen, 930 size_t *pnrcvd) 931 { 932 int sockindex; 933 934 DEBUGASSERT(data); 935 DEBUGASSERT(data->conn); 936 DEBUGASSERT(data->set.buffer_size > 0); 937 938 sockindex = ((data->conn->sockfd != CURL_SOCKET_BAD) && 939 (data->conn->sockfd == data->conn->sock[SECONDARYSOCKET])); 940 if((size_t)data->set.buffer_size < blen) 941 blen = (size_t)data->set.buffer_size; 942 return Curl_conn_recv(data, sockindex, buf, blen, pnrcvd); 943 } 944 945 CURLcode Curl_xfer_send_close(struct Curl_easy *data) 946 { 947 Curl_conn_ev_data_done_send(data); 948 return CURLE_OK; 949 } 950 951 bool Curl_xfer_is_blocked(struct Curl_easy *data) 952 { 953 bool want_send = ((data)->req.keepon & KEEP_SEND); 954 bool want_recv = ((data)->req.keepon & KEEP_RECV); 955 if(!want_send) 956 return want_recv && Curl_xfer_recv_is_paused(data); 957 else if(!want_recv) 958 return want_send && Curl_xfer_send_is_paused(data); 959 else 960 return Curl_xfer_recv_is_paused(data) && Curl_xfer_send_is_paused(data); 961 } 962 963 bool Curl_xfer_send_is_paused(struct Curl_easy *data) 964 { 965 return (data->req.keepon & KEEP_SEND_PAUSE); 966 } 967 968 bool Curl_xfer_recv_is_paused(struct Curl_easy *data) 969 { 970 return (data->req.keepon & KEEP_RECV_PAUSE); 971 } 972 973 CURLcode Curl_xfer_pause_send(struct Curl_easy *data, bool enable) 974 { 975 CURLcode result = CURLE_OK; 976 if(enable) { 977 data->req.keepon |= KEEP_SEND_PAUSE; 978 } 979 else { 980 data->req.keepon &= ~KEEP_SEND_PAUSE; 981 if(Curl_creader_is_paused(data)) 982 result = Curl_creader_unpause(data); 983 } 984 return result; 985 } 986 987 CURLcode Curl_xfer_pause_recv(struct Curl_easy *data, bool enable) 988 { 989 CURLcode result = CURLE_OK; 990 if(enable) { 991 data->req.keepon |= KEEP_RECV_PAUSE; 992 } 993 else { 994 data->req.keepon &= ~KEEP_RECV_PAUSE; 995 if(Curl_cwriter_is_paused(data)) 996 result = Curl_cwriter_unpause(data); 997 } 998 Curl_conn_ev_data_pause(data, enable); 999 return result; 1000 }