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#include "strtoofft.h" 27 28#ifdef HAVE_NETINET_IN_H 29#include <netinet/in.h> 30#endif 31#ifdef HAVE_NETDB_H 32#include <netdb.h> 33#endif 34#ifdef HAVE_ARPA_INET_H 35#include <arpa/inet.h> 36#endif 37#ifdef HAVE_NET_IF_H 38#include <net/if.h> 39#endif 40#ifdef HAVE_SYS_IOCTL_H 41#include <sys/ioctl.h> 42#endif 43#include <signal.h> 44 45#ifdef HAVE_SYS_PARAM_H 46#include <sys/param.h> 47#endif 48 49#ifdef HAVE_SYS_SELECT_H 50#include <sys/select.h> 51#elif defined(HAVE_UNISTD_H) 52#include <unistd.h> 53#endif 54 55#ifndef HAVE_SOCKET 56#error "We can't compile without socket() support!" 57#endif 58 59#include "urldata.h" 60#include <curl/curl.h> 61#include "netrc.h" 62 63#include "content_encoding.h" 64#include "hostip.h" 65#include "cfilters.h" 66#include "transfer.h" 67#include "sendf.h" 68#include "speedcheck.h" 69#include "progress.h" 70#include "http.h" 71#include "url.h" 72#include "getinfo.h" 73#include "vtls/vtls.h" 74#include "vquic/vquic.h" 75#include "select.h" 76#include "multiif.h" 77#include "connect.h" 78#include "http2.h" 79#include "mime.h" 80#include "strcase.h" 81#include "urlapi-int.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 */ 99char *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(strncasecompare(head->data, thisheader, thislen) && 109 Curl_headersep(head->data[thislen]) ) 110 return head->data; 111 } 112 113 return NULL; 114} 115#endif 116 117CURLcode Curl_get_upload_buffer(struct Curl_easy *data) 118{ 119 if(!data->state.ulbuf) { 120 data->state.ulbuf = malloc(data->set.upload_buffer_size); 121 if(!data->state.ulbuf) 122 return CURLE_OUT_OF_MEMORY; 123 } 124 return CURLE_OK; 125} 126 127#ifndef CURL_DISABLE_HTTP 128/* 129 * This function will be called to loop through the trailers buffer 130 * until no more data is available for sending. 131 */ 132static size_t trailers_read(char *buffer, size_t size, size_t nitems, 133 void *raw) 134{ 135 struct Curl_easy *data = (struct Curl_easy *)raw; 136 struct dynbuf *trailers_buf = &data->state.trailers_buf; 137 size_t bytes_left = Curl_dyn_len(trailers_buf) - 138 data->state.trailers_bytes_sent; 139 size_t to_copy = (size*nitems < bytes_left) ? size*nitems : bytes_left; 140 if(to_copy) { 141 memcpy(buffer, 142 Curl_dyn_ptr(trailers_buf) + data->state.trailers_bytes_sent, 143 to_copy); 144 data->state.trailers_bytes_sent += to_copy; 145 } 146 return to_copy; 147} 148 149static size_t trailers_left(void *raw) 150{ 151 struct Curl_easy *data = (struct Curl_easy *)raw; 152 struct dynbuf *trailers_buf = &data->state.trailers_buf; 153 return Curl_dyn_len(trailers_buf) - data->state.trailers_bytes_sent; 154} 155#endif 156 157/* 158 * This function will call the read callback to fill our buffer with data 159 * to upload. 160 */ 161CURLcode Curl_fillreadbuffer(struct Curl_easy *data, size_t bytes, 162 size_t *nreadp) 163{ 164 size_t buffersize = bytes; 165 size_t nread; 166 curl_read_callback readfunc = NULL; 167 void *extra_data = NULL; 168 int eof_index = 0; 169 170#ifndef CURL_DISABLE_HTTP 171 if(data->state.trailers_state == TRAILERS_INITIALIZED) { 172 struct curl_slist *trailers = NULL; 173 CURLcode result; 174 int trailers_ret_code; 175 176 /* at this point we already verified that the callback exists 177 so we compile and store the trailers buffer, then proceed */ 178 infof(data, 179 "Moving trailers state machine from initialized to sending."); 180 data->state.trailers_state = TRAILERS_SENDING; 181 Curl_dyn_init(&data->state.trailers_buf, DYN_TRAILERS); 182 183 data->state.trailers_bytes_sent = 0; 184 Curl_set_in_callback(data, true); 185 trailers_ret_code = data->set.trailer_callback(&trailers, 186 data->set.trailer_data); 187 Curl_set_in_callback(data, false); 188 if(trailers_ret_code == CURL_TRAILERFUNC_OK) { 189 result = Curl_http_compile_trailers(trailers, &data->state.trailers_buf, 190 data); 191 } 192 else { 193 failf(data, "operation aborted by trailing headers callback"); 194 *nreadp = 0; 195 result = CURLE_ABORTED_BY_CALLBACK; 196 } 197 if(result) { 198 Curl_dyn_free(&data->state.trailers_buf); 199 curl_slist_free_all(trailers); 200 return result; 201 } 202 infof(data, "Successfully compiled trailers."); 203 curl_slist_free_all(trailers); 204 } 205#endif 206 207#ifndef CURL_DISABLE_HTTP 208 /* if we are transmitting trailing data, we don't need to write 209 a chunk size so we skip this */ 210 if(data->req.upload_chunky && 211 data->state.trailers_state == TRAILERS_NONE) { 212 /* if chunked Transfer-Encoding */ 213 buffersize -= (8 + 2 + 2); /* 32bit hex + CRLF + CRLF */ 214 data->req.upload_fromhere += (8 + 2); /* 32bit hex + CRLF */ 215 } 216 217 if(data->state.trailers_state == TRAILERS_SENDING) { 218 /* if we're here then that means that we already sent the last empty chunk 219 but we didn't send a final CR LF, so we sent 0 CR LF. We then start 220 pulling trailing data until we have no more at which point we 221 simply return to the previous point in the state machine as if 222 nothing happened. 223 */ 224 readfunc = trailers_read; 225 extra_data = (void *)data; 226 eof_index = 1; 227 } 228 else 229#endif 230 { 231 readfunc = data->state.fread_func; 232 extra_data = data->state.in; 233 } 234 235 if(!data->req.fread_eof[eof_index]) { 236 Curl_set_in_callback(data, true); 237 nread = readfunc(data->req.upload_fromhere, 1, buffersize, extra_data); 238 Curl_set_in_callback(data, false); 239 /* make sure the callback is not called again after EOF */ 240 data->req.fread_eof[eof_index] = !nread; 241 } 242 else 243 nread = 0; 244 245 if(nread == CURL_READFUNC_ABORT) { 246 failf(data, "operation aborted by callback"); 247 *nreadp = 0; 248 return CURLE_ABORTED_BY_CALLBACK; 249 } 250 if(nread == CURL_READFUNC_PAUSE) { 251 struct SingleRequest *k = &data->req; 252 253 if(data->conn->handler->flags & PROTOPT_NONETWORK) { 254 /* protocols that work without network cannot be paused. This is 255 actually only FILE:// just now, and it can't pause since the transfer 256 isn't done using the "normal" procedure. */ 257 failf(data, "Read callback asked for PAUSE when not supported"); 258 return CURLE_READ_ERROR; 259 } 260 261 /* CURL_READFUNC_PAUSE pauses read callbacks that feed socket writes */ 262 k->keepon |= KEEP_SEND_PAUSE; /* mark socket send as paused */ 263 if(data->req.upload_chunky) { 264 /* Back out the preallocation done above */ 265 data->req.upload_fromhere -= (8 + 2); 266 } 267 *nreadp = 0; 268 269 return CURLE_OK; /* nothing was read */ 270 } 271 else if(nread > buffersize) { 272 /* the read function returned a too large value */ 273 *nreadp = 0; 274 failf(data, "read function returned funny value"); 275 return CURLE_READ_ERROR; 276 } 277 278#ifndef CURL_DISABLE_HTTP 279 if(!data->req.forbidchunk && data->req.upload_chunky) { 280 /* if chunked Transfer-Encoding 281 * build chunk: 282 * 283 * <HEX SIZE> CRLF 284 * <DATA> CRLF 285 */ 286 /* On non-ASCII platforms the <DATA> may or may not be 287 translated based on state.prefer_ascii while the protocol 288 portion must always be translated to the network encoding. 289 To further complicate matters, line end conversion might be 290 done later on, so we need to prevent CRLFs from becoming 291 CRCRLFs if that's the case. To do this we use bare LFs 292 here, knowing they'll become CRLFs later on. 293 */ 294 295 bool added_crlf = FALSE; 296 int hexlen = 0; 297 const char *endofline_native; 298 const char *endofline_network; 299 300 if( 301#ifdef CURL_DO_LINEEND_CONV 302 (data->state.prefer_ascii) || 303#endif 304 (data->set.crlf)) { 305 /* \n will become \r\n later on */ 306 endofline_native = "\n"; 307 endofline_network = "\x0a"; 308 } 309 else { 310 endofline_native = "\r\n"; 311 endofline_network = "\x0d\x0a"; 312 } 313 314 /* if we're not handling trailing data, proceed as usual */ 315 if(data->state.trailers_state != TRAILERS_SENDING) { 316 char hexbuffer[11] = ""; 317 hexlen = msnprintf(hexbuffer, sizeof(hexbuffer), 318 "%zx%s", nread, endofline_native); 319 320 /* move buffer pointer */ 321 data->req.upload_fromhere -= hexlen; 322 nread += hexlen; 323 324 /* copy the prefix to the buffer, leaving out the NUL */ 325 memcpy(data->req.upload_fromhere, hexbuffer, hexlen); 326 327 /* always append ASCII CRLF to the data unless 328 we have a valid trailer callback */ 329 if((nread-hexlen) == 0 && 330 data->set.trailer_callback != NULL && 331 data->state.trailers_state == TRAILERS_NONE) { 332 data->state.trailers_state = TRAILERS_INITIALIZED; 333 } 334 else { 335 memcpy(data->req.upload_fromhere + nread, 336 endofline_network, 337 strlen(endofline_network)); 338 added_crlf = TRUE; 339 } 340 } 341 342 if(data->state.trailers_state == TRAILERS_SENDING && 343 !trailers_left(data)) { 344 Curl_dyn_free(&data->state.trailers_buf); 345 data->state.trailers_state = TRAILERS_DONE; 346 data->set.trailer_data = NULL; 347 data->set.trailer_callback = NULL; 348 /* mark the transfer as done */ 349 data->req.upload_done = TRUE; 350 infof(data, "Signaling end of chunked upload after trailers."); 351 } 352 else 353 if((nread - hexlen) == 0 && 354 data->state.trailers_state != TRAILERS_INITIALIZED) { 355 /* mark this as done once this chunk is transferred */ 356 data->req.upload_done = TRUE; 357 infof(data, 358 "Signaling end of chunked upload via terminating chunk."); 359 } 360 361 if(added_crlf) 362 nread += strlen(endofline_network); /* for the added end of line */ 363 } 364#endif 365 366 *nreadp = nread; 367 368 return CURLE_OK; 369} 370 371static int data_pending(struct Curl_easy *data) 372{ 373 struct connectdata *conn = data->conn; 374 375 if(conn->handler->protocol&PROTO_FAMILY_FTP) 376 return Curl_conn_data_pending(data, SECONDARYSOCKET); 377 378 /* in the case of libssh2, we can never be really sure that we have emptied 379 its internal buffers so we MUST always try until we get EAGAIN back */ 380 return conn->handler->protocol&(CURLPROTO_SCP|CURLPROTO_SFTP) || 381 Curl_conn_data_pending(data, FIRSTSOCKET); 382} 383 384/* 385 * Check to see if CURLOPT_TIMECONDITION was met by comparing the time of the 386 * remote document with the time provided by CURLOPT_TIMEVAL 387 */ 388bool Curl_meets_timecondition(struct Curl_easy *data, time_t timeofdoc) 389{ 390 if((timeofdoc == 0) || (data->set.timevalue == 0)) 391 return TRUE; 392 393 switch(data->set.timecondition) { 394 case CURL_TIMECOND_IFMODSINCE: 395 default: 396 if(timeofdoc <= data->set.timevalue) { 397 infof(data, 398 "The requested document is not new enough"); 399 data->info.timecond = TRUE; 400 return FALSE; 401 } 402 break; 403 case CURL_TIMECOND_IFUNMODSINCE: 404 if(timeofdoc >= data->set.timevalue) { 405 infof(data, 406 "The requested document is not old enough"); 407 data->info.timecond = TRUE; 408 return FALSE; 409 } 410 break; 411 } 412 413 return TRUE; 414} 415 416/** 417 * Receive raw response data for the transfer. 418 * @param data the transfer 419 * @param buf buffer to keep response data received 420 * @param blen length of `buf` 421 * @param eos_reliable if EOS detection in underlying connection is reliable 422 * @param err error code in case of -1 return 423 * @return number of bytes read or -1 for error 424 */ 425static ssize_t Curl_xfer_recv_resp(struct Curl_easy *data, 426 char *buf, size_t blen, 427 bool eos_reliable, 428 CURLcode *err) 429{ 430 ssize_t nread; 431 432 DEBUGASSERT(blen > 0); 433 /* If we are reading BODY data and the connection does NOT handle EOF 434 * and we know the size of the BODY data, limit the read amount */ 435 if(!eos_reliable && !data->req.header && data->req.size != -1) { 436 curl_off_t totalleft = data->req.size - data->req.bytecount; 437 if(totalleft <= 0) 438 blen = 0; 439 else if(totalleft < (curl_off_t)blen) 440 blen = (size_t)totalleft; 441 } 442 443 if(!blen) { 444 /* want nothing - continue as if read nothing. */ 445 DEBUGF(infof(data, "readwrite_data: we're done")); 446 *err = CURLE_OK; 447 return 0; 448 } 449 450 *err = Curl_read(data, data->conn->sockfd, buf, blen, &nread); 451 if(*err) 452 return -1; 453 DEBUGASSERT(nread >= 0); 454 *err = CURLE_OK; 455 return nread; 456} 457 458/* 459 * Go ahead and do a read if we have a readable socket or if 460 * the stream was rewound (in which case we have data in a 461 * buffer) 462 */ 463static CURLcode readwrite_data(struct Curl_easy *data, 464 struct SingleRequest *k, 465 int *didwhat, bool *done) 466{ 467 struct connectdata *conn = data->conn; 468 CURLcode result = CURLE_OK; 469 char *buf; 470 size_t blen; 471 int maxloops = 10; 472 curl_off_t total_received = 0; 473 bool is_multiplex = FALSE; 474 475 DEBUGASSERT(data->state.buffer); 476 *done = FALSE; 477 478 /* This is where we loop until we have read everything there is to 479 read or we get a CURLE_AGAIN */ 480 do { 481 bool is_eos = FALSE; 482 size_t bytestoread; 483 ssize_t nread; 484 485 if(!is_multiplex) { 486 /* Multiplexed connection have inherent handling of EOF and we do not 487 * have to carefully restrict the amount we try to read. 488 * Multiplexed changes only in one direction. */ 489 is_multiplex = Curl_conn_is_multiplex(conn, FIRSTSOCKET); 490 } 491 492 buf = data->state.buffer; 493 bytestoread = data->set.buffer_size; 494 495 /* Observe any imposed speed limit */ 496 if(bytestoread && data->set.max_recv_speed) { 497 curl_off_t net_limit = data->set.max_recv_speed - total_received; 498 if(net_limit <= 0) 499 break; 500 if((size_t)net_limit < bytestoread) 501 bytestoread = (size_t)net_limit; 502 } 503 504 nread = Curl_xfer_recv_resp(data, buf, bytestoread, 505 is_multiplex, &result); 506 if(nread < 0) { 507 if(CURLE_AGAIN == result) { 508 result = CURLE_OK; 509 break; /* get out of loop */ 510 } 511 goto out; /* real error */ 512 } 513 514 /* We only get a 0-length read on EndOfStream */ 515 blen = (size_t)nread; 516 is_eos = (blen == 0); 517 *didwhat |= KEEP_RECV; 518 519 if(!blen) { 520 /* if we receive 0 or less here, either the data transfer is done or the 521 server closed the connection and we bail out from this! */ 522 if(is_multiplex) 523 DEBUGF(infof(data, "nread == 0, stream closed, bailing")); 524 else 525 DEBUGF(infof(data, "nread <= 0, server closed connection, bailing")); 526 if(k->eos_written) { /* already did write this to client, leave */ 527 k->keepon = 0; /* stop sending as well */ 528 break; 529 } 530 } 531 total_received += blen; 532 533 result = Curl_xfer_write_resp(data, buf, blen, is_eos, done); 534 if(result || *done) 535 goto out; 536 537 /* if we are done, we stop receiving. On multiplexed connections, 538 * we should read the EOS. Which may arrive as meta data after 539 * the bytes. Not taking it in might lead to RST of streams. */ 540 if((!is_multiplex && data->req.download_done) || is_eos) { 541 data->req.keepon &= ~KEEP_RECV; 542 } 543 /* if we are PAUSEd or stopped receiving, leave the loop */ 544 if((k->keepon & KEEP_RECV_PAUSE) || !(k->keepon & KEEP_RECV)) 545 break; 546 547 } while(maxloops-- && data_pending(data)); 548 549 if(maxloops <= 0) { 550 /* did not read until EAGAIN, mark read-again-please */ 551 data->state.select_bits = CURL_CSELECT_IN; 552 if((k->keepon & KEEP_SENDBITS) == KEEP_SEND) 553 data->state.select_bits |= CURL_CSELECT_OUT; 554 } 555 556 if(((k->keepon & (KEEP_RECV|KEEP_SEND)) == KEEP_SEND) && 557 (conn->bits.close || is_multiplex)) { 558 /* When we've read the entire thing and the close bit is set, the server 559 may now close the connection. If there's now any kind of sending going 560 on from our side, we need to stop that immediately. */ 561 infof(data, "we are done reading and this is set to close, stop send"); 562 k->keepon &= ~KEEP_SEND; /* no writing anymore either */ 563 k->keepon &= ~KEEP_SEND_PAUSE; /* no pausing anymore either */ 564 } 565 566out: 567 if(result) 568 DEBUGF(infof(data, "readwrite_data() -> %d", result)); 569 return result; 570} 571 572CURLcode Curl_done_sending(struct Curl_easy *data, 573 struct SingleRequest *k) 574{ 575 k->keepon &= ~KEEP_SEND; /* we're done writing */ 576 577 /* These functions should be moved into the handler struct! */ 578 Curl_conn_ev_data_done_send(data); 579 580 return CURLE_OK; 581} 582 583#if defined(_WIN32) && defined(USE_WINSOCK) 584#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY 585#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747B 586#endif 587 588static void win_update_buffer_size(curl_socket_t sockfd) 589{ 590 int result; 591 ULONG ideal; 592 DWORD ideallen; 593 result = WSAIoctl(sockfd, SIO_IDEAL_SEND_BACKLOG_QUERY, 0, 0, 594 &ideal, sizeof(ideal), &ideallen, 0, 0); 595 if(result == 0) { 596 setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, 597 (const char *)&ideal, sizeof(ideal)); 598 } 599} 600#else 601#define win_update_buffer_size(x) 602#endif 603 604#define curl_upload_refill_watermark(data) \ 605 ((ssize_t)((data)->set.upload_buffer_size >> 5)) 606 607/* 608 * Send data to upload to the server, when the socket is writable. 609 */ 610static CURLcode readwrite_upload(struct Curl_easy *data, 611 struct connectdata *conn, 612 int *didwhat) 613{ 614 ssize_t i, si; 615 ssize_t bytes_written; 616 CURLcode result; 617 ssize_t nread; /* number of bytes read */ 618 bool sending_http_headers = FALSE; 619 struct SingleRequest *k = &data->req; 620 621 *didwhat |= KEEP_SEND; 622 623 do { 624 curl_off_t nbody; 625 ssize_t offset = 0; 626 627 if(0 != k->upload_present && 628 k->upload_present < curl_upload_refill_watermark(data) && 629 !k->upload_chunky &&/*(variable sized chunked header; append not safe)*/ 630 !k->upload_done && /*!(k->upload_done once k->upload_present sent)*/ 631 !(k->writebytecount + k->upload_present - k->pendingheader == 632 data->state.infilesize)) { 633 offset = k->upload_present; 634 } 635 636 /* only read more data if there's no upload data already 637 present in the upload buffer, or if appending to upload buffer */ 638 if(0 == k->upload_present || offset) { 639 result = Curl_get_upload_buffer(data); 640 if(result) 641 return result; 642 if(offset && k->upload_fromhere != data->state.ulbuf) 643 memmove(data->state.ulbuf, k->upload_fromhere, offset); 644 /* init the "upload from here" pointer */ 645 k->upload_fromhere = data->state.ulbuf; 646 647 if(!k->upload_done) { 648 /* HTTP pollution, this should be written nicer to become more 649 protocol agnostic. */ 650 size_t fillcount; 651 struct HTTP *http = k->p.http; 652 653 if((k->exp100 == EXP100_SENDING_REQUEST) && 654 (http->sending == HTTPSEND_BODY)) { 655 /* If this call is to send body data, we must take some action: 656 We have sent off the full HTTP 1.1 request, and we shall now 657 go into the Expect: 100 state and await such a header */ 658 k->exp100 = EXP100_AWAITING_CONTINUE; /* wait for the header */ 659 k->keepon &= ~KEEP_SEND; /* disable writing */ 660 k->start100 = Curl_now(); /* timeout count starts now */ 661 *didwhat &= ~KEEP_SEND; /* we didn't write anything actually */ 662 /* set a timeout for the multi interface */ 663 Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT); 664 break; 665 } 666 667 if(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)) { 668 if(http->sending == HTTPSEND_REQUEST) 669 /* We're sending the HTTP request headers, not the data. 670 Remember that so we don't change the line endings. */ 671 sending_http_headers = TRUE; 672 else 673 sending_http_headers = FALSE; 674 } 675 676 k->upload_fromhere += offset; 677 result = Curl_fillreadbuffer(data, data->set.upload_buffer_size-offset, 678 &fillcount); 679 k->upload_fromhere -= offset; 680 if(result) 681 return result; 682 683 nread = offset + fillcount; 684 } 685 else 686 nread = 0; /* we're done uploading/reading */ 687 688 if(!nread && (k->keepon & KEEP_SEND_PAUSE)) { 689 /* this is a paused transfer */ 690 break; 691 } 692 if(nread <= 0) { 693 result = Curl_done_sending(data, k); 694 if(result) 695 return result; 696 break; 697 } 698 699 /* store number of bytes available for upload */ 700 k->upload_present = nread; 701 702 /* convert LF to CRLF if so asked */ 703 if((!sending_http_headers) && ( 704#ifdef CURL_DO_LINEEND_CONV 705 /* always convert if we're FTPing in ASCII mode */ 706 (data->state.prefer_ascii) || 707#endif 708 (data->set.crlf))) { 709 /* Do we need to allocate a scratch buffer? */ 710 if(!data->state.scratch) { 711 data->state.scratch = malloc(2 * data->set.upload_buffer_size); 712 if(!data->state.scratch) { 713 failf(data, "Failed to alloc scratch buffer"); 714 715 return CURLE_OUT_OF_MEMORY; 716 } 717 } 718 719 /* 720 * ASCII/EBCDIC Note: This is presumably a text (not binary) 721 * transfer so the data should already be in ASCII. 722 * That means the hex values for ASCII CR (0x0d) & LF (0x0a) 723 * must be used instead of the escape sequences \r & \n. 724 */ 725 if(offset) 726 memcpy(data->state.scratch, k->upload_fromhere, offset); 727 for(i = offset, si = offset; i < nread; i++, si++) { 728 if(k->upload_fromhere[i] == 0x0a) { 729 data->state.scratch[si++] = 0x0d; 730 data->state.scratch[si] = 0x0a; 731 if(!data->set.crlf) { 732 /* we're here only because FTP is in ASCII mode... 733 bump infilesize for the LF we just added */ 734 if(data->state.infilesize != -1) 735 data->state.infilesize++; 736 } 737 } 738 else 739 data->state.scratch[si] = k->upload_fromhere[i]; 740 } 741 742 if(si != nread) { 743 /* only perform the special operation if we really did replace 744 anything */ 745 nread = si; 746 747 /* upload from the new (replaced) buffer instead */ 748 k->upload_fromhere = data->state.scratch; 749 750 /* set the new amount too */ 751 k->upload_present = nread; 752 } 753 } 754 755#ifndef CURL_DISABLE_SMTP 756 if(conn->handler->protocol & PROTO_FAMILY_SMTP) { 757 result = Curl_smtp_escape_eob(data, nread, offset); 758 if(result) 759 return result; 760 } 761#endif /* CURL_DISABLE_SMTP */ 762 } /* if 0 == k->upload_present or appended to upload buffer */ 763 else { 764 /* We have a partial buffer left from a previous "round". Use 765 that instead of reading more data */ 766 } 767 768 /* write to socket (send away data) */ 769 result = Curl_write(data, 770 conn->writesockfd, /* socket to send to */ 771 k->upload_fromhere, /* buffer pointer */ 772 k->upload_present, /* buffer size */ 773 &bytes_written); /* actually sent */ 774 if(result) 775 return result; 776 777#if defined(_WIN32) && defined(USE_WINSOCK) 778 { 779 struct curltime n = Curl_now(); 780 if(Curl_timediff(n, k->last_sndbuf_update) > 1000) { 781 win_update_buffer_size(conn->writesockfd); 782 k->last_sndbuf_update = n; 783 } 784 } 785#endif 786 787 if(k->pendingheader) { 788 /* parts of what was sent was header */ 789 curl_off_t n = CURLMIN(k->pendingheader, bytes_written); 790 /* show the data before we change the pointer upload_fromhere */ 791 Curl_debug(data, CURLINFO_HEADER_OUT, k->upload_fromhere, (size_t)n); 792 k->pendingheader -= n; 793 nbody = bytes_written - n; /* size of the written body part */ 794 } 795 else 796 nbody = bytes_written; 797 798 if(nbody) { 799 /* show the data before we change the pointer upload_fromhere */ 800 Curl_debug(data, CURLINFO_DATA_OUT, 801 &k->upload_fromhere[bytes_written - nbody], 802 (size_t)nbody); 803 804 k->writebytecount += nbody; 805 Curl_pgrsSetUploadCounter(data, k->writebytecount); 806 } 807 808 if((!k->upload_chunky || k->forbidchunk) && 809 (k->writebytecount == data->state.infilesize)) { 810 /* we have sent all data we were supposed to */ 811 k->upload_done = TRUE; 812 infof(data, "We are completely uploaded and fine"); 813 } 814 815 if(k->upload_present != bytes_written) { 816 /* we only wrote a part of the buffer (if anything), deal with it! */ 817 818 /* store the amount of bytes left in the buffer to write */ 819 k->upload_present -= bytes_written; 820 821 /* advance the pointer where to find the buffer when the next send 822 is to happen */ 823 k->upload_fromhere += bytes_written; 824 } 825 else { 826 /* we've uploaded that buffer now */ 827 result = Curl_get_upload_buffer(data); 828 if(result) 829 return result; 830 k->upload_fromhere = data->state.ulbuf; 831 k->upload_present = 0; /* no more bytes left */ 832 833 if(k->upload_done) { 834 result = Curl_done_sending(data, k); 835 if(result) 836 return result; 837 } 838 } 839 840 841 } while(0); /* just to break out from! */ 842 843 return CURLE_OK; 844} 845 846static int select_bits_paused(struct Curl_easy *data, int select_bits) 847{ 848 /* See issue #11982: we really need to be careful not to progress 849 * a transfer direction when that direction is paused. Not all parts 850 * of our state machine are handling PAUSED transfers correctly. So, we 851 * do not want to go there. 852 * NOTE: we are only interested in PAUSE, not HOLD. */ 853 854 /* if there is data in a direction not paused, return false */ 855 if(((select_bits & CURL_CSELECT_IN) && 856 !(data->req.keepon & KEEP_RECV_PAUSE)) || 857 ((select_bits & CURL_CSELECT_OUT) && 858 !(data->req.keepon & KEEP_SEND_PAUSE))) 859 return FALSE; 860 861 return (data->req.keepon & (KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)); 862} 863 864/* 865 * Curl_readwrite() is the low-level function to be called when data is to 866 * be read and written to/from the connection. 867 */ 868CURLcode Curl_readwrite(struct Curl_easy *data, 869 bool *done) 870{ 871 struct connectdata *conn = data->conn; 872 struct SingleRequest *k = &data->req; 873 CURLcode result; 874 struct curltime now; 875 int didwhat = 0; 876 int select_bits; 877 878 if(data->state.select_bits) { 879 if(select_bits_paused(data, data->state.select_bits)) { 880 /* leave the bits unchanged, so they'll tell us what to do when 881 * this transfer gets unpaused. */ 882 DEBUGF(infof(data, "readwrite, select_bits, early return on PAUSED")); 883 result = CURLE_OK; 884 goto out; 885 } 886 select_bits = data->state.select_bits; 887 data->state.select_bits = 0; 888 } 889 else { 890 curl_socket_t fd_read; 891 curl_socket_t fd_write; 892 /* only use the proper socket if the *_HOLD bit is not set simultaneously 893 as then we are in rate limiting state in that transfer direction */ 894 if((k->keepon & KEEP_RECVBITS) == KEEP_RECV) 895 fd_read = conn->sockfd; 896 else 897 fd_read = CURL_SOCKET_BAD; 898 899 if((k->keepon & KEEP_SENDBITS) == KEEP_SEND) 900 fd_write = conn->writesockfd; 901 else 902 fd_write = CURL_SOCKET_BAD; 903 904 select_bits = Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write, 0); 905 } 906 907 if(select_bits == CURL_CSELECT_ERR) { 908 failf(data, "select/poll returned error"); 909 result = CURLE_SEND_ERROR; 910 goto out; 911 } 912 913#ifdef USE_HYPER 914 if(conn->datastream) { 915 result = conn->datastream(data, conn, &didwhat, done, select_bits); 916 if(result || *done) 917 goto out; 918 } 919 else { 920#endif 921 /* We go ahead and do a read if we have a readable socket or if 922 the stream was rewound (in which case we have data in a 923 buffer) */ 924 if((k->keepon & KEEP_RECV) && (select_bits & CURL_CSELECT_IN)) { 925 result = readwrite_data(data, k, &didwhat, done); 926 if(result || *done) 927 goto out; 928 } 929 930 /* If we still have writing to do, we check if we have a writable socket. */ 931 if((k->keepon & KEEP_SEND) && (select_bits & CURL_CSELECT_OUT)) { 932 /* write */ 933 934 result = readwrite_upload(data, conn, &didwhat); 935 if(result) 936 goto out; 937 } 938#ifdef USE_HYPER 939 } 940#endif 941 942 now = Curl_now(); 943 if(!didwhat) { 944 /* no read no write, this is a timeout? */ 945 if(k->exp100 == EXP100_AWAITING_CONTINUE) { 946 /* This should allow some time for the header to arrive, but only a 947 very short time as otherwise it'll be too much wasted time too 948 often. */ 949 950 /* Quoting RFC2616, section "8.2.3 Use of the 100 (Continue) Status": 951 952 Therefore, when a client sends this header field to an origin server 953 (possibly via a proxy) from which it has never seen a 100 (Continue) 954 status, the client SHOULD NOT wait for an indefinite period before 955 sending the request body. 956 957 */ 958 959 timediff_t ms = Curl_timediff(now, k->start100); 960 if(ms >= data->set.expect_100_timeout) { 961 /* we've waited long enough, continue anyway */ 962 k->exp100 = EXP100_SEND_DATA; 963 k->keepon |= KEEP_SEND; 964 Curl_expire_done(data, EXPIRE_100_TIMEOUT); 965 infof(data, "Done waiting for 100-continue"); 966 } 967 } 968 969 result = Curl_conn_ev_data_idle(data); 970 if(result) 971 goto out; 972 } 973 974 if(Curl_pgrsUpdate(data)) 975 result = CURLE_ABORTED_BY_CALLBACK; 976 else 977 result = Curl_speedcheck(data, now); 978 if(result) 979 goto out; 980 981 if(k->keepon) { 982 if(0 > Curl_timeleft(data, &now, FALSE)) { 983 if(k->size != -1) { 984 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T 985 " milliseconds with %" CURL_FORMAT_CURL_OFF_T " out of %" 986 CURL_FORMAT_CURL_OFF_T " bytes received", 987 Curl_timediff(now, data->progress.t_startsingle), 988 k->bytecount, k->size); 989 } 990 else { 991 failf(data, "Operation timed out after %" CURL_FORMAT_TIMEDIFF_T 992 " milliseconds with %" CURL_FORMAT_CURL_OFF_T " bytes received", 993 Curl_timediff(now, data->progress.t_startsingle), 994 k->bytecount); 995 } 996 result = CURLE_OPERATION_TIMEDOUT; 997 goto out; 998 } 999 } 1000 else { 1001 /* 1002 * The transfer has been performed. Just make some general checks before 1003 * returning. 1004 */ 1005 1006 if(!(data->req.no_body) && (k->size != -1) && 1007 (k->bytecount != k->size) && 1008#ifdef CURL_DO_LINEEND_CONV 1009 /* Most FTP servers don't adjust their file SIZE response for CRLFs, 1010 so we'll check to see if the discrepancy can be explained 1011 by the number of CRLFs we've changed to LFs. 1012 */ 1013 (k->bytecount != (k->size + data->state.crlf_conversions)) && 1014#endif /* CURL_DO_LINEEND_CONV */ 1015 !k->newurl) { 1016 failf(data, "transfer closed with %" CURL_FORMAT_CURL_OFF_T 1017 " bytes remaining to read", k->size - k->bytecount); 1018 result = CURLE_PARTIAL_FILE; 1019 goto out; 1020 } 1021 if(Curl_pgrsUpdate(data)) { 1022 result = CURLE_ABORTED_BY_CALLBACK; 1023 goto out; 1024 } 1025 } 1026 1027 /* Now update the "done" boolean we return */ 1028 *done = (0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS))) ? TRUE : FALSE; 1029out: 1030 if(result) 1031 DEBUGF(infof(data, "Curl_readwrite() -> %d", result)); 1032 return result; 1033} 1034 1035/* Curl_init_CONNECT() gets called each time the handle switches to CONNECT 1036 which means this gets called once for each subsequent redirect etc */ 1037void Curl_init_CONNECT(struct Curl_easy *data) 1038{ 1039 data->state.fread_func = data->set.fread_func_set; 1040 data->state.in = data->set.in_set; 1041 data->state.upload = (data->state.httpreq == HTTPREQ_PUT); 1042} 1043 1044/* 1045 * Curl_pretransfer() is called immediately before a transfer starts, and only 1046 * once for one transfer no matter if it has redirects or do multi-pass 1047 * authentication etc. 1048 */ 1049CURLcode Curl_pretransfer(struct Curl_easy *data) 1050{ 1051 CURLcode result; 1052 1053 if(!data->state.url && !data->set.uh) { 1054 /* we can't do anything without URL */ 1055 failf(data, "No URL set"); 1056 return CURLE_URL_MALFORMAT; 1057 } 1058 1059 /* since the URL may have been redirected in a previous use of this handle */ 1060 if(data->state.url_alloc) { 1061 /* the already set URL is allocated, free it first! */ 1062 Curl_safefree(data->state.url); 1063 data->state.url_alloc = FALSE; 1064 } 1065 1066 if(!data->state.url && data->set.uh) { 1067 CURLUcode uc; 1068 free(data->set.str[STRING_SET_URL]); 1069 uc = curl_url_get(data->set.uh, 1070 CURLUPART_URL, &data->set.str[STRING_SET_URL], 0); 1071 if(uc) { 1072 failf(data, "No URL set"); 1073 return CURLE_URL_MALFORMAT; 1074 } 1075 } 1076 1077 if(data->set.postfields && data->set.set_resume_from) { 1078 /* we can't */ 1079 failf(data, "cannot mix POSTFIELDS with RESUME_FROM"); 1080 return CURLE_BAD_FUNCTION_ARGUMENT; 1081 } 1082 1083 data->state.prefer_ascii = data->set.prefer_ascii; 1084#ifdef CURL_LIST_ONLY_PROTOCOL 1085 data->state.list_only = data->set.list_only; 1086#endif 1087 data->state.httpreq = data->set.method; 1088 data->state.url = data->set.str[STRING_SET_URL]; 1089 1090 /* Init the SSL session ID cache here. We do it here since we want to do it 1091 after the *_setopt() calls (that could specify the size of the cache) but 1092 before any transfer takes place. */ 1093 result = Curl_ssl_initsessions(data, data->set.general_ssl.max_ssl_sessions); 1094 if(result) 1095 return result; 1096 1097 data->state.requests = 0; 1098 data->state.followlocation = 0; /* reset the location-follow counter */ 1099 data->state.this_is_a_follow = FALSE; /* reset this */ 1100 data->state.errorbuf = FALSE; /* no error has occurred */ 1101 data->state.httpwant = data->set.httpwant; 1102 data->state.httpversion = 0; 1103 data->state.authproblem = FALSE; 1104 data->state.authhost.want = data->set.httpauth; 1105 data->state.authproxy.want = data->set.proxyauth; 1106 Curl_safefree(data->info.wouldredirect); 1107 Curl_data_priority_clear_state(data); 1108 1109 if(data->state.httpreq == HTTPREQ_PUT) 1110 data->state.infilesize = data->set.filesize; 1111 else if((data->state.httpreq != HTTPREQ_GET) && 1112 (data->state.httpreq != HTTPREQ_HEAD)) { 1113 data->state.infilesize = data->set.postfieldsize; 1114 if(data->set.postfields && (data->state.infilesize == -1)) 1115 data->state.infilesize = (curl_off_t)strlen(data->set.postfields); 1116 } 1117 else 1118 data->state.infilesize = 0; 1119 1120 /* If there is a list of cookie files to read, do it now! */ 1121 Curl_cookie_loadfiles(data); 1122 1123 /* If there is a list of host pairs to deal with */ 1124 if(data->state.resolve) 1125 result = Curl_loadhostpairs(data); 1126 1127 /* If there is a list of hsts files to read */ 1128 Curl_hsts_loadfiles(data); 1129 1130 if(!result) { 1131 /* Allow data->set.use_port to set which port to use. This needs to be 1132 * disabled for example when we follow Location: headers to URLs using 1133 * different ports! */ 1134 data->state.allow_port = TRUE; 1135 1136#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) 1137 /************************************************************* 1138 * Tell signal handler to ignore SIGPIPE 1139 *************************************************************/ 1140 if(!data->set.no_signal) 1141 data->state.prev_signal = signal(SIGPIPE, SIG_IGN); 1142#endif 1143 1144 Curl_initinfo(data); /* reset session-specific information "variables" */ 1145 Curl_pgrsResetTransferSizes(data); 1146 Curl_pgrsStartNow(data); 1147 1148 /* In case the handle is reused and an authentication method was picked 1149 in the session we need to make sure we only use the one(s) we now 1150 consider to be fine */ 1151 data->state.authhost.picked &= data->state.authhost.want; 1152 data->state.authproxy.picked &= data->state.authproxy.want; 1153 1154#ifndef CURL_DISABLE_FTP 1155 data->state.wildcardmatch = data->set.wildcard_enabled; 1156 if(data->state.wildcardmatch) { 1157 struct WildcardData *wc; 1158 if(!data->wildcard) { 1159 data->wildcard = calloc(1, sizeof(struct WildcardData)); 1160 if(!data->wildcard) 1161 return CURLE_OUT_OF_MEMORY; 1162 } 1163 wc = data->wildcard; 1164 if(wc->state < CURLWC_INIT) { 1165 if(wc->ftpwc) 1166 wc->dtor(wc->ftpwc); 1167 Curl_safefree(wc->pattern); 1168 Curl_safefree(wc->path); 1169 result = Curl_wildcard_init(wc); /* init wildcard structures */ 1170 if(result) 1171 return CURLE_OUT_OF_MEMORY; 1172 } 1173 } 1174#endif 1175 result = Curl_hsts_loadcb(data, data->hsts); 1176 } 1177 1178 /* 1179 * Set user-agent. Used for HTTP, but since we can attempt to tunnel 1180 * basically anything through an HTTP proxy we can't limit this based on 1181 * protocol. 1182 */ 1183 if(data->set.str[STRING_USERAGENT]) { 1184 Curl_safefree(data->state.aptr.uagent); 1185 data->state.aptr.uagent = 1186 aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]); 1187 if(!data->state.aptr.uagent) 1188 return CURLE_OUT_OF_MEMORY; 1189 } 1190 1191 if(!result) 1192 result = Curl_setstropt(&data->state.aptr.user, 1193 data->set.str[STRING_USERNAME]); 1194 if(!result) 1195 result = Curl_setstropt(&data->state.aptr.passwd, 1196 data->set.str[STRING_PASSWORD]); 1197 if(!result) 1198 result = Curl_setstropt(&data->state.aptr.proxyuser, 1199 data->set.str[STRING_PROXYUSERNAME]); 1200 if(!result) 1201 result = Curl_setstropt(&data->state.aptr.proxypasswd, 1202 data->set.str[STRING_PROXYPASSWORD]); 1203 1204 data->req.headerbytecount = 0; 1205 Curl_headers_cleanup(data); 1206 return result; 1207} 1208 1209/* 1210 * Curl_posttransfer() is called immediately after a transfer ends 1211 */ 1212CURLcode Curl_posttransfer(struct Curl_easy *data) 1213{ 1214#if defined(HAVE_SIGNAL) && defined(SIGPIPE) && !defined(HAVE_MSG_NOSIGNAL) 1215 /* restore the signal handler for SIGPIPE before we get back */ 1216 if(!data->set.no_signal) 1217 signal(SIGPIPE, data->state.prev_signal); 1218#else 1219 (void)data; /* unused parameter */ 1220#endif 1221 1222 return CURLE_OK; 1223} 1224 1225/* 1226 * Curl_follow() handles the URL redirect magic. Pass in the 'newurl' string 1227 * as given by the remote server and set up the new URL to request. 1228 * 1229 * This function DOES NOT FREE the given url. 1230 */ 1231CURLcode Curl_follow(struct Curl_easy *data, 1232 char *newurl, /* the Location: string */ 1233 followtype type) /* see transfer.h */ 1234{ 1235#ifdef CURL_DISABLE_HTTP 1236 (void)data; 1237 (void)newurl; 1238 (void)type; 1239 /* Location: following will not happen when HTTP is disabled */ 1240 return CURLE_TOO_MANY_REDIRECTS; 1241#else 1242 1243 /* Location: redirect */ 1244 bool disallowport = FALSE; 1245 bool reachedmax = FALSE; 1246 CURLUcode uc; 1247 1248 DEBUGASSERT(type != FOLLOW_NONE); 1249 1250 if(type != FOLLOW_FAKE) 1251 data->state.requests++; /* count all real follows */ 1252 if(type == FOLLOW_REDIR) { 1253 if((data->set.maxredirs != -1) && 1254 (data->state.followlocation >= data->set.maxredirs)) { 1255 reachedmax = TRUE; 1256 type = FOLLOW_FAKE; /* switch to fake to store the would-be-redirected 1257 to URL */ 1258 } 1259 else { 1260 data->state.followlocation++; /* count redirect-followings, including 1261 auth reloads */ 1262 1263 if(data->set.http_auto_referer) { 1264 CURLU *u; 1265 char *referer = NULL; 1266 1267 /* We are asked to automatically set the previous URL as the referer 1268 when we get the next URL. We pick the ->url field, which may or may 1269 not be 100% correct */ 1270 1271 if(data->state.referer_alloc) { 1272 Curl_safefree(data->state.referer); 1273 data->state.referer_alloc = FALSE; 1274 } 1275 1276 /* Make a copy of the URL without credentials and fragment */ 1277 u = curl_url(); 1278 if(!u) 1279 return CURLE_OUT_OF_MEMORY; 1280 1281 uc = curl_url_set(u, CURLUPART_URL, data->state.url, 0); 1282 if(!uc) 1283 uc = curl_url_set(u, CURLUPART_FRAGMENT, NULL, 0); 1284 if(!uc) 1285 uc = curl_url_set(u, CURLUPART_USER, NULL, 0); 1286 if(!uc) 1287 uc = curl_url_set(u, CURLUPART_PASSWORD, NULL, 0); 1288 if(!uc) 1289 uc = curl_url_get(u, CURLUPART_URL, &referer, 0); 1290 1291 curl_url_cleanup(u); 1292 1293 if(uc || !referer) 1294 return CURLE_OUT_OF_MEMORY; 1295 1296 data->state.referer = referer; 1297 data->state.referer_alloc = TRUE; /* yes, free this later */ 1298 } 1299 } 1300 } 1301 1302 if((type != FOLLOW_RETRY) && 1303 (data->req.httpcode != 401) && (data->req.httpcode != 407) && 1304 Curl_is_absolute_url(newurl, NULL, 0, FALSE)) { 1305 /* If this is not redirect due to a 401 or 407 response and an absolute 1306 URL: don't allow a custom port number */ 1307 disallowport = TRUE; 1308 } 1309 1310 DEBUGASSERT(data->state.uh); 1311 uc = curl_url_set(data->state.uh, CURLUPART_URL, newurl, 1312 (type == FOLLOW_FAKE) ? CURLU_NON_SUPPORT_SCHEME : 1313 ((type == FOLLOW_REDIR) ? CURLU_URLENCODE : 0) | 1314 CURLU_ALLOW_SPACE | 1315 (data->set.path_as_is ? CURLU_PATH_AS_IS : 0)); 1316 if(uc) { 1317 if(type != FOLLOW_FAKE) { 1318 failf(data, "The redirect target URL could not be parsed: %s", 1319 curl_url_strerror(uc)); 1320 return Curl_uc_to_curlcode(uc); 1321 } 1322 1323 /* the URL could not be parsed for some reason, but since this is FAKE 1324 mode, just duplicate the field as-is */ 1325 newurl = strdup(newurl); 1326 if(!newurl) 1327 return CURLE_OUT_OF_MEMORY; 1328 } 1329 else { 1330 uc = curl_url_get(data->state.uh, CURLUPART_URL, &newurl, 0); 1331 if(uc) 1332 return Curl_uc_to_curlcode(uc); 1333 1334 /* Clear auth if this redirects to a different port number or protocol, 1335 unless permitted */ 1336 if(!data->set.allow_auth_to_other_hosts && (type != FOLLOW_FAKE)) { 1337 char *portnum; 1338 int port; 1339 bool clear = FALSE; 1340 1341 if(data->set.use_port && data->state.allow_port) 1342 /* a custom port is used */ 1343 port = (int)data->set.use_port; 1344 else { 1345 uc = curl_url_get(data->state.uh, CURLUPART_PORT, &portnum, 1346 CURLU_DEFAULT_PORT); 1347 if(uc) { 1348 free(newurl); 1349 return Curl_uc_to_curlcode(uc); 1350 } 1351 port = atoi(portnum); 1352 free(portnum); 1353 } 1354 if(port != data->info.conn_remote_port) { 1355 infof(data, "Clear auth, redirects to port from %u to %u", 1356 data->info.conn_remote_port, port); 1357 clear = TRUE; 1358 } 1359 else { 1360 char *scheme; 1361 const struct Curl_handler *p; 1362 uc = curl_url_get(data->state.uh, CURLUPART_SCHEME, &scheme, 0); 1363 if(uc) { 1364 free(newurl); 1365 return Curl_uc_to_curlcode(uc); 1366 } 1367 1368 p = Curl_get_scheme_handler(scheme); 1369 if(p && (p->protocol != data->info.conn_protocol)) { 1370 infof(data, "Clear auth, redirects scheme from %s to %s", 1371 data->info.conn_scheme, scheme); 1372 clear = TRUE; 1373 } 1374 free(scheme); 1375 } 1376 if(clear) { 1377 Curl_safefree(data->state.aptr.user); 1378 Curl_safefree(data->state.aptr.passwd); 1379 } 1380 } 1381 } 1382 1383 if(type == FOLLOW_FAKE) { 1384 /* we're only figuring out the new url if we would've followed locations 1385 but now we're done so we can get out! */ 1386 data->info.wouldredirect = newurl; 1387 1388 if(reachedmax) { 1389 failf(data, "Maximum (%ld) redirects followed", data->set.maxredirs); 1390 return CURLE_TOO_MANY_REDIRECTS; 1391 } 1392 return CURLE_OK; 1393 } 1394 1395 if(disallowport) 1396 data->state.allow_port = FALSE; 1397 1398 if(data->state.url_alloc) 1399 Curl_safefree(data->state.url); 1400 1401 data->state.url = newurl; 1402 data->state.url_alloc = TRUE; 1403 1404 infof(data, "Issue another request to this URL: '%s'", data->state.url); 1405 1406 /* 1407 * We get here when the HTTP code is 300-399 (and 401). We need to perform 1408 * differently based on exactly what return code there was. 1409 * 1410 * News from 7.10.6: we can also get here on a 401 or 407, in case we act on 1411 * an HTTP (proxy-) authentication scheme other than Basic. 1412 */ 1413 switch(data->info.httpcode) { 1414 /* 401 - Act on a WWW-Authenticate, we keep on moving and do the 1415 Authorization: XXXX header in the HTTP request code snippet */ 1416 /* 407 - Act on a Proxy-Authenticate, we keep on moving and do the 1417 Proxy-Authorization: XXXX header in the HTTP request code snippet */ 1418 /* 300 - Multiple Choices */ 1419 /* 306 - Not used */ 1420 /* 307 - Temporary Redirect */ 1421 default: /* for all above (and the unknown ones) */ 1422 /* Some codes are explicitly mentioned since I've checked RFC2616 and they 1423 * seem to be OK to POST to. 1424 */ 1425 break; 1426 case 301: /* Moved Permanently */ 1427 /* (quote from RFC7231, section 6.4.2) 1428 * 1429 * Note: For historical reasons, a user agent MAY change the request 1430 * method from POST to GET for the subsequent request. If this 1431 * behavior is undesired, the 307 (Temporary Redirect) status code 1432 * can be used instead. 1433 * 1434 * ---- 1435 * 1436 * Many webservers expect this, so these servers often answers to a POST 1437 * request with an error page. To be sure that libcurl gets the page that 1438 * most user agents would get, libcurl has to force GET. 1439 * 1440 * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and 1441 * can be overridden with CURLOPT_POSTREDIR. 1442 */ 1443 if((data->state.httpreq == HTTPREQ_POST 1444 || data->state.httpreq == HTTPREQ_POST_FORM 1445 || data->state.httpreq == HTTPREQ_POST_MIME) 1446 && !(data->set.keep_post & CURL_REDIR_POST_301)) { 1447 infof(data, "Switch from POST to GET"); 1448 data->state.httpreq = HTTPREQ_GET; 1449 } 1450 break; 1451 case 302: /* Found */ 1452 /* (quote from RFC7231, section 6.4.3) 1453 * 1454 * Note: For historical reasons, a user agent MAY change the request 1455 * method from POST to GET for the subsequent request. If this 1456 * behavior is undesired, the 307 (Temporary Redirect) status code 1457 * can be used instead. 1458 * 1459 * ---- 1460 * 1461 * Many webservers expect this, so these servers often answers to a POST 1462 * request with an error page. To be sure that libcurl gets the page that 1463 * most user agents would get, libcurl has to force GET. 1464 * 1465 * This behavior is forbidden by RFC1945 and the obsolete RFC2616, and 1466 * can be overridden with CURLOPT_POSTREDIR. 1467 */ 1468 if((data->state.httpreq == HTTPREQ_POST 1469 || data->state.httpreq == HTTPREQ_POST_FORM 1470 || data->state.httpreq == HTTPREQ_POST_MIME) 1471 && !(data->set.keep_post & CURL_REDIR_POST_302)) { 1472 infof(data, "Switch from POST to GET"); 1473 data->state.httpreq = HTTPREQ_GET; 1474 } 1475 break; 1476 1477 case 303: /* See Other */ 1478 /* 'See Other' location is not the resource but a substitute for the 1479 * resource. In this case we switch the method to GET/HEAD, unless the 1480 * method is POST and the user specified to keep it as POST. 1481 * https://github.com/curl/curl/issues/5237#issuecomment-614641049 1482 */ 1483 if(data->state.httpreq != HTTPREQ_GET && 1484 ((data->state.httpreq != HTTPREQ_POST && 1485 data->state.httpreq != HTTPREQ_POST_FORM && 1486 data->state.httpreq != HTTPREQ_POST_MIME) || 1487 !(data->set.keep_post & CURL_REDIR_POST_303))) { 1488 data->state.httpreq = HTTPREQ_GET; 1489 infof(data, "Switch to %s", 1490 data->req.no_body?"HEAD":"GET"); 1491 } 1492 break; 1493 case 304: /* Not Modified */ 1494 /* 304 means we did a conditional request and it was "Not modified". 1495 * We shouldn't get any Location: header in this response! 1496 */ 1497 break; 1498 case 305: /* Use Proxy */ 1499 /* (quote from RFC2616, section 10.3.6): 1500 * "The requested resource MUST be accessed through the proxy given 1501 * by the Location field. The Location field gives the URI of the 1502 * proxy. The recipient is expected to repeat this single request 1503 * via the proxy. 305 responses MUST only be generated by origin 1504 * servers." 1505 */ 1506 break; 1507 } 1508 Curl_pgrsTime(data, TIMER_REDIRECT); 1509 Curl_pgrsResetTransferSizes(data); 1510 1511 return CURLE_OK; 1512#endif /* CURL_DISABLE_HTTP */ 1513} 1514 1515/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted. 1516 1517 NOTE: that the *url is malloc()ed. */ 1518CURLcode Curl_retry_request(struct Curl_easy *data, char **url) 1519{ 1520 struct connectdata *conn = data->conn; 1521 bool retry = FALSE; 1522 *url = NULL; 1523 1524 /* if we're talking upload, we can't do the checks below, unless the protocol 1525 is HTTP as when uploading over HTTP we will still get a response */ 1526 if(data->state.upload && 1527 !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP))) 1528 return CURLE_OK; 1529 1530 if((data->req.bytecount + data->req.headerbytecount == 0) && 1531 conn->bits.reuse && 1532 (!data->req.no_body || (conn->handler->protocol & PROTO_FAMILY_HTTP)) 1533#ifndef CURL_DISABLE_RTSP 1534 && (data->set.rtspreq != RTSPREQ_RECEIVE) 1535#endif 1536 ) 1537 /* We got no data, we attempted to reuse a connection. For HTTP this 1538 can be a retry so we try again regardless if we expected a body. 1539 For other protocols we only try again only if we expected a body. 1540 1541 This might happen if the connection was left alive when we were 1542 done using it before, but that was closed when we wanted to read from 1543 it again. Bad luck. Retry the same request on a fresh connect! */ 1544 retry = TRUE; 1545 else if(data->state.refused_stream && 1546 (data->req.bytecount + data->req.headerbytecount == 0) ) { 1547 /* This was sent on a refused stream, safe to rerun. A refused stream 1548 error can typically only happen on HTTP/2 level if the stream is safe 1549 to issue again, but the nghttp2 API can deliver the message to other 1550 streams as well, which is why this adds the check the data counters 1551 too. */ 1552 infof(data, "REFUSED_STREAM, retrying a fresh connect"); 1553 data->state.refused_stream = FALSE; /* clear again */ 1554 retry = TRUE; 1555 } 1556 if(retry) { 1557#define CONN_MAX_RETRIES 5 1558 if(data->state.retrycount++ >= CONN_MAX_RETRIES) { 1559 failf(data, "Connection died, tried %d times before giving up", 1560 CONN_MAX_RETRIES); 1561 data->state.retrycount = 0; 1562 return CURLE_SEND_ERROR; 1563 } 1564 infof(data, "Connection died, retrying a fresh connect (retry count: %d)", 1565 data->state.retrycount); 1566 *url = strdup(data->state.url); 1567 if(!*url) 1568 return CURLE_OUT_OF_MEMORY; 1569 1570 connclose(conn, "retry"); /* close this connection */ 1571 conn->bits.retry = TRUE; /* mark this as a connection we're about 1572 to retry. Marking it this way should 1573 prevent i.e HTTP transfers to return 1574 error just because nothing has been 1575 transferred! */ 1576 1577 1578 if((conn->handler->protocol&PROTO_FAMILY_HTTP) && 1579 data->req.writebytecount) { 1580 data->state.rewindbeforesend = TRUE; 1581 infof(data, "state.rewindbeforesend = TRUE"); 1582 } 1583 } 1584 return CURLE_OK; 1585} 1586 1587/* 1588 * Curl_setup_transfer() is called to setup some basic properties for the 1589 * upcoming transfer. 1590 */ 1591void 1592Curl_setup_transfer( 1593 struct Curl_easy *data, /* transfer */ 1594 int sockindex, /* socket index to read from or -1 */ 1595 curl_off_t size, /* -1 if unknown at this point */ 1596 bool getheader, /* TRUE if header parsing is wanted */ 1597 int writesockindex /* socket index to write to, it may very well be 1598 the same we read from. -1 disables */ 1599 ) 1600{ 1601 struct SingleRequest *k = &data->req; 1602 struct connectdata *conn = data->conn; 1603 struct HTTP *http = data->req.p.http; 1604 bool httpsending; 1605 1606 DEBUGASSERT(conn != NULL); 1607 DEBUGASSERT((sockindex <= 1) && (sockindex >= -1)); 1608 1609 httpsending = ((conn->handler->protocol&PROTO_FAMILY_HTTP) && 1610 (http->sending == HTTPSEND_REQUEST)); 1611 1612 if(conn->bits.multiplex || conn->httpversion >= 20 || httpsending) { 1613 /* when multiplexing, the read/write sockets need to be the same! */ 1614 conn->sockfd = sockindex == -1 ? 1615 ((writesockindex == -1 ? CURL_SOCKET_BAD : conn->sock[writesockindex])) : 1616 conn->sock[sockindex]; 1617 conn->writesockfd = conn->sockfd; 1618 if(httpsending) 1619 /* special and very HTTP-specific */ 1620 writesockindex = FIRSTSOCKET; 1621 } 1622 else { 1623 conn->sockfd = sockindex == -1 ? 1624 CURL_SOCKET_BAD : conn->sock[sockindex]; 1625 conn->writesockfd = writesockindex == -1 ? 1626 CURL_SOCKET_BAD:conn->sock[writesockindex]; 1627 } 1628 k->getheader = getheader; 1629 1630 k->size = size; 1631 1632 /* The code sequence below is placed in this function just because all 1633 necessary input is not always known in do_complete() as this function may 1634 be called after that */ 1635 1636 if(!k->getheader) { 1637 k->header = FALSE; 1638 if(size > 0) 1639 Curl_pgrsSetDownloadSize(data, size); 1640 } 1641 /* we want header and/or body, if neither then don't do this! */ 1642 if(k->getheader || !data->req.no_body) { 1643 1644 if(sockindex != -1) 1645 k->keepon |= KEEP_RECV; 1646 1647 if(writesockindex != -1) { 1648 /* HTTP 1.1 magic: 1649 1650 Even if we require a 100-return code before uploading data, we might 1651 need to write data before that since the REQUEST may not have been 1652 finished sent off just yet. 1653 1654 Thus, we must check if the request has been sent before we set the 1655 state info where we wait for the 100-return code 1656 */ 1657 if((data->state.expect100header) && 1658 (conn->handler->protocol&PROTO_FAMILY_HTTP) && 1659 (http->sending == HTTPSEND_BODY)) { 1660 /* wait with write until we either got 100-continue or a timeout */ 1661 k->exp100 = EXP100_AWAITING_CONTINUE; 1662 k->start100 = Curl_now(); 1663 1664 /* Set a timeout for the multi interface. Add the inaccuracy margin so 1665 that we don't fire slightly too early and get denied to run. */ 1666 Curl_expire(data, data->set.expect_100_timeout, EXPIRE_100_TIMEOUT); 1667 } 1668 else { 1669 if(data->state.expect100header) 1670 /* when we've sent off the rest of the headers, we must await a 1671 100-continue but first finish sending the request */ 1672 k->exp100 = EXP100_SENDING_REQUEST; 1673 1674 /* enable the write bit when we're not waiting for continue */ 1675 k->keepon |= KEEP_SEND; 1676 } 1677 } /* if(writesockindex != -1) */ 1678 } /* if(k->getheader || !data->req.no_body) */ 1679 1680} 1681 1682CURLcode Curl_xfer_write_resp(struct Curl_easy *data, 1683 char *buf, size_t blen, 1684 bool is_eos, bool *done) 1685{ 1686 CURLcode result = CURLE_OK; 1687 1688 if(data->conn->handler->write_resp) { 1689 /* protocol handlers offering this function take full responsibility 1690 * for writing all received download data to the client. */ 1691 result = data->conn->handler->write_resp(data, buf, blen, is_eos, done); 1692 } 1693 else { 1694 /* No special handling by protocol handler, write all received data 1695 * as BODY to the client. */ 1696 if(blen || is_eos) { 1697 int cwtype = CLIENTWRITE_BODY; 1698 if(is_eos) 1699 cwtype |= CLIENTWRITE_EOS; 1700 1701#ifndef CURL_DISABLE_POP3 1702 if(blen && data->conn->handler->protocol & PROTO_FAMILY_POP3) { 1703 result = data->req.ignorebody? CURLE_OK : 1704 Curl_pop3_write(data, buf, blen); 1705 } 1706 else 1707#endif /* CURL_DISABLE_POP3 */ 1708 result = Curl_client_write(data, cwtype, buf, blen); 1709 } 1710 } 1711 1712 if(!result && is_eos) { 1713 /* If we wrote the EOS, we are definitely done */ 1714 data->req.eos_written = TRUE; 1715 data->req.download_done = TRUE; 1716 } 1717 return result; 1718} 1719