1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2012, 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"
77 #define _MPRINTF_REPLACE /* use our functions only */
78 #include <curl/mprintf.h>
80 /* The last #include file should be: */
84 * Forward declarations.
87 static int http_getsock_do(struct connectdata *conn,
90 static int http_should_fail(struct connectdata *conn);
93 static CURLcode https_connecting(struct connectdata *conn, bool *done);
94 static int https_getsock(struct connectdata *conn,
98 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
102 * HTTP handler interface.
104 const struct Curl_handler Curl_handler_http = {
106 ZERO_NULL, /* setup_connection */
107 Curl_http, /* do_it */
108 Curl_http_done, /* done */
109 ZERO_NULL, /* do_more */
110 Curl_http_connect, /* connect_it */
111 ZERO_NULL, /* connecting */
112 ZERO_NULL, /* doing */
113 ZERO_NULL, /* proto_getsock */
114 http_getsock_do, /* doing_getsock */
115 ZERO_NULL, /* domore_getsock */
116 ZERO_NULL, /* perform_getsock */
117 ZERO_NULL, /* disconnect */
118 ZERO_NULL, /* readwrite */
119 PORT_HTTP, /* defport */
120 CURLPROTO_HTTP, /* protocol */
121 PROTOPT_NONE /* flags */
126 * HTTPS handler interface.
128 const struct Curl_handler Curl_handler_https = {
129 "HTTPS", /* scheme */
130 ZERO_NULL, /* setup_connection */
131 Curl_http, /* do_it */
132 Curl_http_done, /* done */
133 ZERO_NULL, /* do_more */
134 Curl_http_connect, /* connect_it */
135 https_connecting, /* connecting */
136 ZERO_NULL, /* doing */
137 https_getsock, /* proto_getsock */
138 http_getsock_do, /* doing_getsock */
139 ZERO_NULL, /* domore_getsock */
140 ZERO_NULL, /* perform_getsock */
141 ZERO_NULL, /* disconnect */
142 ZERO_NULL, /* readwrite */
143 PORT_HTTPS, /* defport */
144 CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
145 PROTOPT_SSL /* flags */
151 * checkheaders() checks the linked list of custom HTTP headers for a
152 * particular header (prefix).
154 * Returns a pointer to the first matching header or NULL if none matched.
156 char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader)
158 struct curl_slist *head;
159 size_t thislen = strlen(thisheader);
161 for(head = data->set.headers; head; head=head->next) {
162 if(Curl_raw_nequal(head->data, thisheader, thislen))
169 * Strip off leading and trailing whitespace from the value in the
170 * given HTTP header line and return a strdupped copy. Returns NULL in
171 * case of allocation failure. Returns an empty string if the header value
172 * consists entirely of whitespace.
174 static char *copy_header_value(const char *h)
183 /* Find the end of the header name */
184 while(*h && (*h != ':'))
188 /* Skip over colon */
191 /* Find the first non-space letter */
193 while(*start && ISSPACE(*start))
196 /* data is in the host encoding so
197 use '\r' and '\n' instead of 0x0d and 0x0a */
198 end = strchr(start, '\r');
200 end = strchr(start, '\n');
202 end = strchr(start, '\0');
206 /* skip all trailing space letters */
207 while((end > start) && ISSPACE(*end))
210 /* get length of the type */
213 value = malloc(len + 1);
217 memcpy(value, start, len);
218 value[len] = 0; /* zero terminate */
224 * http_output_basic() sets up an Authorization: header (or the proxy version)
225 * for HTTP Basic authentication.
229 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
232 char *authorization = NULL;
233 struct SessionHandle *data = conn->data;
240 userp = &conn->allocptr.proxyuserpwd;
241 user = conn->proxyuser;
242 pwd = conn->proxypasswd;
245 userp = &conn->allocptr.userpwd;
250 snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
252 error = Curl_base64_encode(data,
253 data->state.buffer, strlen(data->state.buffer),
254 &authorization, &size);
259 return CURLE_REMOTE_ACCESS_DENIED;
261 Curl_safefree(*userp);
262 *userp = aprintf("%sAuthorization: Basic %s\r\n",
267 return CURLE_OUT_OF_MEMORY;
272 /* pickoneauth() selects the most favourable authentication method from the
273 * ones available and the ones we want.
275 * return TRUE if one was picked
277 static bool pickoneauth(struct auth *pick)
280 /* only deal with authentication we want */
281 unsigned long avail = pick->avail & pick->want;
284 /* The order of these checks is highly relevant, as this will be the order
285 of preference in case of the existence of multiple accepted types. */
286 if(avail & CURLAUTH_GSSNEGOTIATE)
287 pick->picked = CURLAUTH_GSSNEGOTIATE;
288 else if(avail & CURLAUTH_DIGEST)
289 pick->picked = CURLAUTH_DIGEST;
290 else if(avail & CURLAUTH_NTLM)
291 pick->picked = CURLAUTH_NTLM;
292 else if(avail & CURLAUTH_NTLM_WB)
293 pick->picked = CURLAUTH_NTLM_WB;
294 else if(avail & CURLAUTH_BASIC)
295 pick->picked = CURLAUTH_BASIC;
297 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
300 pick->avail = CURLAUTH_NONE; /* clear it here */
306 * Curl_http_perhapsrewind()
308 * If we are doing POST or PUT {
309 * If we have more data to send {
310 * If we are doing NTLM {
311 * Keep sending since we must not disconnect
314 * If there is more than just a little data left to send, close
315 * the current connection by force.
318 * If we have sent any data {
319 * If we don't have track of all the data {
320 * call app to tell it to rewind
323 * rewind internally so that the operation can restart fine
328 static CURLcode http_perhapsrewind(struct connectdata *conn)
330 struct SessionHandle *data = conn->data;
331 struct HTTP *http = data->state.proto.http;
332 curl_off_t bytessent;
333 curl_off_t expectsend = -1; /* default is unknown */
336 /* If this is still NULL, we have not reach very far and we can safely
337 skip this rewinding stuff */
340 switch(data->set.httpreq) {
348 bytessent = http->writebytecount;
350 if(conn->bits.authneg)
351 /* This is a state where we are known to be negotiating and we don't send
355 /* figure out how much data we are expected to send */
356 switch(data->set.httpreq) {
358 if(data->set.postfieldsize != -1)
359 expectsend = data->set.postfieldsize;
360 else if(data->set.postfields)
361 expectsend = (curl_off_t)strlen(data->set.postfields);
364 if(data->set.infilesize != -1)
365 expectsend = data->set.infilesize;
367 case HTTPREQ_POST_FORM:
368 expectsend = http->postsize;
375 conn->bits.rewindaftersend = FALSE; /* default */
377 if((expectsend == -1) || (expectsend > bytessent)) {
378 /* There is still data left to send */
379 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
380 (data->state.authhost.picked == CURLAUTH_NTLM) ||
381 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
382 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
383 if(((expectsend - bytessent) < 2000) ||
384 (conn->ntlm.state != NTLMSTATE_NONE) ||
385 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
386 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
387 data left to send, keep on sending. */
389 /* rewind data when completely done sending! */
390 if(!conn->bits.authneg) {
391 conn->bits.rewindaftersend = TRUE;
392 infof(data, "Rewind stream after send\n");
398 /* this is already marked to get closed */
401 infof(data, "NTLM send, close instead of sending %" FORMAT_OFF_T
402 " bytes\n", (curl_off_t)(expectsend - bytessent));
405 /* This is not NTLM or many bytes left to send: close
407 conn->bits.close = TRUE;
408 data->req.size = 0; /* don't download any more than 0 bytes */
410 /* There still is data left to send, but this connection is marked for
411 closure so we can safely do the rewind right now */
415 /* we rewind now at once since if we already sent something */
416 return Curl_readrewind(conn);
422 * Curl_http_auth_act() gets called when all HTTP headers have been received
423 * and it checks what authentication methods that are available and decides
424 * which one (if any) to use. It will set 'newurl' if an auth method was
428 CURLcode Curl_http_auth_act(struct connectdata *conn)
430 struct SessionHandle *data = conn->data;
431 bool pickhost = FALSE;
432 bool pickproxy = FALSE;
433 CURLcode code = CURLE_OK;
435 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
436 /* this is a transient response code, ignore */
439 if(data->state.authproblem)
440 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
442 if(conn->bits.user_passwd &&
443 ((data->req.httpcode == 401) ||
444 (conn->bits.authneg && data->req.httpcode < 300))) {
445 pickhost = pickoneauth(&data->state.authhost);
447 data->state.authproblem = TRUE;
449 if(conn->bits.proxy_user_passwd &&
450 ((data->req.httpcode == 407) ||
451 (conn->bits.authneg && data->req.httpcode < 300))) {
452 pickproxy = pickoneauth(&data->state.authproxy);
454 data->state.authproblem = TRUE;
457 if(pickhost || pickproxy) {
458 /* In case this is GSS auth, the newurl field is already allocated so
459 we must make sure to free it before allocating a new one. As figured
460 out in bug #2284386 */
461 Curl_safefree(data->req.newurl);
462 data->req.newurl = strdup(data->change.url); /* clone URL */
463 if(!data->req.newurl)
464 return CURLE_OUT_OF_MEMORY;
466 if((data->set.httpreq != HTTPREQ_GET) &&
467 (data->set.httpreq != HTTPREQ_HEAD) &&
468 !conn->bits.rewindaftersend) {
469 code = http_perhapsrewind(conn);
475 else if((data->req.httpcode < 300) &&
476 (!data->state.authhost.done) &&
477 conn->bits.authneg) {
478 /* no (known) authentication available,
479 authentication is not "done" yet and
480 no authentication seems to be required and
481 we didn't try HEAD or GET */
482 if((data->set.httpreq != HTTPREQ_GET) &&
483 (data->set.httpreq != HTTPREQ_HEAD)) {
484 data->req.newurl = strdup(data->change.url); /* clone URL */
485 if(!data->req.newurl)
486 return CURLE_OUT_OF_MEMORY;
487 data->state.authhost.done = TRUE;
490 if(http_should_fail(conn)) {
491 failf (data, "The requested URL returned error: %d",
493 code = CURLE_HTTP_RETURNED_ERROR;
501 * Output the correct authentication header depending on the auth type
502 * and whether or not it is to a proxy.
505 output_auth_headers(struct connectdata *conn,
506 struct auth *authstatus,
511 struct SessionHandle *data = conn->data;
512 const char *auth=NULL;
513 CURLcode result = CURLE_OK;
514 #ifdef USE_HTTP_NEGOTIATE
515 struct negotiatedata *negdata = proxy?
516 &data->state.proxyneg:&data->state.negotiate;
519 #ifdef CURL_DISABLE_CRYPTO_AUTH
524 #ifdef USE_HTTP_NEGOTIATE
525 negdata->state = GSS_AUTHNONE;
526 if((authstatus->picked == CURLAUTH_GSSNEGOTIATE) &&
527 negdata->context && !GSS_ERROR(negdata->status)) {
528 auth="GSS-Negotiate";
529 result = Curl_output_negotiate(conn, proxy);
532 authstatus->done = TRUE;
533 negdata->state = GSS_AUTHSENT;
538 if(authstatus->picked == CURLAUTH_NTLM) {
540 result = Curl_output_ntlm(conn, proxy);
546 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
547 if(authstatus->picked == CURLAUTH_NTLM_WB) {
549 result = Curl_output_ntlm_wb(conn, proxy);
555 #ifndef CURL_DISABLE_CRYPTO_AUTH
556 if(authstatus->picked == CURLAUTH_DIGEST) {
558 result = Curl_output_digest(conn,
560 (const unsigned char *)request,
561 (const unsigned char *)path);
567 if(authstatus->picked == CURLAUTH_BASIC) {
569 if((proxy && conn->bits.proxy_user_passwd &&
570 !Curl_checkheaders(data, "Proxy-authorization:")) ||
571 (!proxy && conn->bits.user_passwd &&
572 !Curl_checkheaders(data, "Authorization:"))) {
574 result = http_output_basic(conn, proxy);
578 /* NOTE: this function should set 'done' TRUE, as the other auth
579 functions work that way */
580 authstatus->done = TRUE;
584 infof(data, "%s auth using %s with user '%s'\n",
585 proxy?"Proxy":"Server", auth,
586 proxy?(conn->proxyuser?conn->proxyuser:""):
587 (conn->user?conn->user:""));
588 authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
591 authstatus->multi = FALSE;
597 * Curl_http_output_auth() setups the authentication headers for the
598 * host/proxy and the correct authentication
599 * method. conn->data->state.authdone is set to TRUE when authentication is
602 * @param conn all information about the current connection
603 * @param request pointer to the request keyword
604 * @param path pointer to the requested path
605 * @param proxytunnel boolean if this is the request setting up a "proxy
611 Curl_http_output_auth(struct connectdata *conn,
614 bool proxytunnel) /* TRUE if this is the request setting
615 up the proxy tunnel */
617 CURLcode result = CURLE_OK;
618 struct SessionHandle *data = conn->data;
619 struct auth *authhost;
620 struct auth *authproxy;
624 authhost = &data->state.authhost;
625 authproxy = &data->state.authproxy;
627 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
628 conn->bits.user_passwd)
629 /* continue please */ ;
631 authhost->done = TRUE;
632 authproxy->done = TRUE;
633 return CURLE_OK; /* no authentication with no user or password */
636 if(authhost->want && !authhost->picked)
637 /* The app has selected one or more methods, but none has been picked
638 so far by a server round-trip. Then we set the picked one to the
639 want one, and if this is one single bit it'll be used instantly. */
640 authhost->picked = authhost->want;
642 if(authproxy->want && !authproxy->picked)
643 /* The app has selected one or more methods, but none has been picked so
644 far by a proxy round-trip. Then we set the picked one to the want one,
645 and if this is one single bit it'll be used instantly. */
646 authproxy->picked = authproxy->want;
648 #ifndef CURL_DISABLE_PROXY
649 /* Send proxy authentication header if needed */
650 if(conn->bits.httpproxy &&
651 (conn->bits.tunnel_proxy == proxytunnel)) {
652 result = output_auth_headers(conn, authproxy, request, path, TRUE);
659 #endif /* CURL_DISABLE_PROXY */
660 /* we have no proxy so let's pretend we're done authenticating
662 authproxy->done = TRUE;
664 /* To prevent the user+password to get sent to other than the original
665 host due to a location-follow, we do some weirdo checks here */
666 if(!data->state.this_is_a_follow ||
668 !data->state.first_host ||
669 data->set.http_disable_hostname_check_before_authentication ||
670 Curl_raw_equal(data->state.first_host, conn->host.name)) {
671 result = output_auth_headers(conn, authhost, request, path, FALSE);
674 authhost->done = TRUE;
681 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
682 * headers. They are dealt with both in the transfer.c main loop and in the
683 * proxy CONNECT loop.
686 CURLcode Curl_http_input_auth(struct connectdata *conn,
688 const char *header) /* the first non-space */
691 * This resource requires authentication
693 struct SessionHandle *data = conn->data;
695 unsigned long *availp;
699 if(httpcode == 407) {
700 start = header+strlen("Proxy-authenticate:");
701 availp = &data->info.proxyauthavail;
702 authp = &data->state.authproxy;
705 start = header+strlen("WWW-Authenticate:");
706 availp = &data->info.httpauthavail;
707 authp = &data->state.authhost;
710 /* pass all white spaces */
711 while(*start && ISSPACE(*start))
715 * Here we check if we want the specific single authentication (using ==) and
716 * if we do, we initiate usage of it.
718 * If the provided authentication is wanted as one out of several accepted
719 * types (using &), we OR this authentication type to the authavail
724 * ->picked is first set to the 'want' value (one or more bits) before the
725 * request is sent, and then it is again set _after_ all response 401/407
726 * headers have been received but then only to a single preferred method
732 #ifdef USE_HTTP_NEGOTIATE
733 if(checkprefix("GSS-Negotiate", start) ||
734 checkprefix("Negotiate", start)) {
736 *availp |= CURLAUTH_GSSNEGOTIATE;
737 authp->avail |= CURLAUTH_GSSNEGOTIATE;
739 if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
740 if(data->state.negotiate.state == GSS_AUTHSENT) {
741 /* if we sent GSS authentication in the outgoing request and we get
742 this back, we're in trouble */
743 infof(data, "Authentication problem. Ignoring this.\n");
744 data->state.authproblem = TRUE;
747 neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
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;
758 data->state.authproblem = TRUE;
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 authp->picked == CURLAUTH_NTLM_WB) {
771 /* NTLM authentication is picked and activated */
773 Curl_input_ntlm(conn, (httpcode == 407)?TRUE:FALSE, start);
774 if(CURLE_OK == ntlm) {
775 data->state.authproblem = FALSE;
776 #ifdef NTLM_WB_ENABLED
777 if(authp->picked == CURLAUTH_NTLM_WB) {
778 *availp &= ~CURLAUTH_NTLM;
779 authp->avail &= ~CURLAUTH_NTLM;
780 *availp |= CURLAUTH_NTLM_WB;
781 authp->avail |= CURLAUTH_NTLM_WB;
783 /* Get the challenge-message which will be passed to
784 * ntlm_auth for generating the type 3 message later */
785 while(*start && ISSPACE(*start))
787 if(checkprefix("NTLM", start)) {
788 start += strlen("NTLM");
789 while(*start && ISSPACE(*start))
792 if((conn->challenge_header = strdup(start)) == NULL)
793 return CURLE_OUT_OF_MEMORY;
799 infof(data, "Authentication problem. Ignoring this.\n");
800 data->state.authproblem = TRUE;
806 #ifndef CURL_DISABLE_CRYPTO_AUTH
807 if(checkprefix("Digest", start)) {
808 if((authp->avail & CURLAUTH_DIGEST) != 0) {
809 infof(data, "Ignoring duplicate digest auth header.\n");
813 *availp |= CURLAUTH_DIGEST;
814 authp->avail |= CURLAUTH_DIGEST;
816 /* We call this function on input Digest headers even if Digest
817 * authentication isn't activated yet, as we need to store the
818 * incoming data from this header in case we are gonna use
820 dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start);
822 if(CURLDIGEST_FINE != dig) {
823 infof(data, "Authentication problem. Ignoring this.\n");
824 data->state.authproblem = TRUE;
830 if(checkprefix("Basic", start)) {
831 *availp |= CURLAUTH_BASIC;
832 authp->avail |= CURLAUTH_BASIC;
833 if(authp->picked == CURLAUTH_BASIC) {
834 /* We asked for Basic authentication but got a 40X back
835 anyway, which basically means our name+password isn't
837 authp->avail = CURLAUTH_NONE;
838 infof(data, "Authentication problem. Ignoring this.\n");
839 data->state.authproblem = TRUE;
843 /* there may be multiple methods on one line, so keep reading */
844 while(*start && *start != ',') /* read up to the next comma */
846 if(*start == ',') /* if we're on a comma, skip it */
848 while(*start && ISSPACE(*start))
855 * http_should_fail() determines whether an HTTP response has gotten us
856 * into an error state or not.
858 * @param conn all information about the current connection
860 * @retval 0 communications should continue
862 * @retval 1 communications should not continue
864 static int http_should_fail(struct connectdata *conn)
866 struct SessionHandle *data;
873 httpcode = data->req.httpcode;
876 ** If we haven't been asked to fail on error,
879 if(!data->set.http_fail_on_error)
883 ** Any code < 400 is never terminal.
888 if(data->state.resume_from &&
889 (data->set.httpreq==HTTPREQ_GET) &&
891 /* "Requested Range Not Satisfiable", just proceed and
892 pretend this is no error */
897 ** Any code >= 400 that's not 401 or 407 is always
900 if((httpcode != 401) &&
905 ** All we have left to deal with is 401 and 407
907 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
910 ** Examine the current authentication state to see if this
911 ** is an error. The idea is for this function to get
912 ** called after processing all the headers in a response
913 ** message. So, if we've been to asked to authenticate a
914 ** particular stage, and we've done it, we're OK. But, if
915 ** we're already completely authenticated, it's not OK to
916 ** get another 401 or 407.
918 ** It is possible for authentication to go stale such that
919 ** the client needs to reauthenticate. Once that info is
920 ** available, use it here.
924 ** Either we're not authenticating, or we're supposed to
925 ** be authenticating something else. This is an error.
927 if((httpcode == 401) && !conn->bits.user_passwd)
929 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
932 return data->state.authproblem;
936 * readmoredata() is a "fread() emulation" to provide POST and/or request
937 * data. It is used when a huge POST is to be made and the entire chunk wasn't
938 * sent in the first send(). This function will then be called from the
939 * transfer.c loop when more data is to be sent to the peer.
941 * Returns the amount of bytes it filled the buffer with.
943 static size_t readmoredata(char *buffer,
948 struct connectdata *conn = (struct connectdata *)userp;
949 struct HTTP *http = conn->data->state.proto.http;
950 size_t fullsize = size * nitems;
952 if(0 == http->postsize)
953 /* nothing to return */
956 /* make sure that a HTTP request is never sent away chunked! */
957 conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
959 if(http->postsize <= (curl_off_t)fullsize) {
960 memcpy(buffer, http->postdata, (size_t)http->postsize);
961 fullsize = (size_t)http->postsize;
963 if(http->backup.postsize) {
964 /* move backup data into focus and continue on that */
965 http->postdata = http->backup.postdata;
966 http->postsize = http->backup.postsize;
967 conn->fread_func = http->backup.fread_func;
968 conn->fread_in = http->backup.fread_in;
970 http->sending++; /* move one step up */
972 http->backup.postsize=0;
980 memcpy(buffer, http->postdata, fullsize);
981 http->postdata += fullsize;
982 http->postsize -= fullsize;
987 /* ------------------------------------------------------------------------- */
988 /* add_buffer functions */
991 * Curl_add_buffer_init() sets up and returns a fine buffer struct
993 Curl_send_buffer *Curl_add_buffer_init(void)
995 return calloc(1, sizeof(Curl_send_buffer));
999 * Curl_add_buffer_send() sends a header buffer and frees all associated
1000 * memory. Body data may be appended to the header data if desired.
1004 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
1005 struct connectdata *conn,
1007 /* add the number of sent bytes to this
1009 long *bytes_written,
1011 /* how much of the buffer contains body data */
1012 size_t included_body_bytes,
1020 struct HTTP *http = conn->data->state.proto.http;
1022 curl_socket_t sockfd;
1025 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1027 sockfd = conn->sock[socketindex];
1029 /* The looping below is required since we use non-blocking sockets, but due
1030 to the circumstances we will just loop and try again and again etc */
1033 size = in->size_used;
1035 headersize = size - included_body_bytes; /* the initial part that isn't body
1038 DEBUGASSERT(size > included_body_bytes);
1040 res = Curl_convert_to_network(conn->data, ptr, headersize);
1041 /* Curl_convert_to_network calls failf if unsuccessful */
1043 /* conversion failed, free memory and return to the caller */
1050 if(conn->handler->flags & PROTOPT_SSL) {
1051 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1052 when we speak HTTPS, as if only a fraction of it is sent now, this data
1053 needs to fit into the normal read-callback buffer later on and that
1054 buffer is using this size.
1057 sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
1059 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1060 library when we attempt to re-send this buffer. Sending the same data
1061 is not enough, we must use the exact same address. For this reason, we
1062 must copy the data to the uploadbuffer first, since that is the buffer
1063 we will be using if this send is retried later.
1065 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1066 ptr = conn->data->state.uploadbuffer;
1071 res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1073 if(CURLE_OK == res) {
1075 * Note that we may not send the entire chunk at once, and we have a set
1076 * number of data bytes at the end of the big buffer (out of which we may
1077 * only send away a part).
1079 /* how much of the header that was sent */
1080 size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
1081 size_t bodylen = amount - headlen;
1083 if(conn->data->set.verbose) {
1084 /* this data _may_ contain binary stuff */
1085 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1087 /* there was body data sent beyond the initial header part, pass that
1088 on to the debug callback too */
1089 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1090 ptr+headlen, bodylen, conn);
1094 /* since we sent a piece of the body here, up the byte counter for it
1096 http->writebytecount += bodylen;
1098 /* 'amount' can never be a very large value here so typecasting it so a
1099 signed 31 bit value should not cause problems even if ssize_t is
1101 *bytes_written += (long)amount;
1104 if((size_t)amount != size) {
1105 /* The whole request could not be sent in one system call. We must
1106 queue it up and send it later when we get the chance. We must not
1107 loop here and wait until it might work again. */
1111 ptr = in->buffer + amount;
1113 /* backup the currently set pointers */
1114 http->backup.fread_func = conn->fread_func;
1115 http->backup.fread_in = conn->fread_in;
1116 http->backup.postdata = http->postdata;
1117 http->backup.postsize = http->postsize;
1119 /* set the new pointers for the request-sending */
1120 conn->fread_func = (curl_read_callback)readmoredata;
1121 conn->fread_in = (void *)conn;
1122 http->postdata = ptr;
1123 http->postsize = (curl_off_t)size;
1125 http->send_buffer = in;
1126 http->sending = HTTPSEND_REQUEST;
1130 http->sending = HTTPSEND_BODY;
1131 /* the full buffer was sent, clean up and return */
1134 if((size_t)amount != size)
1135 /* We have no continue-send mechanism now, fail. This can only happen
1136 when this function is used from the CONNECT sending function. We
1137 currently (stupidly) assume that the whole request is always sent
1138 away in the first single chunk.
1142 return CURLE_SEND_ERROR;
1144 conn->writechannel_inuse = FALSE;
1156 * add_bufferf() add the formatted input to the buffer.
1158 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1163 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1167 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1171 /* If we failed, we cleanup the whole buffer and return error */
1175 return CURLE_OUT_OF_MEMORY;
1179 * add_buffer() appends a memory chunk to the existing buffer
1181 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1186 if(~size < in->size_used) {
1187 /* If resulting used size of send buffer would wrap size_t, cleanup
1188 the whole buffer and return error. Otherwise the required buffer
1189 size will fit into a single allocatable memory chunk */
1190 Curl_safefree(in->buffer);
1192 return CURLE_OUT_OF_MEMORY;
1196 ((in->size_used + size) > (in->size_max - 1))) {
1198 /* If current buffer size isn't enough to hold the result, use a
1199 buffer size that doubles the required size. If this new size
1200 would wrap size_t, then just use the largest possible one */
1202 if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
1203 (~(size*2) < (in->size_used*2)))
1204 new_size = (size_t)-1;
1206 new_size = (in->size_used+size)*2;
1209 /* we have a buffer, enlarge the existing one */
1210 new_rb = realloc(in->buffer, new_size);
1212 /* create a new buffer */
1213 new_rb = malloc(new_size);
1216 /* If we failed, we cleanup the whole buffer and return error */
1217 Curl_safefree(in->buffer);
1219 return CURLE_OUT_OF_MEMORY;
1222 in->buffer = new_rb;
1223 in->size_max = new_size;
1225 memcpy(&in->buffer[in->size_used], inptr, size);
1227 in->size_used += size;
1232 /* end of the add_buffer functions */
1233 /* ------------------------------------------------------------------------- */
1238 * Curl_compareheader()
1240 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1241 * Pass headers WITH the colon.
1244 Curl_compareheader(const char *headerline, /* line to check */
1245 const char *header, /* header keyword _with_ colon */
1246 const char *content) /* content string to find */
1248 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1249 * by a colon (":") and the field value. Field names are case-insensitive.
1250 * The field value MAY be preceded by any amount of LWS, though a single SP
1253 size_t hlen = strlen(header);
1259 if(!Curl_raw_nequal(headerline, header, hlen))
1260 return FALSE; /* doesn't start with header */
1262 /* pass the header */
1263 start = &headerline[hlen];
1265 /* pass all white spaces */
1266 while(*start && ISSPACE(*start))
1269 /* find the end of the header line */
1270 end = strchr(start, '\r'); /* lines end with CRLF */
1272 /* in case there's a non-standard compliant line here */
1273 end = strchr(start, '\n');
1276 /* hm, there's no line ending here, use the zero byte! */
1277 end = strchr(start, '\0');
1280 len = end-start; /* length of the content part of the input line */
1281 clen = strlen(content); /* length of the word to find */
1283 /* find the content string in the rest of the line */
1284 for(;len>=clen;len--, start++) {
1285 if(Curl_raw_nequal(start, content, clen))
1286 return TRUE; /* match! */
1289 return FALSE; /* no match */
1293 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1294 * the generic Curl_connect().
1296 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1298 struct SessionHandle *data;
1303 /* We default to persistent connections. We set this already in this connect
1304 function to make the re-use checks properly be able to check this bit. */
1305 conn->bits.close = FALSE;
1307 if(data->state.used_interface == Curl_if_multi) {
1308 /* when the multi interface is used, the CONNECT procedure might not have
1310 result = Curl_proxy_connect(conn);
1315 if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1316 /* nothing else to do except wait right now - we're not done here. */
1319 if(conn->given->flags & PROTOPT_SSL) {
1320 /* perform SSL initialization */
1321 if(data->state.used_interface == Curl_if_multi) {
1322 result = https_connecting(conn, done);
1328 result = Curl_ssl_connect(conn, FIRSTSOCKET);
1341 /* this returns the socket to wait for in the DO and DOING state for the multi
1342 interface and then we're always _sending_ a request and thus we wait for
1343 the single socket to become writable only */
1344 static int http_getsock_do(struct connectdata *conn,
1345 curl_socket_t *socks,
1349 (void)numsocks; /* unused, we trust it to be at least 1 */
1350 socks[0] = conn->sock[FIRSTSOCKET];
1351 return GETSOCK_WRITESOCK(0);
1355 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1358 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1360 /* perform SSL initialization for this socket */
1361 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1363 conn->bits.close = TRUE; /* a failed connection is marked for closure
1364 to prevent (bad) re-use or similar */
1369 #if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
1370 defined(USE_DARWINSSL)
1371 /* This function is for OpenSSL, GnuTLS, darwinssl, and schannel only.
1372 It should be made to query the generic SSL layer instead. */
1373 static int https_getsock(struct connectdata *conn,
1374 curl_socket_t *socks,
1377 if(conn->handler->flags & PROTOPT_SSL) {
1378 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1381 return GETSOCK_BLANK;
1383 if(connssl->connecting_state == ssl_connect_2_writing) {
1385 socks[0] = conn->sock[FIRSTSOCKET];
1386 return GETSOCK_WRITESOCK(0);
1388 else if(connssl->connecting_state == ssl_connect_2_reading) {
1390 socks[0] = conn->sock[FIRSTSOCKET];
1391 return GETSOCK_READSOCK(0);
1398 static int https_getsock(struct connectdata *conn,
1399 curl_socket_t *socks,
1405 return GETSOCK_BLANK;
1407 #endif /* USE_SSL */
1408 #endif /* USE_SSLEAY || USE_GNUTLS || USE_SCHANNEL */
1411 * Curl_http_done() gets called from Curl_done() after a single HTTP request
1412 * has been performed.
1415 CURLcode Curl_http_done(struct connectdata *conn,
1416 CURLcode status, bool premature)
1418 struct SessionHandle *data = conn->data;
1419 struct HTTP *http =data->state.proto.http;
1421 Curl_unencode_cleanup(conn);
1423 /* set the proper values (possibly modified on POST) */
1424 conn->fread_func = data->set.fread_func; /* restore */
1425 conn->fread_in = data->set.in; /* restore */
1426 conn->seek_func = data->set.seek_func; /* restore */
1427 conn->seek_client = data->set.seek_client; /* restore */
1432 if(http->send_buffer) {
1433 Curl_send_buffer *buff = http->send_buffer;
1437 http->send_buffer = NULL; /* clear the pointer */
1440 if(HTTPREQ_POST_FORM == data->set.httpreq) {
1441 data->req.bytecount = http->readbytecount + http->writebytecount;
1443 Curl_formclean(&http->sendit); /* Now free that whole lot */
1445 /* a file being uploaded was left opened, close it! */
1446 fclose(http->form.fp);
1447 http->form.fp = NULL;
1450 else if(HTTPREQ_PUT == data->set.httpreq)
1451 data->req.bytecount = http->readbytecount + http->writebytecount;
1453 if(status != CURLE_OK)
1456 if(!premature && /* this check is pointless when DONE is called before the
1457 entire operation is complete */
1458 !conn->bits.retry &&
1459 ((http->readbytecount +
1460 data->req.headerbytecount -
1461 data->req.deductheadercount)) <= 0) {
1462 /* If this connection isn't simply closed to be retried, AND nothing was
1463 read from the HTTP server (that counts), this can't be right so we
1464 return an error here */
1465 failf(data, "Empty reply from server");
1466 return CURLE_GOT_NOTHING;
1473 /* Determine if we should use HTTP 1.1 for this request. Reasons to avoid it
1474 are if the user specifically requested HTTP 1.0, if the server we are
1475 connected to only supports 1.0, or if any server previously contacted to
1476 handle this request only supports 1.0. */
1477 static bool use_http_1_1(const struct SessionHandle *data,
1478 const struct connectdata *conn)
1480 return ((data->set.httpversion == CURL_HTTP_VERSION_1_1) ||
1481 ((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
1482 ((conn->httpversion == 11) ||
1483 ((conn->httpversion != 10) &&
1484 (data->state.httpversion != 10))))) ? TRUE : FALSE;
1487 /* check and possibly add an Expect: header */
1488 static CURLcode expect100(struct SessionHandle *data,
1489 struct connectdata *conn,
1490 Curl_send_buffer *req_buffer)
1492 CURLcode result = CURLE_OK;
1494 data->state.expect100header = FALSE; /* default to false unless it is set
1496 if(use_http_1_1(data, conn)) {
1497 /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
1498 100-continue to the headers which actually speeds up post operations
1499 (as there is one packet coming back from the web server) */
1500 ptr = Curl_checkheaders(data, "Expect:");
1502 data->state.expect100header =
1503 Curl_compareheader(ptr, "Expect:", "100-continue");
1506 result = Curl_add_bufferf(req_buffer,
1507 "Expect: 100-continue\r\n");
1508 if(result == CURLE_OK)
1509 data->state.expect100header = TRUE;
1515 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1516 Curl_send_buffer *req_buffer)
1519 struct curl_slist *headers=conn->data->set.headers;
1522 ptr = strchr(headers->data, ':');
1524 /* we require a colon for this to be a true header */
1526 ptr++; /* pass the colon */
1527 while(*ptr && ISSPACE(*ptr))
1531 /* only send this if the contents was non-blank */
1533 if(conn->allocptr.host &&
1534 /* a Host: header was sent already, don't pass on any custom Host:
1535 header as that will produce *two* in the same request! */
1536 checkprefix("Host:", headers->data))
1538 else if(conn->data->set.httpreq == HTTPREQ_POST_FORM &&
1539 /* this header (extended by formdata.c) is sent later */
1540 checkprefix("Content-Type:", headers->data))
1542 else if(conn->bits.authneg &&
1543 /* while doing auth neg, don't allow the custom length since
1544 we will force length zero then */
1545 checkprefix("Content-Length", headers->data))
1547 else if(conn->allocptr.te &&
1548 /* when asking for Transfer-Encoding, don't pass on a custom
1550 checkprefix("Connection", headers->data))
1553 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1561 ptr = strchr(headers->data, ';');
1564 ptr++; /* pass the semicolon */
1565 while(*ptr && ISSPACE(*ptr))
1569 /* this may be used for something else in the future */
1572 if(*(--ptr) == ';') {
1575 /* send no-value custom header if terminated by semicolon */
1577 result = Curl_add_bufferf(req_buffer, "%s\r\n",
1585 headers = headers->next;
1590 CURLcode Curl_add_timecondition(struct SessionHandle *data,
1591 Curl_send_buffer *req_buffer)
1593 const struct tm *tm;
1594 char *buf = data->state.buffer;
1595 CURLcode result = CURLE_OK;
1598 result = Curl_gmtime(data->set.timevalue, &keeptime);
1600 failf(data, "Invalid TIMEVALUE");
1605 /* The If-Modified-Since header family should have their times set in
1606 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1607 * represented in Greenwich Mean Time (GMT), without exception. For the
1608 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1609 * Time)." (see page 20 of RFC2616).
1612 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1613 snprintf(buf, BUFSIZE-1,
1614 "%s, %02d %s %4d %02d:%02d:%02d GMT",
1615 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1617 Curl_month[tm->tm_mon],
1623 switch(data->set.timecondition) {
1624 case CURL_TIMECOND_IFMODSINCE:
1626 result = Curl_add_bufferf(req_buffer,
1627 "If-Modified-Since: %s\r\n", buf);
1629 case CURL_TIMECOND_IFUNMODSINCE:
1630 result = Curl_add_bufferf(req_buffer,
1631 "If-Unmodified-Since: %s\r\n", buf);
1633 case CURL_TIMECOND_LASTMOD:
1634 result = Curl_add_bufferf(req_buffer,
1635 "Last-Modified: %s\r\n", buf);
1643 * Curl_http() gets called from the generic Curl_do() function when a HTTP
1644 * request is to be performed. This creates and sends a properly constructed
1647 CURLcode Curl_http(struct connectdata *conn, bool *done)
1649 struct SessionHandle *data=conn->data;
1650 CURLcode result=CURLE_OK;
1652 const char *ppath = data->state.path;
1653 bool paste_ftp_userpwd = FALSE;
1654 char ftp_typecode[sizeof("/;type=?")] = "";
1655 const char *host = conn->host.name;
1656 const char *te = ""; /* transfer-encoding */
1658 const char *request;
1659 Curl_HttpReq httpreq = data->set.httpreq;
1660 char *addcookies = NULL;
1661 curl_off_t included_body = 0;
1662 const char *httpstring;
1663 Curl_send_buffer *req_buffer;
1664 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1665 int seekerr = CURL_SEEKFUNC_OK;
1667 /* Always consider the DO phase done after this function call, even if there
1668 may be parts of the request that is not yet sent, since we can deal with
1669 the rest of the request in the PERFORM phase. */
1672 /* If there already is a protocol-specific struct allocated for this
1673 sessionhandle, deal with it */
1674 Curl_reset_reqproto(conn);
1676 if(!data->state.proto.http) {
1677 /* Only allocate this struct if we don't already have it! */
1679 http = calloc(1, sizeof(struct HTTP));
1681 return CURLE_OUT_OF_MEMORY;
1682 data->state.proto.http = http;
1685 http = data->state.proto.http;
1687 if(!data->state.this_is_a_follow) {
1688 /* this is not a followed location, get the original host name */
1689 if(data->state.first_host)
1690 /* Free to avoid leaking memory on multiple requests*/
1691 free(data->state.first_host);
1693 data->state.first_host = strdup(conn->host.name);
1694 if(!data->state.first_host)
1695 return CURLE_OUT_OF_MEMORY;
1697 http->writebytecount = http->readbytecount = 0;
1699 if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
1701 httpreq = HTTPREQ_PUT;
1704 /* Now set the 'request' pointer to the proper request string */
1705 if(data->set.str[STRING_CUSTOMREQUEST])
1706 request = data->set.str[STRING_CUSTOMREQUEST];
1708 if(data->set.opt_no_body)
1711 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1714 case HTTPREQ_POST_FORM:
1720 default: /* this should never happen */
1731 /* The User-Agent string might have been allocated in url.c already, because
1732 it might have been used in the proxy connect, but if we have got a header
1733 with the user-agent string specified, we erase the previously made string
1735 if(Curl_checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
1736 free(conn->allocptr.uagent);
1737 conn->allocptr.uagent=NULL;
1740 /* setup the authentication headers */
1741 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1745 if((data->state.authhost.multi || data->state.authproxy.multi) &&
1746 (httpreq != HTTPREQ_GET) &&
1747 (httpreq != HTTPREQ_HEAD)) {
1748 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1749 with content-length zero as a "probe". */
1750 conn->bits.authneg = TRUE;
1753 conn->bits.authneg = FALSE;
1755 Curl_safefree(conn->allocptr.ref);
1756 if(data->change.referer && !Curl_checkheaders(data, "Referer:"))
1757 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1759 conn->allocptr.ref = NULL;
1761 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie:"))
1762 addcookies = data->set.str[STRING_COOKIE];
1764 if(!Curl_checkheaders(data, "Accept-Encoding:") &&
1765 data->set.str[STRING_ENCODING]) {
1766 Curl_safefree(conn->allocptr.accept_encoding);
1767 conn->allocptr.accept_encoding =
1768 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1769 if(!conn->allocptr.accept_encoding)
1770 return CURLE_OUT_OF_MEMORY;
1774 /* we only consider transfer-encoding magic if libz support is built-in */
1776 if(!Curl_checkheaders(data, "TE:") && data->set.http_transfer_encoding) {
1777 /* When we are to insert a TE: header in the request, we must also insert
1778 TE in a Connection: header, so we need to merge the custom provided
1779 Connection: header and prevent the original to get sent. Note that if
1780 the user has inserted his/hers own TE: header we don't do this magic
1781 but then assume that the user will handle it all! */
1782 char *cptr = Curl_checkheaders(data, "Connection:");
1783 #define TE_HEADER "TE: gzip\r\n"
1785 Curl_safefree(conn->allocptr.te);
1787 /* Create the (updated) Connection: header */
1788 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1789 strdup("Connection: TE\r\n" TE_HEADER);
1791 if(!conn->allocptr.te)
1792 return CURLE_OUT_OF_MEMORY;
1796 ptr = Curl_checkheaders(data, "Transfer-Encoding:");
1798 /* Some kind of TE is requested, check if 'chunked' is chosen */
1799 data->req.upload_chunky =
1800 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1803 if((conn->handler->protocol&CURLPROTO_HTTP) &&
1805 (data->set.infilesize == -1)) {
1806 if(conn->bits.authneg)
1807 /* don't enable chunked during auth neg */
1809 else if(use_http_1_1(data, conn)) {
1810 /* HTTP, upload, unknown file size and not HTTP 1.0 */
1811 data->req.upload_chunky = TRUE;
1814 failf(data, "Chunky upload is not supported by HTTP 1.0");
1815 return CURLE_UPLOAD_FAILED;
1819 /* else, no chunky upload */
1820 data->req.upload_chunky = FALSE;
1823 if(data->req.upload_chunky)
1824 te = "Transfer-Encoding: chunked\r\n";
1827 Curl_safefree(conn->allocptr.host);
1829 ptr = Curl_checkheaders(data, "Host:");
1830 if(ptr && (!data->state.this_is_a_follow ||
1831 Curl_raw_equal(data->state.first_host, conn->host.name))) {
1832 #if !defined(CURL_DISABLE_COOKIES)
1833 /* If we have a given custom Host: header, we extract the host name in
1834 order to possibly use it for cookie reasons later on. We only allow the
1835 custom Host: header if this is NOT a redirect, as setting Host: in the
1836 redirected request is being out on thin ice. Except if the host name
1837 is the same as the first one! */
1838 char *cookiehost = copy_header_value(ptr);
1840 return CURLE_OUT_OF_MEMORY;
1842 /* ignore empty data */
1845 /* If the host begins with '[', we start searching for the port after
1846 the bracket has been closed */
1847 int startsearch = 0;
1848 if(*cookiehost == '[') {
1849 char *closingbracket;
1850 /* since the 'cookiehost' is an allocated memory area that will be
1851 freed later we cannot simply increment the pointer */
1852 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
1853 closingbracket = strchr(cookiehost, ']');
1855 *closingbracket = 0;
1858 char *colon = strchr(cookiehost + startsearch, ':');
1860 *colon = 0; /* The host must not include an embedded port number */
1862 Curl_safefree(conn->allocptr.cookiehost);
1863 conn->allocptr.cookiehost = cookiehost;
1867 conn->allocptr.host = NULL;
1870 /* When building Host: headers, we must put the host name within
1871 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
1873 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
1874 (conn->remote_port == PORT_HTTPS)) ||
1875 ((conn->given->protocol&CURLPROTO_HTTP) &&
1876 (conn->remote_port == PORT_HTTP)) )
1877 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
1878 the port number in the host string */
1879 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
1880 conn->bits.ipv6_ip?"[":"",
1882 conn->bits.ipv6_ip?"]":"");
1884 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
1885 conn->bits.ipv6_ip?"[":"",
1887 conn->bits.ipv6_ip?"]":"",
1890 if(!conn->allocptr.host)
1891 /* without Host: we can't make a nice request */
1892 return CURLE_OUT_OF_MEMORY;
1895 #ifndef CURL_DISABLE_PROXY
1896 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
1897 /* Using a proxy but does not tunnel through it */
1899 /* The path sent to the proxy is in fact the entire URL. But if the remote
1900 host is a IDN-name, we must make sure that the request we produce only
1901 uses the encoded host name! */
1902 if(conn->host.dispname != conn->host.name) {
1903 char *url = data->change.url;
1904 ptr = strstr(url, conn->host.dispname);
1906 /* This is where the display name starts in the URL, now replace this
1907 part with the encoded name. TODO: This method of replacing the host
1908 name is rather crude as I believe there's a slight risk that the
1909 user has entered a user name or password that contain the host name
1911 size_t currlen = strlen(conn->host.dispname);
1912 size_t newlen = strlen(conn->host.name);
1913 size_t urllen = strlen(url);
1917 newurl = malloc(urllen + newlen - currlen + 1);
1919 /* copy the part before the host name */
1920 memcpy(newurl, url, ptr - url);
1921 /* append the new host name instead of the old */
1922 memcpy(newurl + (ptr - url), conn->host.name, newlen);
1923 /* append the piece after the host name */
1924 memcpy(newurl + newlen + (ptr - url),
1925 ptr + currlen, /* copy the trailing zero byte too */
1926 urllen - (ptr-url) - currlen + 1);
1927 if(data->change.url_alloc) {
1928 Curl_safefree(data->change.url);
1929 data->change.url_alloc = FALSE;
1931 data->change.url = newurl;
1932 data->change.url_alloc = TRUE;
1935 return CURLE_OUT_OF_MEMORY;
1938 ppath = data->change.url;
1939 if(checkprefix("ftp://", ppath)) {
1940 if(data->set.proxy_transfer_mode) {
1941 /* when doing ftp, append ;type=<a|i> if not present */
1942 char *type = strstr(ppath, ";type=");
1943 if(type && type[6] && type[7] == 0) {
1944 switch (Curl_raw_toupper(type[6])) {
1954 char *p = ftp_typecode;
1955 /* avoid sending invalid URLs like ftp://example.com;type=i if the
1956 * user specified ftp://example.com without the slash */
1957 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
1960 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
1961 data->set.prefer_ascii ? 'a' : 'i');
1964 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
1965 paste_ftp_userpwd = TRUE;
1968 #endif /* CURL_DISABLE_PROXY */
1970 if(HTTPREQ_POST_FORM == httpreq) {
1971 /* we must build the whole post sequence first, so that we have a size of
1972 the whole transfer before we start to send it */
1973 result = Curl_getformdata(data, &http->sendit, data->set.httppost,
1974 Curl_checkheaders(data, "Content-Type:"),
1980 http->p_accept = Curl_checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n";
1982 if(( (HTTPREQ_POST == httpreq) ||
1983 (HTTPREQ_POST_FORM == httpreq) ||
1984 (HTTPREQ_PUT == httpreq) ) &&
1985 data->state.resume_from) {
1986 /**********************************************************************
1987 * Resuming upload in HTTP means that we PUT or POST and that we have
1988 * got a resume_from value set. The resume value has already created
1989 * a Range: header that will be passed along. We need to "fast forward"
1990 * the file the given number of bytes and decrease the assume upload
1991 * file size before we continue this venture in the dark lands of HTTP.
1992 *********************************************************************/
1994 if(data->state.resume_from < 0 ) {
1996 * This is meant to get the size of the present remote-file by itself.
1997 * We don't support this now. Bail out!
1999 data->state.resume_from = 0;
2002 if(data->state.resume_from && !data->state.this_is_a_follow) {
2003 /* do we still game? */
2005 /* Now, let's read off the proper amount of bytes from the
2007 if(conn->seek_func) {
2008 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2012 if(seekerr != CURL_SEEKFUNC_OK) {
2013 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2014 failf(data, "Could not seek stream");
2015 return CURLE_READ_ERROR;
2017 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2019 curl_off_t passed=0;
2021 size_t readthisamountnow =
2022 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
2023 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
2025 size_t actuallyread =
2026 data->set.fread_func(data->state.buffer, 1, readthisamountnow,
2029 passed += actuallyread;
2030 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2031 /* this checks for greater-than only to make sure that the
2032 CURL_READFUNC_ABORT return code still aborts */
2033 failf(data, "Could only read %" FORMAT_OFF_T
2034 " bytes from the input",
2036 return CURLE_READ_ERROR;
2038 } while(passed < data->state.resume_from);
2042 /* now, decrease the size of the read */
2043 if(data->set.infilesize>0) {
2044 data->set.infilesize -= data->state.resume_from;
2046 if(data->set.infilesize <= 0) {
2047 failf(data, "File already completely uploaded");
2048 return CURLE_PARTIAL_FILE;
2051 /* we've passed, proceed as normal */
2054 if(data->state.use_range) {
2056 * A range is selected. We use different headers whether we're downloading
2057 * or uploading and we always let customized headers override our internal
2058 * ones if any such are specified.
2060 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2061 !Curl_checkheaders(data, "Range:")) {
2062 /* if a line like this was already allocated, free the previous one */
2063 if(conn->allocptr.rangeline)
2064 free(conn->allocptr.rangeline);
2065 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2068 else if((httpreq != HTTPREQ_GET) &&
2069 !Curl_checkheaders(data, "Content-Range:")) {
2071 /* if a line like this was already allocated, free the previous one */
2072 if(conn->allocptr.rangeline)
2073 free(conn->allocptr.rangeline);
2075 if(data->set.set_resume_from < 0) {
2076 /* Upload resume was asked for, but we don't know the size of the
2077 remote part so we tell the server (and act accordingly) that we
2078 upload the whole file (again) */
2079 conn->allocptr.rangeline =
2080 aprintf("Content-Range: bytes 0-%" FORMAT_OFF_T
2081 "/%" FORMAT_OFF_T "\r\n",
2082 data->set.infilesize - 1, data->set.infilesize);
2085 else if(data->state.resume_from) {
2086 /* This is because "resume" was selected */
2087 curl_off_t total_expected_size=
2088 data->state.resume_from + data->set.infilesize;
2089 conn->allocptr.rangeline =
2090 aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
2091 "/%" FORMAT_OFF_T "\r\n",
2092 data->state.range, total_expected_size-1,
2093 total_expected_size);
2096 /* Range was selected and then we just pass the incoming range and
2097 append total size */
2098 conn->allocptr.rangeline =
2099 aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
2100 data->state.range, data->set.infilesize);
2102 if(!conn->allocptr.rangeline)
2103 return CURLE_OUT_OF_MEMORY;
2107 /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2109 httpstring= use_http_1_1(data, conn)?"1.1":"1.0";
2111 /* initialize a dynamic send-buffer */
2112 req_buffer = Curl_add_buffer_init();
2115 return CURLE_OUT_OF_MEMORY;
2117 /* add the main request stuff */
2118 /* GET/HEAD/POST/PUT */
2119 result = Curl_add_bufferf(req_buffer, "%s ", request);
2124 if(paste_ftp_userpwd)
2125 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2126 conn->user, conn->passwd,
2127 ppath + sizeof("ftp://") - 1);
2129 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2134 Curl_add_bufferf(req_buffer,
2135 "%s" /* ftp typecode (;type=x) */
2136 " HTTP/%s\r\n" /* HTTP version */
2137 "%s" /* proxyuserpwd */
2140 "%s" /* user agent */
2144 "%s" /* accept-encoding */
2146 "%s" /* Proxy-Connection */
2147 "%s",/* transfer-encoding */
2151 conn->allocptr.proxyuserpwd?
2152 conn->allocptr.proxyuserpwd:"",
2153 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2154 (data->state.use_range && conn->allocptr.rangeline)?
2155 conn->allocptr.rangeline:"",
2156 (data->set.str[STRING_USERAGENT] &&
2157 *data->set.str[STRING_USERAGENT] &&
2158 conn->allocptr.uagent)?
2159 conn->allocptr.uagent:"",
2160 (conn->allocptr.host?conn->allocptr.host:""),
2161 http->p_accept?http->p_accept:"",
2162 conn->allocptr.te?conn->allocptr.te:"",
2163 (data->set.str[STRING_ENCODING] &&
2164 *data->set.str[STRING_ENCODING] &&
2165 conn->allocptr.accept_encoding)?
2166 conn->allocptr.accept_encoding:"",
2167 (data->change.referer && conn->allocptr.ref)?
2168 conn->allocptr.ref:"" /* Referer: <data> */,
2169 (conn->bits.httpproxy &&
2170 !conn->bits.tunnel_proxy &&
2171 !Curl_checkheaders(data, "Proxy-Connection:"))?
2172 "Proxy-Connection: Keep-Alive\r\n":"",
2177 * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
2178 * with basic and digest, it will be freed anyway by the next request
2181 Curl_safefree (conn->allocptr.userpwd);
2182 conn->allocptr.userpwd = NULL;
2187 #if !defined(CURL_DISABLE_COOKIES)
2188 if(data->cookies || addcookies) {
2189 struct Cookie *co=NULL; /* no cookies from start */
2193 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2194 co = Curl_cookie_getlist(data->cookies,
2195 conn->allocptr.cookiehost?
2196 conn->allocptr.cookiehost:host,
2198 (conn->handler->protocol&CURLPROTO_HTTPS)?
2200 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2203 struct Cookie *store=co;
2204 /* now loop through all cookies that matched */
2208 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2212 result = Curl_add_bufferf(req_buffer,
2213 "%s%s=%s", count?"; ":"",
2214 co->name, co->value);
2219 co = co->next; /* next cookie please */
2221 Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2223 if(addcookies && (CURLE_OK == result)) {
2225 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2226 if(CURLE_OK == result) {
2227 result = Curl_add_bufferf(req_buffer, "%s%s",
2233 if(count && (CURLE_OK == result))
2234 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2241 if(data->set.timecondition) {
2242 result = Curl_add_timecondition(data, req_buffer);
2247 result = Curl_add_custom_headers(conn, req_buffer);
2251 http->postdata = NULL; /* nothing to post at this point */
2252 Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
2254 /* If 'authdone' is FALSE, we must not set the write socket index to the
2255 Curl_transfer() call below, as we're not ready to actually upload any
2260 case HTTPREQ_POST_FORM:
2261 if(!http->sendit || conn->bits.authneg) {
2262 /* nothing to post! */
2263 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2267 result = Curl_add_buffer_send(req_buffer, conn,
2268 &data->info.request_size, 0, FIRSTSOCKET);
2270 failf(data, "Failed sending POST request");
2272 /* setup variables for the upcoming transfer */
2273 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2278 if(Curl_FormInit(&http->form, http->sendit)) {
2279 failf(data, "Internal HTTP POST error!");
2280 return CURLE_HTTP_POST_ERROR;
2283 /* Get the currently set callback function pointer and store that in the
2284 form struct since we might want the actual user-provided callback later
2285 on. The conn->fread_func pointer itself will be changed for the
2286 multipart case to the function that returns a multipart formatted
2288 http->form.fread_func = conn->fread_func;
2290 /* Set the read function to read from the generated form data */
2291 conn->fread_func = (curl_read_callback)Curl_FormReader;
2292 conn->fread_in = &http->form;
2294 http->sending = HTTPSEND_BODY;
2296 if(!data->req.upload_chunky &&
2297 !Curl_checkheaders(data, "Content-Length:")) {
2298 /* only add Content-Length if not uploading chunked */
2299 result = Curl_add_bufferf(req_buffer,
2300 "Content-Length: %" FORMAT_OFF_T "\r\n",
2306 result = expect100(data, conn, req_buffer);
2312 /* Get Content-Type: line from Curl_formpostheader.
2315 size_t linelength=0;
2316 contentType = Curl_formpostheader((void *)&http->form,
2319 failf(data, "Could not get Content-Type header line!");
2320 return CURLE_HTTP_POST_ERROR;
2323 result = Curl_add_buffer(req_buffer, contentType, linelength);
2328 /* make the request end in a true CRLF */
2329 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2333 /* set upload size to the progress meter */
2334 Curl_pgrsSetUploadSize(data, http->postsize);
2336 /* fire away the whole request to the server */
2337 result = Curl_add_buffer_send(req_buffer, conn,
2338 &data->info.request_size, 0, FIRSTSOCKET);
2340 failf(data, "Failed sending POST request");
2342 /* setup variables for the upcoming transfer */
2343 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2344 &http->readbytecount, FIRSTSOCKET,
2345 &http->writebytecount);
2348 Curl_formclean(&http->sendit); /* free that whole lot */
2352 /* convert the form data */
2353 result = Curl_convert_form(data, http->sendit);
2355 Curl_formclean(&http->sendit); /* free that whole lot */
2361 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2363 if(conn->bits.authneg)
2366 postsize = data->set.infilesize;
2368 if((postsize != -1) && !data->req.upload_chunky &&
2369 !Curl_checkheaders(data, "Content-Length:")) {
2370 /* only add Content-Length if not uploading chunked */
2371 result = Curl_add_bufferf(req_buffer,
2372 "Content-Length: %" FORMAT_OFF_T "\r\n",
2378 result = expect100(data, conn, req_buffer);
2382 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2386 /* set the upload size to the progress meter */
2387 Curl_pgrsSetUploadSize(data, postsize);
2389 /* this sends the buffer and frees all the buffer resources */
2390 result = Curl_add_buffer_send(req_buffer, conn,
2391 &data->info.request_size, 0, FIRSTSOCKET);
2393 failf(data, "Failed sending PUT request");
2395 /* prepare for transfer */
2396 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2397 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2398 postsize?&http->writebytecount:NULL);
2404 /* this is the simple POST, using x-www-form-urlencoded style */
2406 if(conn->bits.authneg)
2409 /* figure out the size of the postfields */
2410 postsize = (data->set.postfieldsize != -1)?
2411 data->set.postfieldsize:
2412 (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2414 if(!data->req.upload_chunky) {
2415 /* We only set Content-Length and allow a custom Content-Length if
2416 we don't upload data chunked, as RFC2616 forbids us to set both
2417 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2419 if(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length:")) {
2420 /* we allow replacing this header if not during auth negotiation,
2421 although it isn't very wise to actually set your own */
2422 result = Curl_add_bufferf(req_buffer,
2423 "Content-Length: %" FORMAT_OFF_T"\r\n",
2430 if(!Curl_checkheaders(data, "Content-Type:")) {
2431 result = Curl_add_bufferf(req_buffer,
2432 "Content-Type: application/"
2433 "x-www-form-urlencoded\r\n");
2438 /* For really small posts we don't use Expect: headers at all, and for
2439 the somewhat bigger ones we allow the app to disable it. Just make
2440 sure that the expect100header is always set to the preferred value
2442 ptr = Curl_checkheaders(data, "Expect:");
2444 data->state.expect100header =
2445 Curl_compareheader(ptr, "Expect:", "100-continue");
2447 else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2448 result = expect100(data, conn, req_buffer);
2453 data->state.expect100header = FALSE;
2455 if(data->set.postfields) {
2457 if(!data->state.expect100header &&
2458 (postsize < MAX_INITIAL_POST_SIZE)) {
2459 /* if we don't use expect: 100 AND
2460 postsize is less than MAX_INITIAL_POST_SIZE
2462 then append the post data to the HTTP request header. This limit
2463 is no magic limit but only set to prevent really huge POSTs to
2464 get the data duplicated with malloc() and family. */
2466 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2470 if(!data->req.upload_chunky) {
2471 /* We're not sending it 'chunked', append it to the request
2472 already now to reduce the number if send() calls */
2473 result = Curl_add_buffer(req_buffer, data->set.postfields,
2475 included_body = postsize;
2479 /* Append the POST data chunky-style */
2480 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2481 if(CURLE_OK == result) {
2482 result = Curl_add_buffer(req_buffer, data->set.postfields,
2484 if(CURLE_OK == result)
2485 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2486 included_body = postsize + 2;
2489 if(CURLE_OK == result)
2490 result = Curl_add_buffer(req_buffer,
2491 "\x30\x0d\x0a\x0d\x0a", 5);
2497 /* Make sure the progress information is accurate */
2498 Curl_pgrsSetUploadSize(data, postsize);
2501 /* A huge POST coming up, do data separate from the request */
2502 http->postsize = postsize;
2503 http->postdata = data->set.postfields;
2505 http->sending = HTTPSEND_BODY;
2507 conn->fread_func = (curl_read_callback)readmoredata;
2508 conn->fread_in = (void *)conn;
2510 /* set the upload size to the progress meter */
2511 Curl_pgrsSetUploadSize(data, http->postsize);
2513 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2519 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2523 if(data->req.upload_chunky && conn->bits.authneg) {
2524 /* Chunky upload is selected and we're negotiating auth still, send
2526 result = Curl_add_buffer(req_buffer,
2527 "\x30\x0d\x0a\x0d\x0a", 5);
2533 else if(data->set.postfieldsize) {
2534 /* set the upload size to the progress meter */
2535 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2537 /* set the pointer to mark that we will send the post body using the
2538 read callback, but only if we're not in authenticate
2540 if(!conn->bits.authneg) {
2541 http->postdata = (char *)&http->postdata;
2542 http->postsize = postsize;
2546 /* issue the request */
2547 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2548 (size_t)included_body, FIRSTSOCKET);
2551 failf(data, "Failed sending HTTP POST request");
2553 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2554 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2555 http->postdata?&http->writebytecount:NULL);
2559 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2563 /* issue the request */
2564 result = Curl_add_buffer_send(req_buffer, conn,
2565 &data->info.request_size, 0, FIRSTSOCKET);
2568 failf(data, "Failed sending HTTP request");
2570 /* HTTP GET/HEAD download: */
2571 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2572 http->postdata?FIRSTSOCKET:-1,
2573 http->postdata?&http->writebytecount:NULL);
2578 if(http->writebytecount) {
2579 /* if a request-body has been sent off, we make sure this progress is noted
2581 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2582 if(Curl_pgrsUpdate(conn))
2583 result = CURLE_ABORTED_BY_CALLBACK;
2585 if(http->writebytecount >= postsize) {
2586 /* already sent the entire request body, mark the "upload" as
2588 infof(data, "upload completely sent off: %" FORMAT_OFF_T " out of "
2589 "%" FORMAT_OFF_T " bytes\n",
2590 http->writebytecount, postsize);
2591 data->req.upload_done = TRUE;
2592 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2593 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2603 * Returns TRUE if member of the list matches prefix of string
2606 checkhttpprefix(struct SessionHandle *data,
2609 struct curl_slist *head = data->set.http200aliases;
2611 #ifdef CURL_DOES_CONVERSIONS
2612 /* convert from the network encoding using a scratch area */
2613 char *scratch = strdup(s);
2614 if(NULL == scratch) {
2615 failf (data, "Failed to allocate memory for conversion!");
2616 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2618 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2619 /* Curl_convert_from_network calls failf if unsuccessful */
2621 return FALSE; /* can't return CURLE_foobar so return FALSE */
2624 #endif /* CURL_DOES_CONVERSIONS */
2627 if(checkprefix(head->data, s)) {
2634 if(!rc && (checkprefix("HTTP/", s)))
2637 #ifdef CURL_DOES_CONVERSIONS
2639 #endif /* CURL_DOES_CONVERSIONS */
2643 #ifndef CURL_DISABLE_RTSP
2645 checkrtspprefix(struct SessionHandle *data,
2649 #ifdef CURL_DOES_CONVERSIONS
2650 /* convert from the network encoding using a scratch area */
2651 char *scratch = strdup(s);
2652 if(NULL == scratch) {
2653 failf (data, "Failed to allocate memory for conversion!");
2654 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2656 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2657 /* Curl_convert_from_network calls failf if unsuccessful */
2659 return FALSE; /* can't return CURLE_foobar so return FALSE */
2663 (void)data; /* unused */
2664 #endif /* CURL_DOES_CONVERSIONS */
2665 if(checkprefix("RTSP/", s))
2670 #endif /* CURL_DISABLE_RTSP */
2673 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2676 #ifndef CURL_DISABLE_RTSP
2677 if(conn->handler->protocol & CURLPROTO_RTSP)
2678 return checkrtspprefix(data, s);
2681 #endif /* CURL_DISABLE_RTSP */
2683 return checkhttpprefix(data, s);
2687 * header_append() copies a chunk of data to the end of the already received
2688 * header. We make sure that the full string fit in the allocated header
2689 * buffer, or else we enlarge it.
2691 static CURLcode header_append(struct SessionHandle *data,
2692 struct SingleRequest *k,
2695 if(k->hbuflen + length >= data->state.headersize) {
2696 /* We enlarge the header buffer as it is too small */
2701 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2702 /* The reason to have a max limit for this is to avoid the risk of a bad
2703 server feeding libcurl with a never-ending header that will cause
2704 reallocs infinitely */
2705 failf (data, "Avoided giant realloc for header (max is %d)!",
2706 CURL_MAX_HTTP_HEADER);
2707 return CURLE_OUT_OF_MEMORY;
2710 newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2711 hbufp_index = k->hbufp - data->state.headerbuff;
2712 newbuff = realloc(data->state.headerbuff, newsize);
2714 failf (data, "Failed to alloc memory for big header!");
2715 return CURLE_OUT_OF_MEMORY;
2717 data->state.headersize=newsize;
2718 data->state.headerbuff = newbuff;
2719 k->hbufp = data->state.headerbuff + hbufp_index;
2721 memcpy(k->hbufp, k->str_start, length);
2723 k->hbuflen += length;
2729 static void print_http_error(struct SessionHandle *data)
2731 struct SingleRequest *k = &data->req;
2734 /* make sure that data->req.p points to the HTTP status line */
2735 if(!strncmp(beg, "HTTP", 4)) {
2737 /* skip to HTTP status code */
2738 beg = strchr(beg, ' ');
2741 /* find trailing CR */
2742 char end_char = '\r';
2743 char *end = strchr(beg, end_char);
2745 /* try to find LF (workaround for non-compliant HTTP servers) */
2747 end = strchr(beg, end_char);
2751 /* temporarily replace CR or LF by NUL and print the error message */
2753 failf(data, "The requested URL returned error: %s", beg);
2755 /* restore the previously replaced CR or LF */
2762 /* fall-back to printing the HTTP status code only */
2763 failf(data, "The requested URL returned error: %d", k->httpcode);
2767 * Read any HTTP header lines from the server and pass them to the client app.
2769 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2770 struct connectdata *conn,
2775 struct SingleRequest *k = &data->req;
2777 /* header line within buffer loop */
2783 /* str_start is start of line within buf */
2784 k->str_start = k->str;
2786 /* data is in network encoding so use 0x0a instead of '\n' */
2787 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2790 /* Not a complete header line within buffer, append the data to
2791 the end of the headerbuff. */
2792 result = header_append(data, k, *nread);
2796 if(!k->headerline && (k->hbuflen>5)) {
2797 /* make a first check that this looks like a protocol header */
2798 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2799 /* this is not the beginning of a protocol first header line */
2801 k->badheader = HEADER_ALLBAD;
2806 break; /* read more and try again */
2809 /* decrease the size of the remaining (supposed) header line */
2810 rest_length = (k->end_ptr - k->str)+1;
2811 *nread -= (ssize_t)rest_length;
2813 k->str = k->end_ptr + 1; /* move past new line */
2815 full_length = k->str - k->str_start;
2817 result = header_append(data, k, full_length);
2821 k->end_ptr = k->hbufp;
2822 k->p = data->state.headerbuff;
2825 * We now have a FULL header line that p points to
2828 if(!k->headerline) {
2829 /* the first read header */
2830 if((k->hbuflen>5) &&
2831 !checkprotoprefix(data, conn, data->state.headerbuff)) {
2832 /* this is not the beginning of a protocol first header line */
2835 /* since there's more, this is a partial bad header */
2836 k->badheader = HEADER_PARTHEADER;
2838 /* this was all we read so it's all a bad header */
2839 k->badheader = HEADER_ALLBAD;
2840 *nread = (ssize_t)rest_length;
2846 /* headers are in network encoding so
2847 use 0x0a and 0x0d instead of '\n' and '\r' */
2848 if((0x0a == *k->p) || (0x0d == *k->p)) {
2850 /* Zero-length header line means end of headers! */
2852 #ifdef CURL_DOES_CONVERSIONS
2854 *k->p = '\r'; /* replace with CR in host encoding */
2855 k->p++; /* pass the CR byte */
2858 *k->p = '\n'; /* replace with LF in host encoding */
2859 k->p++; /* pass the LF byte */
2863 k->p++; /* pass the \r byte */
2865 k->p++; /* pass the \n byte */
2866 #endif /* CURL_DOES_CONVERSIONS */
2868 if(100 <= k->httpcode && 199 >= k->httpcode) {
2870 * We have made a HTTP PUT or POST and this is 1.1-lingo
2871 * that tells us that the server is OK with this and ready
2872 * to receive the data.
2873 * However, we'll get more headers now so we must get
2874 * back into the header-parsing state!
2877 k->headerline = 0; /* restart the header line counter */
2879 /* if we did wait for this do enable write now! */
2881 k->exp100 = EXP100_SEND_DATA;
2882 k->keepon |= KEEP_SEND;
2886 k->header = FALSE; /* no more header to parse! */
2888 if((k->size == -1) && !k->chunk && !conn->bits.close &&
2889 (conn->httpversion >= 11) &&
2890 !(conn->handler->protocol & CURLPROTO_RTSP) &&
2891 data->set.httpreq != HTTPREQ_HEAD) {
2892 /* On HTTP 1.1, when connection is not to get closed, but no
2893 Content-Length nor Content-Encoding chunked have been
2894 received, according to RFC2616 section 4.4 point 5, we
2895 assume that the server will close the connection to
2896 signal the end of the document. */
2897 infof(data, "no chunk, no close, no size. Assume close to "
2899 conn->bits.close = TRUE;
2904 * When all the headers have been parsed, see if we should give
2905 * up and return an error.
2907 if(http_should_fail(conn)) {
2908 failf (data, "The requested URL returned error: %d",
2910 return CURLE_HTTP_RETURNED_ERROR;
2913 /* now, only output this if the header AND body are requested:
2915 writetype = CLIENTWRITE_HEADER;
2916 if(data->set.include_header)
2917 writetype |= CLIENTWRITE_BODY;
2919 headerlen = k->p - data->state.headerbuff;
2921 result = Curl_client_write(conn, writetype,
2922 data->state.headerbuff,
2927 data->info.header_size += (long)headerlen;
2928 data->req.headerbytecount += (long)headerlen;
2930 data->req.deductheadercount =
2931 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
2933 if(!*stop_reading) {
2934 /* Curl_http_auth_act() checks what authentication methods
2935 * that are available and decides which one (if any) to
2936 * use. It will set 'newurl' if an auth method was picked. */
2937 result = Curl_http_auth_act(conn);
2942 if(k->httpcode >= 300) {
2943 if((!conn->bits.authneg) && !conn->bits.close &&
2944 !conn->bits.rewindaftersend) {
2946 * General treatment of errors when about to send data. Including :
2947 * "417 Expectation Failed", while waiting for 100-continue.
2949 * The check for close above is done simply because of something
2950 * else has already deemed the connection to get closed then
2951 * something else should've considered the big picture and we
2954 * rewindaftersend indicates that something has told libcurl to
2955 * continue sending even if it gets discarded
2958 switch(data->set.httpreq) {
2961 case HTTPREQ_POST_FORM:
2962 /* We got an error response. If this happened before the whole
2963 * request body has been sent we stop sending and mark the
2964 * connection for closure after we've read the entire response.
2966 if(!k->upload_done) {
2967 infof(data, "HTTP error before end of send, stop sending\n");
2968 conn->bits.close = TRUE; /* close after this */
2969 k->upload_done = TRUE;
2970 k->keepon &= ~KEEP_SEND; /* don't send */
2971 if(data->state.expect100header)
2972 k->exp100 = EXP100_FAILED;
2976 default: /* default label present to avoid compiler warnings */
2982 if(conn->bits.rewindaftersend) {
2983 /* We rewind after a complete send, so thus we continue
2985 infof(data, "Keep sending data to get tossed away!\n");
2986 k->keepon |= KEEP_SEND;
2992 * really end-of-headers.
2994 * If we requested a "no body", this is a good time to get
2995 * out and return home.
2997 if(data->set.opt_no_body)
2998 *stop_reading = TRUE;
3000 /* If we know the expected size of this document, we set the
3001 maximum download size to the size of the expected
3002 document or else, we won't know when to stop reading!
3004 Note that we set the download maximum even if we read a
3005 "Connection: close" header, to make sure that
3006 "Content-Length: 0" still prevents us from attempting to
3007 read the (missing) response-body.
3009 /* According to RFC2616 section 4.4, we MUST ignore
3010 Content-Length: headers if we are now receiving data
3011 using chunked Transfer-Encoding.
3014 k->maxdownload = k->size = -1;
3017 /* We do this operation even if no_body is true, since this
3018 data might be retrieved later with curl_easy_getinfo()
3019 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3021 Curl_pgrsSetDownloadSize(data, k->size);
3022 k->maxdownload = k->size;
3025 /* If max download size is *zero* (nothing) we already
3026 have nothing and can safely return ok now! */
3027 if(0 == k->maxdownload)
3028 *stop_reading = TRUE;
3031 /* we make sure that this socket isn't read more now */
3032 k->keepon &= ~KEEP_RECV;
3035 if(data->set.verbose)
3036 Curl_debug(data, CURLINFO_HEADER_IN,
3037 k->str_start, headerlen, conn);
3038 break; /* exit header line loop */
3041 /* We continue reading headers, so reset the line-based
3042 header parsing variables hbufp && hbuflen */
3043 k->hbufp = data->state.headerbuff;
3049 * Checks for special headers coming up.
3052 if(!k->headerline++) {
3053 /* This is the first header, it MUST be the error code line
3054 or else we consider this to be the body right away! */
3055 int httpversion_major;
3056 int rtspversion_major;
3058 #ifdef CURL_DOES_CONVERSIONS
3059 #define HEADER1 scratch
3060 #define SCRATCHSIZE 21
3062 char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
3063 /* We can't really convert this yet because we
3064 don't know if it's the 1st header line or the body.
3065 So we do a partial conversion into a scratch area,
3066 leaving the data at k->p as-is.
3068 strncpy(&scratch[0], k->p, SCRATCHSIZE);
3069 scratch[SCRATCHSIZE] = 0; /* null terminate */
3070 res = Curl_convert_from_network(data,
3074 /* Curl_convert_from_network calls failf if unsuccessful */
3077 #define HEADER1 k->p /* no conversion needed, just use k->p */
3078 #endif /* CURL_DOES_CONVERSIONS */
3080 if(conn->handler->protocol & CURLPROTO_HTTP) {
3081 nc = sscanf(HEADER1,
3087 conn->httpversion += 10 * httpversion_major;
3090 /* this is the real world, not a Nirvana
3091 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3093 nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3094 conn->httpversion = 10;
3096 /* If user has set option HTTP200ALIASES,
3097 compare header line against list of aliases
3100 if(checkhttpprefix(data, k->p)) {
3103 conn->httpversion = 10;
3108 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3109 nc = sscanf(HEADER1,
3115 conn->rtspversion += 10 * rtspversion_major;
3116 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3119 /* TODO: do we care about the other cases here? */
3125 data->info.httpcode = k->httpcode;
3127 data->info.httpversion = conn->httpversion;
3128 if(!data->state.httpversion ||
3129 data->state.httpversion > conn->httpversion)
3130 /* store the lowest server version we encounter */
3131 data->state.httpversion = conn->httpversion;
3134 * This code executes as part of processing the header. As a
3135 * result, it's not totally clear how to interpret the
3136 * response code yet as that depends on what other headers may
3137 * be present. 401 and 407 may be errors, but may be OK
3138 * depending on how authentication is working. Other codes
3139 * are definitely errors, so give up here.
3141 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3142 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3143 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3145 if(data->state.resume_from &&
3146 (data->set.httpreq==HTTPREQ_GET) &&
3147 (k->httpcode == 416)) {
3148 /* "Requested Range Not Satisfiable", just proceed and
3149 pretend this is no error */
3152 /* serious error, go home! */
3153 print_http_error(data);
3154 return CURLE_HTTP_RETURNED_ERROR;
3158 if(conn->httpversion == 10) {
3159 /* Default action for HTTP/1.0 must be to close, unless
3160 we get one of those fancy headers that tell us the
3161 server keeps it open for us! */
3162 infof(data, "HTTP 1.0, assume close after body\n");
3163 conn->bits.close = TRUE;
3165 else if(conn->httpversion >= 11 &&
3166 !conn->bits.close) {
3168 /* If HTTP version is >= 1.1 and connection is persistent
3169 server supports pipelining. */
3171 "HTTP 1.1 or later with persistent connection, "
3172 "pipelining supported\n"));
3173 conn->server_supports_pipelining = TRUE;
3176 switch(k->httpcode) {
3178 /* (quote from RFC2616, section 10.2.5): The server has
3179 * fulfilled the request but does not need to return an
3180 * entity-body ... The 204 response MUST NOT include a
3181 * message-body, and thus is always terminated by the first
3182 * empty line after the header fields. */
3185 /* (quote from RFC2616, section 10.3.5): The 304 response
3186 * MUST NOT contain a message-body, and thus is always
3187 * terminated by the first empty line after the header
3189 if(data->set.timecondition)
3190 data->info.timecond = TRUE;
3193 k->ignorecl = TRUE; /* ignore Content-Length headers */
3201 k->header = FALSE; /* this is not a header line */
3206 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3207 /* Curl_convert_from_network calls failf if unsuccessful */
3211 /* Check for Content-Length: header lines to get size */
3212 if(!k->ignorecl && !data->set.ignorecl &&
3213 checkprefix("Content-Length:", k->p)) {
3214 curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3215 if(data->set.max_filesize &&
3216 contentlength > data->set.max_filesize) {
3217 failf(data, "Maximum file size exceeded");
3218 return CURLE_FILESIZE_EXCEEDED;
3220 if(contentlength >= 0) {
3221 k->size = contentlength;
3222 k->maxdownload = k->size;
3223 /* we set the progress download size already at this point
3224 just to make it easier for apps/callbacks to extract this
3225 info as soon as possible */
3226 Curl_pgrsSetDownloadSize(data, k->size);
3229 /* Negative Content-Length is really odd, and we know it
3230 happens for example when older Apache servers send large
3232 conn->bits.close = TRUE;
3233 infof(data, "Negative content-length: %" FORMAT_OFF_T
3234 ", closing after transfer\n", contentlength);
3237 /* check for Content-Type: header lines to get the MIME-type */
3238 else if(checkprefix("Content-Type:", k->p)) {
3239 char *contenttype = copy_header_value(k->p);
3241 return CURLE_OUT_OF_MEMORY;
3243 /* ignore empty data */
3246 Curl_safefree(data->info.contenttype);
3247 data->info.contenttype = contenttype;
3250 else if((conn->httpversion == 10) &&
3251 conn->bits.httpproxy &&
3252 Curl_compareheader(k->p,
3253 "Proxy-Connection:", "keep-alive")) {
3255 * When a HTTP/1.0 reply comes when using a proxy, the
3256 * 'Proxy-Connection: keep-alive' line tells us the
3257 * connection will be kept alive for our pleasure.
3258 * Default action for 1.0 is to close.
3260 conn->bits.close = FALSE; /* don't close when done */
3261 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3263 else if((conn->httpversion == 11) &&
3264 conn->bits.httpproxy &&
3265 Curl_compareheader(k->p,
3266 "Proxy-Connection:", "close")) {
3268 * We get a HTTP/1.1 response from a proxy and it says it'll
3269 * close down after this transfer.
3271 conn->bits.close = TRUE; /* close when done */
3272 infof(data, "HTTP/1.1 proxy connection set close!\n");
3274 else if((conn->httpversion == 10) &&
3275 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3277 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3278 * tells us the connection will be kept alive for our
3279 * pleasure. Default action for 1.0 is to close.
3281 * [RFC2068, section 19.7.1] */
3282 conn->bits.close = FALSE; /* don't close when done */
3283 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3285 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3287 * [RFC 2616, section 8.1.2.1]
3288 * "Connection: close" is HTTP/1.1 language and means that
3289 * the connection will close when this request has been
3292 conn->bits.close = TRUE; /* close when done */
3294 else if(checkprefix("Transfer-Encoding:", k->p)) {
3295 /* One or more encodings. We check for chunked and/or a compression
3298 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3299 * means that the server will send a series of "chunks". Each
3300 * chunk starts with line with info (including size of the
3301 * coming block) (terminated with CRLF), then a block of data
3302 * with the previously mentioned size. There can be any amount
3303 * of chunks, and a chunk-data set to zero signals the
3308 /* Find the first non-space letter */
3312 /* skip whitespaces and commas */
3313 while(*start && (ISSPACE(*start) || (*start == ',')))
3316 if(checkprefix("chunked", start)) {
3317 k->chunk = TRUE; /* chunks coming our way */
3319 /* init our chunky engine */
3320 Curl_httpchunk_init(conn);
3325 if(k->auto_decoding)
3326 /* TODO: we only support the first mentioned compression for now */
3329 if(checkprefix("identity", start)) {
3330 k->auto_decoding = IDENTITY;
3333 else if(checkprefix("deflate", start)) {
3334 k->auto_decoding = DEFLATE;
3337 else if(checkprefix("gzip", start)) {
3338 k->auto_decoding = GZIP;
3341 else if(checkprefix("x-gzip", start)) {
3342 k->auto_decoding = GZIP;
3345 else if(checkprefix("compress", start)) {
3346 k->auto_decoding = COMPRESS;
3349 else if(checkprefix("x-compress", start)) {
3350 k->auto_decoding = COMPRESS;
3360 else if(checkprefix("Content-Encoding:", k->p) &&
3361 data->set.str[STRING_ENCODING]) {
3363 * Process Content-Encoding. Look for the values: identity,
3364 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3365 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3366 * 2616). zlib cannot handle compress. However, errors are
3367 * handled further down when the response body is processed
3371 /* Find the first non-space letter */
3373 while(*start && ISSPACE(*start))
3376 /* Record the content-encoding for later use */
3377 if(checkprefix("identity", start))
3378 k->auto_decoding = IDENTITY;
3379 else if(checkprefix("deflate", start))
3380 k->auto_decoding = DEFLATE;
3381 else if(checkprefix("gzip", start)
3382 || checkprefix("x-gzip", start))
3383 k->auto_decoding = GZIP;
3384 else if(checkprefix("compress", start)
3385 || checkprefix("x-compress", start))
3386 k->auto_decoding = COMPRESS;
3388 else if(checkprefix("Content-Range:", k->p)) {
3389 /* Content-Range: bytes [num]-
3390 Content-Range: bytes: [num]-
3391 Content-Range: [num]-
3393 The second format was added since Sun's webserver
3394 JavaWebServer/1.1.1 obviously sends the header this way!
3395 The third added since some servers use that!
3398 char *ptr = k->p + 14;
3400 /* Move forward until first digit */
3401 while(*ptr && !ISDIGIT(*ptr))
3404 k->offset = curlx_strtoofft(ptr, NULL, 10);
3406 if(data->state.resume_from == k->offset)
3407 /* we asked for a resume and we got it */
3408 k->content_range = TRUE;
3410 #if !defined(CURL_DISABLE_COOKIES)
3411 else if(data->cookies &&
3412 checkprefix("Set-Cookie:", k->p)) {
3413 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3414 CURL_LOCK_ACCESS_SINGLE);
3415 Curl_cookie_add(data,
3416 data->cookies, TRUE, k->p+11,
3417 /* If there is a custom-set Host: name, use it
3418 here, or else use real peer host name. */
3419 conn->allocptr.cookiehost?
3420 conn->allocptr.cookiehost:conn->host.name,
3422 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3425 else if(checkprefix("Last-Modified:", k->p) &&
3426 (data->set.timecondition || data->set.get_filetime) ) {
3427 time_t secs=time(NULL);
3428 k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3430 if(data->set.get_filetime)
3431 data->info.filetime = (long)k->timeofdoc;
3433 else if((checkprefix("WWW-Authenticate:", k->p) &&
3434 (401 == k->httpcode)) ||
3435 (checkprefix("Proxy-authenticate:", k->p) &&
3436 (407 == k->httpcode))) {
3437 result = Curl_http_input_auth(conn, k->httpcode, k->p);
3441 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3442 checkprefix("Location:", k->p) &&
3443 !data->req.location) {
3444 /* this is the URL that the server advises us to use instead */
3445 char *location = copy_header_value(k->p);
3447 return CURLE_OUT_OF_MEMORY;
3449 /* ignore empty data */
3452 data->req.location = location;
3454 if(data->set.http_follow_location) {
3455 DEBUGASSERT(!data->req.newurl);
3456 data->req.newurl = strdup(data->req.location); /* clone */
3457 if(!data->req.newurl)
3458 return CURLE_OUT_OF_MEMORY;
3460 /* some cases of POST and PUT etc needs to rewind the data
3461 stream at this point */
3462 result = http_perhapsrewind(conn);
3468 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3469 result = Curl_rtsp_parseheader(conn, k->p);
3475 * End of header-checks. Write them to the client.
3478 writetype = CLIENTWRITE_HEADER;
3479 if(data->set.include_header)
3480 writetype |= CLIENTWRITE_BODY;
3482 if(data->set.verbose)
3483 Curl_debug(data, CURLINFO_HEADER_IN,
3484 k->p, (size_t)k->hbuflen, conn);
3486 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3490 data->info.header_size += (long)k->hbuflen;
3491 data->req.headerbytecount += (long)k->hbuflen;
3493 /* reset hbufp pointer && hbuflen */
3494 k->hbufp = data->state.headerbuff;
3497 while(!*stop_reading && *k->str); /* header line within buffer */
3499 /* We might have reached the end of the header part here, but
3500 there might be a non-header part left in the end of the read
3506 #endif /* CURL_DISABLE_HTTP */