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