1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
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.
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.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #ifndef CURL_DISABLE_HTTP
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
34 #ifdef HAVE_ARPA_INET_H
35 #include <arpa/inet.h>
40 #ifdef HAVE_SYS_IOCTL_H
41 #include <sys/ioctl.h>
44 #ifdef HAVE_SYS_PARAM_H
45 #include <sys/param.h>
49 #include <curl/curl.h>
54 #include "curl_base64.h"
58 #include "http_digest.h"
59 #include "curl_ntlm.h"
60 #include "curl_ntlm_wb.h"
61 #include "http_negotiate.h"
66 #include "curl_memory.h"
68 #include "parsedate.h" /* for the week day and month names */
69 #include "strtoofft.h"
72 #include "content_encoding.h"
73 #include "http_proxy.h"
75 #include "non-ascii.h"
79 #define _MPRINTF_REPLACE /* use our functions only */
80 #include <curl/mprintf.h>
82 /* The last #include file should be: */
86 * Forward declarations.
89 static int http_getsock_do(struct connectdata *conn,
92 static int http_should_fail(struct connectdata *conn);
95 static CURLcode https_connecting(struct connectdata *conn, bool *done);
96 static int https_getsock(struct connectdata *conn,
100 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
104 * HTTP handler interface.
106 const struct Curl_handler Curl_handler_http = {
108 ZERO_NULL, /* setup_connection */
109 Curl_http, /* do_it */
110 Curl_http_done, /* done */
111 ZERO_NULL, /* do_more */
112 Curl_http_connect, /* connect_it */
113 ZERO_NULL, /* connecting */
114 ZERO_NULL, /* doing */
115 ZERO_NULL, /* proto_getsock */
116 http_getsock_do, /* doing_getsock */
117 ZERO_NULL, /* domore_getsock */
118 ZERO_NULL, /* perform_getsock */
119 ZERO_NULL, /* disconnect */
120 ZERO_NULL, /* readwrite */
121 PORT_HTTP, /* defport */
122 CURLPROTO_HTTP, /* protocol */
123 PROTOPT_NONE /* flags */
128 * HTTPS handler interface.
130 const struct Curl_handler Curl_handler_https = {
131 "HTTPS", /* 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 https_connecting, /* connecting */
138 ZERO_NULL, /* doing */
139 https_getsock, /* proto_getsock */
140 http_getsock_do, /* doing_getsock */
141 ZERO_NULL, /* domore_getsock */
142 ZERO_NULL, /* perform_getsock */
143 ZERO_NULL, /* disconnect */
144 ZERO_NULL, /* readwrite */
145 PORT_HTTPS, /* defport */
146 CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
147 PROTOPT_SSL /* flags */
153 * checkheaders() checks the linked list of custom HTTP headers for a
154 * particular header (prefix).
156 * Returns a pointer to the first matching header or NULL if none matched.
158 char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader)
160 struct curl_slist *head;
161 size_t thislen = strlen(thisheader);
163 for(head = data->set.headers; head; head=head->next) {
164 if(Curl_raw_nequal(head->data, thisheader, thislen))
171 * Strip off leading and trailing whitespace from the value in the
172 * given HTTP header line and return a strdupped copy. Returns NULL in
173 * case of allocation failure. Returns an empty string if the header value
174 * consists entirely of whitespace.
176 static char *copy_header_value(const char *h)
185 /* Find the end of the header name */
186 while(*h && (*h != ':'))
190 /* Skip over colon */
193 /* Find the first non-space letter */
195 while(*start && ISSPACE(*start))
198 /* data is in the host encoding so
199 use '\r' and '\n' instead of 0x0d and 0x0a */
200 end = strchr(start, '\r');
202 end = strchr(start, '\n');
204 end = strchr(start, '\0');
208 /* skip all trailing space letters */
209 while((end > start) && ISSPACE(*end))
212 /* get length of the type */
215 value = malloc(len + 1);
219 memcpy(value, start, len);
220 value[len] = 0; /* zero terminate */
226 * http_output_basic() sets up an Authorization: header (or the proxy version)
227 * for HTTP Basic authentication.
231 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
234 char *authorization = NULL;
235 struct SessionHandle *data = conn->data;
242 userp = &conn->allocptr.proxyuserpwd;
243 user = conn->proxyuser;
244 pwd = conn->proxypasswd;
247 userp = &conn->allocptr.userpwd;
252 snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
254 error = Curl_base64_encode(data,
255 data->state.buffer, strlen(data->state.buffer),
256 &authorization, &size);
261 return CURLE_REMOTE_ACCESS_DENIED;
263 Curl_safefree(*userp);
264 *userp = aprintf("%sAuthorization: Basic %s\r\n",
269 return CURLE_OUT_OF_MEMORY;
274 /* pickoneauth() selects the most favourable authentication method from the
275 * ones available and the ones we want.
277 * return TRUE if one was picked
279 static bool pickoneauth(struct auth *pick)
282 /* only deal with authentication we want */
283 unsigned long avail = pick->avail & pick->want;
286 /* The order of these checks is highly relevant, as this will be the order
287 of preference in case of the existence of multiple accepted types. */
288 if(avail & CURLAUTH_GSSNEGOTIATE)
289 pick->picked = CURLAUTH_GSSNEGOTIATE;
290 else if(avail & CURLAUTH_DIGEST)
291 pick->picked = CURLAUTH_DIGEST;
292 else if(avail & CURLAUTH_NTLM)
293 pick->picked = CURLAUTH_NTLM;
294 else if(avail & CURLAUTH_NTLM_WB)
295 pick->picked = CURLAUTH_NTLM_WB;
296 else if(avail & CURLAUTH_BASIC)
297 pick->picked = CURLAUTH_BASIC;
299 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
302 pick->avail = CURLAUTH_NONE; /* clear it here */
308 * Curl_http_perhapsrewind()
310 * If we are doing POST or PUT {
311 * If we have more data to send {
312 * If we are doing NTLM {
313 * Keep sending since we must not disconnect
316 * If there is more than just a little data left to send, close
317 * the current connection by force.
320 * If we have sent any data {
321 * If we don't have track of all the data {
322 * call app to tell it to rewind
325 * rewind internally so that the operation can restart fine
330 static CURLcode http_perhapsrewind(struct connectdata *conn)
332 struct SessionHandle *data = conn->data;
333 struct HTTP *http = data->state.proto.http;
334 curl_off_t bytessent;
335 curl_off_t expectsend = -1; /* default is unknown */
338 /* If this is still NULL, we have not reach very far and we can safely
339 skip this rewinding stuff */
342 switch(data->set.httpreq) {
350 bytessent = http->writebytecount;
352 if(conn->bits.authneg)
353 /* This is a state where we are known to be negotiating and we don't send
357 /* figure out how much data we are expected to send */
358 switch(data->set.httpreq) {
360 if(data->set.postfieldsize != -1)
361 expectsend = data->set.postfieldsize;
362 else if(data->set.postfields)
363 expectsend = (curl_off_t)strlen(data->set.postfields);
366 if(data->set.infilesize != -1)
367 expectsend = data->set.infilesize;
369 case HTTPREQ_POST_FORM:
370 expectsend = http->postsize;
377 conn->bits.rewindaftersend = FALSE; /* default */
379 if((expectsend == -1) || (expectsend > bytessent)) {
380 /* There is still data left to send */
381 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
382 (data->state.authhost.picked == CURLAUTH_NTLM) ||
383 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
384 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
385 if(((expectsend - bytessent) < 2000) ||
386 (conn->ntlm.state != NTLMSTATE_NONE) ||
387 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
388 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
389 data left to send, keep on sending. */
391 /* rewind data when completely done sending! */
392 if(!conn->bits.authneg) {
393 conn->bits.rewindaftersend = TRUE;
394 infof(data, "Rewind stream after send\n");
400 /* this is already marked to get closed */
403 infof(data, "NTLM send, close instead of sending %" FORMAT_OFF_T
404 " bytes\n", (curl_off_t)(expectsend - bytessent));
407 /* This is not NTLM or many bytes left to send: close
409 conn->bits.close = TRUE;
410 data->req.size = 0; /* don't download any more than 0 bytes */
412 /* There still is data left to send, but this connection is marked for
413 closure so we can safely do the rewind right now */
417 /* we rewind now at once since if we already sent something */
418 return Curl_readrewind(conn);
424 * Curl_http_auth_act() gets called when all HTTP headers have been received
425 * and it checks what authentication methods that are available and decides
426 * which one (if any) to use. It will set 'newurl' if an auth method was
430 CURLcode Curl_http_auth_act(struct connectdata *conn)
432 struct SessionHandle *data = conn->data;
433 bool pickhost = FALSE;
434 bool pickproxy = FALSE;
435 CURLcode code = CURLE_OK;
437 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
438 /* this is a transient response code, ignore */
441 if(data->state.authproblem)
442 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
444 if(conn->bits.user_passwd &&
445 ((data->req.httpcode == 401) ||
446 (conn->bits.authneg && data->req.httpcode < 300))) {
447 pickhost = pickoneauth(&data->state.authhost);
449 data->state.authproblem = TRUE;
451 if(conn->bits.proxy_user_passwd &&
452 ((data->req.httpcode == 407) ||
453 (conn->bits.authneg && data->req.httpcode < 300))) {
454 pickproxy = pickoneauth(&data->state.authproxy);
456 data->state.authproblem = TRUE;
459 if(pickhost || pickproxy) {
460 /* In case this is GSS auth, the newurl field is already allocated so
461 we must make sure to free it before allocating a new one. As figured
462 out in bug #2284386 */
463 Curl_safefree(data->req.newurl);
464 data->req.newurl = strdup(data->change.url); /* clone URL */
465 if(!data->req.newurl)
466 return CURLE_OUT_OF_MEMORY;
468 if((data->set.httpreq != HTTPREQ_GET) &&
469 (data->set.httpreq != HTTPREQ_HEAD) &&
470 !conn->bits.rewindaftersend) {
471 code = http_perhapsrewind(conn);
477 else if((data->req.httpcode < 300) &&
478 (!data->state.authhost.done) &&
479 conn->bits.authneg) {
480 /* no (known) authentication available,
481 authentication is not "done" yet and
482 no authentication seems to be required and
483 we didn't try HEAD or GET */
484 if((data->set.httpreq != HTTPREQ_GET) &&
485 (data->set.httpreq != HTTPREQ_HEAD)) {
486 data->req.newurl = strdup(data->change.url); /* clone URL */
487 if(!data->req.newurl)
488 return CURLE_OUT_OF_MEMORY;
489 data->state.authhost.done = TRUE;
492 if(http_should_fail(conn)) {
493 failf (data, "The requested URL returned error: %d",
495 code = CURLE_HTTP_RETURNED_ERROR;
503 * Output the correct authentication header depending on the auth type
504 * and whether or not it is to a proxy.
507 output_auth_headers(struct connectdata *conn,
508 struct auth *authstatus,
513 struct SessionHandle *data = conn->data;
514 const char *auth=NULL;
515 CURLcode result = CURLE_OK;
516 #ifdef USE_HTTP_NEGOTIATE
517 struct negotiatedata *negdata = proxy?
518 &data->state.proxyneg:&data->state.negotiate;
521 #ifdef CURL_DISABLE_CRYPTO_AUTH
526 #ifdef USE_HTTP_NEGOTIATE
527 negdata->state = GSS_AUTHNONE;
528 if((authstatus->picked == CURLAUTH_GSSNEGOTIATE) &&
529 negdata->context && !GSS_ERROR(negdata->status)) {
530 auth="GSS-Negotiate";
531 result = Curl_output_negotiate(conn, proxy);
534 authstatus->done = TRUE;
535 negdata->state = GSS_AUTHSENT;
540 if(authstatus->picked == CURLAUTH_NTLM) {
542 result = Curl_output_ntlm(conn, proxy);
548 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
549 if(authstatus->picked == CURLAUTH_NTLM_WB) {
551 result = Curl_output_ntlm_wb(conn, proxy);
557 #ifndef CURL_DISABLE_CRYPTO_AUTH
558 if(authstatus->picked == CURLAUTH_DIGEST) {
560 result = Curl_output_digest(conn,
562 (const unsigned char *)request,
563 (const unsigned char *)path);
569 if(authstatus->picked == CURLAUTH_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:"))) {
576 result = http_output_basic(conn, proxy);
580 /* NOTE: this function should set 'done' TRUE, as the other auth
581 functions work that way */
582 authstatus->done = TRUE;
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 = (!authstatus->done) ? TRUE : FALSE;
593 authstatus->multi = FALSE;
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
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
613 Curl_http_output_auth(struct connectdata *conn,
616 bool proxytunnel) /* TRUE if this is the request setting
617 up the proxy tunnel */
619 CURLcode result = CURLE_OK;
620 struct SessionHandle *data = conn->data;
621 struct auth *authhost;
622 struct auth *authproxy;
626 authhost = &data->state.authhost;
627 authproxy = &data->state.authproxy;
629 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
630 conn->bits.user_passwd)
631 /* continue please */ ;
633 authhost->done = TRUE;
634 authproxy->done = TRUE;
635 return CURLE_OK; /* no authentication with no user or password */
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;
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;
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);
661 #endif /* CURL_DISABLE_PROXY */
662 /* we have no proxy so let's pretend we're done authenticating
664 authproxy->done = TRUE;
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 ||
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);
676 authhost->done = TRUE;
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.
688 CURLcode Curl_http_input_auth(struct connectdata *conn,
690 const char *header) /* the first non-space */
693 * This resource requires authentication
695 struct SessionHandle *data = conn->data;
697 unsigned long *availp;
701 if(httpcode == 407) {
702 start = header+strlen("Proxy-authenticate:");
703 availp = &data->info.proxyauthavail;
704 authp = &data->state.authproxy;
707 start = header+strlen("WWW-Authenticate:");
708 availp = &data->info.httpauthavail;
709 authp = &data->state.authhost;
712 /* pass all white spaces */
713 while(*start && ISSPACE(*start))
717 * Here we check if we want the specific single authentication (using ==) and
718 * if we do, we initiate usage of it.
720 * If the provided authentication is wanted as one out of several accepted
721 * types (using &), we OR this authentication type to the authavail
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
734 #ifdef USE_HTTP_NEGOTIATE
735 if(checkprefix("GSS-Negotiate", start) ||
736 checkprefix("Negotiate", start)) {
738 *availp |= CURLAUTH_GSSNEGOTIATE;
739 authp->avail |= CURLAUTH_GSSNEGOTIATE;
741 if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
742 if(data->state.negotiate.state == GSS_AUTHSENT) {
743 /* if we sent GSS authentication in the outgoing request and we get
744 this back, we're in trouble */
745 infof(data, "Authentication problem. Ignoring this.\n");
746 data->state.authproblem = TRUE;
749 neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
751 DEBUGASSERT(!data->req.newurl);
752 data->req.newurl = strdup(data->change.url);
753 if(!data->req.newurl)
754 return CURLE_OUT_OF_MEMORY;
755 data->state.authproblem = FALSE;
756 /* we received GSS auth info and we dealt with it fine */
757 data->state.negotiate.state = GSS_AUTHRECV;
760 data->state.authproblem = TRUE;
767 /* NTLM support requires the SSL crypto libs */
768 if(checkprefix("NTLM", start)) {
769 *availp |= CURLAUTH_NTLM;
770 authp->avail |= CURLAUTH_NTLM;
771 if(authp->picked == CURLAUTH_NTLM ||
772 authp->picked == CURLAUTH_NTLM_WB) {
773 /* NTLM authentication is picked and activated */
775 Curl_input_ntlm(conn, (httpcode == 407)?TRUE:FALSE, start);
776 if(CURLE_OK == ntlm) {
777 data->state.authproblem = FALSE;
778 #ifdef NTLM_WB_ENABLED
779 if(authp->picked == CURLAUTH_NTLM_WB) {
780 *availp &= ~CURLAUTH_NTLM;
781 authp->avail &= ~CURLAUTH_NTLM;
782 *availp |= CURLAUTH_NTLM_WB;
783 authp->avail |= CURLAUTH_NTLM_WB;
785 /* Get the challenge-message which will be passed to
786 * ntlm_auth for generating the type 3 message later */
787 while(*start && ISSPACE(*start))
789 if(checkprefix("NTLM", start)) {
790 start += strlen("NTLM");
791 while(*start && ISSPACE(*start))
794 if((conn->challenge_header = strdup(start)) == NULL)
795 return CURLE_OUT_OF_MEMORY;
801 infof(data, "Authentication problem. Ignoring this.\n");
802 data->state.authproblem = TRUE;
808 #ifndef CURL_DISABLE_CRYPTO_AUTH
809 if(checkprefix("Digest", start)) {
810 if((authp->avail & CURLAUTH_DIGEST) != 0) {
811 infof(data, "Ignoring duplicate digest auth header.\n");
815 *availp |= CURLAUTH_DIGEST;
816 authp->avail |= CURLAUTH_DIGEST;
818 /* We call this function on input Digest headers even if Digest
819 * authentication isn't activated yet, as we need to store the
820 * incoming data from this header in case we are gonna use
822 dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start);
824 if(CURLDIGEST_FINE != dig) {
825 infof(data, "Authentication problem. Ignoring this.\n");
826 data->state.authproblem = TRUE;
832 if(checkprefix("Basic", start)) {
833 *availp |= CURLAUTH_BASIC;
834 authp->avail |= CURLAUTH_BASIC;
835 if(authp->picked == CURLAUTH_BASIC) {
836 /* We asked for Basic authentication but got a 40X back
837 anyway, which basically means our name+password isn't
839 authp->avail = CURLAUTH_NONE;
840 infof(data, "Authentication problem. Ignoring this.\n");
841 data->state.authproblem = TRUE;
845 /* there may be multiple methods on one line, so keep reading */
846 while(*start && *start != ',') /* read up to the next comma */
848 if(*start == ',') /* if we're on a comma, skip it */
850 while(*start && ISSPACE(*start))
857 * http_should_fail() determines whether an HTTP response has gotten us
858 * into an error state or not.
860 * @param conn all information about the current connection
862 * @retval 0 communications should continue
864 * @retval 1 communications should not continue
866 static int http_should_fail(struct connectdata *conn)
868 struct SessionHandle *data;
875 httpcode = data->req.httpcode;
878 ** If we haven't been asked to fail on error,
881 if(!data->set.http_fail_on_error)
885 ** Any code < 400 is never terminal.
890 if(data->state.resume_from &&
891 (data->set.httpreq==HTTPREQ_GET) &&
893 /* "Requested Range Not Satisfiable", just proceed and
894 pretend this is no error */
899 ** Any code >= 400 that's not 401 or 407 is always
902 if((httpcode != 401) &&
907 ** All we have left to deal with is 401 and 407
909 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
912 ** Examine the current authentication state to see if this
913 ** is an error. The idea is for this function to get
914 ** called after processing all the headers in a response
915 ** message. So, if we've been to asked to authenticate a
916 ** particular stage, and we've done it, we're OK. But, if
917 ** we're already completely authenticated, it's not OK to
918 ** get another 401 or 407.
920 ** It is possible for authentication to go stale such that
921 ** the client needs to reauthenticate. Once that info is
922 ** available, use it here.
926 ** Either we're not authenticating, or we're supposed to
927 ** be authenticating something else. This is an error.
929 if((httpcode == 401) && !conn->bits.user_passwd)
931 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
934 return data->state.authproblem;
938 * readmoredata() is a "fread() emulation" to provide POST and/or request
939 * data. It is used when a huge POST is to be made and the entire chunk wasn't
940 * sent in the first send(). This function will then be called from the
941 * transfer.c loop when more data is to be sent to the peer.
943 * Returns the amount of bytes it filled the buffer with.
945 static size_t readmoredata(char *buffer,
950 struct connectdata *conn = (struct connectdata *)userp;
951 struct HTTP *http = conn->data->state.proto.http;
952 size_t fullsize = size * nitems;
954 if(0 == http->postsize)
955 /* nothing to return */
958 /* make sure that a HTTP request is never sent away chunked! */
959 conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
961 if(http->postsize <= (curl_off_t)fullsize) {
962 memcpy(buffer, http->postdata, (size_t)http->postsize);
963 fullsize = (size_t)http->postsize;
965 if(http->backup.postsize) {
966 /* move backup data into focus and continue on that */
967 http->postdata = http->backup.postdata;
968 http->postsize = http->backup.postsize;
969 conn->fread_func = http->backup.fread_func;
970 conn->fread_in = http->backup.fread_in;
972 http->sending++; /* move one step up */
974 http->backup.postsize=0;
982 memcpy(buffer, http->postdata, fullsize);
983 http->postdata += fullsize;
984 http->postsize -= fullsize;
989 /* ------------------------------------------------------------------------- */
990 /* add_buffer functions */
993 * Curl_add_buffer_init() sets up and returns a fine buffer struct
995 Curl_send_buffer *Curl_add_buffer_init(void)
997 return calloc(1, sizeof(Curl_send_buffer));
1001 * Curl_add_buffer_send() sends a header buffer and frees all associated
1002 * memory. Body data may be appended to the header data if desired.
1006 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
1007 struct connectdata *conn,
1009 /* add the number of sent bytes to this
1011 long *bytes_written,
1013 /* how much of the buffer contains body data */
1014 size_t included_body_bytes,
1022 struct HTTP *http = conn->data->state.proto.http;
1024 curl_socket_t sockfd;
1027 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1029 sockfd = conn->sock[socketindex];
1031 /* The looping below is required since we use non-blocking sockets, but due
1032 to the circumstances we will just loop and try again and again etc */
1035 size = in->size_used;
1037 headersize = size - included_body_bytes; /* the initial part that isn't body
1040 DEBUGASSERT(size > included_body_bytes);
1042 res = Curl_convert_to_network(conn->data, ptr, headersize);
1043 /* Curl_convert_to_network calls failf if unsuccessful */
1045 /* conversion failed, free memory and return to the caller */
1052 if(conn->handler->flags & PROTOPT_SSL) {
1053 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1054 when we speak HTTPS, as if only a fraction of it is sent now, this data
1055 needs to fit into the normal read-callback buffer later on and that
1056 buffer is using this size.
1059 sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
1061 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1062 library when we attempt to re-send this buffer. Sending the same data
1063 is not enough, we must use the exact same address. For this reason, we
1064 must copy the data to the uploadbuffer first, since that is the buffer
1065 we will be using if this send is retried later.
1067 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1068 ptr = conn->data->state.uploadbuffer;
1073 res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1075 if(CURLE_OK == res) {
1077 * Note that we may not send the entire chunk at once, and we have a set
1078 * number of data bytes at the end of the big buffer (out of which we may
1079 * only send away a part).
1081 /* how much of the header that was sent */
1082 size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
1083 size_t bodylen = amount - headlen;
1085 if(conn->data->set.verbose) {
1086 /* this data _may_ contain binary stuff */
1087 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1089 /* there was body data sent beyond the initial header part, pass that
1090 on to the debug callback too */
1091 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1092 ptr+headlen, bodylen, conn);
1096 /* since we sent a piece of the body here, up the byte counter for it
1098 http->writebytecount += bodylen;
1100 /* 'amount' can never be a very large value here so typecasting it so a
1101 signed 31 bit value should not cause problems even if ssize_t is
1103 *bytes_written += (long)amount;
1106 if((size_t)amount != size) {
1107 /* The whole request could not be sent in one system call. We must
1108 queue it up and send it later when we get the chance. We must not
1109 loop here and wait until it might work again. */
1113 ptr = in->buffer + amount;
1115 /* backup the currently set pointers */
1116 http->backup.fread_func = conn->fread_func;
1117 http->backup.fread_in = conn->fread_in;
1118 http->backup.postdata = http->postdata;
1119 http->backup.postsize = http->postsize;
1121 /* set the new pointers for the request-sending */
1122 conn->fread_func = (curl_read_callback)readmoredata;
1123 conn->fread_in = (void *)conn;
1124 http->postdata = ptr;
1125 http->postsize = (curl_off_t)size;
1127 http->send_buffer = in;
1128 http->sending = HTTPSEND_REQUEST;
1132 http->sending = HTTPSEND_BODY;
1133 /* the full buffer was sent, clean up and return */
1136 if((size_t)amount != size)
1137 /* We have no continue-send mechanism now, fail. This can only happen
1138 when this function is used from the CONNECT sending function. We
1139 currently (stupidly) assume that the whole request is always sent
1140 away in the first single chunk.
1144 return CURLE_SEND_ERROR;
1146 conn->writechannel_inuse = FALSE;
1158 * add_bufferf() add the formatted input to the buffer.
1160 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1165 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1169 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1173 /* If we failed, we cleanup the whole buffer and return error */
1177 return CURLE_OUT_OF_MEMORY;
1181 * add_buffer() appends a memory chunk to the existing buffer
1183 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1188 if(~size < in->size_used) {
1189 /* If resulting used size of send buffer would wrap size_t, cleanup
1190 the whole buffer and return error. Otherwise the required buffer
1191 size will fit into a single allocatable memory chunk */
1192 Curl_safefree(in->buffer);
1194 return CURLE_OUT_OF_MEMORY;
1198 ((in->size_used + size) > (in->size_max - 1))) {
1200 /* If current buffer size isn't enough to hold the result, use a
1201 buffer size that doubles the required size. If this new size
1202 would wrap size_t, then just use the largest possible one */
1204 if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
1205 (~(size*2) < (in->size_used*2)))
1206 new_size = (size_t)-1;
1208 new_size = (in->size_used+size)*2;
1211 /* we have a buffer, enlarge the existing one */
1212 new_rb = realloc(in->buffer, new_size);
1214 /* create a new buffer */
1215 new_rb = malloc(new_size);
1218 /* If we failed, we cleanup the whole buffer and return error */
1219 Curl_safefree(in->buffer);
1221 return CURLE_OUT_OF_MEMORY;
1224 in->buffer = new_rb;
1225 in->size_max = new_size;
1227 memcpy(&in->buffer[in->size_used], inptr, size);
1229 in->size_used += size;
1234 /* end of the add_buffer functions */
1235 /* ------------------------------------------------------------------------- */
1240 * Curl_compareheader()
1242 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1243 * Pass headers WITH the colon.
1246 Curl_compareheader(const char *headerline, /* line to check */
1247 const char *header, /* header keyword _with_ colon */
1248 const char *content) /* content string to find */
1250 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1251 * by a colon (":") and the field value. Field names are case-insensitive.
1252 * The field value MAY be preceded by any amount of LWS, though a single SP
1255 size_t hlen = strlen(header);
1261 if(!Curl_raw_nequal(headerline, header, hlen))
1262 return FALSE; /* doesn't start with header */
1264 /* pass the header */
1265 start = &headerline[hlen];
1267 /* pass all white spaces */
1268 while(*start && ISSPACE(*start))
1271 /* find the end of the header line */
1272 end = strchr(start, '\r'); /* lines end with CRLF */
1274 /* in case there's a non-standard compliant line here */
1275 end = strchr(start, '\n');
1278 /* hm, there's no line ending here, use the zero byte! */
1279 end = strchr(start, '\0');
1282 len = end-start; /* length of the content part of the input line */
1283 clen = strlen(content); /* length of the word to find */
1285 /* find the content string in the rest of the line */
1286 for(;len>=clen;len--, start++) {
1287 if(Curl_raw_nequal(start, content, clen))
1288 return TRUE; /* match! */
1291 return FALSE; /* no match */
1295 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1296 * the generic Curl_connect().
1298 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1302 /* We default to persistent connections. We set this already in this connect
1303 function to make the re-use checks properly be able to check this bit. */
1304 conn->bits.close = FALSE;
1306 /* the CONNECT procedure might not have been completed */
1307 result = Curl_proxy_connect(conn);
1311 if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1312 /* nothing else to do except wait right now - we're not done here. */
1315 if(conn->given->flags & PROTOPT_SSL) {
1316 /* perform SSL initialization */
1317 result = https_connecting(conn, done);
1327 /* this returns the socket to wait for in the DO and DOING state for the multi
1328 interface and then we're always _sending_ a request and thus we wait for
1329 the single socket to become writable only */
1330 static int http_getsock_do(struct connectdata *conn,
1331 curl_socket_t *socks,
1335 (void)numsocks; /* unused, we trust it to be at least 1 */
1336 socks[0] = conn->sock[FIRSTSOCKET];
1337 return GETSOCK_WRITESOCK(0);
1341 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1344 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1346 /* perform SSL initialization for this socket */
1347 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1349 conn->bits.close = TRUE; /* a failed connection is marked for closure
1350 to prevent (bad) re-use or similar */
1355 #if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
1356 defined(USE_DARWINSSL)
1357 /* This function is for OpenSSL, GnuTLS, darwinssl, and schannel only.
1358 It should be made to query the generic SSL layer instead. */
1359 static int https_getsock(struct connectdata *conn,
1360 curl_socket_t *socks,
1363 if(conn->handler->flags & PROTOPT_SSL) {
1364 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1367 return GETSOCK_BLANK;
1369 if(connssl->connecting_state == ssl_connect_2_writing) {
1371 socks[0] = conn->sock[FIRSTSOCKET];
1372 return GETSOCK_WRITESOCK(0);
1374 else if(connssl->connecting_state == ssl_connect_2_reading) {
1376 socks[0] = conn->sock[FIRSTSOCKET];
1377 return GETSOCK_READSOCK(0);
1384 static int https_getsock(struct connectdata *conn,
1385 curl_socket_t *socks,
1391 return GETSOCK_BLANK;
1393 #endif /* USE_SSL */
1394 #endif /* USE_SSLEAY || USE_GNUTLS || USE_SCHANNEL */
1397 * Curl_http_done() gets called from Curl_done() after a single HTTP request
1398 * has been performed.
1401 CURLcode Curl_http_done(struct connectdata *conn,
1402 CURLcode status, bool premature)
1404 struct SessionHandle *data = conn->data;
1405 struct HTTP *http =data->state.proto.http;
1407 Curl_unencode_cleanup(conn);
1409 /* set the proper values (possibly modified on POST) */
1410 conn->fread_func = data->set.fread_func; /* restore */
1411 conn->fread_in = data->set.in; /* restore */
1412 conn->seek_func = data->set.seek_func; /* restore */
1413 conn->seek_client = data->set.seek_client; /* restore */
1418 if(http->send_buffer) {
1419 Curl_send_buffer *buff = http->send_buffer;
1423 http->send_buffer = NULL; /* clear the pointer */
1426 if(HTTPREQ_POST_FORM == data->set.httpreq) {
1427 data->req.bytecount = http->readbytecount + http->writebytecount;
1429 Curl_formclean(&http->sendit); /* Now free that whole lot */
1431 /* a file being uploaded was left opened, close it! */
1432 fclose(http->form.fp);
1433 http->form.fp = NULL;
1436 else if(HTTPREQ_PUT == data->set.httpreq)
1437 data->req.bytecount = http->readbytecount + http->writebytecount;
1439 if(status != CURLE_OK)
1442 if(!premature && /* this check is pointless when DONE is called before the
1443 entire operation is complete */
1444 !conn->bits.retry &&
1445 ((http->readbytecount +
1446 data->req.headerbytecount -
1447 data->req.deductheadercount)) <= 0) {
1448 /* If this connection isn't simply closed to be retried, AND nothing was
1449 read from the HTTP server (that counts), this can't be right so we
1450 return an error here */
1451 failf(data, "Empty reply from server");
1452 return CURLE_GOT_NOTHING;
1459 /* Determine if we should use HTTP 1.1 for this request. Reasons to avoid it
1460 are if the user specifically requested HTTP 1.0, if the server we are
1461 connected to only supports 1.0, or if any server previously contacted to
1462 handle this request only supports 1.0. */
1463 static bool use_http_1_1(const struct SessionHandle *data,
1464 const struct connectdata *conn)
1466 return ((data->set.httpversion == CURL_HTTP_VERSION_1_1) ||
1467 ((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
1468 ((conn->httpversion == 11) ||
1469 ((conn->httpversion != 10) &&
1470 (data->state.httpversion != 10))))) ? TRUE : FALSE;
1473 /* check and possibly add an Expect: header */
1474 static CURLcode expect100(struct SessionHandle *data,
1475 struct connectdata *conn,
1476 Curl_send_buffer *req_buffer)
1478 CURLcode result = CURLE_OK;
1480 data->state.expect100header = FALSE; /* default to false unless it is set
1482 if(use_http_1_1(data, conn)) {
1483 /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
1484 100-continue to the headers which actually speeds up post operations
1485 (as there is one packet coming back from the web server) */
1486 ptr = Curl_checkheaders(data, "Expect:");
1488 data->state.expect100header =
1489 Curl_compareheader(ptr, "Expect:", "100-continue");
1492 result = Curl_add_bufferf(req_buffer,
1493 "Expect: 100-continue\r\n");
1494 if(result == CURLE_OK)
1495 data->state.expect100header = TRUE;
1501 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1502 Curl_send_buffer *req_buffer)
1505 struct curl_slist *headers=conn->data->set.headers;
1508 ptr = strchr(headers->data, ':');
1510 /* we require a colon for this to be a true header */
1512 ptr++; /* pass the colon */
1513 while(*ptr && ISSPACE(*ptr))
1517 /* only send this if the contents was non-blank */
1519 if(conn->allocptr.host &&
1520 /* a Host: header was sent already, don't pass on any custom Host:
1521 header as that will produce *two* in the same request! */
1522 checkprefix("Host:", headers->data))
1524 else if(conn->data->set.httpreq == HTTPREQ_POST_FORM &&
1525 /* this header (extended by formdata.c) is sent later */
1526 checkprefix("Content-Type:", headers->data))
1528 else if(conn->bits.authneg &&
1529 /* while doing auth neg, don't allow the custom length since
1530 we will force length zero then */
1531 checkprefix("Content-Length", headers->data))
1533 else if(conn->allocptr.te &&
1534 /* when asking for Transfer-Encoding, don't pass on a custom
1536 checkprefix("Connection", headers->data))
1539 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1547 ptr = strchr(headers->data, ';');
1550 ptr++; /* pass the semicolon */
1551 while(*ptr && ISSPACE(*ptr))
1555 /* this may be used for something else in the future */
1558 if(*(--ptr) == ';') {
1561 /* send no-value custom header if terminated by semicolon */
1563 result = Curl_add_bufferf(req_buffer, "%s\r\n",
1571 headers = headers->next;
1576 CURLcode Curl_add_timecondition(struct SessionHandle *data,
1577 Curl_send_buffer *req_buffer)
1579 const struct tm *tm;
1580 char *buf = data->state.buffer;
1581 CURLcode result = CURLE_OK;
1584 result = Curl_gmtime(data->set.timevalue, &keeptime);
1586 failf(data, "Invalid TIMEVALUE");
1591 /* The If-Modified-Since header family should have their times set in
1592 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1593 * represented in Greenwich Mean Time (GMT), without exception. For the
1594 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1595 * Time)." (see page 20 of RFC2616).
1598 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1599 snprintf(buf, BUFSIZE-1,
1600 "%s, %02d %s %4d %02d:%02d:%02d GMT",
1601 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1603 Curl_month[tm->tm_mon],
1609 switch(data->set.timecondition) {
1610 case CURL_TIMECOND_IFMODSINCE:
1612 result = Curl_add_bufferf(req_buffer,
1613 "If-Modified-Since: %s\r\n", buf);
1615 case CURL_TIMECOND_IFUNMODSINCE:
1616 result = Curl_add_bufferf(req_buffer,
1617 "If-Unmodified-Since: %s\r\n", buf);
1619 case CURL_TIMECOND_LASTMOD:
1620 result = Curl_add_bufferf(req_buffer,
1621 "Last-Modified: %s\r\n", buf);
1629 * Curl_http() gets called from the generic Curl_do() function when a HTTP
1630 * request is to be performed. This creates and sends a properly constructed
1633 CURLcode Curl_http(struct connectdata *conn, bool *done)
1635 struct SessionHandle *data=conn->data;
1636 CURLcode result=CURLE_OK;
1638 const char *ppath = data->state.path;
1639 bool paste_ftp_userpwd = FALSE;
1640 char ftp_typecode[sizeof("/;type=?")] = "";
1641 const char *host = conn->host.name;
1642 const char *te = ""; /* transfer-encoding */
1644 const char *request;
1645 Curl_HttpReq httpreq = data->set.httpreq;
1646 char *addcookies = NULL;
1647 curl_off_t included_body = 0;
1648 const char *httpstring;
1649 Curl_send_buffer *req_buffer;
1650 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1651 int seekerr = CURL_SEEKFUNC_OK;
1653 /* Always consider the DO phase done after this function call, even if there
1654 may be parts of the request that is not yet sent, since we can deal with
1655 the rest of the request in the PERFORM phase. */
1658 /* If there already is a protocol-specific struct allocated for this
1659 sessionhandle, deal with it */
1660 Curl_reset_reqproto(conn);
1662 if(!data->state.proto.http) {
1663 /* Only allocate this struct if we don't already have it! */
1665 http = calloc(1, sizeof(struct HTTP));
1667 return CURLE_OUT_OF_MEMORY;
1668 data->state.proto.http = http;
1671 http = data->state.proto.http;
1673 if(!data->state.this_is_a_follow) {
1674 /* this is not a followed location, get the original host name */
1675 if(data->state.first_host)
1676 /* Free to avoid leaking memory on multiple requests*/
1677 free(data->state.first_host);
1679 data->state.first_host = strdup(conn->host.name);
1680 if(!data->state.first_host)
1681 return CURLE_OUT_OF_MEMORY;
1683 http->writebytecount = http->readbytecount = 0;
1685 if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
1687 httpreq = HTTPREQ_PUT;
1690 /* Now set the 'request' pointer to the proper request string */
1691 if(data->set.str[STRING_CUSTOMREQUEST])
1692 request = data->set.str[STRING_CUSTOMREQUEST];
1694 if(data->set.opt_no_body)
1697 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1700 case HTTPREQ_POST_FORM:
1706 default: /* this should never happen */
1717 /* The User-Agent string might have been allocated in url.c already, because
1718 it might have been used in the proxy connect, but if we have got a header
1719 with the user-agent string specified, we erase the previously made string
1721 if(Curl_checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
1722 free(conn->allocptr.uagent);
1723 conn->allocptr.uagent=NULL;
1726 /* setup the authentication headers */
1727 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1731 if((data->state.authhost.multi || data->state.authproxy.multi) &&
1732 (httpreq != HTTPREQ_GET) &&
1733 (httpreq != HTTPREQ_HEAD)) {
1734 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1735 with content-length zero as a "probe". */
1736 conn->bits.authneg = TRUE;
1739 conn->bits.authneg = FALSE;
1741 Curl_safefree(conn->allocptr.ref);
1742 if(data->change.referer && !Curl_checkheaders(data, "Referer:")) {
1743 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1744 if(!conn->allocptr.ref)
1745 return CURLE_OUT_OF_MEMORY;
1748 conn->allocptr.ref = NULL;
1750 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie:"))
1751 addcookies = data->set.str[STRING_COOKIE];
1753 if(!Curl_checkheaders(data, "Accept-Encoding:") &&
1754 data->set.str[STRING_ENCODING]) {
1755 Curl_safefree(conn->allocptr.accept_encoding);
1756 conn->allocptr.accept_encoding =
1757 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1758 if(!conn->allocptr.accept_encoding)
1759 return CURLE_OUT_OF_MEMORY;
1763 /* we only consider transfer-encoding magic if libz support is built-in */
1765 if(!Curl_checkheaders(data, "TE:") && data->set.http_transfer_encoding) {
1766 /* When we are to insert a TE: header in the request, we must also insert
1767 TE in a Connection: header, so we need to merge the custom provided
1768 Connection: header and prevent the original to get sent. Note that if
1769 the user has inserted his/hers own TE: header we don't do this magic
1770 but then assume that the user will handle it all! */
1771 char *cptr = Curl_checkheaders(data, "Connection:");
1772 #define TE_HEADER "TE: gzip\r\n"
1774 Curl_safefree(conn->allocptr.te);
1776 /* Create the (updated) Connection: header */
1777 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1778 strdup("Connection: TE\r\n" TE_HEADER);
1780 if(!conn->allocptr.te)
1781 return CURLE_OUT_OF_MEMORY;
1785 ptr = Curl_checkheaders(data, "Transfer-Encoding:");
1787 /* Some kind of TE is requested, check if 'chunked' is chosen */
1788 data->req.upload_chunky =
1789 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1792 if((conn->handler->protocol&CURLPROTO_HTTP) &&
1794 (data->set.infilesize == -1)) {
1795 if(conn->bits.authneg)
1796 /* don't enable chunked during auth neg */
1798 else if(use_http_1_1(data, conn)) {
1799 /* HTTP, upload, unknown file size and not HTTP 1.0 */
1800 data->req.upload_chunky = TRUE;
1803 failf(data, "Chunky upload is not supported by HTTP 1.0");
1804 return CURLE_UPLOAD_FAILED;
1808 /* else, no chunky upload */
1809 data->req.upload_chunky = FALSE;
1812 if(data->req.upload_chunky)
1813 te = "Transfer-Encoding: chunked\r\n";
1816 Curl_safefree(conn->allocptr.host);
1818 ptr = Curl_checkheaders(data, "Host:");
1819 if(ptr && (!data->state.this_is_a_follow ||
1820 Curl_raw_equal(data->state.first_host, conn->host.name))) {
1821 #if !defined(CURL_DISABLE_COOKIES)
1822 /* If we have a given custom Host: header, we extract the host name in
1823 order to possibly use it for cookie reasons later on. We only allow the
1824 custom Host: header if this is NOT a redirect, as setting Host: in the
1825 redirected request is being out on thin ice. Except if the host name
1826 is the same as the first one! */
1827 char *cookiehost = copy_header_value(ptr);
1829 return CURLE_OUT_OF_MEMORY;
1831 /* ignore empty data */
1834 /* If the host begins with '[', we start searching for the port after
1835 the bracket has been closed */
1836 int startsearch = 0;
1837 if(*cookiehost == '[') {
1838 char *closingbracket;
1839 /* since the 'cookiehost' is an allocated memory area that will be
1840 freed later we cannot simply increment the pointer */
1841 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
1842 closingbracket = strchr(cookiehost, ']');
1844 *closingbracket = 0;
1847 char *colon = strchr(cookiehost + startsearch, ':');
1849 *colon = 0; /* The host must not include an embedded port number */
1851 Curl_safefree(conn->allocptr.cookiehost);
1852 conn->allocptr.cookiehost = cookiehost;
1856 conn->allocptr.host = NULL;
1859 /* When building Host: headers, we must put the host name within
1860 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
1862 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
1863 (conn->remote_port == PORT_HTTPS)) ||
1864 ((conn->given->protocol&CURLPROTO_HTTP) &&
1865 (conn->remote_port == PORT_HTTP)) )
1866 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
1867 the port number in the host string */
1868 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
1869 conn->bits.ipv6_ip?"[":"",
1871 conn->bits.ipv6_ip?"]":"");
1873 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
1874 conn->bits.ipv6_ip?"[":"",
1876 conn->bits.ipv6_ip?"]":"",
1879 if(!conn->allocptr.host)
1880 /* without Host: we can't make a nice request */
1881 return CURLE_OUT_OF_MEMORY;
1884 #ifndef CURL_DISABLE_PROXY
1885 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
1886 /* Using a proxy but does not tunnel through it */
1888 /* The path sent to the proxy is in fact the entire URL. But if the remote
1889 host is a IDN-name, we must make sure that the request we produce only
1890 uses the encoded host name! */
1891 if(conn->host.dispname != conn->host.name) {
1892 char *url = data->change.url;
1893 ptr = strstr(url, conn->host.dispname);
1895 /* This is where the display name starts in the URL, now replace this
1896 part with the encoded name. TODO: This method of replacing the host
1897 name is rather crude as I believe there's a slight risk that the
1898 user has entered a user name or password that contain the host name
1900 size_t currlen = strlen(conn->host.dispname);
1901 size_t newlen = strlen(conn->host.name);
1902 size_t urllen = strlen(url);
1906 newurl = malloc(urllen + newlen - currlen + 1);
1908 /* copy the part before the host name */
1909 memcpy(newurl, url, ptr - url);
1910 /* append the new host name instead of the old */
1911 memcpy(newurl + (ptr - url), conn->host.name, newlen);
1912 /* append the piece after the host name */
1913 memcpy(newurl + newlen + (ptr - url),
1914 ptr + currlen, /* copy the trailing zero byte too */
1915 urllen - (ptr-url) - currlen + 1);
1916 if(data->change.url_alloc) {
1917 Curl_safefree(data->change.url);
1918 data->change.url_alloc = FALSE;
1920 data->change.url = newurl;
1921 data->change.url_alloc = TRUE;
1924 return CURLE_OUT_OF_MEMORY;
1927 ppath = data->change.url;
1928 if(checkprefix("ftp://", ppath)) {
1929 if(data->set.proxy_transfer_mode) {
1930 /* when doing ftp, append ;type=<a|i> if not present */
1931 char *type = strstr(ppath, ";type=");
1932 if(type && type[6] && type[7] == 0) {
1933 switch (Curl_raw_toupper(type[6])) {
1943 char *p = ftp_typecode;
1944 /* avoid sending invalid URLs like ftp://example.com;type=i if the
1945 * user specified ftp://example.com without the slash */
1946 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
1949 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
1950 data->set.prefer_ascii ? 'a' : 'i');
1953 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
1954 paste_ftp_userpwd = TRUE;
1957 #endif /* CURL_DISABLE_PROXY */
1959 if(HTTPREQ_POST_FORM == httpreq) {
1960 /* we must build the whole post sequence first, so that we have a size of
1961 the whole transfer before we start to send it */
1962 result = Curl_getformdata(data, &http->sendit, data->set.httppost,
1963 Curl_checkheaders(data, "Content-Type:"),
1969 http->p_accept = Curl_checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n";
1971 if(( (HTTPREQ_POST == httpreq) ||
1972 (HTTPREQ_POST_FORM == httpreq) ||
1973 (HTTPREQ_PUT == httpreq) ) &&
1974 data->state.resume_from) {
1975 /**********************************************************************
1976 * Resuming upload in HTTP means that we PUT or POST and that we have
1977 * got a resume_from value set. The resume value has already created
1978 * a Range: header that will be passed along. We need to "fast forward"
1979 * the file the given number of bytes and decrease the assume upload
1980 * file size before we continue this venture in the dark lands of HTTP.
1981 *********************************************************************/
1983 if(data->state.resume_from < 0 ) {
1985 * This is meant to get the size of the present remote-file by itself.
1986 * We don't support this now. Bail out!
1988 data->state.resume_from = 0;
1991 if(data->state.resume_from && !data->state.this_is_a_follow) {
1992 /* do we still game? */
1994 /* Now, let's read off the proper amount of bytes from the
1996 if(conn->seek_func) {
1997 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2001 if(seekerr != CURL_SEEKFUNC_OK) {
2002 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2003 failf(data, "Could not seek stream");
2004 return CURLE_READ_ERROR;
2006 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2008 curl_off_t passed=0;
2010 size_t readthisamountnow =
2011 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
2012 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
2014 size_t actuallyread =
2015 data->set.fread_func(data->state.buffer, 1, readthisamountnow,
2018 passed += actuallyread;
2019 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2020 /* this checks for greater-than only to make sure that the
2021 CURL_READFUNC_ABORT return code still aborts */
2022 failf(data, "Could only read %" FORMAT_OFF_T
2023 " bytes from the input",
2025 return CURLE_READ_ERROR;
2027 } while(passed < data->state.resume_from);
2031 /* now, decrease the size of the read */
2032 if(data->set.infilesize>0) {
2033 data->set.infilesize -= data->state.resume_from;
2035 if(data->set.infilesize <= 0) {
2036 failf(data, "File already completely uploaded");
2037 return CURLE_PARTIAL_FILE;
2040 /* we've passed, proceed as normal */
2043 if(data->state.use_range) {
2045 * A range is selected. We use different headers whether we're downloading
2046 * or uploading and we always let customized headers override our internal
2047 * ones if any such are specified.
2049 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2050 !Curl_checkheaders(data, "Range:")) {
2051 /* if a line like this was already allocated, free the previous one */
2052 if(conn->allocptr.rangeline)
2053 free(conn->allocptr.rangeline);
2054 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2057 else if((httpreq != HTTPREQ_GET) &&
2058 !Curl_checkheaders(data, "Content-Range:")) {
2060 /* if a line like this was already allocated, free the previous one */
2061 if(conn->allocptr.rangeline)
2062 free(conn->allocptr.rangeline);
2064 if(data->set.set_resume_from < 0) {
2065 /* Upload resume was asked for, but we don't know the size of the
2066 remote part so we tell the server (and act accordingly) that we
2067 upload the whole file (again) */
2068 conn->allocptr.rangeline =
2069 aprintf("Content-Range: bytes 0-%" FORMAT_OFF_T
2070 "/%" FORMAT_OFF_T "\r\n",
2071 data->set.infilesize - 1, data->set.infilesize);
2074 else if(data->state.resume_from) {
2075 /* This is because "resume" was selected */
2076 curl_off_t total_expected_size=
2077 data->state.resume_from + data->set.infilesize;
2078 conn->allocptr.rangeline =
2079 aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
2080 "/%" FORMAT_OFF_T "\r\n",
2081 data->state.range, total_expected_size-1,
2082 total_expected_size);
2085 /* Range was selected and then we just pass the incoming range and
2086 append total size */
2087 conn->allocptr.rangeline =
2088 aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
2089 data->state.range, data->set.infilesize);
2091 if(!conn->allocptr.rangeline)
2092 return CURLE_OUT_OF_MEMORY;
2096 /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2098 httpstring= use_http_1_1(data, conn)?"1.1":"1.0";
2100 /* initialize a dynamic send-buffer */
2101 req_buffer = Curl_add_buffer_init();
2104 return CURLE_OUT_OF_MEMORY;
2106 /* add the main request stuff */
2107 /* GET/HEAD/POST/PUT */
2108 result = Curl_add_bufferf(req_buffer, "%s ", request);
2113 if(paste_ftp_userpwd)
2114 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2115 conn->user, conn->passwd,
2116 ppath + sizeof("ftp://") - 1);
2118 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2123 Curl_add_bufferf(req_buffer,
2124 "%s" /* ftp typecode (;type=x) */
2125 " HTTP/%s\r\n" /* HTTP version */
2126 "%s" /* proxyuserpwd */
2129 "%s" /* user agent */
2133 "%s" /* accept-encoding */
2135 "%s" /* Proxy-Connection */
2136 "%s",/* transfer-encoding */
2140 conn->allocptr.proxyuserpwd?
2141 conn->allocptr.proxyuserpwd:"",
2142 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2143 (data->state.use_range && conn->allocptr.rangeline)?
2144 conn->allocptr.rangeline:"",
2145 (data->set.str[STRING_USERAGENT] &&
2146 *data->set.str[STRING_USERAGENT] &&
2147 conn->allocptr.uagent)?
2148 conn->allocptr.uagent:"",
2149 (conn->allocptr.host?conn->allocptr.host:""),
2150 http->p_accept?http->p_accept:"",
2151 conn->allocptr.te?conn->allocptr.te:"",
2152 (data->set.str[STRING_ENCODING] &&
2153 *data->set.str[STRING_ENCODING] &&
2154 conn->allocptr.accept_encoding)?
2155 conn->allocptr.accept_encoding:"",
2156 (data->change.referer && conn->allocptr.ref)?
2157 conn->allocptr.ref:"" /* Referer: <data> */,
2158 (conn->bits.httpproxy &&
2159 !conn->bits.tunnel_proxy &&
2160 !Curl_checkheaders(data, "Proxy-Connection:"))?
2161 "Proxy-Connection: Keep-Alive\r\n":"",
2166 * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
2167 * with basic and digest, it will be freed anyway by the next request
2170 Curl_safefree (conn->allocptr.userpwd);
2171 conn->allocptr.userpwd = NULL;
2176 #if !defined(CURL_DISABLE_COOKIES)
2177 if(data->cookies || addcookies) {
2178 struct Cookie *co=NULL; /* no cookies from start */
2182 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2183 co = Curl_cookie_getlist(data->cookies,
2184 conn->allocptr.cookiehost?
2185 conn->allocptr.cookiehost:host,
2187 (conn->handler->protocol&CURLPROTO_HTTPS)?
2189 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2192 struct Cookie *store=co;
2193 /* now loop through all cookies that matched */
2197 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2201 result = Curl_add_bufferf(req_buffer,
2202 "%s%s=%s", count?"; ":"",
2203 co->name, co->value);
2208 co = co->next; /* next cookie please */
2210 Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2212 if(addcookies && (CURLE_OK == result)) {
2214 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2215 if(CURLE_OK == result) {
2216 result = Curl_add_bufferf(req_buffer, "%s%s",
2222 if(count && (CURLE_OK == result))
2223 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2230 if(data->set.timecondition) {
2231 result = Curl_add_timecondition(data, req_buffer);
2236 result = Curl_add_custom_headers(conn, req_buffer);
2240 http->postdata = NULL; /* nothing to post at this point */
2241 Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
2243 /* If 'authdone' is FALSE, we must not set the write socket index to the
2244 Curl_transfer() call below, as we're not ready to actually upload any
2249 case HTTPREQ_POST_FORM:
2250 if(!http->sendit || conn->bits.authneg) {
2251 /* nothing to post! */
2252 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2256 result = Curl_add_buffer_send(req_buffer, conn,
2257 &data->info.request_size, 0, FIRSTSOCKET);
2259 failf(data, "Failed sending POST request");
2261 /* setup variables for the upcoming transfer */
2262 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2267 if(Curl_FormInit(&http->form, http->sendit)) {
2268 failf(data, "Internal HTTP POST error!");
2269 return CURLE_HTTP_POST_ERROR;
2272 /* Get the currently set callback function pointer and store that in the
2273 form struct since we might want the actual user-provided callback later
2274 on. The conn->fread_func pointer itself will be changed for the
2275 multipart case to the function that returns a multipart formatted
2277 http->form.fread_func = conn->fread_func;
2279 /* Set the read function to read from the generated form data */
2280 conn->fread_func = (curl_read_callback)Curl_FormReader;
2281 conn->fread_in = &http->form;
2283 http->sending = HTTPSEND_BODY;
2285 if(!data->req.upload_chunky &&
2286 !Curl_checkheaders(data, "Content-Length:")) {
2287 /* only add Content-Length if not uploading chunked */
2288 result = Curl_add_bufferf(req_buffer,
2289 "Content-Length: %" FORMAT_OFF_T "\r\n",
2295 result = expect100(data, conn, req_buffer);
2301 /* Get Content-Type: line from Curl_formpostheader.
2304 size_t linelength=0;
2305 contentType = Curl_formpostheader((void *)&http->form,
2308 failf(data, "Could not get Content-Type header line!");
2309 return CURLE_HTTP_POST_ERROR;
2312 result = Curl_add_buffer(req_buffer, contentType, linelength);
2317 /* make the request end in a true CRLF */
2318 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2322 /* set upload size to the progress meter */
2323 Curl_pgrsSetUploadSize(data, http->postsize);
2325 /* fire away the whole request to the server */
2326 result = Curl_add_buffer_send(req_buffer, conn,
2327 &data->info.request_size, 0, FIRSTSOCKET);
2329 failf(data, "Failed sending POST request");
2331 /* setup variables for the upcoming transfer */
2332 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2333 &http->readbytecount, FIRSTSOCKET,
2334 &http->writebytecount);
2337 Curl_formclean(&http->sendit); /* free that whole lot */
2341 /* convert the form data */
2342 result = Curl_convert_form(data, http->sendit);
2344 Curl_formclean(&http->sendit); /* free that whole lot */
2350 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2352 if(conn->bits.authneg)
2355 postsize = data->set.infilesize;
2357 if((postsize != -1) && !data->req.upload_chunky &&
2358 !Curl_checkheaders(data, "Content-Length:")) {
2359 /* only add Content-Length if not uploading chunked */
2360 result = Curl_add_bufferf(req_buffer,
2361 "Content-Length: %" FORMAT_OFF_T "\r\n",
2367 result = expect100(data, conn, req_buffer);
2371 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2375 /* set the upload size to the progress meter */
2376 Curl_pgrsSetUploadSize(data, postsize);
2378 /* this sends the buffer and frees all the buffer resources */
2379 result = Curl_add_buffer_send(req_buffer, conn,
2380 &data->info.request_size, 0, FIRSTSOCKET);
2382 failf(data, "Failed sending PUT request");
2384 /* prepare for transfer */
2385 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2386 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2387 postsize?&http->writebytecount:NULL);
2393 /* this is the simple POST, using x-www-form-urlencoded style */
2395 if(conn->bits.authneg)
2398 /* figure out the size of the postfields */
2399 postsize = (data->set.postfieldsize != -1)?
2400 data->set.postfieldsize:
2401 (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2403 if(!data->req.upload_chunky) {
2404 /* We only set Content-Length and allow a custom Content-Length if
2405 we don't upload data chunked, as RFC2616 forbids us to set both
2406 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2408 if(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length:")) {
2409 /* we allow replacing this header if not during auth negotiation,
2410 although it isn't very wise to actually set your own */
2411 result = Curl_add_bufferf(req_buffer,
2412 "Content-Length: %" FORMAT_OFF_T"\r\n",
2419 if(!Curl_checkheaders(data, "Content-Type:")) {
2420 result = Curl_add_bufferf(req_buffer,
2421 "Content-Type: application/"
2422 "x-www-form-urlencoded\r\n");
2427 /* For really small posts we don't use Expect: headers at all, and for
2428 the somewhat bigger ones we allow the app to disable it. Just make
2429 sure that the expect100header is always set to the preferred value
2431 ptr = Curl_checkheaders(data, "Expect:");
2433 data->state.expect100header =
2434 Curl_compareheader(ptr, "Expect:", "100-continue");
2436 else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2437 result = expect100(data, conn, req_buffer);
2442 data->state.expect100header = FALSE;
2444 if(data->set.postfields) {
2446 if(!data->state.expect100header &&
2447 (postsize < MAX_INITIAL_POST_SIZE)) {
2448 /* if we don't use expect: 100 AND
2449 postsize is less than MAX_INITIAL_POST_SIZE
2451 then append the post data to the HTTP request header. This limit
2452 is no magic limit but only set to prevent really huge POSTs to
2453 get the data duplicated with malloc() and family. */
2455 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2459 if(!data->req.upload_chunky) {
2460 /* We're not sending it 'chunked', append it to the request
2461 already now to reduce the number if send() calls */
2462 result = Curl_add_buffer(req_buffer, data->set.postfields,
2464 included_body = postsize;
2468 /* Append the POST data chunky-style */
2469 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2470 if(CURLE_OK == result) {
2471 result = Curl_add_buffer(req_buffer, data->set.postfields,
2473 if(CURLE_OK == result)
2474 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2475 included_body = postsize + 2;
2478 if(CURLE_OK == result)
2479 result = Curl_add_buffer(req_buffer,
2480 "\x30\x0d\x0a\x0d\x0a", 5);
2486 /* Make sure the progress information is accurate */
2487 Curl_pgrsSetUploadSize(data, postsize);
2490 /* A huge POST coming up, do data separate from the request */
2491 http->postsize = postsize;
2492 http->postdata = data->set.postfields;
2494 http->sending = HTTPSEND_BODY;
2496 conn->fread_func = (curl_read_callback)readmoredata;
2497 conn->fread_in = (void *)conn;
2499 /* set the upload size to the progress meter */
2500 Curl_pgrsSetUploadSize(data, http->postsize);
2502 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2508 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2512 if(data->req.upload_chunky && conn->bits.authneg) {
2513 /* Chunky upload is selected and we're negotiating auth still, send
2515 result = Curl_add_buffer(req_buffer,
2516 "\x30\x0d\x0a\x0d\x0a", 5);
2522 else if(data->set.postfieldsize) {
2523 /* set the upload size to the progress meter */
2524 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2526 /* set the pointer to mark that we will send the post body using the
2527 read callback, but only if we're not in authenticate
2529 if(!conn->bits.authneg) {
2530 http->postdata = (char *)&http->postdata;
2531 http->postsize = postsize;
2535 /* issue the request */
2536 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2537 (size_t)included_body, FIRSTSOCKET);
2540 failf(data, "Failed sending HTTP POST request");
2542 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2543 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2544 http->postdata?&http->writebytecount:NULL);
2548 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2552 /* issue the request */
2553 result = Curl_add_buffer_send(req_buffer, conn,
2554 &data->info.request_size, 0, FIRSTSOCKET);
2557 failf(data, "Failed sending HTTP request");
2559 /* HTTP GET/HEAD download: */
2560 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2561 http->postdata?FIRSTSOCKET:-1,
2562 http->postdata?&http->writebytecount:NULL);
2567 if(http->writebytecount) {
2568 /* if a request-body has been sent off, we make sure this progress is noted
2570 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2571 if(Curl_pgrsUpdate(conn))
2572 result = CURLE_ABORTED_BY_CALLBACK;
2574 if(http->writebytecount >= postsize) {
2575 /* already sent the entire request body, mark the "upload" as
2577 infof(data, "upload completely sent off: %" FORMAT_OFF_T " out of "
2578 "%" FORMAT_OFF_T " bytes\n",
2579 http->writebytecount, postsize);
2580 data->req.upload_done = TRUE;
2581 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2582 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2592 * Returns TRUE if member of the list matches prefix of string
2595 checkhttpprefix(struct SessionHandle *data,
2598 struct curl_slist *head = data->set.http200aliases;
2600 #ifdef CURL_DOES_CONVERSIONS
2601 /* convert from the network encoding using a scratch area */
2602 char *scratch = strdup(s);
2603 if(NULL == scratch) {
2604 failf (data, "Failed to allocate memory for conversion!");
2605 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2607 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2608 /* Curl_convert_from_network calls failf if unsuccessful */
2610 return FALSE; /* can't return CURLE_foobar so return FALSE */
2613 #endif /* CURL_DOES_CONVERSIONS */
2616 if(checkprefix(head->data, s)) {
2623 if(!rc && (checkprefix("HTTP/", s)))
2626 #ifdef CURL_DOES_CONVERSIONS
2628 #endif /* CURL_DOES_CONVERSIONS */
2632 #ifndef CURL_DISABLE_RTSP
2634 checkrtspprefix(struct SessionHandle *data,
2638 #ifdef CURL_DOES_CONVERSIONS
2639 /* convert from the network encoding using a scratch area */
2640 char *scratch = strdup(s);
2641 if(NULL == scratch) {
2642 failf (data, "Failed to allocate memory for conversion!");
2643 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2645 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2646 /* Curl_convert_from_network calls failf if unsuccessful */
2648 return FALSE; /* can't return CURLE_foobar so return FALSE */
2652 (void)data; /* unused */
2653 #endif /* CURL_DOES_CONVERSIONS */
2654 if(checkprefix("RTSP/", s))
2659 #endif /* CURL_DISABLE_RTSP */
2662 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2665 #ifndef CURL_DISABLE_RTSP
2666 if(conn->handler->protocol & CURLPROTO_RTSP)
2667 return checkrtspprefix(data, s);
2670 #endif /* CURL_DISABLE_RTSP */
2672 return checkhttpprefix(data, s);
2676 * header_append() copies a chunk of data to the end of the already received
2677 * header. We make sure that the full string fit in the allocated header
2678 * buffer, or else we enlarge it.
2680 static CURLcode header_append(struct SessionHandle *data,
2681 struct SingleRequest *k,
2684 if(k->hbuflen + length >= data->state.headersize) {
2685 /* We enlarge the header buffer as it is too small */
2690 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2691 /* The reason to have a max limit for this is to avoid the risk of a bad
2692 server feeding libcurl with a never-ending header that will cause
2693 reallocs infinitely */
2694 failf (data, "Avoided giant realloc for header (max is %d)!",
2695 CURL_MAX_HTTP_HEADER);
2696 return CURLE_OUT_OF_MEMORY;
2699 newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2700 hbufp_index = k->hbufp - data->state.headerbuff;
2701 newbuff = realloc(data->state.headerbuff, newsize);
2703 failf (data, "Failed to alloc memory for big header!");
2704 return CURLE_OUT_OF_MEMORY;
2706 data->state.headersize=newsize;
2707 data->state.headerbuff = newbuff;
2708 k->hbufp = data->state.headerbuff + hbufp_index;
2710 memcpy(k->hbufp, k->str_start, length);
2712 k->hbuflen += length;
2718 static void print_http_error(struct SessionHandle *data)
2720 struct SingleRequest *k = &data->req;
2723 /* make sure that data->req.p points to the HTTP status line */
2724 if(!strncmp(beg, "HTTP", 4)) {
2726 /* skip to HTTP status code */
2727 beg = strchr(beg, ' ');
2730 /* find trailing CR */
2731 char end_char = '\r';
2732 char *end = strchr(beg, end_char);
2734 /* try to find LF (workaround for non-compliant HTTP servers) */
2736 end = strchr(beg, end_char);
2740 /* temporarily replace CR or LF by NUL and print the error message */
2742 failf(data, "The requested URL returned error: %s", beg);
2744 /* restore the previously replaced CR or LF */
2751 /* fall-back to printing the HTTP status code only */
2752 failf(data, "The requested URL returned error: %d", k->httpcode);
2756 * Read any HTTP header lines from the server and pass them to the client app.
2758 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2759 struct connectdata *conn,
2764 struct SingleRequest *k = &data->req;
2766 /* header line within buffer loop */
2772 /* str_start is start of line within buf */
2773 k->str_start = k->str;
2775 /* data is in network encoding so use 0x0a instead of '\n' */
2776 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2779 /* Not a complete header line within buffer, append the data to
2780 the end of the headerbuff. */
2781 result = header_append(data, k, *nread);
2785 if(!k->headerline && (k->hbuflen>5)) {
2786 /* make a first check that this looks like a protocol header */
2787 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2788 /* this is not the beginning of a protocol first header line */
2790 k->badheader = HEADER_ALLBAD;
2795 break; /* read more and try again */
2798 /* decrease the size of the remaining (supposed) header line */
2799 rest_length = (k->end_ptr - k->str)+1;
2800 *nread -= (ssize_t)rest_length;
2802 k->str = k->end_ptr + 1; /* move past new line */
2804 full_length = k->str - k->str_start;
2806 result = header_append(data, k, full_length);
2810 k->end_ptr = k->hbufp;
2811 k->p = data->state.headerbuff;
2814 * We now have a FULL header line that p points to
2817 if(!k->headerline) {
2818 /* the first read header */
2819 if((k->hbuflen>5) &&
2820 !checkprotoprefix(data, conn, data->state.headerbuff)) {
2821 /* this is not the beginning of a protocol first header line */
2824 /* since there's more, this is a partial bad header */
2825 k->badheader = HEADER_PARTHEADER;
2827 /* this was all we read so it's all a bad header */
2828 k->badheader = HEADER_ALLBAD;
2829 *nread = (ssize_t)rest_length;
2835 /* headers are in network encoding so
2836 use 0x0a and 0x0d instead of '\n' and '\r' */
2837 if((0x0a == *k->p) || (0x0d == *k->p)) {
2839 /* Zero-length header line means end of headers! */
2841 #ifdef CURL_DOES_CONVERSIONS
2843 *k->p = '\r'; /* replace with CR in host encoding */
2844 k->p++; /* pass the CR byte */
2847 *k->p = '\n'; /* replace with LF in host encoding */
2848 k->p++; /* pass the LF byte */
2852 k->p++; /* pass the \r byte */
2854 k->p++; /* pass the \n byte */
2855 #endif /* CURL_DOES_CONVERSIONS */
2857 if(100 <= k->httpcode && 199 >= k->httpcode) {
2859 * We have made a HTTP PUT or POST and this is 1.1-lingo
2860 * that tells us that the server is OK with this and ready
2861 * to receive the data.
2862 * However, we'll get more headers now so we must get
2863 * back into the header-parsing state!
2866 k->headerline = 0; /* restart the header line counter */
2868 /* if we did wait for this do enable write now! */
2870 k->exp100 = EXP100_SEND_DATA;
2871 k->keepon |= KEEP_SEND;
2875 k->header = FALSE; /* no more header to parse! */
2877 if((k->size == -1) && !k->chunk && !conn->bits.close &&
2878 (conn->httpversion >= 11) &&
2879 !(conn->handler->protocol & CURLPROTO_RTSP) &&
2880 data->set.httpreq != HTTPREQ_HEAD) {
2881 /* On HTTP 1.1, when connection is not to get closed, but no
2882 Content-Length nor Content-Encoding chunked have been
2883 received, according to RFC2616 section 4.4 point 5, we
2884 assume that the server will close the connection to
2885 signal the end of the document. */
2886 infof(data, "no chunk, no close, no size. Assume close to "
2888 conn->bits.close = TRUE;
2893 * When all the headers have been parsed, see if we should give
2894 * up and return an error.
2896 if(http_should_fail(conn)) {
2897 failf (data, "The requested URL returned error: %d",
2899 return CURLE_HTTP_RETURNED_ERROR;
2902 /* now, only output this if the header AND body are requested:
2904 writetype = CLIENTWRITE_HEADER;
2905 if(data->set.include_header)
2906 writetype |= CLIENTWRITE_BODY;
2908 headerlen = k->p - data->state.headerbuff;
2910 result = Curl_client_write(conn, writetype,
2911 data->state.headerbuff,
2916 data->info.header_size += (long)headerlen;
2917 data->req.headerbytecount += (long)headerlen;
2919 data->req.deductheadercount =
2920 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
2922 if(!*stop_reading) {
2923 /* Curl_http_auth_act() checks what authentication methods
2924 * that are available and decides which one (if any) to
2925 * use. It will set 'newurl' if an auth method was picked. */
2926 result = Curl_http_auth_act(conn);
2931 if(k->httpcode >= 300) {
2932 if((!conn->bits.authneg) && !conn->bits.close &&
2933 !conn->bits.rewindaftersend) {
2935 * General treatment of errors when about to send data. Including :
2936 * "417 Expectation Failed", while waiting for 100-continue.
2938 * The check for close above is done simply because of something
2939 * else has already deemed the connection to get closed then
2940 * something else should've considered the big picture and we
2943 * rewindaftersend indicates that something has told libcurl to
2944 * continue sending even if it gets discarded
2947 switch(data->set.httpreq) {
2950 case HTTPREQ_POST_FORM:
2951 /* We got an error response. If this happened before the whole
2952 * request body has been sent we stop sending and mark the
2953 * connection for closure after we've read the entire response.
2955 if(!k->upload_done) {
2956 infof(data, "HTTP error before end of send, stop sending\n");
2957 conn->bits.close = TRUE; /* close after this */
2958 k->upload_done = TRUE;
2959 k->keepon &= ~KEEP_SEND; /* don't send */
2960 if(data->state.expect100header)
2961 k->exp100 = EXP100_FAILED;
2965 default: /* default label present to avoid compiler warnings */
2971 if(conn->bits.rewindaftersend) {
2972 /* We rewind after a complete send, so thus we continue
2974 infof(data, "Keep sending data to get tossed away!\n");
2975 k->keepon |= KEEP_SEND;
2981 * really end-of-headers.
2983 * If we requested a "no body", this is a good time to get
2984 * out and return home.
2986 if(data->set.opt_no_body)
2987 *stop_reading = TRUE;
2989 /* If we know the expected size of this document, we set the
2990 maximum download size to the size of the expected
2991 document or else, we won't know when to stop reading!
2993 Note that we set the download maximum even if we read a
2994 "Connection: close" header, to make sure that
2995 "Content-Length: 0" still prevents us from attempting to
2996 read the (missing) response-body.
2998 /* According to RFC2616 section 4.4, we MUST ignore
2999 Content-Length: headers if we are now receiving data
3000 using chunked Transfer-Encoding.
3003 k->maxdownload = k->size = -1;
3006 /* We do this operation even if no_body is true, since this
3007 data might be retrieved later with curl_easy_getinfo()
3008 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3010 Curl_pgrsSetDownloadSize(data, k->size);
3011 k->maxdownload = k->size;
3014 /* If max download size is *zero* (nothing) we already
3015 have nothing and can safely return ok now! */
3016 if(0 == k->maxdownload)
3017 *stop_reading = TRUE;
3020 /* we make sure that this socket isn't read more now */
3021 k->keepon &= ~KEEP_RECV;
3024 if(data->set.verbose)
3025 Curl_debug(data, CURLINFO_HEADER_IN,
3026 k->str_start, headerlen, conn);
3027 break; /* exit header line loop */
3030 /* We continue reading headers, so reset the line-based
3031 header parsing variables hbufp && hbuflen */
3032 k->hbufp = data->state.headerbuff;
3038 * Checks for special headers coming up.
3041 if(!k->headerline++) {
3042 /* This is the first header, it MUST be the error code line
3043 or else we consider this to be the body right away! */
3044 int httpversion_major;
3045 int rtspversion_major;
3047 #ifdef CURL_DOES_CONVERSIONS
3048 #define HEADER1 scratch
3049 #define SCRATCHSIZE 21
3051 char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
3052 /* We can't really convert this yet because we
3053 don't know if it's the 1st header line or the body.
3054 So we do a partial conversion into a scratch area,
3055 leaving the data at k->p as-is.
3057 strncpy(&scratch[0], k->p, SCRATCHSIZE);
3058 scratch[SCRATCHSIZE] = 0; /* null terminate */
3059 res = Curl_convert_from_network(data,
3063 /* Curl_convert_from_network calls failf if unsuccessful */
3066 #define HEADER1 k->p /* no conversion needed, just use k->p */
3067 #endif /* CURL_DOES_CONVERSIONS */
3069 if(conn->handler->protocol & CURLPROTO_HTTP) {
3070 nc = sscanf(HEADER1,
3076 conn->httpversion += 10 * httpversion_major;
3079 /* this is the real world, not a Nirvana
3080 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3082 nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3083 conn->httpversion = 10;
3085 /* If user has set option HTTP200ALIASES,
3086 compare header line against list of aliases
3089 if(checkhttpprefix(data, k->p)) {
3092 conn->httpversion = 10;
3097 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3098 nc = sscanf(HEADER1,
3104 conn->rtspversion += 10 * rtspversion_major;
3105 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3108 /* TODO: do we care about the other cases here? */
3114 data->info.httpcode = k->httpcode;
3116 data->info.httpversion = conn->httpversion;
3117 if(!data->state.httpversion ||
3118 data->state.httpversion > conn->httpversion)
3119 /* store the lowest server version we encounter */
3120 data->state.httpversion = conn->httpversion;
3123 * This code executes as part of processing the header. As a
3124 * result, it's not totally clear how to interpret the
3125 * response code yet as that depends on what other headers may
3126 * be present. 401 and 407 may be errors, but may be OK
3127 * depending on how authentication is working. Other codes
3128 * are definitely errors, so give up here.
3130 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3131 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3132 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3134 if(data->state.resume_from &&
3135 (data->set.httpreq==HTTPREQ_GET) &&
3136 (k->httpcode == 416)) {
3137 /* "Requested Range Not Satisfiable", just proceed and
3138 pretend this is no error */
3141 /* serious error, go home! */
3142 print_http_error(data);
3143 return CURLE_HTTP_RETURNED_ERROR;
3147 if(conn->httpversion == 10) {
3148 /* Default action for HTTP/1.0 must be to close, unless
3149 we get one of those fancy headers that tell us the
3150 server keeps it open for us! */
3151 infof(data, "HTTP 1.0, assume close after body\n");
3152 conn->bits.close = TRUE;
3154 else if(conn->httpversion >= 11 &&
3155 !conn->bits.close) {
3156 struct connectbundle *cb_ptr;
3158 /* If HTTP version is >= 1.1 and connection is persistent
3159 server supports pipelining. */
3161 "HTTP 1.1 or later with persistent connection, "
3162 "pipelining supported\n"));
3163 /* Activate pipelining if needed */
3164 cb_ptr = conn->bundle;
3166 if(!Curl_pipeline_site_blacklisted(data, conn))
3167 cb_ptr->server_supports_pipelining = TRUE;
3171 switch(k->httpcode) {
3173 /* (quote from RFC2616, section 10.2.5): The server has
3174 * fulfilled the request but does not need to return an
3175 * entity-body ... The 204 response MUST NOT include a
3176 * message-body, and thus is always terminated by the first
3177 * empty line after the header fields. */
3180 /* (quote from RFC2616, section 10.3.5): The 304 response
3181 * MUST NOT contain a message-body, and thus is always
3182 * terminated by the first empty line after the header
3184 if(data->set.timecondition)
3185 data->info.timecond = TRUE;
3188 k->ignorecl = TRUE; /* ignore Content-Length headers */
3196 k->header = FALSE; /* this is not a header line */
3201 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3202 /* Curl_convert_from_network calls failf if unsuccessful */
3206 /* Check for Content-Length: header lines to get size */
3207 if(!k->ignorecl && !data->set.ignorecl &&
3208 checkprefix("Content-Length:", k->p)) {
3209 curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3210 if(data->set.max_filesize &&
3211 contentlength > data->set.max_filesize) {
3212 failf(data, "Maximum file size exceeded");
3213 return CURLE_FILESIZE_EXCEEDED;
3215 if(contentlength >= 0) {
3216 k->size = contentlength;
3217 k->maxdownload = k->size;
3218 /* we set the progress download size already at this point
3219 just to make it easier for apps/callbacks to extract this
3220 info as soon as possible */
3221 Curl_pgrsSetDownloadSize(data, k->size);
3224 /* Negative Content-Length is really odd, and we know it
3225 happens for example when older Apache servers send large
3227 conn->bits.close = TRUE;
3228 infof(data, "Negative content-length: %" FORMAT_OFF_T
3229 ", closing after transfer\n", contentlength);
3232 /* check for Content-Type: header lines to get the MIME-type */
3233 else if(checkprefix("Content-Type:", k->p)) {
3234 char *contenttype = copy_header_value(k->p);
3236 return CURLE_OUT_OF_MEMORY;
3238 /* ignore empty data */
3241 Curl_safefree(data->info.contenttype);
3242 data->info.contenttype = contenttype;
3245 else if(checkprefix("Server:", k->p)) {
3246 char *server_name = copy_header_value(k->p);
3248 /* Turn off pipelining if the server version is blacklisted */
3249 if(conn->bundle && conn->bundle->server_supports_pipelining) {
3250 if(Curl_pipeline_server_blacklisted(data, server_name))
3251 conn->bundle->server_supports_pipelining = FALSE;
3253 Curl_safefree(server_name);
3255 else if((conn->httpversion == 10) &&
3256 conn->bits.httpproxy &&
3257 Curl_compareheader(k->p,
3258 "Proxy-Connection:", "keep-alive")) {
3260 * When a HTTP/1.0 reply comes when using a proxy, the
3261 * 'Proxy-Connection: keep-alive' line tells us the
3262 * connection will be kept alive for our pleasure.
3263 * Default action for 1.0 is to close.
3265 conn->bits.close = FALSE; /* don't close when done */
3266 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3268 else if((conn->httpversion == 11) &&
3269 conn->bits.httpproxy &&
3270 Curl_compareheader(k->p,
3271 "Proxy-Connection:", "close")) {
3273 * We get a HTTP/1.1 response from a proxy and it says it'll
3274 * close down after this transfer.
3276 conn->bits.close = TRUE; /* close when done */
3277 infof(data, "HTTP/1.1 proxy connection set close!\n");
3279 else if((conn->httpversion == 10) &&
3280 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3282 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3283 * tells us the connection will be kept alive for our
3284 * pleasure. Default action for 1.0 is to close.
3286 * [RFC2068, section 19.7.1] */
3287 conn->bits.close = FALSE; /* don't close when done */
3288 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3290 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3292 * [RFC 2616, section 8.1.2.1]
3293 * "Connection: close" is HTTP/1.1 language and means that
3294 * the connection will close when this request has been
3297 conn->bits.close = TRUE; /* close when done */
3299 else if(checkprefix("Transfer-Encoding:", k->p)) {
3300 /* One or more encodings. We check for chunked and/or a compression
3303 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3304 * means that the server will send a series of "chunks". Each
3305 * chunk starts with line with info (including size of the
3306 * coming block) (terminated with CRLF), then a block of data
3307 * with the previously mentioned size. There can be any amount
3308 * of chunks, and a chunk-data set to zero signals the
3313 /* Find the first non-space letter */
3317 /* skip whitespaces and commas */
3318 while(*start && (ISSPACE(*start) || (*start == ',')))
3321 if(checkprefix("chunked", start)) {
3322 k->chunk = TRUE; /* chunks coming our way */
3324 /* init our chunky engine */
3325 Curl_httpchunk_init(conn);
3330 if(k->auto_decoding)
3331 /* TODO: we only support the first mentioned compression for now */
3334 if(checkprefix("identity", start)) {
3335 k->auto_decoding = IDENTITY;
3338 else if(checkprefix("deflate", start)) {
3339 k->auto_decoding = DEFLATE;
3342 else if(checkprefix("gzip", start)) {
3343 k->auto_decoding = GZIP;
3346 else if(checkprefix("x-gzip", start)) {
3347 k->auto_decoding = GZIP;
3350 else if(checkprefix("compress", start)) {
3351 k->auto_decoding = COMPRESS;
3354 else if(checkprefix("x-compress", start)) {
3355 k->auto_decoding = COMPRESS;
3365 else if(checkprefix("Content-Encoding:", k->p) &&
3366 data->set.str[STRING_ENCODING]) {
3368 * Process Content-Encoding. Look for the values: identity,
3369 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3370 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3371 * 2616). zlib cannot handle compress. However, errors are
3372 * handled further down when the response body is processed
3376 /* Find the first non-space letter */
3378 while(*start && ISSPACE(*start))
3381 /* Record the content-encoding for later use */
3382 if(checkprefix("identity", start))
3383 k->auto_decoding = IDENTITY;
3384 else if(checkprefix("deflate", start))
3385 k->auto_decoding = DEFLATE;
3386 else if(checkprefix("gzip", start)
3387 || checkprefix("x-gzip", start))
3388 k->auto_decoding = GZIP;
3389 else if(checkprefix("compress", start)
3390 || checkprefix("x-compress", start))
3391 k->auto_decoding = COMPRESS;
3393 else if(checkprefix("Content-Range:", k->p)) {
3394 /* Content-Range: bytes [num]-
3395 Content-Range: bytes: [num]-
3396 Content-Range: [num]-
3398 The second format was added since Sun's webserver
3399 JavaWebServer/1.1.1 obviously sends the header this way!
3400 The third added since some servers use that!
3403 char *ptr = k->p + 14;
3405 /* Move forward until first digit */
3406 while(*ptr && !ISDIGIT(*ptr))
3409 k->offset = curlx_strtoofft(ptr, NULL, 10);
3411 if(data->state.resume_from == k->offset)
3412 /* we asked for a resume and we got it */
3413 k->content_range = TRUE;
3415 #if !defined(CURL_DISABLE_COOKIES)
3416 else if(data->cookies &&
3417 checkprefix("Set-Cookie:", k->p)) {
3418 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3419 CURL_LOCK_ACCESS_SINGLE);
3420 Curl_cookie_add(data,
3421 data->cookies, TRUE, k->p+11,
3422 /* If there is a custom-set Host: name, use it
3423 here, or else use real peer host name. */
3424 conn->allocptr.cookiehost?
3425 conn->allocptr.cookiehost:conn->host.name,
3427 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3430 else if(checkprefix("Last-Modified:", k->p) &&
3431 (data->set.timecondition || data->set.get_filetime) ) {
3432 time_t secs=time(NULL);
3433 k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3435 if(data->set.get_filetime)
3436 data->info.filetime = (long)k->timeofdoc;
3438 else if((checkprefix("WWW-Authenticate:", k->p) &&
3439 (401 == k->httpcode)) ||
3440 (checkprefix("Proxy-authenticate:", k->p) &&
3441 (407 == k->httpcode))) {
3442 result = Curl_http_input_auth(conn, k->httpcode, k->p);
3446 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3447 checkprefix("Location:", k->p) &&
3448 !data->req.location) {
3449 /* this is the URL that the server advises us to use instead */
3450 char *location = copy_header_value(k->p);
3452 return CURLE_OUT_OF_MEMORY;
3454 /* ignore empty data */
3457 data->req.location = location;
3459 if(data->set.http_follow_location) {
3460 DEBUGASSERT(!data->req.newurl);
3461 data->req.newurl = strdup(data->req.location); /* clone */
3462 if(!data->req.newurl)
3463 return CURLE_OUT_OF_MEMORY;
3465 /* some cases of POST and PUT etc needs to rewind the data
3466 stream at this point */
3467 result = http_perhapsrewind(conn);
3473 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3474 result = Curl_rtsp_parseheader(conn, k->p);
3480 * End of header-checks. Write them to the client.
3483 writetype = CLIENTWRITE_HEADER;
3484 if(data->set.include_header)
3485 writetype |= CLIENTWRITE_BODY;
3487 if(data->set.verbose)
3488 Curl_debug(data, CURLINFO_HEADER_IN,
3489 k->p, (size_t)k->hbuflen, conn);
3491 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3495 data->info.header_size += (long)k->hbuflen;
3496 data->req.headerbytecount += (long)k->hbuflen;
3498 /* reset hbufp pointer && hbuflen */
3499 k->hbufp = data->state.headerbuff;
3502 while(!*stop_reading && *k->str); /* header line within buffer */
3504 /* We might have reached the end of the header part here, but
3505 there might be a non-header part left in the end of the read
3511 #endif /* CURL_DISABLE_HTTP */