1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel (at) 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.haxx.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 ***************************************************************************/ 22 23 #include "curl_setup.h" 24 25 #ifndef CURL_DISABLE_HTTP 26 27 #ifdef HAVE_NETINET_IN_H 28 #include <netinet/in.h> 29 #endif 30 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 44 #ifdef HAVE_SYS_PARAM_H 45 #include <sys/param.h> 46 #endif 47 48 #include "urldata.h" 49 #include <curl/curl.h> 50 #include "transfer.h" 51 #include "sendf.h" 52 #include "formdata.h" 53 #include "mime.h" 54 #include "progress.h" 55 #include "curl_base64.h" 56 #include "cookie.h" 57 #include "vauth/vauth.h" 58 #include "vtls/vtls.h" 59 #include "http_digest.h" 60 #include "http_ntlm.h" 61 #include "curl_ntlm_wb.h" 62 #include "http_negotiate.h" 63 #include "url.h" 64 #include "share.h" 65 #include "hostip.h" 66 #include "http.h" 67 #include "select.h" 68 #include "parsedate.h" /* for the week day and month names */ 69 #include "strtoofft.h" 70 #include "multiif.h" 71 #include "strcase.h" 72 #include "content_encoding.h" 73 #include "http_proxy.h" 74 #include "warnless.h" 75 #include "non-ascii.h" 76 #include "pipeline.h" 77 #include "http2.h" 78 #include "connect.h" 79 #include "strdup.h" 80 81 /* The last 3 #include files should be in this order */ 82 #include "curl_printf.h" 83 #include "curl_memory.h" 84 #include "memdebug.h" 85 86 /* 87 * Forward declarations. 88 */ 89 90 static int http_getsock_do(struct connectdata *conn, 91 curl_socket_t *socks, 92 int numsocks); 93 static int http_should_fail(struct connectdata *conn); 94 95 #ifdef USE_SSL 96 static CURLcode https_connecting(struct connectdata *conn, bool *done); 97 static int https_getsock(struct connectdata *conn, 98 curl_socket_t *socks, 99 int numsocks); 100 #else 101 #define https_connecting(x,y) CURLE_COULDNT_CONNECT 102 #endif 103 104 /* 105 * HTTP handler interface. 106 */ 107 const struct Curl_handler Curl_handler_http = { 108 "HTTP", /* scheme */ 109 Curl_http_setup_conn, /* setup_connection */ 110 Curl_http, /* do_it */ 111 Curl_http_done, /* done */ 112 ZERO_NULL, /* do_more */ 113 Curl_http_connect, /* connect_it */ 114 ZERO_NULL, /* connecting */ 115 ZERO_NULL, /* doing */ 116 ZERO_NULL, /* proto_getsock */ 117 http_getsock_do, /* doing_getsock */ 118 ZERO_NULL, /* domore_getsock */ 119 ZERO_NULL, /* perform_getsock */ 120 ZERO_NULL, /* disconnect */ 121 ZERO_NULL, /* readwrite */ 122 ZERO_NULL, /* connection_check */ 123 PORT_HTTP, /* defport */ 124 CURLPROTO_HTTP, /* protocol */ 125 PROTOPT_CREDSPERREQUEST /* flags */ 126 }; 127 128 #ifdef USE_SSL 129 /* 130 * HTTPS handler interface. 131 */ 132 const struct Curl_handler Curl_handler_https = { 133 "HTTPS", /* scheme */ 134 Curl_http_setup_conn, /* setup_connection */ 135 Curl_http, /* do_it */ 136 Curl_http_done, /* done */ 137 ZERO_NULL, /* do_more */ 138 Curl_http_connect, /* connect_it */ 139 https_connecting, /* connecting */ 140 ZERO_NULL, /* doing */ 141 https_getsock, /* proto_getsock */ 142 http_getsock_do, /* doing_getsock */ 143 ZERO_NULL, /* domore_getsock */ 144 ZERO_NULL, /* perform_getsock */ 145 ZERO_NULL, /* disconnect */ 146 ZERO_NULL, /* readwrite */ 147 ZERO_NULL, /* connection_check */ 148 PORT_HTTPS, /* defport */ 149 CURLPROTO_HTTPS, /* protocol */ 150 PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */ 151 }; 152 #endif 153 154 CURLcode Curl_http_setup_conn(struct connectdata *conn) 155 { 156 /* allocate the HTTP-specific struct for the Curl_easy, only to survive 157 during this request */ 158 struct HTTP *http; 159 DEBUGASSERT(conn->data->req.protop == NULL); 160 161 http = calloc(1, sizeof(struct HTTP)); 162 if(!http) 163 return CURLE_OUT_OF_MEMORY; 164 165 Curl_mime_initpart(&http->form, conn->data); 166 conn->data->req.protop = http; 167 168 Curl_http2_setup_conn(conn); 169 Curl_http2_setup_req(conn->data); 170 171 return CURLE_OK; 172 } 173 174 175 /* 176 * checkProxyHeaders() checks the linked list of custom proxy headers 177 * if proxy headers are not available, then it will lookup into http header 178 * link list 179 * 180 * It takes a connectdata struct as input instead of the Curl_easy simply 181 * to know if this is a proxy request or not, as it then might check a 182 * different header list. 183 */ 184 char *Curl_checkProxyheaders(const struct connectdata *conn, 185 const char *thisheader) 186 { 187 struct curl_slist *head; 188 size_t thislen = strlen(thisheader); 189 struct Curl_easy *data = conn->data; 190 191 for(head = (conn->bits.proxy && data->set.sep_headers) ? 192 data->set.proxyheaders : data->set.headers; 193 head; head = head->next) { 194 if(strncasecompare(head->data, thisheader, thislen)) 195 return head->data; 196 } 197 198 return NULL; 199 } 200 201 /* 202 * Strip off leading and trailing whitespace from the value in the 203 * given HTTP header line and return a strdupped copy. Returns NULL in 204 * case of allocation failure. Returns an empty string if the header value 205 * consists entirely of whitespace. 206 */ 207 char *Curl_copy_header_value(const char *header) 208 { 209 const char *start; 210 const char *end; 211 char *value; 212 size_t len; 213 214 DEBUGASSERT(header); 215 216 /* Find the end of the header name */ 217 while(*header && (*header != ':')) 218 ++header; 219 220 if(*header) 221 /* Skip over colon */ 222 ++header; 223 224 /* Find the first non-space letter */ 225 start = header; 226 while(*start && ISSPACE(*start)) 227 start++; 228 229 /* data is in the host encoding so 230 use '\r' and '\n' instead of 0x0d and 0x0a */ 231 end = strchr(start, '\r'); 232 if(!end) 233 end = strchr(start, '\n'); 234 if(!end) 235 end = strchr(start, '\0'); 236 if(!end) 237 return NULL; 238 239 /* skip all trailing space letters */ 240 while((end > start) && ISSPACE(*end)) 241 end--; 242 243 /* get length of the type */ 244 len = end - start + 1; 245 246 value = malloc(len + 1); 247 if(!value) 248 return NULL; 249 250 memcpy(value, start, len); 251 value[len] = 0; /* zero terminate */ 252 253 return value; 254 } 255 256 /* 257 * http_output_basic() sets up an Authorization: header (or the proxy version) 258 * for HTTP Basic authentication. 259 * 260 * Returns CURLcode. 261 */ 262 static CURLcode http_output_basic(struct connectdata *conn, bool proxy) 263 { 264 size_t size = 0; 265 char *authorization = NULL; 266 struct Curl_easy *data = conn->data; 267 char **userp; 268 const char *user; 269 const char *pwd; 270 CURLcode result; 271 char *out; 272 273 if(proxy) { 274 userp = &conn->allocptr.proxyuserpwd; 275 user = conn->http_proxy.user; 276 pwd = conn->http_proxy.passwd; 277 } 278 else { 279 userp = &conn->allocptr.userpwd; 280 user = conn->user; 281 pwd = conn->passwd; 282 } 283 284 out = aprintf("%s:%s", user, pwd); 285 if(!out) 286 return CURLE_OUT_OF_MEMORY; 287 288 result = Curl_base64_encode(data, out, strlen(out), &authorization, &size); 289 if(result) 290 goto fail; 291 292 if(!authorization) { 293 result = CURLE_REMOTE_ACCESS_DENIED; 294 goto fail; 295 } 296 297 free(*userp); 298 *userp = aprintf("%sAuthorization: Basic %s\r\n", 299 proxy ? "Proxy-" : "", 300 authorization); 301 free(authorization); 302 if(!*userp) { 303 result = CURLE_OUT_OF_MEMORY; 304 goto fail; 305 } 306 307 fail: 308 free(out); 309 return result; 310 } 311 312 /* pickoneauth() selects the most favourable authentication method from the 313 * ones available and the ones we want. 314 * 315 * return TRUE if one was picked 316 */ 317 static bool pickoneauth(struct auth *pick) 318 { 319 bool picked; 320 /* only deal with authentication we want */ 321 unsigned long avail = pick->avail & pick->want; 322 picked = TRUE; 323 324 /* The order of these checks is highly relevant, as this will be the order 325 of preference in case of the existence of multiple accepted types. */ 326 if(avail & CURLAUTH_NEGOTIATE) 327 pick->picked = CURLAUTH_NEGOTIATE; 328 else if(avail & CURLAUTH_DIGEST) 329 pick->picked = CURLAUTH_DIGEST; 330 else if(avail & CURLAUTH_NTLM) 331 pick->picked = CURLAUTH_NTLM; 332 else if(avail & CURLAUTH_NTLM_WB) 333 pick->picked = CURLAUTH_NTLM_WB; 334 else if(avail & CURLAUTH_BASIC) 335 pick->picked = CURLAUTH_BASIC; 336 else { 337 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */ 338 picked = FALSE; 339 } 340 pick->avail = CURLAUTH_NONE; /* clear it here */ 341 342 return picked; 343 } 344 345 /* 346 * Curl_http_perhapsrewind() 347 * 348 * If we are doing POST or PUT { 349 * If we have more data to send { 350 * If we are doing NTLM { 351 * Keep sending since we must not disconnect 352 * } 353 * else { 354 * If there is more than just a little data left to send, close 355 * the current connection by force. 356 * } 357 * } 358 * If we have sent any data { 359 * If we don't have track of all the data { 360 * call app to tell it to rewind 361 * } 362 * else { 363 * rewind internally so that the operation can restart fine 364 * } 365 * } 366 * } 367 */ 368 static CURLcode http_perhapsrewind(struct connectdata *conn) 369 { 370 struct Curl_easy *data = conn->data; 371 struct HTTP *http = data->req.protop; 372 curl_off_t bytessent; 373 curl_off_t expectsend = -1; /* default is unknown */ 374 375 if(!http) 376 /* If this is still NULL, we have not reach very far and we can safely 377 skip this rewinding stuff */ 378 return CURLE_OK; 379 380 switch(data->set.httpreq) { 381 case HTTPREQ_GET: 382 case HTTPREQ_HEAD: 383 return CURLE_OK; 384 default: 385 break; 386 } 387 388 bytessent = http->writebytecount; 389 390 if(conn->bits.authneg) { 391 /* This is a state where we are known to be negotiating and we don't send 392 any data then. */ 393 expectsend = 0; 394 } 395 else if(!conn->bits.protoconnstart) { 396 /* HTTP CONNECT in progress: there is no body */ 397 expectsend = 0; 398 } 399 else { 400 /* figure out how much data we are expected to send */ 401 switch(data->set.httpreq) { 402 case HTTPREQ_POST: 403 if(data->state.infilesize != -1) 404 expectsend = data->state.infilesize; 405 break; 406 case HTTPREQ_PUT: 407 if(data->state.infilesize != -1) 408 expectsend = data->state.infilesize; 409 break; 410 case HTTPREQ_POST_FORM: 411 case HTTPREQ_POST_MIME: 412 expectsend = http->postsize; 413 break; 414 default: 415 break; 416 } 417 } 418 419 conn->bits.rewindaftersend = FALSE; /* default */ 420 421 if((expectsend == -1) || (expectsend > bytessent)) { 422 #if defined(USE_NTLM) 423 /* There is still data left to send */ 424 if((data->state.authproxy.picked == CURLAUTH_NTLM) || 425 (data->state.authhost.picked == CURLAUTH_NTLM) || 426 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) || 427 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) { 428 if(((expectsend - bytessent) < 2000) || 429 (conn->ntlm.state != NTLMSTATE_NONE) || 430 (conn->proxyntlm.state != NTLMSTATE_NONE)) { 431 /* The NTLM-negotiation has started *OR* there is just a little (<2K) 432 data left to send, keep on sending. */ 433 434 /* rewind data when completely done sending! */ 435 if(!conn->bits.authneg) { 436 conn->bits.rewindaftersend = TRUE; 437 infof(data, "Rewind stream after send\n"); 438 } 439 440 return CURLE_OK; 441 } 442 443 if(conn->bits.close) 444 /* this is already marked to get closed */ 445 return CURLE_OK; 446 447 infof(data, "NTLM send, close instead of sending %" 448 CURL_FORMAT_CURL_OFF_T " bytes\n", 449 (curl_off_t)(expectsend - bytessent)); 450 } 451 #endif 452 453 /* This is not NTLM or many bytes left to send: close */ 454 streamclose(conn, "Mid-auth HTTP and much data left to send"); 455 data->req.size = 0; /* don't download any more than 0 bytes */ 456 457 /* There still is data left to send, but this connection is marked for 458 closure so we can safely do the rewind right now */ 459 } 460 461 if(bytessent) 462 /* we rewind now at once since if we already sent something */ 463 return Curl_readrewind(conn); 464 465 return CURLE_OK; 466 } 467 468 /* 469 * Curl_http_auth_act() gets called when all HTTP headers have been received 470 * and it checks what authentication methods that are available and decides 471 * which one (if any) to use. It will set 'newurl' if an auth method was 472 * picked. 473 */ 474 475 CURLcode Curl_http_auth_act(struct connectdata *conn) 476 { 477 struct Curl_easy *data = conn->data; 478 bool pickhost = FALSE; 479 bool pickproxy = FALSE; 480 CURLcode result = CURLE_OK; 481 482 if(100 <= data->req.httpcode && 199 >= data->req.httpcode) 483 /* this is a transient response code, ignore */ 484 return CURLE_OK; 485 486 if(data->state.authproblem) 487 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK; 488 489 if(conn->bits.user_passwd && 490 ((data->req.httpcode == 401) || 491 (conn->bits.authneg && data->req.httpcode < 300))) { 492 pickhost = pickoneauth(&data->state.authhost); 493 if(!pickhost) 494 data->state.authproblem = TRUE; 495 } 496 if(conn->bits.proxy_user_passwd && 497 ((data->req.httpcode == 407) || 498 (conn->bits.authneg && data->req.httpcode < 300))) { 499 pickproxy = pickoneauth(&data->state.authproxy); 500 if(!pickproxy) 501 data->state.authproblem = TRUE; 502 } 503 504 if(pickhost || pickproxy) { 505 /* In case this is GSS auth, the newurl field is already allocated so 506 we must make sure to free it before allocating a new one. As figured 507 out in bug #2284386 */ 508 Curl_safefree(data->req.newurl); 509 data->req.newurl = strdup(data->change.url); /* clone URL */ 510 if(!data->req.newurl) 511 return CURLE_OUT_OF_MEMORY; 512 513 if((data->set.httpreq != HTTPREQ_GET) && 514 (data->set.httpreq != HTTPREQ_HEAD) && 515 !conn->bits.rewindaftersend) { 516 result = http_perhapsrewind(conn); 517 if(result) 518 return result; 519 } 520 } 521 else if((data->req.httpcode < 300) && 522 (!data->state.authhost.done) && 523 conn->bits.authneg) { 524 /* no (known) authentication available, 525 authentication is not "done" yet and 526 no authentication seems to be required and 527 we didn't try HEAD or GET */ 528 if((data->set.httpreq != HTTPREQ_GET) && 529 (data->set.httpreq != HTTPREQ_HEAD)) { 530 data->req.newurl = strdup(data->change.url); /* clone URL */ 531 if(!data->req.newurl) 532 return CURLE_OUT_OF_MEMORY; 533 data->state.authhost.done = TRUE; 534 } 535 } 536 if(http_should_fail(conn)) { 537 failf(data, "The requested URL returned error: %d", 538 data->req.httpcode); 539 result = CURLE_HTTP_RETURNED_ERROR; 540 } 541 542 return result; 543 } 544 545 /* 546 * Output the correct authentication header depending on the auth type 547 * and whether or not it is to a proxy. 548 */ 549 static CURLcode 550 output_auth_headers(struct connectdata *conn, 551 struct auth *authstatus, 552 const char *request, 553 const char *path, 554 bool proxy) 555 { 556 const char *auth = NULL; 557 CURLcode result = CURLE_OK; 558 #if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO) 559 struct Curl_easy *data = conn->data; 560 #endif 561 #ifdef USE_SPNEGO 562 struct negotiatedata *negdata = proxy ? 563 &data->state.proxyneg : &data->state.negotiate; 564 #endif 565 566 #ifdef CURL_DISABLE_CRYPTO_AUTH 567 (void)request; 568 (void)path; 569 #endif 570 571 #ifdef USE_SPNEGO 572 negdata->state = GSS_AUTHNONE; 573 if((authstatus->picked == CURLAUTH_NEGOTIATE) && 574 negdata->context && !GSS_ERROR(negdata->status)) { 575 auth = "Negotiate"; 576 result = Curl_output_negotiate(conn, proxy); 577 if(result) 578 return result; 579 authstatus->done = TRUE; 580 negdata->state = GSS_AUTHSENT; 581 } 582 else 583 #endif 584 #ifdef USE_NTLM 585 if(authstatus->picked == CURLAUTH_NTLM) { 586 auth = "NTLM"; 587 result = Curl_output_ntlm(conn, proxy); 588 if(result) 589 return result; 590 } 591 else 592 #endif 593 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED) 594 if(authstatus->picked == CURLAUTH_NTLM_WB) { 595 auth = "NTLM_WB"; 596 result = Curl_output_ntlm_wb(conn, proxy); 597 if(result) 598 return result; 599 } 600 else 601 #endif 602 #ifndef CURL_DISABLE_CRYPTO_AUTH 603 if(authstatus->picked == CURLAUTH_DIGEST) { 604 auth = "Digest"; 605 result = Curl_output_digest(conn, 606 proxy, 607 (const unsigned char *)request, 608 (const unsigned char *)path); 609 if(result) 610 return result; 611 } 612 else 613 #endif 614 if(authstatus->picked == CURLAUTH_BASIC) { 615 /* Basic */ 616 if((proxy && conn->bits.proxy_user_passwd && 617 !Curl_checkProxyheaders(conn, "Proxy-authorization:")) || 618 (!proxy && conn->bits.user_passwd && 619 !Curl_checkheaders(conn, "Authorization:"))) { 620 auth = "Basic"; 621 result = http_output_basic(conn, proxy); 622 if(result) 623 return result; 624 } 625 626 /* NOTE: this function should set 'done' TRUE, as the other auth 627 functions work that way */ 628 authstatus->done = TRUE; 629 } 630 631 if(auth) { 632 infof(data, "%s auth using %s with user '%s'\n", 633 proxy ? "Proxy" : "Server", auth, 634 proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") : 635 (conn->user ? conn->user : "")); 636 authstatus->multipass = (!authstatus->done) ? TRUE : FALSE; 637 } 638 else 639 authstatus->multipass = FALSE; 640 641 return CURLE_OK; 642 } 643 644 /** 645 * Curl_http_output_auth() setups the authentication headers for the 646 * host/proxy and the correct authentication 647 * method. conn->data->state.authdone is set to TRUE when authentication is 648 * done. 649 * 650 * @param conn all information about the current connection 651 * @param request pointer to the request keyword 652 * @param path pointer to the requested path 653 * @param proxytunnel boolean if this is the request setting up a "proxy 654 * tunnel" 655 * 656 * @returns CURLcode 657 */ 658 CURLcode 659 Curl_http_output_auth(struct connectdata *conn, 660 const char *request, 661 const char *path, 662 bool proxytunnel) /* TRUE if this is the request setting 663 up the proxy tunnel */ 664 { 665 CURLcode result = CURLE_OK; 666 struct Curl_easy *data = conn->data; 667 struct auth *authhost; 668 struct auth *authproxy; 669 670 DEBUGASSERT(data); 671 672 authhost = &data->state.authhost; 673 authproxy = &data->state.authproxy; 674 675 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) || 676 conn->bits.user_passwd) 677 /* continue please */; 678 else { 679 authhost->done = TRUE; 680 authproxy->done = TRUE; 681 return CURLE_OK; /* no authentication with no user or password */ 682 } 683 684 if(authhost->want && !authhost->picked) 685 /* The app has selected one or more methods, but none has been picked 686 so far by a server round-trip. Then we set the picked one to the 687 want one, and if this is one single bit it'll be used instantly. */ 688 authhost->picked = authhost->want; 689 690 if(authproxy->want && !authproxy->picked) 691 /* The app has selected one or more methods, but none has been picked so 692 far by a proxy round-trip. Then we set the picked one to the want one, 693 and if this is one single bit it'll be used instantly. */ 694 authproxy->picked = authproxy->want; 695 696 #ifndef CURL_DISABLE_PROXY 697 /* Send proxy authentication header if needed */ 698 if(conn->bits.httpproxy && 699 (conn->bits.tunnel_proxy == proxytunnel)) { 700 result = output_auth_headers(conn, authproxy, request, path, TRUE); 701 if(result) 702 return result; 703 } 704 else 705 #else 706 (void)proxytunnel; 707 #endif /* CURL_DISABLE_PROXY */ 708 /* we have no proxy so let's pretend we're done authenticating 709 with it */ 710 authproxy->done = TRUE; 711 712 /* To prevent the user+password to get sent to other than the original 713 host due to a location-follow, we do some weirdo checks here */ 714 if(!data->state.this_is_a_follow || 715 conn->bits.netrc || 716 !data->state.first_host || 717 data->set.allow_auth_to_other_hosts || 718 strcasecompare(data->state.first_host, conn->host.name)) { 719 result = output_auth_headers(conn, authhost, request, path, FALSE); 720 } 721 else 722 authhost->done = TRUE; 723 724 return result; 725 } 726 727 /* 728 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate: 729 * headers. They are dealt with both in the transfer.c main loop and in the 730 * proxy CONNECT loop. 731 */ 732 733 CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy, 734 const char *auth) /* the first non-space */ 735 { 736 /* 737 * This resource requires authentication 738 */ 739 struct Curl_easy *data = conn->data; 740 741 #ifdef USE_SPNEGO 742 struct negotiatedata *negdata = proxy? 743 &data->state.proxyneg:&data->state.negotiate; 744 #endif 745 unsigned long *availp; 746 struct auth *authp; 747 748 if(proxy) { 749 availp = &data->info.proxyauthavail; 750 authp = &data->state.authproxy; 751 } 752 else { 753 availp = &data->info.httpauthavail; 754 authp = &data->state.authhost; 755 } 756 757 /* 758 * Here we check if we want the specific single authentication (using ==) and 759 * if we do, we initiate usage of it. 760 * 761 * If the provided authentication is wanted as one out of several accepted 762 * types (using &), we OR this authentication type to the authavail 763 * variable. 764 * 765 * Note: 766 * 767 * ->picked is first set to the 'want' value (one or more bits) before the 768 * request is sent, and then it is again set _after_ all response 401/407 769 * headers have been received but then only to a single preferred method 770 * (bit). 771 */ 772 773 while(*auth) { 774 #ifdef USE_SPNEGO 775 if(checkprefix("Negotiate", auth)) { 776 if((authp->avail & CURLAUTH_NEGOTIATE) || 777 Curl_auth_is_spnego_supported()) { 778 *availp |= CURLAUTH_NEGOTIATE; 779 authp->avail |= CURLAUTH_NEGOTIATE; 780 781 if(authp->picked == CURLAUTH_NEGOTIATE) { 782 if(negdata->state == GSS_AUTHSENT || 783 negdata->state == GSS_AUTHNONE) { 784 CURLcode result = Curl_input_negotiate(conn, proxy, auth); 785 if(!result) { 786 DEBUGASSERT(!data->req.newurl); 787 data->req.newurl = strdup(data->change.url); 788 if(!data->req.newurl) 789 return CURLE_OUT_OF_MEMORY; 790 data->state.authproblem = FALSE; 791 /* we received a GSS auth token and we dealt with it fine */ 792 negdata->state = GSS_AUTHRECV; 793 } 794 else 795 data->state.authproblem = TRUE; 796 } 797 } 798 } 799 } 800 else 801 #endif 802 #ifdef USE_NTLM 803 /* NTLM support requires the SSL crypto libs */ 804 if(checkprefix("NTLM", auth)) { 805 if((authp->avail & CURLAUTH_NTLM) || 806 (authp->avail & CURLAUTH_NTLM_WB) || 807 Curl_auth_is_ntlm_supported()) { 808 *availp |= CURLAUTH_NTLM; 809 authp->avail |= CURLAUTH_NTLM; 810 811 if(authp->picked == CURLAUTH_NTLM || 812 authp->picked == CURLAUTH_NTLM_WB) { 813 /* NTLM authentication is picked and activated */ 814 CURLcode result = Curl_input_ntlm(conn, proxy, auth); 815 if(!result) { 816 data->state.authproblem = FALSE; 817 #ifdef NTLM_WB_ENABLED 818 if(authp->picked == CURLAUTH_NTLM_WB) { 819 *availp &= ~CURLAUTH_NTLM; 820 authp->avail &= ~CURLAUTH_NTLM; 821 *availp |= CURLAUTH_NTLM_WB; 822 authp->avail |= CURLAUTH_NTLM_WB; 823 824 /* Get the challenge-message which will be passed to 825 * ntlm_auth for generating the type 3 message later */ 826 while(*auth && ISSPACE(*auth)) 827 auth++; 828 if(checkprefix("NTLM", auth)) { 829 auth += strlen("NTLM"); 830 while(*auth && ISSPACE(*auth)) 831 auth++; 832 if(*auth) { 833 conn->challenge_header = strdup(auth); 834 if(!conn->challenge_header) 835 return CURLE_OUT_OF_MEMORY; 836 } 837 } 838 } 839 #endif 840 } 841 else { 842 infof(data, "Authentication problem. Ignoring this.\n"); 843 data->state.authproblem = TRUE; 844 } 845 } 846 } 847 } 848 else 849 #endif 850 #ifndef CURL_DISABLE_CRYPTO_AUTH 851 if(checkprefix("Digest", auth)) { 852 if((authp->avail & CURLAUTH_DIGEST) != 0) 853 infof(data, "Ignoring duplicate digest auth header.\n"); 854 else if(Curl_auth_is_digest_supported()) { 855 CURLcode result; 856 857 *availp |= CURLAUTH_DIGEST; 858 authp->avail |= CURLAUTH_DIGEST; 859 860 /* We call this function on input Digest headers even if Digest 861 * authentication isn't activated yet, as we need to store the 862 * incoming data from this header in case we are going to use 863 * Digest */ 864 result = Curl_input_digest(conn, proxy, auth); 865 if(result) { 866 infof(data, "Authentication problem. Ignoring this.\n"); 867 data->state.authproblem = TRUE; 868 } 869 } 870 } 871 else 872 #endif 873 if(checkprefix("Basic", auth)) { 874 *availp |= CURLAUTH_BASIC; 875 authp->avail |= CURLAUTH_BASIC; 876 if(authp->picked == CURLAUTH_BASIC) { 877 /* We asked for Basic authentication but got a 40X back 878 anyway, which basically means our name+password isn't 879 valid. */ 880 authp->avail = CURLAUTH_NONE; 881 infof(data, "Authentication problem. Ignoring this.\n"); 882 data->state.authproblem = TRUE; 883 } 884 } 885 886 /* there may be multiple methods on one line, so keep reading */ 887 while(*auth && *auth != ',') /* read up to the next comma */ 888 auth++; 889 if(*auth == ',') /* if we're on a comma, skip it */ 890 auth++; 891 while(*auth && ISSPACE(*auth)) 892 auth++; 893 } 894 895 return CURLE_OK; 896 } 897 898 /** 899 * http_should_fail() determines whether an HTTP response has gotten us 900 * into an error state or not. 901 * 902 * @param conn all information about the current connection 903 * 904 * @retval 0 communications should continue 905 * 906 * @retval 1 communications should not continue 907 */ 908 static int http_should_fail(struct connectdata *conn) 909 { 910 struct Curl_easy *data; 911 int httpcode; 912 913 DEBUGASSERT(conn); 914 data = conn->data; 915 DEBUGASSERT(data); 916 917 httpcode = data->req.httpcode; 918 919 /* 920 ** If we haven't been asked to fail on error, 921 ** don't fail. 922 */ 923 if(!data->set.http_fail_on_error) 924 return 0; 925 926 /* 927 ** Any code < 400 is never terminal. 928 */ 929 if(httpcode < 400) 930 return 0; 931 932 /* 933 ** Any code >= 400 that's not 401 or 407 is always 934 ** a terminal error 935 */ 936 if((httpcode != 401) && (httpcode != 407)) 937 return 1; 938 939 /* 940 ** All we have left to deal with is 401 and 407 941 */ 942 DEBUGASSERT((httpcode == 401) || (httpcode == 407)); 943 944 /* 945 ** Examine the current authentication state to see if this 946 ** is an error. The idea is for this function to get 947 ** called after processing all the headers in a response 948 ** message. So, if we've been to asked to authenticate a 949 ** particular stage, and we've done it, we're OK. But, if 950 ** we're already completely authenticated, it's not OK to 951 ** get another 401 or 407. 952 ** 953 ** It is possible for authentication to go stale such that 954 ** the client needs to reauthenticate. Once that info is 955 ** available, use it here. 956 */ 957 958 /* 959 ** Either we're not authenticating, or we're supposed to 960 ** be authenticating something else. This is an error. 961 */ 962 if((httpcode == 401) && !conn->bits.user_passwd) 963 return TRUE; 964 if((httpcode == 407) && !conn->bits.proxy_user_passwd) 965 return TRUE; 966 967 return data->state.authproblem; 968 } 969 970 /* 971 * readmoredata() is a "fread() emulation" to provide POST and/or request 972 * data. It is used when a huge POST is to be made and the entire chunk wasn't 973 * sent in the first send(). This function will then be called from the 974 * transfer.c loop when more data is to be sent to the peer. 975 * 976 * Returns the amount of bytes it filled the buffer with. 977 */ 978 static size_t readmoredata(char *buffer, 979 size_t size, 980 size_t nitems, 981 void *userp) 982 { 983 struct connectdata *conn = (struct connectdata *)userp; 984 struct HTTP *http = conn->data->req.protop; 985 size_t fullsize = size * nitems; 986 987 if(!http->postsize) 988 /* nothing to return */ 989 return 0; 990 991 /* make sure that a HTTP request is never sent away chunked! */ 992 conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE; 993 994 if(http->postsize <= (curl_off_t)fullsize) { 995 memcpy(buffer, http->postdata, (size_t)http->postsize); 996 fullsize = (size_t)http->postsize; 997 998 if(http->backup.postsize) { 999 /* move backup data into focus and continue on that */ 1000 http->postdata = http->backup.postdata; 1001 http->postsize = http->backup.postsize; 1002 conn->data->state.fread_func = http->backup.fread_func; 1003 conn->data->state.in = http->backup.fread_in; 1004 1005 http->sending++; /* move one step up */ 1006 1007 http->backup.postsize = 0; 1008 } 1009 else 1010 http->postsize = 0; 1011 1012 return fullsize; 1013 } 1014 1015 memcpy(buffer, http->postdata, fullsize); 1016 http->postdata += fullsize; 1017 http->postsize -= fullsize; 1018 1019 return fullsize; 1020 } 1021 1022 /* ------------------------------------------------------------------------- */ 1023 /* add_buffer functions */ 1024 1025 /* 1026 * Curl_add_buffer_init() sets up and returns a fine buffer struct 1027 */ 1028 Curl_send_buffer *Curl_add_buffer_init(void) 1029 { 1030 return calloc(1, sizeof(Curl_send_buffer)); 1031 } 1032 1033 /* 1034 * Curl_add_buffer_free() frees all associated resources. 1035 */ 1036 void Curl_add_buffer_free(Curl_send_buffer *buff) 1037 { 1038 if(buff) /* deal with NULL input */ 1039 free(buff->buffer); 1040 free(buff); 1041 } 1042 1043 /* 1044 * Curl_add_buffer_send() sends a header buffer and frees all associated 1045 * memory. Body data may be appended to the header data if desired. 1046 * 1047 * Returns CURLcode 1048 */ 1049 CURLcode Curl_add_buffer_send(Curl_send_buffer *in, 1050 struct connectdata *conn, 1051 1052 /* add the number of sent bytes to this 1053 counter */ 1054 long *bytes_written, 1055 1056 /* how much of the buffer contains body data */ 1057 size_t included_body_bytes, 1058 int socketindex) 1059 1060 { 1061 ssize_t amount; 1062 CURLcode result; 1063 char *ptr; 1064 size_t size; 1065 struct HTTP *http = conn->data->req.protop; 1066 size_t sendsize; 1067 curl_socket_t sockfd; 1068 size_t headersize; 1069 1070 DEBUGASSERT(socketindex <= SECONDARYSOCKET); 1071 1072 sockfd = conn->sock[socketindex]; 1073 1074 /* The looping below is required since we use non-blocking sockets, but due 1075 to the circumstances we will just loop and try again and again etc */ 1076 1077 ptr = in->buffer; 1078 size = in->size_used; 1079 1080 headersize = size - included_body_bytes; /* the initial part that isn't body 1081 is header */ 1082 1083 DEBUGASSERT(size > included_body_bytes); 1084 1085 result = Curl_convert_to_network(conn->data, ptr, headersize); 1086 /* Curl_convert_to_network calls failf if unsuccessful */ 1087 if(result) { 1088 /* conversion failed, free memory and return to the caller */ 1089 Curl_add_buffer_free(in); 1090 return result; 1091 } 1092 1093 if((conn->handler->flags & PROTOPT_SSL || 1094 conn->http_proxy.proxytype == CURLPROXY_HTTPS) 1095 && conn->httpversion != 20) { 1096 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk 1097 when we speak HTTPS, as if only a fraction of it is sent now, this data 1098 needs to fit into the normal read-callback buffer later on and that 1099 buffer is using this size. 1100 */ 1101 1102 sendsize = CURLMIN(size, CURL_MAX_WRITE_SIZE); 1103 1104 /* OpenSSL is very picky and we must send the SAME buffer pointer to the 1105 library when we attempt to re-send this buffer. Sending the same data 1106 is not enough, we must use the exact same address. For this reason, we 1107 must copy the data to the uploadbuffer first, since that is the buffer 1108 we will be using if this send is retried later. 1109 */ 1110 memcpy(conn->data->state.uploadbuffer, ptr, sendsize); 1111 ptr = conn->data->state.uploadbuffer; 1112 } 1113 else 1114 sendsize = size; 1115 1116 result = Curl_write(conn, sockfd, ptr, sendsize, &amount); 1117 1118 if(!result) { 1119 /* 1120 * Note that we may not send the entire chunk at once, and we have a set 1121 * number of data bytes at the end of the big buffer (out of which we may 1122 * only send away a part). 1123 */ 1124 /* how much of the header that was sent */ 1125 size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount; 1126 size_t bodylen = amount - headlen; 1127 1128 if(conn->data->set.verbose) { 1129 /* this data _may_ contain binary stuff */ 1130 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn); 1131 if(bodylen) { 1132 /* there was body data sent beyond the initial header part, pass that 1133 on to the debug callback too */ 1134 Curl_debug(conn->data, CURLINFO_DATA_OUT, 1135 ptr + headlen, bodylen, conn); 1136 } 1137 } 1138 1139 /* 'amount' can never be a very large value here so typecasting it so a 1140 signed 31 bit value should not cause problems even if ssize_t is 1141 64bit */ 1142 *bytes_written += (long)amount; 1143 1144 if(http) { 1145 /* if we sent a piece of the body here, up the byte counter for it 1146 accordingly */ 1147 http->writebytecount += bodylen; 1148 1149 if((size_t)amount != size) { 1150 /* The whole request could not be sent in one system call. We must 1151 queue it up and send it later when we get the chance. We must not 1152 loop here and wait until it might work again. */ 1153 1154 size -= amount; 1155 1156 ptr = in->buffer + amount; 1157 1158 /* backup the currently set pointers */ 1159 http->backup.fread_func = conn->data->state.fread_func; 1160 http->backup.fread_in = conn->data->state.in; 1161 http->backup.postdata = http->postdata; 1162 http->backup.postsize = http->postsize; 1163 1164 /* set the new pointers for the request-sending */ 1165 conn->data->state.fread_func = (curl_read_callback)readmoredata; 1166 conn->data->state.in = (void *)conn; 1167 http->postdata = ptr; 1168 http->postsize = (curl_off_t)size; 1169 1170 http->send_buffer = in; 1171 http->sending = HTTPSEND_REQUEST; 1172 1173 return CURLE_OK; 1174 } 1175 http->sending = HTTPSEND_BODY; 1176 /* the full buffer was sent, clean up and return */ 1177 } 1178 else { 1179 if((size_t)amount != size) 1180 /* We have no continue-send mechanism now, fail. This can only happen 1181 when this function is used from the CONNECT sending function. We 1182 currently (stupidly) assume that the whole request is always sent 1183 away in the first single chunk. 1184 1185 This needs FIXing. 1186 */ 1187 return CURLE_SEND_ERROR; 1188 Curl_pipeline_leave_write(conn); 1189 } 1190 } 1191 Curl_add_buffer_free(in); 1192 1193 return result; 1194 } 1195 1196 1197 /* 1198 * add_bufferf() add the formatted input to the buffer. 1199 */ 1200 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...) 1201 { 1202 char *s; 1203 va_list ap; 1204 va_start(ap, fmt); 1205 s = vaprintf(fmt, ap); /* this allocs a new string to append */ 1206 va_end(ap); 1207 1208 if(s) { 1209 CURLcode result = Curl_add_buffer(in, s, strlen(s)); 1210 free(s); 1211 return result; 1212 } 1213 /* If we failed, we cleanup the whole buffer and return error */ 1214 free(in->buffer); 1215 free(in); 1216 return CURLE_OUT_OF_MEMORY; 1217 } 1218 1219 /* 1220 * add_buffer() appends a memory chunk to the existing buffer 1221 */ 1222 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size) 1223 { 1224 char *new_rb; 1225 size_t new_size; 1226 1227 if(~size < in->size_used) { 1228 /* If resulting used size of send buffer would wrap size_t, cleanup 1229 the whole buffer and return error. Otherwise the required buffer 1230 size will fit into a single allocatable memory chunk */ 1231 Curl_safefree(in->buffer); 1232 free(in); 1233 return CURLE_OUT_OF_MEMORY; 1234 } 1235 1236 if(!in->buffer || 1237 ((in->size_used + size) > (in->size_max - 1))) { 1238 1239 /* If current buffer size isn't enough to hold the result, use a 1240 buffer size that doubles the required size. If this new size 1241 would wrap size_t, then just use the largest possible one */ 1242 1243 if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) || 1244 (~(size * 2) < (in->size_used * 2))) 1245 new_size = (size_t)-1; 1246 else 1247 new_size = (in->size_used + size) * 2; 1248 1249 if(in->buffer) 1250 /* we have a buffer, enlarge the existing one */ 1251 new_rb = Curl_saferealloc(in->buffer, new_size); 1252 else 1253 /* create a new buffer */ 1254 new_rb = malloc(new_size); 1255 1256 if(!new_rb) { 1257 /* If we failed, we cleanup the whole buffer and return error */ 1258 free(in); 1259 return CURLE_OUT_OF_MEMORY; 1260 } 1261 1262 in->buffer = new_rb; 1263 in->size_max = new_size; 1264 } 1265 memcpy(&in->buffer[in->size_used], inptr, size); 1266 1267 in->size_used += size; 1268 1269 return CURLE_OK; 1270 } 1271 1272 /* end of the add_buffer functions */ 1273 /* ------------------------------------------------------------------------- */ 1274 1275 1276 1277 /* 1278 * Curl_compareheader() 1279 * 1280 * Returns TRUE if 'headerline' contains the 'header' with given 'content'. 1281 * Pass headers WITH the colon. 1282 */ 1283 bool 1284 Curl_compareheader(const char *headerline, /* line to check */ 1285 const char *header, /* header keyword _with_ colon */ 1286 const char *content) /* content string to find */ 1287 { 1288 /* RFC2616, section 4.2 says: "Each header field consists of a name followed 1289 * by a colon (":") and the field value. Field names are case-insensitive. 1290 * The field value MAY be preceded by any amount of LWS, though a single SP 1291 * is preferred." */ 1292 1293 size_t hlen = strlen(header); 1294 size_t clen; 1295 size_t len; 1296 const char *start; 1297 const char *end; 1298 1299 if(!strncasecompare(headerline, header, hlen)) 1300 return FALSE; /* doesn't start with header */ 1301 1302 /* pass the header */ 1303 start = &headerline[hlen]; 1304 1305 /* pass all white spaces */ 1306 while(*start && ISSPACE(*start)) 1307 start++; 1308 1309 /* find the end of the header line */ 1310 end = strchr(start, '\r'); /* lines end with CRLF */ 1311 if(!end) { 1312 /* in case there's a non-standard compliant line here */ 1313 end = strchr(start, '\n'); 1314 1315 if(!end) 1316 /* hm, there's no line ending here, use the zero byte! */ 1317 end = strchr(start, '\0'); 1318 } 1319 1320 len = end-start; /* length of the content part of the input line */ 1321 clen = strlen(content); /* length of the word to find */ 1322 1323 /* find the content string in the rest of the line */ 1324 for(; len >= clen; len--, start++) { 1325 if(strncasecompare(start, content, clen)) 1326 return TRUE; /* match! */ 1327 } 1328 1329 return FALSE; /* no match */ 1330 } 1331 1332 /* 1333 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from 1334 * the generic Curl_connect(). 1335 */ 1336 CURLcode Curl_http_connect(struct connectdata *conn, bool *done) 1337 { 1338 CURLcode result; 1339 1340 /* We default to persistent connections. We set this already in this connect 1341 function to make the re-use checks properly be able to check this bit. */ 1342 connkeep(conn, "HTTP default"); 1343 1344 /* the CONNECT procedure might not have been completed */ 1345 result = Curl_proxy_connect(conn, FIRSTSOCKET); 1346 if(result) 1347 return result; 1348 1349 if(conn->bits.proxy_connect_closed) 1350 /* this is not an error, just part of the connection negotiation */ 1351 return CURLE_OK; 1352 1353 if(CONNECT_FIRSTSOCKET_PROXY_SSL()) 1354 return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */ 1355 1356 if(Curl_connect_ongoing(conn)) 1357 /* nothing else to do except wait right now - we're not done here. */ 1358 return CURLE_OK; 1359 1360 if(conn->given->protocol & CURLPROTO_HTTPS) { 1361 /* perform SSL initialization */ 1362 result = https_connecting(conn, done); 1363 if(result) 1364 return result; 1365 } 1366 else 1367 *done = TRUE; 1368 1369 return CURLE_OK; 1370 } 1371 1372 /* this returns the socket to wait for in the DO and DOING state for the multi 1373 interface and then we're always _sending_ a request and thus we wait for 1374 the single socket to become writable only */ 1375 static int http_getsock_do(struct connectdata *conn, 1376 curl_socket_t *socks, 1377 int numsocks) 1378 { 1379 /* write mode */ 1380 (void)numsocks; /* unused, we trust it to be at least 1 */ 1381 socks[0] = conn->sock[FIRSTSOCKET]; 1382 return GETSOCK_WRITESOCK(0); 1383 } 1384 1385 #ifdef USE_SSL 1386 static CURLcode https_connecting(struct connectdata *conn, bool *done) 1387 { 1388 CURLcode result; 1389 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL)); 1390 1391 /* perform SSL initialization for this socket */ 1392 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done); 1393 if(result) 1394 connclose(conn, "Failed HTTPS connection"); 1395 1396 return result; 1397 } 1398 1399 static int https_getsock(struct connectdata *conn, 1400 curl_socket_t *socks, 1401 int numsocks) 1402 { 1403 if(conn->handler->flags & PROTOPT_SSL) 1404 return Curl_ssl_getsock(conn, socks, numsocks); 1405 return GETSOCK_BLANK; 1406 } 1407 #endif /* USE_SSL */ 1408 1409 /* 1410 * Curl_http_done() gets called after a single HTTP request has been 1411 * performed. 1412 */ 1413 1414 CURLcode Curl_http_done(struct connectdata *conn, 1415 CURLcode status, bool premature) 1416 { 1417 struct Curl_easy *data = conn->data; 1418 struct HTTP *http = data->req.protop; 1419 1420 /* Clear multipass flag. If authentication isn't done yet, then it will get 1421 * a chance to be set back to true when we output the next auth header */ 1422 data->state.authhost.multipass = FALSE; 1423 data->state.authproxy.multipass = FALSE; 1424 1425 Curl_unencode_cleanup(conn); 1426 1427 #ifdef USE_SPNEGO 1428 if(data->state.proxyneg.state == GSS_AUTHSENT || 1429 data->state.negotiate.state == GSS_AUTHSENT) { 1430 /* add forbid re-use if http-code != 401/407 as a WA only needed for 1431 * 401/407 that signal auth failure (empty) otherwise state will be RECV 1432 * with current code. 1433 * Do not close CONNECT_ONLY connections. */ 1434 if((data->req.httpcode != 401) && (data->req.httpcode != 407) && 1435 !data->set.connect_only) 1436 streamclose(conn, "Negotiate transfer completed"); 1437 Curl_cleanup_negotiate(data); 1438 } 1439 #endif 1440 1441 /* set the proper values (possibly modified on POST) */ 1442 conn->seek_func = data->set.seek_func; /* restore */ 1443 conn->seek_client = data->set.seek_client; /* restore */ 1444 1445 if(!http) 1446 return CURLE_OK; 1447 1448 if(http->send_buffer) { 1449 Curl_add_buffer_free(http->send_buffer); 1450 http->send_buffer = NULL; /* clear the pointer */ 1451 } 1452 1453 Curl_http2_done(conn, premature); 1454 1455 Curl_mime_cleanpart(&http->form); 1456 1457 switch(data->set.httpreq) { 1458 case HTTPREQ_PUT: 1459 case HTTPREQ_POST_FORM: 1460 case HTTPREQ_POST_MIME: 1461 data->req.bytecount = http->readbytecount + http->writebytecount; 1462 break; 1463 default: 1464 break; 1465 } 1466 1467 if(status) 1468 return status; 1469 1470 if(!premature && /* this check is pointless when DONE is called before the 1471 entire operation is complete */ 1472 !conn->bits.retry && 1473 !data->set.connect_only && 1474 (http->readbytecount + 1475 data->req.headerbytecount - 1476 data->req.deductheadercount) <= 0) { 1477 /* If this connection isn't simply closed to be retried, AND nothing was 1478 read from the HTTP server (that counts), this can't be right so we 1479 return an error here */ 1480 failf(data, "Empty reply from server"); 1481 return CURLE_GOT_NOTHING; 1482 } 1483 1484 return CURLE_OK; 1485 } 1486 1487 /* 1488 * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons 1489 * to avoid it include: 1490 * 1491 * - if the user specifically requested HTTP 1.0 1492 * - if the server we are connected to only supports 1.0 1493 * - if any server previously contacted to handle this request only supports 1494 * 1.0. 1495 */ 1496 static bool use_http_1_1plus(const struct Curl_easy *data, 1497 const struct connectdata *conn) 1498 { 1499 if((data->state.httpversion == 10) || (conn->httpversion == 10)) 1500 return FALSE; 1501 if((data->set.httpversion == CURL_HTTP_VERSION_1_0) && 1502 (conn->httpversion <= 10)) 1503 return FALSE; 1504 return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) || 1505 (data->set.httpversion >= CURL_HTTP_VERSION_1_1)); 1506 } 1507 1508 static const char *get_http_string(const struct Curl_easy *data, 1509 const struct connectdata *conn) 1510 { 1511 #ifdef USE_NGHTTP2 1512 if(conn->proto.httpc.h2) 1513 return "2"; 1514 #endif 1515 1516 if(use_http_1_1plus(data, conn)) 1517 return "1.1"; 1518 1519 return "1.0"; 1520 } 1521 1522 /* check and possibly add an Expect: header */ 1523 static CURLcode expect100(struct Curl_easy *data, 1524 struct connectdata *conn, 1525 Curl_send_buffer *req_buffer) 1526 { 1527 CURLcode result = CURLE_OK; 1528 const char *ptr; 1529 data->state.expect100header = FALSE; /* default to false unless it is set 1530 to TRUE below */ 1531 if(use_http_1_1plus(data, conn) && 1532 (conn->httpversion != 20)) { 1533 /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an 1534 Expect: 100-continue to the headers which actually speeds up post 1535 operations (as there is one packet coming back from the web server) */ 1536 ptr = Curl_checkheaders(conn, "Expect:"); 1537 if(ptr) { 1538 data->state.expect100header = 1539 Curl_compareheader(ptr, "Expect:", "100-continue"); 1540 } 1541 else { 1542 result = Curl_add_bufferf(req_buffer, 1543 "Expect: 100-continue\r\n"); 1544 if(!result) 1545 data->state.expect100header = TRUE; 1546 } 1547 } 1548 1549 return result; 1550 } 1551 1552 enum proxy_use { 1553 HEADER_SERVER, /* direct to server */ 1554 HEADER_PROXY, /* regular request to proxy */ 1555 HEADER_CONNECT /* sending CONNECT to a proxy */ 1556 }; 1557 1558 CURLcode Curl_add_custom_headers(struct connectdata *conn, 1559 bool is_connect, 1560 Curl_send_buffer *req_buffer) 1561 { 1562 char *ptr; 1563 struct curl_slist *h[2]; 1564 struct curl_slist *headers; 1565 int numlists = 1; /* by default */ 1566 struct Curl_easy *data = conn->data; 1567 int i; 1568 1569 enum proxy_use proxy; 1570 1571 if(is_connect) 1572 proxy = HEADER_CONNECT; 1573 else 1574 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy? 1575 HEADER_PROXY:HEADER_SERVER; 1576 1577 switch(proxy) { 1578 case HEADER_SERVER: 1579 h[0] = data->set.headers; 1580 break; 1581 case HEADER_PROXY: 1582 h[0] = data->set.headers; 1583 if(data->set.sep_headers) { 1584 h[1] = data->set.proxyheaders; 1585 numlists++; 1586 } 1587 break; 1588 case HEADER_CONNECT: 1589 if(data->set.sep_headers) 1590 h[0] = data->set.proxyheaders; 1591 else 1592 h[0] = data->set.headers; 1593 break; 1594 } 1595 1596 /* loop through one or two lists */ 1597 for(i = 0; i < numlists; i++) { 1598 headers = h[i]; 1599 1600 while(headers) { 1601 ptr = strchr(headers->data, ':'); 1602 if(ptr) { 1603 /* we require a colon for this to be a true header */ 1604 1605 ptr++; /* pass the colon */ 1606 while(*ptr && ISSPACE(*ptr)) 1607 ptr++; 1608 1609 if(*ptr) { 1610 /* only send this if the contents was non-blank */ 1611 1612 if(conn->allocptr.host && 1613 /* a Host: header was sent already, don't pass on any custom Host: 1614 header as that will produce *two* in the same request! */ 1615 checkprefix("Host:", headers->data)) 1616 ; 1617 else if(data->set.httpreq == HTTPREQ_POST_FORM && 1618 /* this header (extended by formdata.c) is sent later */ 1619 checkprefix("Content-Type:", headers->data)) 1620 ; 1621 else if(data->set.httpreq == HTTPREQ_POST_MIME && 1622 /* this header is sent later */ 1623 checkprefix("Content-Type:", headers->data)) 1624 ; 1625 else if(conn->bits.authneg && 1626 /* while doing auth neg, don't allow the custom length since 1627 we will force length zero then */ 1628 checkprefix("Content-Length:", headers->data)) 1629 ; 1630 else if(conn->allocptr.te && 1631 /* when asking for Transfer-Encoding, don't pass on a custom 1632 Connection: */ 1633 checkprefix("Connection:", headers->data)) 1634 ; 1635 else if((conn->httpversion == 20) && 1636 checkprefix("Transfer-Encoding:", headers->data)) 1637 /* HTTP/2 doesn't support chunked requests */ 1638 ; 1639 else if(checkprefix("Authorization:", headers->data) && 1640 /* be careful of sending this potentially sensitive header to 1641 other hosts */ 1642 (data->state.this_is_a_follow && 1643 data->state.first_host && 1644 !data->set.allow_auth_to_other_hosts && 1645 !strcasecompare(data->state.first_host, conn->host.name))) 1646 ; 1647 else { 1648 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n", 1649 headers->data); 1650 if(result) 1651 return result; 1652 } 1653 } 1654 } 1655 else { 1656 ptr = strchr(headers->data, ';'); 1657 if(ptr) { 1658 1659 ptr++; /* pass the semicolon */ 1660 while(*ptr && ISSPACE(*ptr)) 1661 ptr++; 1662 1663 if(*ptr) { 1664 /* this may be used for something else in the future */ 1665 } 1666 else { 1667 if(*(--ptr) == ';') { 1668 CURLcode result; 1669 1670 /* send no-value custom header if terminated by semicolon */ 1671 *ptr = ':'; 1672 result = Curl_add_bufferf(req_buffer, "%s\r\n", 1673 headers->data); 1674 1675 /* restore the previous value */ 1676 *ptr = ';'; 1677 1678 if(result) 1679 return result; 1680 } 1681 } 1682 } 1683 } 1684 headers = headers->next; 1685 } 1686 } 1687 1688 return CURLE_OK; 1689 } 1690 1691 CURLcode Curl_add_timecondition(struct Curl_easy *data, 1692 Curl_send_buffer *req_buffer) 1693 { 1694 const struct tm *tm; 1695 struct tm keeptime; 1696 CURLcode result; 1697 char datestr[80]; 1698 const char *condp; 1699 1700 if(data->set.timecondition == CURL_TIMECOND_NONE) 1701 /* no condition was asked for */ 1702 return CURLE_OK; 1703 1704 result = Curl_gmtime(data->set.timevalue, &keeptime); 1705 if(result) { 1706 failf(data, "Invalid TIMEVALUE"); 1707 return result; 1708 } 1709 tm = &keeptime; 1710 1711 switch(data->set.timecondition) { 1712 default: 1713 return CURLE_BAD_FUNCTION_ARGUMENT; 1714 1715 case CURL_TIMECOND_IFMODSINCE: 1716 condp = "If-Modified-Since"; 1717 break; 1718 case CURL_TIMECOND_IFUNMODSINCE: 1719 condp = "If-Unmodified-Since"; 1720 break; 1721 case CURL_TIMECOND_LASTMOD: 1722 condp = "Last-Modified"; 1723 break; 1724 } 1725 1726 /* The If-Modified-Since header family should have their times set in 1727 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be 1728 * represented in Greenwich Mean Time (GMT), without exception. For the 1729 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal 1730 * Time)." (see page 20 of RFC2616). 1731 */ 1732 1733 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ 1734 snprintf(datestr, sizeof(datestr), 1735 "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", 1736 condp, 1737 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], 1738 tm->tm_mday, 1739 Curl_month[tm->tm_mon], 1740 tm->tm_year + 1900, 1741 tm->tm_hour, 1742 tm->tm_min, 1743 tm->tm_sec); 1744 1745 result = Curl_add_buffer(req_buffer, datestr, strlen(datestr)); 1746 1747 return result; 1748 } 1749 1750 /* 1751 * Curl_http() gets called from the generic multi_do() function when a HTTP 1752 * request is to be performed. This creates and sends a properly constructed 1753 * HTTP request. 1754 */ 1755 CURLcode Curl_http(struct connectdata *conn, bool *done) 1756 { 1757 struct Curl_easy *data = conn->data; 1758 CURLcode result = CURLE_OK; 1759 struct HTTP *http; 1760 const char *ppath = data->state.path; 1761 bool paste_ftp_userpwd = FALSE; 1762 char ftp_typecode[sizeof("/;type=?")] = ""; 1763 const char *host = conn->host.name; 1764 const char *te = ""; /* transfer-encoding */ 1765 const char *ptr; 1766 const char *request; 1767 Curl_HttpReq httpreq = data->set.httpreq; 1768 #if !defined(CURL_DISABLE_COOKIES) 1769 char *addcookies = NULL; 1770 #endif 1771 curl_off_t included_body = 0; 1772 const char *httpstring; 1773 Curl_send_buffer *req_buffer; 1774 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */ 1775 int seekerr = CURL_SEEKFUNC_CANTSEEK; 1776 1777 /* Always consider the DO phase done after this function call, even if there 1778 may be parts of the request that is not yet sent, since we can deal with 1779 the rest of the request in the PERFORM phase. */ 1780 *done = TRUE; 1781 1782 if(conn->httpversion < 20) { /* unless the connection is re-used and already 1783 http2 */ 1784 switch(conn->negnpn) { 1785 case CURL_HTTP_VERSION_2: 1786 conn->httpversion = 20; /* we know we're on HTTP/2 now */ 1787 1788 result = Curl_http2_switched(conn, NULL, 0); 1789 if(result) 1790 return result; 1791 break; 1792 case CURL_HTTP_VERSION_1_1: 1793 /* continue with HTTP/1.1 when explicitly requested */ 1794 break; 1795 default: 1796 /* Check if user wants to use HTTP/2 with clear TCP*/ 1797 #ifdef USE_NGHTTP2 1798 if(conn->data->set.httpversion == 1799 CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) { 1800 DEBUGF(infof(data, "HTTP/2 over clean TCP\n")); 1801 conn->httpversion = 20; 1802 1803 result = Curl_http2_switched(conn, NULL, 0); 1804 if(result) 1805 return result; 1806 } 1807 #endif 1808 break; 1809 } 1810 } 1811 else { 1812 /* prepare for a http2 request */ 1813 result = Curl_http2_setup(conn); 1814 if(result) 1815 return result; 1816 } 1817 1818 http = data->req.protop; 1819 1820 if(!data->state.this_is_a_follow) { 1821 /* Free to avoid leaking memory on multiple requests*/ 1822 free(data->state.first_host); 1823 1824 data->state.first_host = strdup(conn->host.name); 1825 if(!data->state.first_host) 1826 return CURLE_OUT_OF_MEMORY; 1827 1828 data->state.first_remote_port = conn->remote_port; 1829 } 1830 http->writebytecount = http->readbytecount = 0; 1831 1832 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) && 1833 data->set.upload) { 1834 httpreq = HTTPREQ_PUT; 1835 } 1836 1837 /* Now set the 'request' pointer to the proper request string */ 1838 if(data->set.str[STRING_CUSTOMREQUEST]) 1839 request = data->set.str[STRING_CUSTOMREQUEST]; 1840 else { 1841 if(data->set.opt_no_body) 1842 request = "HEAD"; 1843 else { 1844 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST)); 1845 switch(httpreq) { 1846 case HTTPREQ_POST: 1847 case HTTPREQ_POST_FORM: 1848 case HTTPREQ_POST_MIME: 1849 request = "POST"; 1850 break; 1851 case HTTPREQ_PUT: 1852 request = "PUT"; 1853 break; 1854 case HTTPREQ_OPTIONS: 1855 request = "OPTIONS"; 1856 break; 1857 default: /* this should never happen */ 1858 case HTTPREQ_GET: 1859 request = "GET"; 1860 break; 1861 case HTTPREQ_HEAD: 1862 request = "HEAD"; 1863 break; 1864 } 1865 } 1866 } 1867 1868 /* The User-Agent string might have been allocated in url.c already, because 1869 it might have been used in the proxy connect, but if we have got a header 1870 with the user-agent string specified, we erase the previously made string 1871 here. */ 1872 if(Curl_checkheaders(conn, "User-Agent:")) { 1873 free(conn->allocptr.uagent); 1874 conn->allocptr.uagent = NULL; 1875 } 1876 1877 /* setup the authentication headers */ 1878 result = Curl_http_output_auth(conn, request, ppath, FALSE); 1879 if(result) 1880 return result; 1881 1882 if((data->state.authhost.multipass || data->state.authproxy.multipass) && 1883 (httpreq != HTTPREQ_GET) && 1884 (httpreq != HTTPREQ_HEAD)) { 1885 /* Auth is required and we are not authenticated yet. Make a PUT or POST 1886 with content-length zero as a "probe". */ 1887 conn->bits.authneg = TRUE; 1888 } 1889 else 1890 conn->bits.authneg = FALSE; 1891 1892 Curl_safefree(conn->allocptr.ref); 1893 if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) { 1894 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer); 1895 if(!conn->allocptr.ref) 1896 return CURLE_OUT_OF_MEMORY; 1897 } 1898 else 1899 conn->allocptr.ref = NULL; 1900 1901 #if !defined(CURL_DISABLE_COOKIES) 1902 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:")) 1903 addcookies = data->set.str[STRING_COOKIE]; 1904 #endif 1905 1906 if(!Curl_checkheaders(conn, "Accept-Encoding:") && 1907 data->set.str[STRING_ENCODING]) { 1908 Curl_safefree(conn->allocptr.accept_encoding); 1909 conn->allocptr.accept_encoding = 1910 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]); 1911 if(!conn->allocptr.accept_encoding) 1912 return CURLE_OUT_OF_MEMORY; 1913 } 1914 else { 1915 Curl_safefree(conn->allocptr.accept_encoding); 1916 conn->allocptr.accept_encoding = NULL; 1917 } 1918 1919 #ifdef HAVE_LIBZ 1920 /* we only consider transfer-encoding magic if libz support is built-in */ 1921 1922 if(!Curl_checkheaders(conn, "TE:") && 1923 data->set.http_transfer_encoding) { 1924 /* When we are to insert a TE: header in the request, we must also insert 1925 TE in a Connection: header, so we need to merge the custom provided 1926 Connection: header and prevent the original to get sent. Note that if 1927 the user has inserted his/hers own TE: header we don't do this magic 1928 but then assume that the user will handle it all! */ 1929 char *cptr = Curl_checkheaders(conn, "Connection:"); 1930 #define TE_HEADER "TE: gzip\r\n" 1931 1932 Curl_safefree(conn->allocptr.te); 1933 1934 /* Create the (updated) Connection: header */ 1935 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr): 1936 strdup("Connection: TE\r\n" TE_HEADER); 1937 1938 if(!conn->allocptr.te) 1939 return CURLE_OUT_OF_MEMORY; 1940 } 1941 #endif 1942 1943 switch(httpreq) { 1944 case HTTPREQ_POST_MIME: 1945 http->sendit = &data->set.mimepost; 1946 break; 1947 case HTTPREQ_POST_FORM: 1948 /* Convert the form structure into a mime structure. */ 1949 Curl_mime_cleanpart(&http->form); 1950 result = Curl_getformdata(data, &http->form, data->set.httppost, 1951 data->state.fread_func); 1952 if(result) 1953 return result; 1954 http->sendit = &http->form; 1955 break; 1956 default: 1957 http->sendit = NULL; 1958 } 1959 1960 if(http->sendit) { 1961 const char *cthdr = Curl_checkheaders(conn, "Content-Type:"); 1962 1963 /* Read and seek body only. */ 1964 http->sendit->flags |= MIME_BODY_ONLY; 1965 1966 /* Prepare the mime structure headers & set content type. */ 1967 1968 if(cthdr) 1969 for(cthdr += 13; *cthdr == ' '; cthdr++) 1970 ; 1971 else if(http->sendit->kind == MIMEKIND_MULTIPART) 1972 cthdr = "multipart/form-data"; 1973 1974 curl_mime_headers(http->sendit, data->set.headers, 0); 1975 result = Curl_mime_prepare_headers(http->sendit, cthdr, 1976 NULL, MIMESTRATEGY_FORM); 1977 curl_mime_headers(http->sendit, NULL, 0); 1978 if(!result) 1979 result = Curl_mime_rewind(http->sendit); 1980 if(result) 1981 return result; 1982 http->postsize = Curl_mime_size(http->sendit); 1983 } 1984 1985 ptr = Curl_checkheaders(conn, "Transfer-Encoding:"); 1986 if(ptr) { 1987 /* Some kind of TE is requested, check if 'chunked' is chosen */ 1988 data->req.upload_chunky = 1989 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked"); 1990 } 1991 else { 1992 if((conn->handler->protocol & PROTO_FAMILY_HTTP) && 1993 (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) && 1994 http->postsize < 0) || 1995 (data->set.upload && data->state.infilesize == -1))) { 1996 if(conn->bits.authneg) 1997 /* don't enable chunked during auth neg */ 1998 ; 1999 else if(use_http_1_1plus(data, conn)) { 2000 /* HTTP, upload, unknown file size and not HTTP 1.0 */ 2001 data->req.upload_chunky = TRUE; 2002 } 2003 else { 2004 failf(data, "Chunky upload is not supported by HTTP 1.0"); 2005 return CURLE_UPLOAD_FAILED; 2006 } 2007 } 2008 else { 2009 /* else, no chunky upload */ 2010 data->req.upload_chunky = FALSE; 2011 } 2012 2013 if(data->req.upload_chunky) 2014 te = "Transfer-Encoding: chunked\r\n"; 2015 } 2016 2017 Curl_safefree(conn->allocptr.host); 2018 2019 ptr = Curl_checkheaders(conn, "Host:"); 2020 if(ptr && (!data->state.this_is_a_follow || 2021 strcasecompare(data->state.first_host, conn->host.name))) { 2022 #if !defined(CURL_DISABLE_COOKIES) 2023 /* If we have a given custom Host: header, we extract the host name in 2024 order to possibly use it for cookie reasons later on. We only allow the 2025 custom Host: header if this is NOT a redirect, as setting Host: in the 2026 redirected request is being out on thin ice. Except if the host name 2027 is the same as the first one! */ 2028 char *cookiehost = Curl_copy_header_value(ptr); 2029 if(!cookiehost) 2030 return CURLE_OUT_OF_MEMORY; 2031 if(!*cookiehost) 2032 /* ignore empty data */ 2033 free(cookiehost); 2034 else { 2035 /* If the host begins with '[', we start searching for the port after 2036 the bracket has been closed */ 2037 int startsearch = 0; 2038 if(*cookiehost == '[') { 2039 char *closingbracket; 2040 /* since the 'cookiehost' is an allocated memory area that will be 2041 freed later we cannot simply increment the pointer */ 2042 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1); 2043 closingbracket = strchr(cookiehost, ']'); 2044 if(closingbracket) 2045 *closingbracket = 0; 2046 } 2047 else { 2048 char *colon = strchr(cookiehost + startsearch, ':'); 2049 if(colon) 2050 *colon = 0; /* The host must not include an embedded port number */ 2051 } 2052 Curl_safefree(conn->allocptr.cookiehost); 2053 conn->allocptr.cookiehost = cookiehost; 2054 } 2055 #endif 2056 2057 if(strcmp("Host:", ptr)) { 2058 conn->allocptr.host = aprintf("%s\r\n", ptr); 2059 if(!conn->allocptr.host) 2060 return CURLE_OUT_OF_MEMORY; 2061 } 2062 else 2063 /* when clearing the header */ 2064 conn->allocptr.host = NULL; 2065 } 2066 else { 2067 /* When building Host: headers, we must put the host name within 2068 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */ 2069 2070 if(((conn->given->protocol&CURLPROTO_HTTPS) && 2071 (conn->remote_port == PORT_HTTPS)) || 2072 ((conn->given->protocol&CURLPROTO_HTTP) && 2073 (conn->remote_port == PORT_HTTP)) ) 2074 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include 2075 the port number in the host string */ 2076 conn->allocptr.host = aprintf("Host: %s%s%s\r\n", 2077 conn->bits.ipv6_ip?"[":"", 2078 host, 2079 conn->bits.ipv6_ip?"]":""); 2080 else 2081 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n", 2082 conn->bits.ipv6_ip?"[":"", 2083 host, 2084 conn->bits.ipv6_ip?"]":"", 2085 conn->remote_port); 2086 2087 if(!conn->allocptr.host) 2088 /* without Host: we can't make a nice request */ 2089 return CURLE_OUT_OF_MEMORY; 2090 } 2091 2092 #ifndef CURL_DISABLE_PROXY 2093 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) { 2094 /* Using a proxy but does not tunnel through it */ 2095 2096 /* The path sent to the proxy is in fact the entire URL. But if the remote 2097 host is a IDN-name, we must make sure that the request we produce only 2098 uses the encoded host name! */ 2099 if(conn->host.dispname != conn->host.name) { 2100 char *url = data->change.url; 2101 ptr = strstr(url, conn->host.dispname); 2102 if(ptr) { 2103 /* This is where the display name starts in the URL, now replace this 2104 part with the encoded name. TODO: This method of replacing the host 2105 name is rather crude as I believe there's a slight risk that the 2106 user has entered a user name or password that contain the host name 2107 string. */ 2108 size_t currlen = strlen(conn->host.dispname); 2109 size_t newlen = strlen(conn->host.name); 2110 size_t urllen = strlen(url); 2111 2112 char *newurl; 2113 2114 newurl = malloc(urllen + newlen - currlen + 1); 2115 if(newurl) { 2116 /* copy the part before the host name */ 2117 memcpy(newurl, url, ptr - url); 2118 /* append the new host name instead of the old */ 2119 memcpy(newurl + (ptr - url), conn->host.name, newlen); 2120 /* append the piece after the host name */ 2121 memcpy(newurl + newlen + (ptr - url), 2122 ptr + currlen, /* copy the trailing zero byte too */ 2123 urllen - (ptr-url) - currlen + 1); 2124 if(data->change.url_alloc) { 2125 Curl_safefree(data->change.url); 2126 data->change.url_alloc = FALSE; 2127 } 2128 data->change.url = newurl; 2129 data->change.url_alloc = TRUE; 2130 } 2131 else 2132 return CURLE_OUT_OF_MEMORY; 2133 } 2134 } 2135 ppath = data->change.url; 2136 if(checkprefix("ftp://", ppath)) { 2137 if(data->set.proxy_transfer_mode) { 2138 /* when doing ftp, append ;type=<a|i> if not present */ 2139 char *type = strstr(ppath, ";type="); 2140 if(type && type[6] && type[7] == 0) { 2141 switch(Curl_raw_toupper(type[6])) { 2142 case 'A': 2143 case 'D': 2144 case 'I': 2145 break; 2146 default: 2147 type = NULL; 2148 } 2149 } 2150 if(!type) { 2151 char *p = ftp_typecode; 2152 /* avoid sending invalid URLs like ftp://example.com;type=i if the 2153 * user specified ftp://example.com without the slash */ 2154 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') { 2155 *p++ = '/'; 2156 } 2157 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c", 2158 data->set.prefer_ascii ? 'a' : 'i'); 2159 } 2160 } 2161 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url) 2162 paste_ftp_userpwd = TRUE; 2163 } 2164 } 2165 #endif /* CURL_DISABLE_PROXY */ 2166 2167 http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n"; 2168 2169 if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) && 2170 data->state.resume_from) { 2171 /********************************************************************** 2172 * Resuming upload in HTTP means that we PUT or POST and that we have 2173 * got a resume_from value set. The resume value has already created 2174 * a Range: header that will be passed along. We need to "fast forward" 2175 * the file the given number of bytes and decrease the assume upload 2176 * file size before we continue this venture in the dark lands of HTTP. 2177 * Resuming mime/form posting at an offset > 0 has no sense and is ignored. 2178 *********************************************************************/ 2179 2180 if(data->state.resume_from < 0) { 2181 /* 2182 * This is meant to get the size of the present remote-file by itself. 2183 * We don't support this now. Bail out! 2184 */ 2185 data->state.resume_from = 0; 2186 } 2187 2188 if(data->state.resume_from && !data->state.this_is_a_follow) { 2189 /* do we still game? */ 2190 2191 /* Now, let's read off the proper amount of bytes from the 2192 input. */ 2193 if(conn->seek_func) { 2194 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from, 2195 SEEK_SET); 2196 } 2197 2198 if(seekerr != CURL_SEEKFUNC_OK) { 2199 curl_off_t passed = 0; 2200 2201 if(seekerr != CURL_SEEKFUNC_CANTSEEK) { 2202 failf(data, "Could not seek stream"); 2203 return CURLE_READ_ERROR; 2204 } 2205 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */ 2206 do { 2207 size_t readthisamountnow = 2208 (data->state.resume_from - passed > data->set.buffer_size) ? 2209 (size_t)data->set.buffer_size : 2210 curlx_sotouz(data->state.resume_from - passed); 2211 2212 size_t actuallyread = 2213 data->state.fread_func(data->state.buffer, 1, readthisamountnow, 2214 data->state.in); 2215 2216 passed += actuallyread; 2217 if((actuallyread == 0) || (actuallyread > readthisamountnow)) { 2218 /* this checks for greater-than only to make sure that the 2219 CURL_READFUNC_ABORT return code still aborts */ 2220 failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T 2221 " bytes from the input", passed); 2222 return CURLE_READ_ERROR; 2223 } 2224 } while(passed < data->state.resume_from); 2225 } 2226 2227 /* now, decrease the size of the read */ 2228 if(data->state.infilesize>0) { 2229 data->state.infilesize -= data->state.resume_from; 2230 2231 if(data->state.infilesize <= 0) { 2232 failf(data, "File already completely uploaded"); 2233 return CURLE_PARTIAL_FILE; 2234 } 2235 } 2236 /* we've passed, proceed as normal */ 2237 } 2238 } 2239 if(data->state.use_range) { 2240 /* 2241 * A range is selected. We use different headers whether we're downloading 2242 * or uploading and we always let customized headers override our internal 2243 * ones if any such are specified. 2244 */ 2245 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) && 2246 !Curl_checkheaders(conn, "Range:")) { 2247 /* if a line like this was already allocated, free the previous one */ 2248 free(conn->allocptr.rangeline); 2249 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n", 2250 data->state.range); 2251 } 2252 else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) && 2253 !Curl_checkheaders(conn, "Content-Range:")) { 2254 2255 /* if a line like this was already allocated, free the previous one */ 2256 free(conn->allocptr.rangeline); 2257 2258 if(data->set.set_resume_from < 0) { 2259 /* Upload resume was asked for, but we don't know the size of the 2260 remote part so we tell the server (and act accordingly) that we 2261 upload the whole file (again) */ 2262 conn->allocptr.rangeline = 2263 aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T 2264 "/%" CURL_FORMAT_CURL_OFF_T "\r\n", 2265 data->state.infilesize - 1, data->state.infilesize); 2266 2267 } 2268 else if(data->state.resume_from) { 2269 /* This is because "resume" was selected */ 2270 curl_off_t total_expected_size = 2271 data->state.resume_from + data->state.infilesize; 2272 conn->allocptr.rangeline = 2273 aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T 2274 "/%" CURL_FORMAT_CURL_OFF_T "\r\n", 2275 data->state.range, total_expected_size-1, 2276 total_expected_size); 2277 } 2278 else { 2279 /* Range was selected and then we just pass the incoming range and 2280 append total size */ 2281 conn->allocptr.rangeline = 2282 aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n", 2283 data->state.range, data->state.infilesize); 2284 } 2285 if(!conn->allocptr.rangeline) 2286 return CURLE_OUT_OF_MEMORY; 2287 } 2288 } 2289 2290 httpstring = get_http_string(data, conn); 2291 2292 /* initialize a dynamic send-buffer */ 2293 req_buffer = Curl_add_buffer_init(); 2294 2295 if(!req_buffer) 2296 return CURLE_OUT_OF_MEMORY; 2297 2298 /* add the main request stuff */ 2299 /* GET/HEAD/POST/PUT */ 2300 result = Curl_add_bufferf(req_buffer, "%s ", request); 2301 if(result) 2302 return result; 2303 2304 if(data->set.str[STRING_TARGET]) 2305 ppath = data->set.str[STRING_TARGET]; 2306 2307 /* url */ 2308 if(paste_ftp_userpwd) 2309 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s", 2310 conn->user, conn->passwd, 2311 ppath + sizeof("ftp://") - 1); 2312 else 2313 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath)); 2314 if(result) 2315 return result; 2316 2317 result = 2318 Curl_add_bufferf(req_buffer, 2319 "%s" /* ftp typecode (;type=x) */ 2320 " HTTP/%s\r\n" /* HTTP version */ 2321 "%s" /* host */ 2322 "%s" /* proxyuserpwd */ 2323 "%s" /* userpwd */ 2324 "%s" /* range */ 2325 "%s" /* user agent */ 2326 "%s" /* accept */ 2327 "%s" /* TE: */ 2328 "%s" /* accept-encoding */ 2329 "%s" /* referer */ 2330 "%s" /* Proxy-Connection */ 2331 "%s",/* transfer-encoding */ 2332 2333 ftp_typecode, 2334 httpstring, 2335 (conn->allocptr.host?conn->allocptr.host:""), 2336 conn->allocptr.proxyuserpwd? 2337 conn->allocptr.proxyuserpwd:"", 2338 conn->allocptr.userpwd?conn->allocptr.userpwd:"", 2339 (data->state.use_range && conn->allocptr.rangeline)? 2340 conn->allocptr.rangeline:"", 2341 (data->set.str[STRING_USERAGENT] && 2342 *data->set.str[STRING_USERAGENT] && 2343 conn->allocptr.uagent)? 2344 conn->allocptr.uagent:"", 2345 http->p_accept?http->p_accept:"", 2346 conn->allocptr.te?conn->allocptr.te:"", 2347 (data->set.str[STRING_ENCODING] && 2348 *data->set.str[STRING_ENCODING] && 2349 conn->allocptr.accept_encoding)? 2350 conn->allocptr.accept_encoding:"", 2351 (data->change.referer && conn->allocptr.ref)? 2352 conn->allocptr.ref:"" /* Referer: <data> */, 2353 (conn->bits.httpproxy && 2354 !conn->bits.tunnel_proxy && 2355 !Curl_checkProxyheaders(conn, "Proxy-Connection:"))? 2356 "Proxy-Connection: Keep-Alive\r\n":"", 2357 te 2358 ); 2359 2360 /* clear userpwd and proxyuserpwd to avoid re-using old credentials 2361 * from re-used connections */ 2362 Curl_safefree(conn->allocptr.userpwd); 2363 Curl_safefree(conn->allocptr.proxyuserpwd); 2364 2365 if(result) 2366 return result; 2367 2368 if(!(conn->handler->flags&PROTOPT_SSL) && 2369 conn->httpversion != 20 && 2370 (data->set.httpversion == CURL_HTTP_VERSION_2)) { 2371 /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done 2372 over SSL */ 2373 result = Curl_http2_request_upgrade(req_buffer, conn); 2374 if(result) 2375 return result; 2376 } 2377 2378 #if !defined(CURL_DISABLE_COOKIES) 2379 if(data->cookies || addcookies) { 2380 struct Cookie *co = NULL; /* no cookies from start */ 2381 int count = 0; 2382 2383 if(data->cookies) { 2384 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); 2385 co = Curl_cookie_getlist(data->cookies, 2386 conn->allocptr.cookiehost? 2387 conn->allocptr.cookiehost:host, 2388 data->state.path, 2389 (conn->handler->protocol&CURLPROTO_HTTPS)? 2390 TRUE:FALSE); 2391 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); 2392 } 2393 if(co) { 2394 struct Cookie *store = co; 2395 /* now loop through all cookies that matched */ 2396 while(co) { 2397 if(co->value) { 2398 if(0 == count) { 2399 result = Curl_add_bufferf(req_buffer, "Cookie: "); 2400 if(result) 2401 break; 2402 } 2403 result = Curl_add_bufferf(req_buffer, 2404 "%s%s=%s", count?"; ":"", 2405 co->name, co->value); 2406 if(result) 2407 break; 2408 count++; 2409 } 2410 co = co->next; /* next cookie please */ 2411 } 2412 Curl_cookie_freelist(store); 2413 } 2414 if(addcookies && !result) { 2415 if(!count) 2416 result = Curl_add_bufferf(req_buffer, "Cookie: "); 2417 if(!result) { 2418 result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"", 2419 addcookies); 2420 count++; 2421 } 2422 } 2423 if(count && !result) 2424 result = Curl_add_buffer(req_buffer, "\r\n", 2); 2425 2426 if(result) 2427 return result; 2428 } 2429 #endif 2430 2431 result = Curl_add_timecondition(data, req_buffer); 2432 if(result) 2433 return result; 2434 2435 result = Curl_add_custom_headers(conn, FALSE, req_buffer); 2436 if(result) 2437 return result; 2438 2439 http->postdata = NULL; /* nothing to post at this point */ 2440 Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */ 2441 2442 /* If 'authdone' is FALSE, we must not set the write socket index to the 2443 Curl_transfer() call below, as we're not ready to actually upload any 2444 data yet. */ 2445 2446 switch(httpreq) { 2447 2448 case HTTPREQ_PUT: /* Let's PUT the data to the server! */ 2449 2450 if(conn->bits.authneg) 2451 postsize = 0; 2452 else 2453 postsize = data->state.infilesize; 2454 2455 if((postsize != -1) && !data->req.upload_chunky && 2456 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) { 2457 /* only add Content-Length if not uploading chunked */ 2458 result = Curl_add_bufferf(req_buffer, 2459 "Content-Length: %" CURL_FORMAT_CURL_OFF_T 2460 "\r\n", postsize); 2461 if(result) 2462 return result; 2463 } 2464 2465 if(postsize != 0) { 2466 result = expect100(data, conn, req_buffer); 2467 if(result) 2468 return result; 2469 } 2470 2471 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */ 2472 if(result) 2473 return result; 2474 2475 /* set the upload size to the progress meter */ 2476 Curl_pgrsSetUploadSize(data, postsize); 2477 2478 /* this sends the buffer and frees all the buffer resources */ 2479 result = Curl_add_buffer_send(req_buffer, conn, 2480 &data->info.request_size, 0, FIRSTSOCKET); 2481 if(result) 2482 failf(data, "Failed sending PUT request"); 2483 else 2484 /* prepare for transfer */ 2485 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, 2486 &http->readbytecount, postsize?FIRSTSOCKET:-1, 2487 postsize?&http->writebytecount:NULL); 2488 if(result) 2489 return result; 2490 break; 2491 2492 case HTTPREQ_POST_FORM: 2493 case HTTPREQ_POST_MIME: 2494 /* This is form posting using mime data. */ 2495 if(conn->bits.authneg) { 2496 /* nothing to post! */ 2497 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n"); 2498 if(result) 2499 return result; 2500 2501 result = Curl_add_buffer_send(req_buffer, conn, 2502 &data->info.request_size, 0, FIRSTSOCKET); 2503 if(result) 2504 failf(data, "Failed sending POST request"); 2505 else 2506 /* setup variables for the upcoming transfer */ 2507 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount, 2508 -1, NULL); 2509 break; 2510 } 2511 2512 postsize = http->postsize; 2513 2514 /* We only set Content-Length and allow a custom Content-Length if 2515 we don't upload data chunked, as RFC2616 forbids us to set both 2516 kinds of headers (Transfer-Encoding: chunked and Content-Length) */ 2517 if(postsize != -1 && !data->req.upload_chunky && 2518 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) { 2519 /* we allow replacing this header if not during auth negotiation, 2520 although it isn't very wise to actually set your own */ 2521 result = Curl_add_bufferf(req_buffer, 2522 "Content-Length: %" CURL_FORMAT_CURL_OFF_T 2523 "\r\n", postsize); 2524 if(result) 2525 return result; 2526 } 2527 2528 /* Output mime-generated headers. */ 2529 { 2530 struct curl_slist *hdr; 2531 2532 for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) { 2533 result = Curl_add_bufferf(req_buffer, "%s\r\n", hdr->data); 2534 if(result) 2535 return result; 2536 } 2537 } 2538 2539 /* For really small posts we don't use Expect: headers at all, and for 2540 the somewhat bigger ones we allow the app to disable it. Just make 2541 sure that the expect100header is always set to the preferred value 2542 here. */ 2543 ptr = Curl_checkheaders(conn, "Expect:"); 2544 if(ptr) { 2545 data->state.expect100header = 2546 Curl_compareheader(ptr, "Expect:", "100-continue"); 2547 } 2548 else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) { 2549 result = expect100(data, conn, req_buffer); 2550 if(result) 2551 return result; 2552 } 2553 else 2554 data->state.expect100header = FALSE; 2555 2556 /* make the request end in a true CRLF */ 2557 result = Curl_add_buffer(req_buffer, "\r\n", 2); 2558 if(result) 2559 return result; 2560 2561 /* set the upload size to the progress meter */ 2562 Curl_pgrsSetUploadSize(data, postsize); 2563 2564 /* Read from mime structure. */ 2565 data->state.fread_func = (curl_read_callback) Curl_mime_read; 2566 data->state.in = (void *) http->sendit; 2567 http->sending = HTTPSEND_BODY; 2568 2569 /* this sends the buffer and frees all the buffer resources */ 2570 result = Curl_add_buffer_send(req_buffer, conn, 2571 &data->info.request_size, 0, FIRSTSOCKET); 2572 if(result) 2573 failf(data, "Failed sending POST request"); 2574 else 2575 /* prepare for transfer */ 2576 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, 2577 &http->readbytecount, postsize?FIRSTSOCKET:-1, 2578 postsize?&http->writebytecount:NULL); 2579 if(result) 2580 return result; 2581 2582 break; 2583 2584 case HTTPREQ_POST: 2585 /* this is the simple POST, using x-www-form-urlencoded style */ 2586 2587 if(conn->bits.authneg) 2588 postsize = 0; 2589 else 2590 /* the size of the post body */ 2591 postsize = data->state.infilesize; 2592 2593 /* We only set Content-Length and allow a custom Content-Length if 2594 we don't upload data chunked, as RFC2616 forbids us to set both 2595 kinds of headers (Transfer-Encoding: chunked and Content-Length) */ 2596 if((postsize != -1) && !data->req.upload_chunky && 2597 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) { 2598 /* we allow replacing this header if not during auth negotiation, 2599 although it isn't very wise to actually set your own */ 2600 result = Curl_add_bufferf(req_buffer, 2601 "Content-Length: %" CURL_FORMAT_CURL_OFF_T 2602 "\r\n", postsize); 2603 if(result) 2604 return result; 2605 } 2606 2607 if(!Curl_checkheaders(conn, "Content-Type:")) { 2608 result = Curl_add_bufferf(req_buffer, 2609 "Content-Type: application/" 2610 "x-www-form-urlencoded\r\n"); 2611 if(result) 2612 return result; 2613 } 2614 2615 /* For really small posts we don't use Expect: headers at all, and for 2616 the somewhat bigger ones we allow the app to disable it. Just make 2617 sure that the expect100header is always set to the preferred value 2618 here. */ 2619 ptr = Curl_checkheaders(conn, "Expect:"); 2620 if(ptr) { 2621 data->state.expect100header = 2622 Curl_compareheader(ptr, "Expect:", "100-continue"); 2623 } 2624 else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) { 2625 result = expect100(data, conn, req_buffer); 2626 if(result) 2627 return result; 2628 } 2629 else 2630 data->state.expect100header = FALSE; 2631 2632 if(data->set.postfields) { 2633 2634 /* In HTTP2, we send request body in DATA frame regardless of 2635 its size. */ 2636 if(conn->httpversion != 20 && 2637 !data->state.expect100header && 2638 (postsize < MAX_INITIAL_POST_SIZE)) { 2639 /* if we don't use expect: 100 AND 2640 postsize is less than MAX_INITIAL_POST_SIZE 2641 2642 then append the post data to the HTTP request header. This limit 2643 is no magic limit but only set to prevent really huge POSTs to 2644 get the data duplicated with malloc() and family. */ 2645 2646 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ 2647 if(result) 2648 return result; 2649 2650 if(!data->req.upload_chunky) { 2651 /* We're not sending it 'chunked', append it to the request 2652 already now to reduce the number if send() calls */ 2653 result = Curl_add_buffer(req_buffer, data->set.postfields, 2654 (size_t)postsize); 2655 included_body = postsize; 2656 } 2657 else { 2658 if(postsize) { 2659 /* Append the POST data chunky-style */ 2660 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize); 2661 if(!result) { 2662 result = Curl_add_buffer(req_buffer, data->set.postfields, 2663 (size_t)postsize); 2664 if(!result) 2665 result = Curl_add_buffer(req_buffer, "\r\n", 2); 2666 included_body = postsize + 2; 2667 } 2668 } 2669 if(!result) 2670 result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5); 2671 /* 0 CR LF CR LF */ 2672 included_body += 5; 2673 } 2674 if(result) 2675 return result; 2676 /* Make sure the progress information is accurate */ 2677 Curl_pgrsSetUploadSize(data, postsize); 2678 } 2679 else { 2680 /* A huge POST coming up, do data separate from the request */ 2681 http->postsize = postsize; 2682 http->postdata = data->set.postfields; 2683 2684 http->sending = HTTPSEND_BODY; 2685 2686 data->state.fread_func = (curl_read_callback)readmoredata; 2687 data->state.in = (void *)conn; 2688 2689 /* set the upload size to the progress meter */ 2690 Curl_pgrsSetUploadSize(data, http->postsize); 2691 2692 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ 2693 if(result) 2694 return result; 2695 } 2696 } 2697 else { 2698 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */ 2699 if(result) 2700 return result; 2701 2702 if(data->req.upload_chunky && conn->bits.authneg) { 2703 /* Chunky upload is selected and we're negotiating auth still, send 2704 end-of-data only */ 2705 result = Curl_add_buffer(req_buffer, 2706 "\x30\x0d\x0a\x0d\x0a", 5); 2707 /* 0 CR LF CR LF */ 2708 if(result) 2709 return result; 2710 } 2711 2712 else if(data->state.infilesize) { 2713 /* set the upload size to the progress meter */ 2714 Curl_pgrsSetUploadSize(data, postsize?postsize:-1); 2715 2716 /* set the pointer to mark that we will send the post body using the 2717 read callback, but only if we're not in authenticate 2718 negotiation */ 2719 if(!conn->bits.authneg) { 2720 http->postdata = (char *)&http->postdata; 2721 http->postsize = postsize; 2722 } 2723 } 2724 } 2725 /* issue the request */ 2726 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size, 2727 (size_t)included_body, FIRSTSOCKET); 2728 2729 if(result) 2730 failf(data, "Failed sending HTTP POST request"); 2731 else 2732 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, 2733 &http->readbytecount, http->postdata?FIRSTSOCKET:-1, 2734 http->postdata?&http->writebytecount:NULL); 2735 break; 2736 2737 default: 2738 result = Curl_add_buffer(req_buffer, "\r\n", 2); 2739 if(result) 2740 return result; 2741 2742 /* issue the request */ 2743 result = Curl_add_buffer_send(req_buffer, conn, 2744 &data->info.request_size, 0, FIRSTSOCKET); 2745 2746 if(result) 2747 failf(data, "Failed sending HTTP request"); 2748 else 2749 /* HTTP GET/HEAD download: */ 2750 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount, 2751 http->postdata?FIRSTSOCKET:-1, 2752 http->postdata?&http->writebytecount:NULL); 2753 } 2754 if(result) 2755 return result; 2756 2757 if(http->writebytecount) { 2758 /* if a request-body has been sent off, we make sure this progress is noted 2759 properly */ 2760 Curl_pgrsSetUploadCounter(data, http->writebytecount); 2761 if(Curl_pgrsUpdate(conn)) 2762 result = CURLE_ABORTED_BY_CALLBACK; 2763 2764 if(http->writebytecount >= postsize) { 2765 /* already sent the entire request body, mark the "upload" as 2766 complete */ 2767 infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T 2768 " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n", 2769 http->writebytecount, postsize); 2770 data->req.upload_done = TRUE; 2771 data->req.keepon &= ~KEEP_SEND; /* we're done writing */ 2772 data->req.exp100 = EXP100_SEND_DATA; /* already sent */ 2773 Curl_expire_done(data, EXPIRE_100_TIMEOUT); 2774 } 2775 } 2776 2777 if((conn->httpversion == 20) && data->req.upload_chunky) 2778 /* upload_chunky was set above to set up the request in a chunky fashion, 2779 but is disabled here again to avoid that the chunked encoded version is 2780 actually used when sending the request body over h2 */ 2781 data->req.upload_chunky = FALSE; 2782 return result; 2783 } 2784 2785 /* 2786 * checkhttpprefix() 2787 * 2788 * Returns TRUE if member of the list matches prefix of string 2789 */ 2790 static bool 2791 checkhttpprefix(struct Curl_easy *data, 2792 const char *s) 2793 { 2794 struct curl_slist *head = data->set.http200aliases; 2795 bool rc = FALSE; 2796 #ifdef CURL_DOES_CONVERSIONS 2797 /* convert from the network encoding using a scratch area */ 2798 char *scratch = strdup(s); 2799 if(NULL == scratch) { 2800 failf(data, "Failed to allocate memory for conversion!"); 2801 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */ 2802 } 2803 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) { 2804 /* Curl_convert_from_network calls failf if unsuccessful */ 2805 free(scratch); 2806 return FALSE; /* can't return CURLE_foobar so return FALSE */ 2807 } 2808 s = scratch; 2809 #endif /* CURL_DOES_CONVERSIONS */ 2810 2811 while(head) { 2812 if(checkprefix(head->data, s)) { 2813 rc = TRUE; 2814 break; 2815 } 2816 head = head->next; 2817 } 2818 2819 if(!rc && (checkprefix("HTTP/", s))) 2820 rc = TRUE; 2821 2822 #ifdef CURL_DOES_CONVERSIONS 2823 free(scratch); 2824 #endif /* CURL_DOES_CONVERSIONS */ 2825 return rc; 2826 } 2827 2828 #ifndef CURL_DISABLE_RTSP 2829 static bool 2830 checkrtspprefix(struct Curl_easy *data, 2831 const char *s) 2832 { 2833 bool result = FALSE; 2834 2835 #ifdef CURL_DOES_CONVERSIONS 2836 /* convert from the network encoding using a scratch area */ 2837 char *scratch = strdup(s); 2838 if(NULL == scratch) { 2839 failf(data, "Failed to allocate memory for conversion!"); 2840 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */ 2841 } 2842 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) { 2843 /* Curl_convert_from_network calls failf if unsuccessful */ 2844 result = FALSE; /* can't return CURLE_foobar so return FALSE */ 2845 } 2846 else 2847 result = checkprefix("RTSP/", scratch)? TRUE: FALSE; 2848 free(scratch); 2849 #else 2850 (void)data; /* unused */ 2851 result = checkprefix("RTSP/", s)? TRUE: FALSE; 2852 #endif /* CURL_DOES_CONVERSIONS */ 2853 2854 return result; 2855 } 2856 #endif /* CURL_DISABLE_RTSP */ 2857 2858 static bool 2859 checkprotoprefix(struct Curl_easy *data, struct connectdata *conn, 2860 const char *s) 2861 { 2862 #ifndef CURL_DISABLE_RTSP 2863 if(conn->handler->protocol & CURLPROTO_RTSP) 2864 return checkrtspprefix(data, s); 2865 #else 2866 (void)conn; 2867 #endif /* CURL_DISABLE_RTSP */ 2868 2869 return checkhttpprefix(data, s); 2870 } 2871 2872 /* 2873 * header_append() copies a chunk of data to the end of the already received 2874 * header. We make sure that the full string fit in the allocated header 2875 * buffer, or else we enlarge it. 2876 */ 2877 static CURLcode header_append(struct Curl_easy *data, 2878 struct SingleRequest *k, 2879 size_t length) 2880 { 2881 if(k->hbuflen + length >= data->state.headersize) { 2882 /* We enlarge the header buffer as it is too small */ 2883 char *newbuff; 2884 size_t hbufp_index; 2885 size_t newsize; 2886 2887 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) { 2888 /* The reason to have a max limit for this is to avoid the risk of a bad 2889 server feeding libcurl with a never-ending header that will cause 2890 reallocs infinitely */ 2891 failf(data, "Avoided giant realloc for header (max is %d)!", 2892 CURL_MAX_HTTP_HEADER); 2893 return CURLE_OUT_OF_MEMORY; 2894 } 2895 2896 newsize = CURLMAX((k->hbuflen + length) * 3 / 2, data->state.headersize*2); 2897 hbufp_index = k->hbufp - data->state.headerbuff; 2898 newbuff = realloc(data->state.headerbuff, newsize); 2899 if(!newbuff) { 2900 failf(data, "Failed to alloc memory for big header!"); 2901 return CURLE_OUT_OF_MEMORY; 2902 } 2903 data->state.headersize = newsize; 2904 data->state.headerbuff = newbuff; 2905 k->hbufp = data->state.headerbuff + hbufp_index; 2906 } 2907 memcpy(k->hbufp, k->str_start, length); 2908 k->hbufp += length; 2909 k->hbuflen += length; 2910 *k->hbufp = 0; 2911 2912 return CURLE_OK; 2913 } 2914 2915 static void print_http_error(struct Curl_easy *data) 2916 { 2917 struct SingleRequest *k = &data->req; 2918 char *beg = k->p; 2919 2920 /* make sure that data->req.p points to the HTTP status line */ 2921 if(!strncmp(beg, "HTTP", 4)) { 2922 2923 /* skip to HTTP status code */ 2924 beg = strchr(beg, ' '); 2925 if(beg && *++beg) { 2926 2927 /* find trailing CR */ 2928 char end_char = '\r'; 2929 char *end = strchr(beg, end_char); 2930 if(!end) { 2931 /* try to find LF (workaround for non-compliant HTTP servers) */ 2932 end_char = '\n'; 2933 end = strchr(beg, end_char); 2934 } 2935 2936 if(end) { 2937 /* temporarily replace CR or LF by NUL and print the error message */ 2938 *end = '\0'; 2939 failf(data, "The requested URL returned error: %s", beg); 2940 2941 /* restore the previously replaced CR or LF */ 2942 *end = end_char; 2943 return; 2944 } 2945 } 2946 } 2947 2948 /* fall-back to printing the HTTP status code only */ 2949 failf(data, "The requested URL returned error: %d", k->httpcode); 2950 } 2951 2952 /* 2953 * Read any HTTP header lines from the server and pass them to the client app. 2954 */ 2955 CURLcode Curl_http_readwrite_headers(struct Curl_easy *data, 2956 struct connectdata *conn, 2957 ssize_t *nread, 2958 bool *stop_reading) 2959 { 2960 CURLcode result; 2961 struct SingleRequest *k = &data->req; 2962 2963 /* header line within buffer loop */ 2964 do { 2965 size_t rest_length; 2966 size_t full_length; 2967 int writetype; 2968 2969 /* str_start is start of line within buf */ 2970 k->str_start = k->str; 2971 2972 /* data is in network encoding so use 0x0a instead of '\n' */ 2973 k->end_ptr = memchr(k->str_start, 0x0a, *nread); 2974 2975 if(!k->end_ptr) { 2976 /* Not a complete header line within buffer, append the data to 2977 the end of the headerbuff. */ 2978 result = header_append(data, k, *nread); 2979 if(result) 2980 return result; 2981 2982 if(!k->headerline && (k->hbuflen>5)) { 2983 /* make a first check that this looks like a protocol header */ 2984 if(!checkprotoprefix(data, conn, data->state.headerbuff)) { 2985 /* this is not the beginning of a protocol first header line */ 2986 k->header = FALSE; 2987 k->badheader = HEADER_ALLBAD; 2988 break; 2989 } 2990 } 2991 2992 break; /* read more and try again */ 2993 } 2994 2995 /* decrease the size of the remaining (supposed) header line */ 2996 rest_length = (k->end_ptr - k->str) + 1; 2997 *nread -= (ssize_t)rest_length; 2998 2999 k->str = k->end_ptr + 1; /* move past new line */ 3000 3001 full_length = k->str - k->str_start; 3002 3003 result = header_append(data, k, full_length); 3004 if(result) 3005 return result; 3006 3007 k->end_ptr = k->hbufp; 3008 k->p = data->state.headerbuff; 3009 3010 /**** 3011 * We now have a FULL header line that p points to 3012 *****/ 3013 3014 if(!k->headerline) { 3015 /* the first read header */ 3016 if((k->hbuflen>5) && 3017 !checkprotoprefix(data, conn, data->state.headerbuff)) { 3018 /* this is not the beginning of a protocol first header line */ 3019 k->header = FALSE; 3020 if(*nread) 3021 /* since there's more, this is a partial bad header */ 3022 k->badheader = HEADER_PARTHEADER; 3023 else { 3024 /* this was all we read so it's all a bad header */ 3025 k->badheader = HEADER_ALLBAD; 3026 *nread = (ssize_t)rest_length; 3027 } 3028 break; 3029 } 3030 } 3031 3032 /* headers are in network encoding so 3033 use 0x0a and 0x0d instead of '\n' and '\r' */ 3034 if((0x0a == *k->p) || (0x0d == *k->p)) { 3035 size_t headerlen; 3036 /* Zero-length header line means end of headers! */ 3037 3038 #ifdef CURL_DOES_CONVERSIONS 3039 if(0x0d == *k->p) { 3040 *k->p = '\r'; /* replace with CR in host encoding */ 3041 k->p++; /* pass the CR byte */ 3042 } 3043 if(0x0a == *k->p) { 3044 *k->p = '\n'; /* replace with LF in host encoding */ 3045 k->p++; /* pass the LF byte */ 3046 } 3047 #else 3048 if('\r' == *k->p) 3049 k->p++; /* pass the \r byte */ 3050 if('\n' == *k->p) 3051 k->p++; /* pass the \n byte */ 3052 #endif /* CURL_DOES_CONVERSIONS */ 3053 3054 if(100 <= k->httpcode && 199 >= k->httpcode) { 3055 /* "A user agent MAY ignore unexpected 1xx status responses." */ 3056 switch(k->httpcode) { 3057 case 100: 3058 /* 3059 * We have made a HTTP PUT or POST and this is 1.1-lingo 3060 * that tells us that the server is OK with this and ready 3061 * to receive the data. 3062 * However, we'll get more headers now so we must get 3063 * back into the header-parsing state! 3064 */ 3065 k->header = TRUE; 3066 k->headerline = 0; /* restart the header line counter */ 3067 3068 /* if we did wait for this do enable write now! */ 3069 if(k->exp100 > EXP100_SEND_DATA) { 3070 k->exp100 = EXP100_SEND_DATA; 3071 k->keepon |= KEEP_SEND; 3072 Curl_expire_done(data, EXPIRE_100_TIMEOUT); 3073 } 3074 break; 3075 case 101: 3076 /* Switching Protocols */ 3077 if(k->upgr101 == UPGR101_REQUESTED) { 3078 /* Switching to HTTP/2 */ 3079 infof(data, "Received 101\n"); 3080 k->upgr101 = UPGR101_RECEIVED; 3081 3082 /* we'll get more headers (HTTP/2 response) */ 3083 k->header = TRUE; 3084 k->headerline = 0; /* restart the header line counter */ 3085 3086 /* switch to http2 now. The bytes after response headers 3087 are also processed here, otherwise they are lost. */ 3088 result = Curl_http2_switched(conn, k->str, *nread); 3089 if(result) 3090 return result; 3091 *nread = 0; 3092 } 3093 else { 3094 /* Switching to another protocol (e.g. WebSocket) */ 3095 k->header = FALSE; /* no more header to parse! */ 3096 } 3097 break; 3098 default: 3099 /* the status code 1xx indicates a provisional response, so 3100 we'll get another set of headers */ 3101 k->header = TRUE; 3102 k->headerline = 0; /* restart the header line counter */ 3103 break; 3104 } 3105 } 3106 else { 3107 k->header = FALSE; /* no more header to parse! */ 3108 3109 if((k->size == -1) && !k->chunk && !conn->bits.close && 3110 (conn->httpversion == 11) && 3111 !(conn->handler->protocol & CURLPROTO_RTSP) && 3112 data->set.httpreq != HTTPREQ_HEAD) { 3113 /* On HTTP 1.1, when connection is not to get closed, but no 3114 Content-Length nor Transfer-Encoding chunked have been 3115 received, according to RFC2616 section 4.4 point 5, we 3116 assume that the server will close the connection to 3117 signal the end of the document. */ 3118 infof(data, "no chunk, no close, no size. Assume close to " 3119 "signal end\n"); 3120 streamclose(conn, "HTTP: No end-of-message indicator"); 3121 } 3122 } 3123 3124 /* At this point we have some idea about the fate of the connection. 3125 If we are closing the connection it may result auth failure. */ 3126 #if defined(USE_NTLM) 3127 if(conn->bits.close && 3128 (((data->req.httpcode == 401) && 3129 (conn->ntlm.state == NTLMSTATE_TYPE2)) || 3130 ((data->req.httpcode == 407) && 3131 (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) { 3132 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n"); 3133 data->state.authproblem = TRUE; 3134 } 3135 #endif 3136 3137 /* 3138 * When all the headers have been parsed, see if we should give 3139 * up and return an error. 3140 */ 3141 if(http_should_fail(conn)) { 3142 failf(data, "The requested URL returned error: %d", 3143 k->httpcode); 3144 return CURLE_HTTP_RETURNED_ERROR; 3145 } 3146 3147 /* now, only output this if the header AND body are requested: 3148 */ 3149 writetype = CLIENTWRITE_HEADER; 3150 if(data->set.include_header) 3151 writetype |= CLIENTWRITE_BODY; 3152 3153 headerlen = k->p - data->state.headerbuff; 3154 3155 result = Curl_client_write(conn, writetype, 3156 data->state.headerbuff, 3157 headerlen); 3158 if(result) 3159 return result; 3160 3161 data->info.header_size += (long)headerlen; 3162 data->req.headerbytecount += (long)headerlen; 3163 3164 data->req.deductheadercount = 3165 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0; 3166 3167 /* Curl_http_auth_act() checks what authentication methods 3168 * that are available and decides which one (if any) to 3169 * use. It will set 'newurl' if an auth method was picked. */ 3170 result = Curl_http_auth_act(conn); 3171 3172 if(result) 3173 return result; 3174 3175 if(k->httpcode >= 300) { 3176 if((!conn->bits.authneg) && !conn->bits.close && 3177 !conn->bits.rewindaftersend) { 3178 /* 3179 * General treatment of errors when about to send data. Including : 3180 * "417 Expectation Failed", while waiting for 100-continue. 3181 * 3182 * The check for close above is done simply because of something 3183 * else has already deemed the connection to get closed then 3184 * something else should've considered the big picture and we 3185 * avoid this check. 3186 * 3187 * rewindaftersend indicates that something has told libcurl to 3188 * continue sending even if it gets discarded 3189 */ 3190 3191 switch(data->set.httpreq) { 3192 case HTTPREQ_PUT: 3193 case HTTPREQ_POST: 3194 case HTTPREQ_POST_FORM: 3195 case HTTPREQ_POST_MIME: 3196 /* We got an error response. If this happened before the whole 3197 * request body has been sent we stop sending and mark the 3198 * connection for closure after we've read the entire response. 3199 */ 3200 Curl_expire_done(data, EXPIRE_100_TIMEOUT); 3201 if(!k->upload_done) { 3202 if(data->set.http_keep_sending_on_error) { 3203 infof(data, "HTTP error before end of send, keep sending\n"); 3204 if(k->exp100 > EXP100_SEND_DATA) { 3205 k->exp100 = EXP100_SEND_DATA; 3206 k->keepon |= KEEP_SEND; 3207 } 3208 } 3209 else { 3210 infof(data, "HTTP error before end of send, stop sending\n"); 3211 streamclose(conn, "Stop sending data before everything sent"); 3212 k->upload_done = TRUE; 3213 k->keepon &= ~KEEP_SEND; /* don't send */ 3214 if(data->state.expect100header) 3215 k->exp100 = EXP100_FAILED; 3216 } 3217 } 3218 break; 3219 3220 default: /* default label present to avoid compiler warnings */ 3221 break; 3222 } 3223 } 3224 3225 if(conn->bits.rewindaftersend) { 3226 /* We rewind after a complete send, so thus we continue 3227 sending now */ 3228 infof(data, "Keep sending data to get tossed away!\n"); 3229 k->keepon |= KEEP_SEND; 3230 } 3231 } 3232 3233 if(!k->header) { 3234 /* 3235 * really end-of-headers. 3236 * 3237 * If we requested a "no body", this is a good time to get 3238 * out and return home. 3239 */ 3240 if(data->set.opt_no_body) 3241 *stop_reading = TRUE; 3242 #ifndef CURL_DISABLE_RTSP 3243 else if((conn->handler->protocol & CURLPROTO_RTSP) && 3244 (data->set.rtspreq == RTSPREQ_DESCRIBE) && 3245 (k->size <= -1)) 3246 /* Respect section 4.4 of rfc2326: If the Content-Length header is 3247 absent, a length 0 must be assumed. It will prevent libcurl from 3248 hanging on DESCRIBE request that got refused for whatever 3249 reason */ 3250 *stop_reading = TRUE; 3251 #endif 3252 else { 3253 /* If we know the expected size of this document, we set the 3254 maximum download size to the size of the expected 3255 document or else, we won't know when to stop reading! 3256 3257 Note that we set the download maximum even if we read a 3258 "Connection: close" header, to make sure that 3259 "Content-Length: 0" still prevents us from attempting to 3260 read the (missing) response-body. 3261 */ 3262 /* According to RFC2616 section 4.4, we MUST ignore 3263 Content-Length: headers if we are now receiving data 3264 using chunked Transfer-Encoding. 3265 */ 3266 if(k->chunk) 3267 k->maxdownload = k->size = -1; 3268 } 3269 if(-1 != k->size) { 3270 /* We do this operation even if no_body is true, since this 3271 data might be retrieved later with curl_easy_getinfo() 3272 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */ 3273 3274 Curl_pgrsSetDownloadSize(data, k->size); 3275 k->maxdownload = k->size; 3276 } 3277 3278 /* If max download size is *zero* (nothing) we already have 3279 nothing and can safely return ok now! But for HTTP/2, we'd 3280 like to call http2_handle_stream_close to properly close a 3281 stream. In order to do this, we keep reading until we 3282 close the stream. */ 3283 if(0 == k->maxdownload 3284 #if defined(USE_NGHTTP2) 3285 && !((conn->handler->protocol & PROTO_FAMILY_HTTP) && 3286 conn->httpversion == 20) 3287 #endif 3288 ) 3289 *stop_reading = TRUE; 3290 3291 if(*stop_reading) { 3292 /* we make sure that this socket isn't read more now */ 3293 k->keepon &= ~KEEP_RECV; 3294 } 3295 3296 if(data->set.verbose) 3297 Curl_debug(data, CURLINFO_HEADER_IN, 3298 k->str_start, headerlen, conn); 3299 break; /* exit header line loop */ 3300 } 3301 3302 /* We continue reading headers, so reset the line-based 3303 header parsing variables hbufp && hbuflen */ 3304 k->hbufp = data->state.headerbuff; 3305 k->hbuflen = 0; 3306 continue; 3307 } 3308 3309 /* 3310 * Checks for special headers coming up. 3311 */ 3312 3313 if(!k->headerline++) { 3314 /* This is the first header, it MUST be the error code line 3315 or else we consider this to be the body right away! */ 3316 int httpversion_major; 3317 int rtspversion_major; 3318 int nc = 0; 3319 #ifdef CURL_DOES_CONVERSIONS 3320 #define HEADER1 scratch 3321 #define SCRATCHSIZE 21 3322 CURLcode res; 3323 char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */ 3324 /* We can't really convert this yet because we 3325 don't know if it's the 1st header line or the body. 3326 So we do a partial conversion into a scratch area, 3327 leaving the data at k->p as-is. 3328 */ 3329 strncpy(&scratch[0], k->p, SCRATCHSIZE); 3330 scratch[SCRATCHSIZE] = 0; /* null terminate */ 3331 res = Curl_convert_from_network(data, 3332 &scratch[0], 3333 SCRATCHSIZE); 3334 if(res) 3335 /* Curl_convert_from_network calls failf if unsuccessful */ 3336 return res; 3337 #else 3338 #define HEADER1 k->p /* no conversion needed, just use k->p */ 3339 #endif /* CURL_DOES_CONVERSIONS */ 3340 3341 if(conn->handler->protocol & PROTO_FAMILY_HTTP) { 3342 /* 3343 * https://tools.ietf.org/html/rfc7230#section-3.1.2 3344 * 3345 * The response code is always a three-digit number in HTTP as the spec 3346 * says. We try to allow any number here, but we cannot make 3347 * guarantees on future behaviors since it isn't within the protocol. 3348 */ 3349 char separator; 3350 nc = sscanf(HEADER1, 3351 " HTTP/%1d.%1d%c%3d", 3352 &httpversion_major, 3353 &conn->httpversion, 3354 &separator, 3355 &k->httpcode); 3356 3357 if(nc == 1 && httpversion_major == 2 && 3358 1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) { 3359 conn->httpversion = 0; 3360 nc = 4; 3361 separator = ' '; 3362 } 3363 3364 if((nc == 4) && (' ' == separator)) { 3365 conn->httpversion += 10 * httpversion_major; 3366 3367 if(k->upgr101 == UPGR101_RECEIVED) { 3368 /* supposedly upgraded to http2 now */ 3369 if(conn->httpversion != 20) 3370 infof(data, "Lying server, not serving HTTP/2\n"); 3371 } 3372 } 3373 else if(!nc) { 3374 /* this is the real world, not a Nirvana 3375 NCSA 1.5.x returns this crap when asked for HTTP/1.1 3376 */ 3377 nc = sscanf(HEADER1, " HTTP %3d", &k->httpcode); 3378 conn->httpversion = 10; 3379 3380 /* If user has set option HTTP200ALIASES, 3381 compare header line against list of aliases 3382 */ 3383 if(!nc) { 3384 if(checkhttpprefix(data, k->p)) { 3385 nc = 1; 3386 k->httpcode = 200; 3387 conn->httpversion = 10; 3388 } 3389 } 3390 } 3391 else { 3392 failf(data, "Unsupported HTTP version in response\n"); 3393 return CURLE_UNSUPPORTED_PROTOCOL; 3394 } 3395 } 3396 else if(conn->handler->protocol & CURLPROTO_RTSP) { 3397 char separator; 3398 nc = sscanf(HEADER1, 3399 " RTSP/%1d.%1d%c%3d", 3400 &rtspversion_major, 3401 &conn->rtspversion, 3402 &separator, 3403 &k->httpcode); 3404 if((nc == 4) && (' ' == separator)) { 3405 conn->rtspversion += 10 * rtspversion_major; 3406 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */ 3407 } 3408 else { 3409 /* TODO: do we care about the other cases here? */ 3410 nc = 0; 3411 } 3412 } 3413 3414 if(nc) { 3415 data->info.httpcode = k->httpcode; 3416 3417 data->info.httpversion = conn->httpversion; 3418 if(!data->state.httpversion || 3419 data->state.httpversion > conn->httpversion) 3420 /* store the lowest server version we encounter */ 3421 data->state.httpversion = conn->httpversion; 3422 3423 /* 3424 * This code executes as part of processing the header. As a 3425 * result, it's not totally clear how to interpret the 3426 * response code yet as that depends on what other headers may 3427 * be present. 401 and 407 may be errors, but may be OK 3428 * depending on how authentication is working. Other codes 3429 * are definitely errors, so give up here. 3430 */ 3431 if(data->set.http_fail_on_error && (k->httpcode >= 400) && 3432 ((k->httpcode != 401) || !conn->bits.user_passwd) && 3433 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) { 3434 3435 if(data->state.resume_from && 3436 (data->set.httpreq == HTTPREQ_GET) && 3437 (k->httpcode == 416)) { 3438 /* "Requested Range Not Satisfiable", just proceed and 3439 pretend this is no error */ 3440 } 3441 else { 3442 /* serious error, go home! */ 3443 print_http_error(data); 3444 return CURLE_HTTP_RETURNED_ERROR; 3445 } 3446 } 3447 3448 if(conn->httpversion == 10) { 3449 /* Default action for HTTP/1.0 must be to close, unless 3450 we get one of those fancy headers that tell us the 3451 server keeps it open for us! */ 3452 infof(data, "HTTP 1.0, assume close after body\n"); 3453 connclose(conn, "HTTP/1.0 close after body"); 3454 } 3455 else if(conn->httpversion == 20 || 3456 (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) { 3457 DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n")); 3458 3459 /* HTTP/2 cannot blacklist multiplexing since it is a core 3460 functionality of the protocol */ 3461 conn->bundle->multiuse = BUNDLE_MULTIPLEX; 3462 } 3463 else if(conn->httpversion >= 11 && 3464 !conn->bits.close) { 3465 /* If HTTP version is >= 1.1 and connection is persistent 3466 server supports pipelining. */ 3467 DEBUGF(infof(data, 3468 "HTTP 1.1 or later with persistent connection, " 3469 "pipelining supported\n")); 3470 /* Activate pipelining if needed */ 3471 if(conn->bundle) { 3472 if(!Curl_pipeline_site_blacklisted(data, conn)) 3473 conn->bundle->multiuse = BUNDLE_PIPELINING; 3474 } 3475 } 3476 3477 switch(k->httpcode) { 3478 case 204: 3479 /* (quote from RFC2616, section 10.2.5): The server has 3480 * fulfilled the request but does not need to return an 3481 * entity-body ... The 204 response MUST NOT include a 3482 * message-body, and thus is always terminated by the first 3483 * empty line after the header fields. */ 3484 /* FALLTHROUGH */ 3485 case 304: 3486 /* (quote from RFC2616, section 10.3.5): The 304 response 3487 * MUST NOT contain a message-body, and thus is always 3488 * terminated by the first empty line after the header 3489 * fields. */ 3490 if(data->set.timecondition) 3491 data->info.timecond = TRUE; 3492 k->size = 0; 3493 k->maxdownload = 0; 3494 k->ignorecl = TRUE; /* ignore Content-Length headers */ 3495 break; 3496 default: 3497 /* nothing */ 3498 break; 3499 } 3500 } 3501 else { 3502 k->header = FALSE; /* this is not a header line */ 3503 break; 3504 } 3505 } 3506 3507 result = Curl_convert_from_network(data, k->p, strlen(k->p)); 3508 /* Curl_convert_from_network calls failf if unsuccessful */ 3509 if(result) 3510 return result; 3511 3512 /* Check for Content-Length: header lines to get size */ 3513 if(!k->ignorecl && !data->set.ignorecl && 3514 checkprefix("Content-Length:", k->p)) { 3515 curl_off_t contentlength; 3516 CURLofft offt = curlx_strtoofft(k->p + 15, NULL, 10, &contentlength); 3517 3518 if(offt == CURL_OFFT_OK) { 3519 if(data->set.max_filesize && 3520 contentlength > data->set.max_filesize) { 3521 failf(data, "Maximum file size exceeded"); 3522 return CURLE_FILESIZE_EXCEEDED; 3523 } 3524 k->size = contentlength; 3525 k->maxdownload = k->size; 3526 /* we set the progress download size already at this point 3527 just to make it easier for apps/callbacks to extract this 3528 info as soon as possible */ 3529 Curl_pgrsSetDownloadSize(data, k->size); 3530 } 3531 else if(offt == CURL_OFFT_FLOW) { 3532 /* out of range */ 3533 if(data->set.max_filesize) { 3534 failf(data, "Maximum file size exceeded"); 3535 return CURLE_FILESIZE_EXCEEDED; 3536 } 3537 streamclose(conn, "overflow content-length"); 3538 infof(data, "Overflow Content-Length: value!\n"); 3539 } 3540 else { 3541 /* negative or just rubbish - bad HTTP */ 3542 failf(data, "Invalid Content-Length: value"); 3543 return CURLE_WEIRD_SERVER_REPLY; 3544 } 3545 } 3546 /* check for Content-Type: header lines to get the MIME-type */ 3547 else if(checkprefix("Content-Type:", k->p)) { 3548 char *contenttype = Curl_copy_header_value(k->p); 3549 if(!contenttype) 3550 return CURLE_OUT_OF_MEMORY; 3551 if(!*contenttype) 3552 /* ignore empty data */ 3553 free(contenttype); 3554 else { 3555 Curl_safefree(data->info.contenttype); 3556 data->info.contenttype = contenttype; 3557 } 3558 } 3559 else if(checkprefix("Server:", k->p)) { 3560 if(conn->httpversion < 20) { 3561 /* only do this for non-h2 servers */ 3562 char *server_name = Curl_copy_header_value(k->p); 3563 3564 /* Turn off pipelining if the server version is blacklisted */ 3565 if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) { 3566 if(Curl_pipeline_server_blacklisted(data, server_name)) 3567 conn->bundle->multiuse = BUNDLE_NO_MULTIUSE; 3568 } 3569 free(server_name); 3570 } 3571 } 3572 else if((conn->httpversion == 10) && 3573 conn->bits.httpproxy && 3574 Curl_compareheader(k->p, 3575 "Proxy-Connection:", "keep-alive")) { 3576 /* 3577 * When a HTTP/1.0 reply comes when using a proxy, the 3578 * 'Proxy-Connection: keep-alive' line tells us the 3579 * connection will be kept alive for our pleasure. 3580 * Default action for 1.0 is to close. 3581 */ 3582 connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */ 3583 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n"); 3584 } 3585 else if((conn->httpversion == 11) && 3586 conn->bits.httpproxy && 3587 Curl_compareheader(k->p, 3588 "Proxy-Connection:", "close")) { 3589 /* 3590 * We get a HTTP/1.1 response from a proxy and it says it'll 3591 * close down after this transfer. 3592 */ 3593 connclose(conn, "Proxy-Connection: asked to close after done"); 3594 infof(data, "HTTP/1.1 proxy connection set close!\n"); 3595 } 3596 else if((conn->httpversion == 10) && 3597 Curl_compareheader(k->p, "Connection:", "keep-alive")) { 3598 /* 3599 * A HTTP/1.0 reply with the 'Connection: keep-alive' line 3600 * tells us the connection will be kept alive for our 3601 * pleasure. Default action for 1.0 is to close. 3602 * 3603 * [RFC2068, section 19.7.1] */ 3604 connkeep(conn, "Connection keep-alive"); 3605 infof(data, "HTTP/1.0 connection set to keep alive!\n"); 3606 } 3607 else if(Curl_compareheader(k->p, "Connection:", "close")) { 3608 /* 3609 * [RFC 2616, section 8.1.2.1] 3610 * "Connection: close" is HTTP/1.1 language and means that 3611 * the connection will close when this request has been 3612 * served. 3613 */ 3614 streamclose(conn, "Connection: close used"); 3615 } 3616 else if(checkprefix("Transfer-Encoding:", k->p)) { 3617 /* One or more encodings. We check for chunked and/or a compression 3618 algorithm. */ 3619 /* 3620 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding 3621 * means that the server will send a series of "chunks". Each 3622 * chunk starts with line with info (including size of the 3623 * coming block) (terminated with CRLF), then a block of data 3624 * with the previously mentioned size. There can be any amount 3625 * of chunks, and a chunk-data set to zero signals the 3626 * end-of-chunks. */ 3627 3628 result = Curl_build_unencoding_stack(conn, k->p + 18, TRUE); 3629 if(result) 3630 return result; 3631 } 3632 else if(checkprefix("Content-Encoding:", k->p) && 3633 data->set.str[STRING_ENCODING]) { 3634 /* 3635 * Process Content-Encoding. Look for the values: identity, 3636 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and 3637 * x-compress are the same as gzip and compress. (Sec 3.5 RFC 3638 * 2616). zlib cannot handle compress. However, errors are 3639 * handled further down when the response body is processed 3640 */ 3641 result = Curl_build_unencoding_stack(conn, k->p + 17, FALSE); 3642 if(result) 3643 return result; 3644 } 3645 else if(checkprefix("Content-Range:", k->p)) { 3646 /* Content-Range: bytes [num]- 3647 Content-Range: bytes: [num]- 3648 Content-Range: [num]- 3649 Content-Range: [asterisk]/[total] 3650 3651 The second format was added since Sun's webserver 3652 JavaWebServer/1.1.1 obviously sends the header this way! 3653 The third added since some servers use that! 3654 The forth means the requested range was unsatisfied. 3655 */ 3656 3657 char *ptr = k->p + 14; 3658 3659 /* Move forward until first digit or asterisk */ 3660 while(*ptr && !ISDIGIT(*ptr) && *ptr != '*') 3661 ptr++; 3662 3663 /* if it truly stopped on a digit */ 3664 if(ISDIGIT(*ptr)) { 3665 if(!curlx_strtoofft(ptr, NULL, 10, &k->offset)) { 3666 if(data->state.resume_from == k->offset) 3667 /* we asked for a resume and we got it */ 3668 k->content_range = TRUE; 3669 } 3670 } 3671 else 3672 data->state.resume_from = 0; /* get everything */ 3673 } 3674 #if !defined(CURL_DISABLE_COOKIES) 3675 else if(data->cookies && 3676 checkprefix("Set-Cookie:", k->p)) { 3677 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, 3678 CURL_LOCK_ACCESS_SINGLE); 3679 Curl_cookie_add(data, 3680 data->cookies, TRUE, k->p + 11, 3681 /* If there is a custom-set Host: name, use it 3682 here, or else use real peer host name. */ 3683 conn->allocptr.cookiehost? 3684 conn->allocptr.cookiehost:conn->host.name, 3685 data->state.path); 3686 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); 3687 } 3688 #endif 3689 else if(checkprefix("Last-Modified:", k->p) && 3690 (data->set.timecondition || data->set.get_filetime) ) { 3691 time_t secs = time(NULL); 3692 k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"), 3693 &secs); 3694 if(data->set.get_filetime) 3695 data->info.filetime = (long)k->timeofdoc; 3696 } 3697 else if((checkprefix("WWW-Authenticate:", k->p) && 3698 (401 == k->httpcode)) || 3699 (checkprefix("Proxy-authenticate:", k->p) && 3700 (407 == k->httpcode))) { 3701 3702 bool proxy = (k->httpcode == 407) ? TRUE : FALSE; 3703 char *auth = Curl_copy_header_value(k->p); 3704 if(!auth) 3705 return CURLE_OUT_OF_MEMORY; 3706 3707 result = Curl_http_input_auth(conn, proxy, auth); 3708 3709 free(auth); 3710 3711 if(result) 3712 return result; 3713 } 3714 else if((k->httpcode >= 300 && k->httpcode < 400) && 3715 checkprefix("Location:", k->p) && 3716 !data->req.location) { 3717 /* this is the URL that the server advises us to use instead */ 3718 char *location = Curl_copy_header_value(k->p); 3719 if(!location) 3720 return CURLE_OUT_OF_MEMORY; 3721 if(!*location) 3722 /* ignore empty data */ 3723 free(location); 3724 else { 3725 data->req.location = location; 3726 3727 if(data->set.http_follow_location) { 3728 DEBUGASSERT(!data->req.newurl); 3729 data->req.newurl = strdup(data->req.location); /* clone */ 3730 if(!data->req.newurl) 3731 return CURLE_OUT_OF_MEMORY; 3732 3733 /* some cases of POST and PUT etc needs to rewind the data 3734 stream at this point */ 3735 result = http_perhapsrewind(conn); 3736 if(result) 3737 return result; 3738 } 3739 } 3740 } 3741 else if(conn->handler->protocol & CURLPROTO_RTSP) { 3742 result = Curl_rtsp_parseheader(conn, k->p); 3743 if(result) 3744 return result; 3745 } 3746 3747 /* 3748 * End of header-checks. Write them to the client. 3749 */ 3750 3751 writetype = CLIENTWRITE_HEADER; 3752 if(data->set.include_header) 3753 writetype |= CLIENTWRITE_BODY; 3754 3755 if(data->set.verbose) 3756 Curl_debug(data, CURLINFO_HEADER_IN, 3757 k->p, (size_t)k->hbuflen, conn); 3758 3759 result = Curl_client_write(conn, writetype, k->p, k->hbuflen); 3760 if(result) 3761 return result; 3762 3763 data->info.header_size += (long)k->hbuflen; 3764 data->req.headerbytecount += (long)k->hbuflen; 3765 3766 /* reset hbufp pointer && hbuflen */ 3767 k->hbufp = data->state.headerbuff; 3768 k->hbuflen = 0; 3769 } 3770 while(*k->str); /* header line within buffer */ 3771 3772 /* We might have reached the end of the header part here, but 3773 there might be a non-header part left in the end of the read 3774 buffer. */ 3775 3776 return CURLE_OK; 3777 } 3778 3779 #endif /* CURL_DISABLE_HTTP */ 3780