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