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