1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2011, 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 ***************************************************************************/
25 #ifndef CURL_DISABLE_HTTP
27 #ifdef HAVE_SYS_SOCKET_H
28 #include <sys/socket.h>
30 #ifdef HAVE_NETINET_IN_H
31 #include <netinet/in.h>
40 #ifdef HAVE_ARPA_INET_H
41 #include <arpa/inet.h>
46 #ifdef HAVE_SYS_IOCTL_H
47 #include <sys/ioctl.h>
50 #ifdef HAVE_SYS_PARAM_H
51 #include <sys/param.h>
55 #include <curl/curl.h>
60 #include "curl_base64.h"
64 #include "http_digest.h"
65 #include "http_ntlm.h"
66 #include "http_negotiate.h"
71 #include "curl_memory.h"
73 #include "parsedate.h" /* for the week day and month names */
74 #include "strtoofft.h"
77 #include "content_encoding.h"
78 #include "http_proxy.h"
80 #include "non-ascii.h"
82 #define _MPRINTF_REPLACE /* use our functions only */
83 #include <curl/mprintf.h>
85 /* The last #include file should be: */
89 * Forward declarations.
92 static int http_getsock_do(struct connectdata *conn,
95 static int http_should_fail(struct connectdata *conn);
98 static CURLcode https_connecting(struct connectdata *conn, bool *done);
99 static int https_getsock(struct connectdata *conn,
100 curl_socket_t *socks,
103 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
107 * HTTP handler interface.
109 const struct Curl_handler Curl_handler_http = {
111 ZERO_NULL, /* setup_connection */
112 Curl_http, /* do_it */
113 Curl_http_done, /* done */
114 ZERO_NULL, /* do_more */
115 Curl_http_connect, /* connect_it */
116 ZERO_NULL, /* connecting */
117 ZERO_NULL, /* doing */
118 ZERO_NULL, /* proto_getsock */
119 http_getsock_do, /* doing_getsock */
120 ZERO_NULL, /* perform_getsock */
121 ZERO_NULL, /* disconnect */
122 ZERO_NULL, /* readwrite */
123 PORT_HTTP, /* defport */
124 CURLPROTO_HTTP, /* protocol */
125 PROTOPT_NONE /* flags */
130 * HTTPS handler interface.
132 const struct Curl_handler Curl_handler_https = {
133 "HTTPS", /* scheme */
134 ZERO_NULL, /* setup_connection */
135 Curl_http, /* do_it */
136 Curl_http_done, /* done */
137 ZERO_NULL, /* do_more */
138 Curl_http_connect, /* connect_it */
139 https_connecting, /* connecting */
140 ZERO_NULL, /* doing */
141 https_getsock, /* proto_getsock */
142 http_getsock_do, /* doing_getsock */
143 ZERO_NULL, /* perform_getsock */
144 ZERO_NULL, /* disconnect */
145 ZERO_NULL, /* readwrite */
146 PORT_HTTPS, /* defport */
147 CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
148 PROTOPT_SSL /* flags */
154 * checkheaders() checks the linked list of custom HTTP headers for a
155 * particular header (prefix).
157 * Returns a pointer to the first matching header or NULL if none matched.
159 char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader)
161 struct curl_slist *head;
162 size_t thislen = strlen(thisheader);
164 for(head = data->set.headers; head; head=head->next) {
165 if(Curl_raw_nequal(head->data, thisheader, thislen))
172 * Strip off leading and trailing whitespace from the value in the
173 * given HTTP header line and return a strdupped copy. Returns NULL in
174 * case of allocation failure. Returns an empty string if the header value
175 * consists entirely of whitespace.
177 static char *copy_header_value(const char *h)
186 /* Find the end of the header name */
187 while(*h && (*h != ':'))
191 /* Skip over colon */
194 /* Find the first non-space letter */
196 while(*start && ISSPACE(*start))
199 /* data is in the host encoding so
200 use '\r' and '\n' instead of 0x0d and 0x0a */
201 end = strchr(start, '\r');
203 end = strchr(start, '\n');
205 end = strchr(start, '\0');
209 /* skip all trailing space letters */
210 while((end > start) && ISSPACE(*end))
213 /* get length of the type */
216 value = malloc(len + 1);
220 memcpy(value, start, len);
221 value[len] = 0; /* zero terminate */
227 * http_output_basic() sets up an Authorization: header (or the proxy version)
228 * for HTTP Basic authentication.
232 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
235 char *authorization = NULL;
236 struct SessionHandle *data = conn->data;
243 userp = &conn->allocptr.proxyuserpwd;
244 user = conn->proxyuser;
245 pwd = conn->proxypasswd;
248 userp = &conn->allocptr.userpwd;
253 snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
255 error = Curl_base64_encode(data,
256 data->state.buffer, strlen(data->state.buffer),
257 &authorization, &size);
262 return CURLE_REMOTE_ACCESS_DENIED;
264 Curl_safefree(*userp);
265 *userp = aprintf("%sAuthorization: Basic %s\r\n",
270 return CURLE_OUT_OF_MEMORY;
275 /* pickoneauth() selects the most favourable authentication method from the
276 * ones available and the ones we want.
278 * return TRUE if one was picked
280 static bool pickoneauth(struct auth *pick)
283 /* only deal with authentication we want */
284 long avail = pick->avail & pick->want;
287 /* The order of these checks is highly relevant, as this will be the order
288 of preference in case of the existence of multiple accepted types. */
289 if(avail & CURLAUTH_GSSNEGOTIATE)
290 pick->picked = CURLAUTH_GSSNEGOTIATE;
291 else if(avail & CURLAUTH_DIGEST)
292 pick->picked = CURLAUTH_DIGEST;
293 else if(avail & CURLAUTH_NTLM)
294 pick->picked = CURLAUTH_NTLM;
295 else if(avail & CURLAUTH_NTLM_SSO)
296 pick->picked = CURLAUTH_NTLM_SSO;
297 else if(avail & CURLAUTH_BASIC)
298 pick->picked = CURLAUTH_BASIC;
300 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
303 pick->avail = CURLAUTH_NONE; /* clear it here */
309 * Curl_http_perhapsrewind()
311 * If we are doing POST or PUT {
312 * If we have more data to send {
313 * If we are doing NTLM {
314 * Keep sending since we must not disconnect
317 * If there is more than just a little data left to send, close
318 * the current connection by force.
321 * If we have sent any data {
322 * If we don't have track of all the data {
323 * call app to tell it to rewind
326 * rewind internally so that the operation can restart fine
331 static CURLcode http_perhapsrewind(struct connectdata *conn)
333 struct SessionHandle *data = conn->data;
334 struct HTTP *http = data->state.proto.http;
335 curl_off_t bytessent;
336 curl_off_t expectsend = -1; /* default is unknown */
339 /* If this is still NULL, we have not reach very far and we can safely
340 skip this rewinding stuff */
343 switch(data->set.httpreq) {
351 bytessent = http->writebytecount;
353 if(conn->bits.authneg)
354 /* This is a state where we are known to be negotiating and we don't send
358 /* figure out how much data we are expected to send */
359 switch(data->set.httpreq) {
361 if(data->set.postfieldsize != -1)
362 expectsend = data->set.postfieldsize;
363 else if(data->set.postfields)
364 expectsend = (curl_off_t)strlen(data->set.postfields);
367 if(data->set.infilesize != -1)
368 expectsend = data->set.infilesize;
370 case HTTPREQ_POST_FORM:
371 expectsend = http->postsize;
378 conn->bits.rewindaftersend = FALSE; /* default */
380 if((expectsend == -1) || (expectsend > bytessent)) {
381 /* There is still data left to send */
382 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
383 (data->state.authhost.picked == CURLAUTH_NTLM) ||
384 (data->state.authproxy.picked == CURLAUTH_NTLM_SSO) ||
385 (data->state.authhost.picked == CURLAUTH_NTLM_SSO)) {
386 if(((expectsend - bytessent) < 2000) ||
387 (conn->ntlm.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 NTLM with 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);
549 if(authstatus->picked == CURLAUTH_NTLM_SSO) {
551 #ifdef WINBIND_NTLM_AUTH_ENABLED
552 result = Curl_output_ntlm_sso(conn, proxy);
556 return CURLE_REMOTE_ACCESS_DENIED;
561 #ifndef CURL_DISABLE_CRYPTO_AUTH
562 if(authstatus->picked == CURLAUTH_DIGEST) {
564 result = Curl_output_digest(conn,
566 (const unsigned char *)request,
567 (const unsigned char *)path);
573 if(authstatus->picked == CURLAUTH_BASIC) {
575 if((proxy && conn->bits.proxy_user_passwd &&
576 !Curl_checkheaders(data, "Proxy-authorization:")) ||
577 (!proxy && conn->bits.user_passwd &&
578 !Curl_checkheaders(data, "Authorization:"))) {
580 result = http_output_basic(conn, proxy);
584 /* NOTE: this function should set 'done' TRUE, as the other auth
585 functions work that way */
586 authstatus->done = TRUE;
590 infof(data, "%s auth using %s with user '%s'\n",
591 proxy?"Proxy":"Server", auth,
592 proxy?(conn->proxyuser?conn->proxyuser:""):
593 (conn->user?conn->user:""));
594 authstatus->multi = (bool)(!authstatus->done);
597 authstatus->multi = FALSE;
603 * Curl_http_output_auth() setups the authentication headers for the
604 * host/proxy and the correct authentication
605 * method. conn->data->state.authdone is set to TRUE when authentication is
608 * @param conn all information about the current connection
609 * @param request pointer to the request keyword
610 * @param path pointer to the requested path
611 * @param proxytunnel boolean if this is the request setting up a "proxy
617 Curl_http_output_auth(struct connectdata *conn,
620 bool proxytunnel) /* TRUE if this is the request setting
621 up the proxy tunnel */
623 CURLcode result = CURLE_OK;
624 struct SessionHandle *data = conn->data;
625 struct auth *authhost;
626 struct auth *authproxy;
630 authhost = &data->state.authhost;
631 authproxy = &data->state.authproxy;
633 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
634 conn->bits.user_passwd)
635 /* continue please */ ;
637 authhost->done = TRUE;
638 authproxy->done = TRUE;
639 return CURLE_OK; /* no authentication with no user or password */
642 if(authhost->want && !authhost->picked)
643 /* The app has selected one or more methods, but none has been picked
644 so far by a server round-trip. Then we set the picked one to the
645 want one, and if this is one single bit it'll be used instantly. */
646 authhost->picked = authhost->want;
648 if(authproxy->want && !authproxy->picked)
649 /* The app has selected one or more methods, but none has been picked so
650 far by a proxy round-trip. Then we set the picked one to the want one,
651 and if this is one single bit it'll be used instantly. */
652 authproxy->picked = authproxy->want;
654 #ifndef CURL_DISABLE_PROXY
655 /* Send proxy authentication header if needed */
656 if(conn->bits.httpproxy &&
657 (conn->bits.tunnel_proxy == proxytunnel)) {
658 result = output_auth_headers(conn, authproxy, request, path, TRUE);
665 #endif /* CURL_DISABLE_PROXY */
666 /* we have no proxy so let's pretend we're done authenticating
668 authproxy->done = TRUE;
670 /* To prevent the user+password to get sent to other than the original
671 host due to a location-follow, we do some weirdo checks here */
672 if(!data->state.this_is_a_follow ||
674 !data->state.first_host ||
675 data->set.http_disable_hostname_check_before_authentication ||
676 Curl_raw_equal(data->state.first_host, conn->host.name)) {
677 result = output_auth_headers(conn, authhost, request, path, FALSE);
680 authhost->done = TRUE;
687 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
688 * headers. They are dealt with both in the transfer.c main loop and in the
689 * proxy CONNECT loop.
692 CURLcode Curl_http_input_auth(struct connectdata *conn,
694 const char *header) /* the first non-space */
697 * This resource requires authentication
699 struct SessionHandle *data = conn->data;
705 if(httpcode == 407) {
706 start = header+strlen("Proxy-authenticate:");
707 availp = &data->info.proxyauthavail;
708 authp = &data->state.authproxy;
711 start = header+strlen("WWW-Authenticate:");
712 availp = &data->info.httpauthavail;
713 authp = &data->state.authhost;
716 /* pass all white spaces */
717 while(*start && ISSPACE(*start))
721 * Here we check if we want the specific single authentication (using ==) and
722 * if we do, we initiate usage of it.
724 * If the provided authentication is wanted as one out of several accepted
725 * types (using &), we OR this authentication type to the authavail
730 * ->picked is first set to the 'want' value (one or more bits) before the
731 * request is sent, and then it is again set _after_ all response 401/407
732 * headers have been received but then only to a single preferred method
737 #ifdef USE_HTTP_NEGOTIATE
738 if(checkprefix("GSS-Negotiate", start) ||
739 checkprefix("Negotiate", start)) {
741 *availp |= CURLAUTH_GSSNEGOTIATE;
742 authp->avail |= CURLAUTH_GSSNEGOTIATE;
744 if(data->state.negotiate.state == GSS_AUTHSENT) {
745 /* if we sent GSS authentication in the outgoing request and we get this
746 back, we're in trouble */
747 infof(data, "Authentication problem. Ignoring this.\n");
748 data->state.authproblem = TRUE;
751 neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
753 DEBUGASSERT(!data->req.newurl);
754 data->req.newurl = strdup(data->change.url);
755 if(!data->req.newurl)
756 return CURLE_OUT_OF_MEMORY;
757 data->state.authproblem = FALSE;
758 /* we received GSS auth info and we dealt with it fine */
759 data->state.negotiate.state = GSS_AUTHRECV;
762 data->state.authproblem = TRUE;
769 /* NTLM support requires the SSL crypto libs */
770 if(checkprefix("NTLM", start)) {
771 *availp |= CURLAUTH_NTLM;
772 authp->avail |= CURLAUTH_NTLM;
773 if(authp->picked == CURLAUTH_NTLM ||
774 authp->picked == CURLAUTH_NTLM_SSO) {
775 /* NTLM authentication is picked and activated */
777 Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
778 if(CURLE_OK == ntlm) {
779 data->state.authproblem = FALSE;
780 #ifdef WINBIND_NTLM_AUTH_ENABLED
781 if(authp->picked == CURLAUTH_NTLM_SSO) {
782 *availp &= ~CURLAUTH_NTLM;
783 authp->avail &= ~CURLAUTH_NTLM;
784 *availp |= CURLAUTH_NTLM_SSO;
785 authp->avail |= CURLAUTH_NTLM_SSO;
787 /* Get the challenge-message which will be passed to
788 * ntlm_auth for generating the type 3 message later */
789 while(*start && ISSPACE(*start))
791 if(checkprefix("NTLM", start)) {
792 start += strlen("NTLM");
793 while(*start && ISSPACE(*start))
796 if((conn->challenge_header = strdup(start)) == NULL)
797 return CURLE_OUT_OF_MEMORY;
803 infof(data, "Authentication problem. Ignoring this.\n");
804 data->state.authproblem = TRUE;
810 #ifndef CURL_DISABLE_CRYPTO_AUTH
811 if(checkprefix("Digest", start)) {
812 if((authp->avail & CURLAUTH_DIGEST) != 0) {
813 infof(data, "Ignoring duplicate digest auth header.\n");
817 *availp |= CURLAUTH_DIGEST;
818 authp->avail |= CURLAUTH_DIGEST;
820 /* We call this function on input Digest headers even if Digest
821 * authentication isn't activated yet, as we need to store the
822 * incoming data from this header in case we are gonna use Digest. */
823 dig = Curl_input_digest(conn, (bool)(httpcode == 407), start);
825 if(CURLDIGEST_FINE != dig) {
826 infof(data, "Authentication problem. Ignoring this.\n");
827 data->state.authproblem = TRUE;
833 if(checkprefix("Basic", start)) {
834 *availp |= CURLAUTH_BASIC;
835 authp->avail |= CURLAUTH_BASIC;
836 if(authp->picked == CURLAUTH_BASIC) {
837 /* We asked for Basic authentication but got a 40X back
838 anyway, which basically means our name+password isn't
840 authp->avail = CURLAUTH_NONE;
841 infof(data, "Authentication problem. Ignoring this.\n");
842 data->state.authproblem = TRUE;
850 * http_should_fail() determines whether an HTTP response has gotten us
851 * into an error state or not.
853 * @param conn all information about the current connection
855 * @retval 0 communications should continue
857 * @retval 1 communications should not continue
859 static int http_should_fail(struct connectdata *conn)
861 struct SessionHandle *data;
868 httpcode = data->req.httpcode;
871 ** If we haven't been asked to fail on error,
874 if(!data->set.http_fail_on_error)
878 ** Any code < 400 is never terminal.
883 if(data->state.resume_from &&
884 (data->set.httpreq==HTTPREQ_GET) &&
886 /* "Requested Range Not Satisfiable", just proceed and
887 pretend this is no error */
892 ** Any code >= 400 that's not 401 or 407 is always
895 if((httpcode != 401) &&
900 ** All we have left to deal with is 401 and 407
902 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
905 ** Examine the current authentication state to see if this
906 ** is an error. The idea is for this function to get
907 ** called after processing all the headers in a response
908 ** message. So, if we've been to asked to authenticate a
909 ** particular stage, and we've done it, we're OK. But, if
910 ** we're already completely authenticated, it's not OK to
911 ** get another 401 or 407.
913 ** It is possible for authentication to go stale such that
914 ** the client needs to reauthenticate. Once that info is
915 ** available, use it here.
919 ** Either we're not authenticating, or we're supposed to
920 ** be authenticating something else. This is an error.
922 if((httpcode == 401) && !conn->bits.user_passwd)
924 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
927 return data->state.authproblem;
931 * readmoredata() is a "fread() emulation" to provide POST and/or request
932 * data. It is used when a huge POST is to be made and the entire chunk wasn't
933 * sent in the first send(). This function will then be called from the
934 * transfer.c loop when more data is to be sent to the peer.
936 * Returns the amount of bytes it filled the buffer with.
938 static size_t readmoredata(char *buffer,
943 struct connectdata *conn = (struct connectdata *)userp;
944 struct HTTP *http = conn->data->state.proto.http;
945 size_t fullsize = size * nitems;
947 if(0 == http->postsize)
948 /* nothing to return */
951 /* make sure that a HTTP request is never sent away chunked! */
952 conn->data->req.forbidchunk = (bool)(http->sending == HTTPSEND_REQUEST);
954 if(http->postsize <= (curl_off_t)fullsize) {
955 memcpy(buffer, http->postdata, (size_t)http->postsize);
956 fullsize = (size_t)http->postsize;
958 if(http->backup.postsize) {
959 /* move backup data into focus and continue on that */
960 http->postdata = http->backup.postdata;
961 http->postsize = http->backup.postsize;
962 conn->fread_func = http->backup.fread_func;
963 conn->fread_in = http->backup.fread_in;
965 http->sending++; /* move one step up */
967 http->backup.postsize=0;
975 memcpy(buffer, http->postdata, fullsize);
976 http->postdata += fullsize;
977 http->postsize -= fullsize;
982 /* ------------------------------------------------------------------------- */
983 /* add_buffer functions */
986 * Curl_add_buffer_init() sets up and returns a fine buffer struct
988 Curl_send_buffer *Curl_add_buffer_init(void)
990 return calloc(1, sizeof(Curl_send_buffer));
994 * Curl_add_buffer_send() sends a header buffer and frees all associated
995 * memory. Body data may be appended to the header data if desired.
999 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
1000 struct connectdata *conn,
1002 /* add the number of sent bytes to this
1004 long *bytes_written,
1006 /* how much of the buffer contains body data */
1007 size_t included_body_bytes,
1015 struct HTTP *http = conn->data->state.proto.http;
1017 curl_socket_t sockfd;
1020 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1022 sockfd = conn->sock[socketindex];
1024 /* The looping below is required since we use non-blocking sockets, but due
1025 to the circumstances we will just loop and try again and again etc */
1028 size = in->size_used;
1030 headersize = size - included_body_bytes; /* the initial part that isn't body
1033 DEBUGASSERT(size > included_body_bytes);
1035 res = Curl_convert_to_network(conn->data, ptr, headersize);
1036 /* Curl_convert_to_network calls failf if unsuccessful */
1038 /* conversion failed, free memory and return to the caller */
1045 if(conn->handler->flags & PROTOPT_SSL) {
1046 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1047 when we speak HTTPS, as if only a fraction of it is sent now, this data
1048 needs to fit into the normal read-callback buffer later on and that
1049 buffer is using this size.
1052 sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
1054 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1055 library when we attempt to re-send this buffer. Sending the same data
1056 is not enough, we must use the exact same address. For this reason, we
1057 must copy the data to the uploadbuffer first, since that is the buffer
1058 we will be using if this send is retried later.
1060 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1061 ptr = conn->data->state.uploadbuffer;
1066 res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1068 if(CURLE_OK == res) {
1070 * Note that we may not send the entire chunk at once, and we have a set
1071 * number of data bytes at the end of the big buffer (out of which we may
1072 * only send away a part).
1074 /* how much of the header that was sent */
1075 size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
1076 size_t bodylen = amount - headlen;
1078 if(conn->data->set.verbose) {
1079 /* this data _may_ contain binary stuff */
1080 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1081 if((size_t)amount > headlen) {
1082 /* there was body data sent beyond the initial header part, pass that
1083 on to the debug callback too */
1084 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1085 ptr+headlen, bodylen, conn);
1089 /* since we sent a piece of the body here, up the byte counter for it
1091 http->writebytecount += bodylen;
1093 /* 'amount' can never be a very large value here so typecasting it so a
1094 signed 31 bit value should not cause problems even if ssize_t is
1096 *bytes_written += (long)amount;
1099 if((size_t)amount != size) {
1100 /* The whole request could not be sent in one system call. We must
1101 queue it up and send it later when we get the chance. We must not
1102 loop here and wait until it might work again. */
1106 ptr = in->buffer + amount;
1108 /* backup the currently set pointers */
1109 http->backup.fread_func = conn->fread_func;
1110 http->backup.fread_in = conn->fread_in;
1111 http->backup.postdata = http->postdata;
1112 http->backup.postsize = http->postsize;
1114 /* set the new pointers for the request-sending */
1115 conn->fread_func = (curl_read_callback)readmoredata;
1116 conn->fread_in = (void *)conn;
1117 http->postdata = ptr;
1118 http->postsize = (curl_off_t)size;
1120 http->send_buffer = in;
1121 http->sending = HTTPSEND_REQUEST;
1125 http->sending = HTTPSEND_BODY;
1126 /* the full buffer was sent, clean up and return */
1129 if((size_t)amount != size)
1130 /* We have no continue-send mechanism now, fail. This can only happen
1131 when this function is used from the CONNECT sending function. We
1132 currently (stupidly) assume that the whole request is always sent
1133 away in the first single chunk.
1137 return CURLE_SEND_ERROR;
1139 conn->writechannel_inuse = FALSE;
1151 * add_bufferf() add the formatted input to the buffer.
1153 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1158 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1162 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1166 /* If we failed, we cleanup the whole buffer and return error */
1170 return CURLE_OUT_OF_MEMORY;
1174 * add_buffer() appends a memory chunk to the existing buffer
1176 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1181 if(~size < in->size_used) {
1182 /* If resulting used size of send buffer would wrap size_t, cleanup
1183 the whole buffer and return error. Otherwise the required buffer
1184 size will fit into a single allocatable memory chunk */
1185 Curl_safefree(in->buffer);
1187 return CURLE_OUT_OF_MEMORY;
1191 ((in->size_used + size) > (in->size_max - 1))) {
1193 /* If current buffer size isn't enough to hold the result, use a
1194 buffer size that doubles the required size. If this new size
1195 would wrap size_t, then just use the largest possible one */
1197 if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
1198 (~(size*2) < (in->size_used*2)))
1199 new_size = (size_t)-1;
1201 new_size = (in->size_used+size)*2;
1204 /* we have a buffer, enlarge the existing one */
1205 new_rb = realloc(in->buffer, new_size);
1207 /* create a new buffer */
1208 new_rb = malloc(new_size);
1211 /* If we failed, we cleanup the whole buffer and return error */
1212 Curl_safefree(in->buffer);
1214 return CURLE_OUT_OF_MEMORY;
1217 in->buffer = new_rb;
1218 in->size_max = new_size;
1220 memcpy(&in->buffer[in->size_used], inptr, size);
1222 in->size_used += size;
1227 /* end of the add_buffer functions */
1228 /* ------------------------------------------------------------------------- */
1233 * Curl_compareheader()
1235 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1236 * Pass headers WITH the colon.
1239 Curl_compareheader(const char *headerline, /* line to check */
1240 const char *header, /* header keyword _with_ colon */
1241 const char *content) /* content string to find */
1243 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1244 * by a colon (":") and the field value. Field names are case-insensitive.
1245 * The field value MAY be preceded by any amount of LWS, though a single SP
1248 size_t hlen = strlen(header);
1254 if(!Curl_raw_nequal(headerline, header, hlen))
1255 return FALSE; /* doesn't start with header */
1257 /* pass the header */
1258 start = &headerline[hlen];
1260 /* pass all white spaces */
1261 while(*start && ISSPACE(*start))
1264 /* find the end of the header line */
1265 end = strchr(start, '\r'); /* lines end with CRLF */
1267 /* in case there's a non-standard compliant line here */
1268 end = strchr(start, '\n');
1271 /* hm, there's no line ending here, use the zero byte! */
1272 end = strchr(start, '\0');
1275 len = end-start; /* length of the content part of the input line */
1276 clen = strlen(content); /* length of the word to find */
1278 /* find the content string in the rest of the line */
1279 for(;len>=clen;len--, start++) {
1280 if(Curl_raw_nequal(start, content, clen))
1281 return TRUE; /* match! */
1284 return FALSE; /* no match */
1288 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1289 * the generic Curl_connect().
1291 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1293 struct SessionHandle *data;
1298 /* We default to persistent connections. We set this already in this connect
1299 function to make the re-use checks properly be able to check this bit. */
1300 conn->bits.close = FALSE;
1302 #ifndef CURL_DISABLE_PROXY
1303 /* If we are not using a proxy and we want a secure connection, perform SSL
1304 * initialization & connection now. If using a proxy with https, then we
1305 * must tell the proxy to CONNECT to the host we want to talk to. Only
1306 * after the connect has occurred, can we start talking SSL
1308 if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
1310 /* either SSL over proxy, or explicitly asked for */
1311 result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
1314 if(CURLE_OK != result)
1318 if(conn->bits.tunnel_connecting) {
1319 /* nothing else to do except wait right now - we're not done here. */
1322 #endif /* CURL_DISABLE_PROXY */
1324 if(conn->given->flags & PROTOPT_SSL) {
1325 /* perform SSL initialization */
1326 if(data->state.used_interface == Curl_if_multi) {
1327 result = https_connecting(conn, done);
1333 result = Curl_ssl_connect(conn, FIRSTSOCKET);
1346 /* this returns the socket to wait for in the DO and DOING state for the multi
1347 interface and then we're always _sending_ a request and thus we wait for
1348 the single socket to become writable only */
1349 static int http_getsock_do(struct connectdata *conn,
1350 curl_socket_t *socks,
1354 (void)numsocks; /* unused, we trust it to be at least 1 */
1355 socks[0] = conn->sock[FIRSTSOCKET];
1356 return GETSOCK_WRITESOCK(0);
1360 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1363 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1365 /* perform SSL initialization for this socket */
1366 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1368 conn->bits.close = TRUE; /* a failed connection is marked for closure
1369 to prevent (bad) re-use or similar */
1374 #if defined(USE_SSLEAY) || defined(USE_GNUTLS)
1375 /* This function is for OpenSSL and GnuTLS only. It should be made to query
1376 the generic SSL layer instead. */
1377 static int https_getsock(struct connectdata *conn,
1378 curl_socket_t *socks,
1381 if(conn->handler->flags & PROTOPT_SSL) {
1382 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1385 return GETSOCK_BLANK;
1387 if(connssl->connecting_state == ssl_connect_2_writing) {
1389 socks[0] = conn->sock[FIRSTSOCKET];
1390 return GETSOCK_WRITESOCK(0);
1392 else if(connssl->connecting_state == ssl_connect_2_reading) {
1394 socks[0] = conn->sock[FIRSTSOCKET];
1395 return GETSOCK_READSOCK(0);
1401 #if defined(USE_NSS) || defined(USE_QSOSSL) || \
1402 defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_CYASSL)
1403 static int https_getsock(struct connectdata *conn,
1404 curl_socket_t *socks,
1410 return GETSOCK_BLANK;
1412 #endif /* USE_AXTLS || USE_POLARSSL || USE_QSOSSL || USE_NSS */
1413 #endif /* USE_SSLEAY || USE_GNUTLS */
1416 * Curl_http_done() gets called from Curl_done() after a single HTTP request
1417 * has been performed.
1420 CURLcode Curl_http_done(struct connectdata *conn,
1421 CURLcode status, bool premature)
1423 struct SessionHandle *data = conn->data;
1424 struct HTTP *http =data->state.proto.http;
1426 Curl_unencode_cleanup(conn);
1428 /* set the proper values (possibly modified on POST) */
1429 conn->fread_func = data->set.fread_func; /* restore */
1430 conn->fread_in = data->set.in; /* restore */
1431 conn->seek_func = data->set.seek_func; /* restore */
1432 conn->seek_client = data->set.seek_client; /* restore */
1437 if(http->send_buffer) {
1438 Curl_send_buffer *buff = http->send_buffer;
1442 http->send_buffer = NULL; /* clear the pointer */
1445 if(HTTPREQ_POST_FORM == data->set.httpreq) {
1446 data->req.bytecount = http->readbytecount + http->writebytecount;
1448 Curl_formclean(&http->sendit); /* Now free that whole lot */
1450 /* a file being uploaded was left opened, close it! */
1451 fclose(http->form.fp);
1452 http->form.fp = NULL;
1455 else if(HTTPREQ_PUT == data->set.httpreq)
1456 data->req.bytecount = http->readbytecount + http->writebytecount;
1458 if(status != CURLE_OK)
1461 if(!premature && /* this check is pointless when DONE is called before the
1462 entire operation is complete */
1463 !conn->bits.retry &&
1464 ((http->readbytecount +
1465 data->req.headerbytecount -
1466 data->req.deductheadercount)) <= 0) {
1467 /* If this connection isn't simply closed to be retried, AND nothing was
1468 read from the HTTP server (that counts), this can't be right so we
1469 return an error here */
1470 failf(data, "Empty reply from server");
1471 return CURLE_GOT_NOTHING;
1478 /* Determine if we should use HTTP 1.1 for this request. Reasons to avoid it
1479 are if the user specifically requested HTTP 1.0, if the server we are
1480 connected to only supports 1.0, or if any server previously contacted to
1481 handle this request only supports 1.0. */
1482 static bool use_http_1_1(const struct SessionHandle *data,
1483 const struct connectdata *conn)
1485 return (bool)((data->set.httpversion == CURL_HTTP_VERSION_1_1) ||
1486 ((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
1487 ((conn->httpversion == 11) ||
1488 ((conn->httpversion != 10) &&
1489 (data->state.httpversion != 10)))));
1492 /* check and possibly add an Expect: header */
1493 static CURLcode expect100(struct SessionHandle *data,
1494 struct connectdata *conn,
1495 Curl_send_buffer *req_buffer)
1497 CURLcode result = CURLE_OK;
1499 data->state.expect100header = FALSE; /* default to false unless it is set
1501 if(use_http_1_1(data, conn)) {
1502 /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
1503 100-continue to the headers which actually speeds up post operations
1504 (as there is one packet coming back from the web server) */
1505 ptr = Curl_checkheaders(data, "Expect:");
1507 data->state.expect100header =
1508 Curl_compareheader(ptr, "Expect:", "100-continue");
1511 result = Curl_add_bufferf(req_buffer,
1512 "Expect: 100-continue\r\n");
1513 if(result == CURLE_OK)
1514 data->state.expect100header = TRUE;
1520 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1521 Curl_send_buffer *req_buffer)
1524 struct curl_slist *headers=conn->data->set.headers;
1527 ptr = strchr(headers->data, ':');
1529 /* we require a colon for this to be a true header */
1531 ptr++; /* pass the colon */
1532 while(*ptr && ISSPACE(*ptr))
1536 /* only send this if the contents was non-blank */
1538 if(conn->allocptr.host &&
1539 /* a Host: header was sent already, don't pass on any custom Host:
1540 header as that will produce *two* in the same request! */
1541 checkprefix("Host:", headers->data))
1543 else if(conn->data->set.httpreq == HTTPREQ_POST_FORM &&
1544 /* this header (extended by formdata.c) is sent later */
1545 checkprefix("Content-Type:", headers->data))
1547 else if(conn->bits.authneg &&
1548 /* while doing auth neg, don't allow the custom length since
1549 we will force length zero then */
1550 checkprefix("Content-Length", headers->data))
1552 else if(conn->allocptr.te &&
1553 /* when asking for Transfer-Encoding, don't pass on a custom
1555 checkprefix("Connection", headers->data))
1558 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1565 headers = headers->next;
1570 CURLcode Curl_add_timecondition(struct SessionHandle *data,
1571 Curl_send_buffer *req_buffer)
1573 const struct tm *tm;
1574 char *buf = data->state.buffer;
1575 CURLcode result = CURLE_OK;
1578 result = Curl_gmtime(data->set.timevalue, &keeptime);
1580 failf(data, "Invalid TIMEVALUE\n");
1585 /* The If-Modified-Since header family should have their times set in
1586 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1587 * represented in Greenwich Mean Time (GMT), without exception. For the
1588 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1589 * Time)." (see page 20 of RFC2616).
1592 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1593 snprintf(buf, BUFSIZE-1,
1594 "%s, %02d %s %4d %02d:%02d:%02d GMT",
1595 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1597 Curl_month[tm->tm_mon],
1603 switch(data->set.timecondition) {
1604 case CURL_TIMECOND_IFMODSINCE:
1606 result = Curl_add_bufferf(req_buffer,
1607 "If-Modified-Since: %s\r\n", buf);
1609 case CURL_TIMECOND_IFUNMODSINCE:
1610 result = Curl_add_bufferf(req_buffer,
1611 "If-Unmodified-Since: %s\r\n", buf);
1613 case CURL_TIMECOND_LASTMOD:
1614 result = Curl_add_bufferf(req_buffer,
1615 "Last-Modified: %s\r\n", buf);
1623 * Curl_http() gets called from the generic Curl_do() function when a HTTP
1624 * request is to be performed. This creates and sends a properly constructed
1627 CURLcode Curl_http(struct connectdata *conn, bool *done)
1629 struct SessionHandle *data=conn->data;
1630 CURLcode result=CURLE_OK;
1632 const char *ppath = data->state.path;
1633 bool paste_ftp_userpwd = FALSE;
1634 char ftp_typecode[sizeof("/;type=?")] = "";
1635 const char *host = conn->host.name;
1636 const char *te = ""; /* transfer-encoding */
1638 const char *request;
1639 Curl_HttpReq httpreq = data->set.httpreq;
1640 char *addcookies = NULL;
1641 curl_off_t included_body = 0;
1642 const char *httpstring;
1643 Curl_send_buffer *req_buffer;
1644 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1645 int seekerr = CURL_SEEKFUNC_OK;
1647 /* Always consider the DO phase done after this function call, even if there
1648 may be parts of the request that is not yet sent, since we can deal with
1649 the rest of the request in the PERFORM phase. */
1652 /* If there already is a protocol-specific struct allocated for this
1653 sessionhandle, deal with it */
1654 Curl_reset_reqproto(conn);
1656 if(!data->state.proto.http) {
1657 /* Only allocate this struct if we don't already have it! */
1659 http = calloc(1, sizeof(struct HTTP));
1661 return CURLE_OUT_OF_MEMORY;
1662 data->state.proto.http = http;
1665 http = data->state.proto.http;
1667 if(!data->state.this_is_a_follow) {
1668 /* this is not a followed location, get the original host name */
1669 if(data->state.first_host)
1670 /* Free to avoid leaking memory on multiple requests*/
1671 free(data->state.first_host);
1673 data->state.first_host = strdup(conn->host.name);
1674 if(!data->state.first_host)
1675 return CURLE_OUT_OF_MEMORY;
1677 http->writebytecount = http->readbytecount = 0;
1679 if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
1681 httpreq = HTTPREQ_PUT;
1684 /* Now set the 'request' pointer to the proper request string */
1685 if(data->set.str[STRING_CUSTOMREQUEST])
1686 request = data->set.str[STRING_CUSTOMREQUEST];
1688 if(data->set.opt_no_body)
1691 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1694 case HTTPREQ_POST_FORM:
1700 default: /* this should never happen */
1711 /* The User-Agent string might have been allocated in url.c already, because
1712 it might have been used in the proxy connect, but if we have got a header
1713 with the user-agent string specified, we erase the previously made string
1715 if(Curl_checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
1716 free(conn->allocptr.uagent);
1717 conn->allocptr.uagent=NULL;
1720 /* setup the authentication headers */
1721 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1725 if((data->state.authhost.multi || data->state.authproxy.multi) &&
1726 (httpreq != HTTPREQ_GET) &&
1727 (httpreq != HTTPREQ_HEAD)) {
1728 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1729 with content-length zero as a "probe". */
1730 conn->bits.authneg = TRUE;
1733 conn->bits.authneg = FALSE;
1735 Curl_safefree(conn->allocptr.ref);
1736 if(data->change.referer && !Curl_checkheaders(data, "Referer:"))
1737 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1739 conn->allocptr.ref = NULL;
1741 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie:"))
1742 addcookies = data->set.str[STRING_COOKIE];
1744 if(!Curl_checkheaders(data, "Accept-Encoding:") &&
1745 data->set.str[STRING_ENCODING]) {
1746 Curl_safefree(conn->allocptr.accept_encoding);
1747 conn->allocptr.accept_encoding =
1748 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1749 if(!conn->allocptr.accept_encoding)
1750 return CURLE_OUT_OF_MEMORY;
1754 /* we only consider transfer-encoding magic if libz support is built-in */
1756 if(!Curl_checkheaders(data, "TE:") && data->set.http_transfer_encoding) {
1757 /* When we are to insert a TE: header in the request, we must also insert
1758 TE in a Connection: header, so we need to merge the custom provided
1759 Connection: header and prevent the original to get sent. Note that if
1760 the user has inserted his/hers own TE: header we don't do this magic
1761 but then assume that the user will handle it all! */
1762 char *cptr = Curl_checkheaders(data, "Connection:");
1763 #define TE_HEADER "TE: gzip\r\n"
1765 Curl_safefree(conn->allocptr.te);
1767 /* Create the (updated) Connection: header */
1768 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1769 strdup("Connection: TE\r\n" TE_HEADER);
1771 if(!conn->allocptr.te)
1772 return CURLE_OUT_OF_MEMORY;
1776 ptr = Curl_checkheaders(data, "Transfer-Encoding:");
1778 /* Some kind of TE is requested, check if 'chunked' is chosen */
1779 data->req.upload_chunky =
1780 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1783 if((conn->handler->protocol&CURLPROTO_HTTP) &&
1785 (data->set.infilesize == -1)) {
1786 if(conn->bits.authneg)
1787 /* don't enable chunked during auth neg */
1789 else if(use_http_1_1(data, conn)) {
1790 /* HTTP, upload, unknown file size and not HTTP 1.0 */
1791 data->req.upload_chunky = TRUE;
1794 failf(data, "Chunky upload is not supported by HTTP 1.0");
1795 return CURLE_UPLOAD_FAILED;
1799 /* else, no chunky upload */
1800 data->req.upload_chunky = FALSE;
1803 if(data->req.upload_chunky)
1804 te = "Transfer-Encoding: chunked\r\n";
1807 Curl_safefree(conn->allocptr.host);
1809 ptr = Curl_checkheaders(data, "Host:");
1810 if(ptr && (!data->state.this_is_a_follow ||
1811 Curl_raw_equal(data->state.first_host, conn->host.name))) {
1812 #if !defined(CURL_DISABLE_COOKIES)
1813 /* If we have a given custom Host: header, we extract the host name in
1814 order to possibly use it for cookie reasons later on. We only allow the
1815 custom Host: header if this is NOT a redirect, as setting Host: in the
1816 redirected request is being out on thin ice. Except if the host name
1817 is the same as the first one! */
1818 char *cookiehost = copy_header_value(ptr);
1820 return CURLE_OUT_OF_MEMORY;
1822 /* ignore empty data */
1825 char *colon = strchr(cookiehost, ':');
1827 *colon = 0; /* The host must not include an embedded port number */
1828 Curl_safefree(conn->allocptr.cookiehost);
1829 conn->allocptr.cookiehost = cookiehost;
1833 conn->allocptr.host = NULL;
1836 /* When building Host: headers, we must put the host name within
1837 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
1839 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
1840 (conn->remote_port == PORT_HTTPS)) ||
1841 ((conn->given->protocol&CURLPROTO_HTTP) &&
1842 (conn->remote_port == PORT_HTTP)) )
1843 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
1844 the port number in the host string */
1845 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
1846 conn->bits.ipv6_ip?"[":"",
1848 conn->bits.ipv6_ip?"]":"");
1850 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
1851 conn->bits.ipv6_ip?"[":"",
1853 conn->bits.ipv6_ip?"]":"",
1856 if(!conn->allocptr.host)
1857 /* without Host: we can't make a nice request */
1858 return CURLE_OUT_OF_MEMORY;
1861 #ifndef CURL_DISABLE_PROXY
1862 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
1863 /* Using a proxy but does not tunnel through it */
1865 /* The path sent to the proxy is in fact the entire URL. But if the remote
1866 host is a IDN-name, we must make sure that the request we produce only
1867 uses the encoded host name! */
1868 if(conn->host.dispname != conn->host.name) {
1869 char *url = data->change.url;
1870 ptr = strstr(url, conn->host.dispname);
1872 /* This is where the display name starts in the URL, now replace this
1873 part with the encoded name. TODO: This method of replacing the host
1874 name is rather crude as I believe there's a slight risk that the
1875 user has entered a user name or password that contain the host name
1877 size_t currlen = strlen(conn->host.dispname);
1878 size_t newlen = strlen(conn->host.name);
1879 size_t urllen = strlen(url);
1883 newurl = malloc(urllen + newlen - currlen + 1);
1885 /* copy the part before the host name */
1886 memcpy(newurl, url, ptr - url);
1887 /* append the new host name instead of the old */
1888 memcpy(newurl + (ptr - url), conn->host.name, newlen);
1889 /* append the piece after the host name */
1890 memcpy(newurl + newlen + (ptr - url),
1891 ptr + currlen, /* copy the trailing zero byte too */
1892 urllen - (ptr-url) - currlen + 1);
1893 if(data->change.url_alloc)
1894 free(data->change.url);
1895 data->change.url = newurl;
1896 data->change.url_alloc = TRUE;
1899 return CURLE_OUT_OF_MEMORY;
1902 ppath = data->change.url;
1903 if(checkprefix("ftp://", ppath)) {
1904 if(data->set.proxy_transfer_mode) {
1905 /* when doing ftp, append ;type=<a|i> if not present */
1906 char *type = strstr(ppath, ";type=");
1907 if(type && type[6] && type[7] == 0) {
1908 switch (Curl_raw_toupper(type[6])) {
1918 char *p = ftp_typecode;
1919 /* avoid sending invalid URLs like ftp://example.com;type=i if the
1920 * user specified ftp://example.com without the slash */
1921 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
1924 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
1925 data->set.prefer_ascii ? 'a' : 'i');
1928 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
1929 paste_ftp_userpwd = TRUE;
1932 #endif /* CURL_DISABLE_PROXY */
1934 if(HTTPREQ_POST_FORM == httpreq) {
1935 /* we must build the whole post sequence first, so that we have a size of
1936 the whole transfer before we start to send it */
1937 result = Curl_getformdata(data, &http->sendit, data->set.httppost,
1938 Curl_checkheaders(data, "Content-Type:"),
1944 http->p_accept = Curl_checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n";
1946 if(( (HTTPREQ_POST == httpreq) ||
1947 (HTTPREQ_POST_FORM == httpreq) ||
1948 (HTTPREQ_PUT == httpreq) ) &&
1949 data->state.resume_from) {
1950 /**********************************************************************
1951 * Resuming upload in HTTP means that we PUT or POST and that we have
1952 * got a resume_from value set. The resume value has already created
1953 * a Range: header that will be passed along. We need to "fast forward"
1954 * the file the given number of bytes and decrease the assume upload
1955 * file size before we continue this venture in the dark lands of HTTP.
1956 *********************************************************************/
1958 if(data->state.resume_from < 0 ) {
1960 * This is meant to get the size of the present remote-file by itself.
1961 * We don't support this now. Bail out!
1963 data->state.resume_from = 0;
1966 if(data->state.resume_from && !data->state.this_is_a_follow) {
1967 /* do we still game? */
1969 /* Now, let's read off the proper amount of bytes from the
1971 if(conn->seek_func) {
1972 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1976 if(seekerr != CURL_SEEKFUNC_OK) {
1977 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1978 failf(data, "Could not seek stream");
1979 return CURLE_READ_ERROR;
1981 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1983 curl_off_t passed=0;
1985 size_t readthisamountnow =
1986 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1987 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1989 size_t actuallyread =
1990 data->set.fread_func(data->state.buffer, 1, readthisamountnow,
1993 passed += actuallyread;
1994 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1995 /* this checks for greater-than only to make sure that the
1996 CURL_READFUNC_ABORT return code still aborts */
1997 failf(data, "Could only read %" FORMAT_OFF_T
1998 " bytes from the input",
2000 return CURLE_READ_ERROR;
2002 } while(passed < data->state.resume_from);
2006 /* now, decrease the size of the read */
2007 if(data->set.infilesize>0) {
2008 data->set.infilesize -= data->state.resume_from;
2010 if(data->set.infilesize <= 0) {
2011 failf(data, "File already completely uploaded");
2012 return CURLE_PARTIAL_FILE;
2015 /* we've passed, proceed as normal */
2018 if(data->state.use_range) {
2020 * A range is selected. We use different headers whether we're downloading
2021 * or uploading and we always let customized headers override our internal
2022 * ones if any such are specified.
2024 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2025 !Curl_checkheaders(data, "Range:")) {
2026 /* if a line like this was already allocated, free the previous one */
2027 if(conn->allocptr.rangeline)
2028 free(conn->allocptr.rangeline);
2029 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2032 else if((httpreq != HTTPREQ_GET) &&
2033 !Curl_checkheaders(data, "Content-Range:")) {
2035 /* if a line like this was already allocated, free the previous one */
2036 if(conn->allocptr.rangeline)
2037 free(conn->allocptr.rangeline);
2039 if(data->set.set_resume_from < 0) {
2040 /* Upload resume was asked for, but we don't know the size of the
2041 remote part so we tell the server (and act accordingly) that we
2042 upload the whole file (again) */
2043 conn->allocptr.rangeline =
2044 aprintf("Content-Range: bytes 0-%" FORMAT_OFF_T
2045 "/%" FORMAT_OFF_T "\r\n",
2046 data->set.infilesize - 1, data->set.infilesize);
2049 else if(data->state.resume_from) {
2050 /* This is because "resume" was selected */
2051 curl_off_t total_expected_size=
2052 data->state.resume_from + data->set.infilesize;
2053 conn->allocptr.rangeline =
2054 aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
2055 "/%" FORMAT_OFF_T "\r\n",
2056 data->state.range, total_expected_size-1,
2057 total_expected_size);
2060 /* Range was selected and then we just pass the incoming range and
2061 append total size */
2062 conn->allocptr.rangeline =
2063 aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
2064 data->state.range, data->set.infilesize);
2066 if(!conn->allocptr.rangeline)
2067 return CURLE_OUT_OF_MEMORY;
2071 /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2073 httpstring= use_http_1_1(data, conn)?"1.1":"1.0";
2075 /* initialize a dynamic send-buffer */
2076 req_buffer = Curl_add_buffer_init();
2079 return CURLE_OUT_OF_MEMORY;
2081 /* add the main request stuff */
2082 /* GET/HEAD/POST/PUT */
2083 result = Curl_add_bufferf(req_buffer, "%s ", request);
2088 if(paste_ftp_userpwd)
2089 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2090 conn->user, conn->passwd,
2091 ppath + sizeof("ftp://") - 1);
2093 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2097 result = Curl_add_bufferf(req_buffer,
2098 "%s" /* ftp typecode (;type=x) */
2099 " HTTP/%s\r\n" /* HTTP version */
2100 "%s" /* proxyuserpwd */
2103 "%s" /* user agent */
2107 "%s" /* accept-encoding */
2109 "%s" /* Proxy-Connection */
2110 "%s",/* transfer-encoding */
2114 conn->allocptr.proxyuserpwd?
2115 conn->allocptr.proxyuserpwd:"",
2116 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2117 (data->state.use_range && conn->allocptr.rangeline)?
2118 conn->allocptr.rangeline:"",
2119 (data->set.str[STRING_USERAGENT] &&
2120 *data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)?
2121 conn->allocptr.uagent:"",
2122 (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
2123 http->p_accept?http->p_accept:"",
2124 conn->allocptr.te?conn->allocptr.te:"",
2125 (data->set.str[STRING_ENCODING] &&
2126 *data->set.str[STRING_ENCODING] &&
2127 conn->allocptr.accept_encoding)?
2128 conn->allocptr.accept_encoding:"",
2129 (data->change.referer && conn->allocptr.ref)?
2130 conn->allocptr.ref:"" /* Referer: <data> */,
2131 (conn->bits.httpproxy &&
2132 !conn->bits.tunnel_proxy &&
2133 !Curl_checkheaders(data, "Proxy-Connection:"))?
2134 "Proxy-Connection: Keep-Alive\r\n":"",
2139 * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
2140 * with basic and digest, it will be freed anyway by the next request
2143 Curl_safefree (conn->allocptr.userpwd);
2144 conn->allocptr.userpwd = NULL;
2149 #if !defined(CURL_DISABLE_COOKIES)
2150 if(data->cookies || addcookies) {
2151 struct Cookie *co=NULL; /* no cookies from start */
2155 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2156 co = Curl_cookie_getlist(data->cookies,
2157 conn->allocptr.cookiehost?
2158 conn->allocptr.cookiehost:host,
2160 (bool)(conn->handler->protocol&CURLPROTO_HTTPS?
2162 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2165 struct Cookie *store=co;
2166 /* now loop through all cookies that matched */
2170 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2174 result = Curl_add_bufferf(req_buffer,
2175 "%s%s=%s", count?"; ":"",
2176 co->name, co->value);
2181 co = co->next; /* next cookie please */
2183 Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2185 if(addcookies && (CURLE_OK == result)) {
2187 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2188 if(CURLE_OK == result) {
2189 result = Curl_add_bufferf(req_buffer, "%s%s",
2195 if(count && (CURLE_OK == result))
2196 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2203 if(data->set.timecondition) {
2204 result = Curl_add_timecondition(data, req_buffer);
2209 result = Curl_add_custom_headers(conn, req_buffer);
2213 http->postdata = NULL; /* nothing to post at this point */
2214 Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
2216 /* If 'authdone' is FALSE, we must not set the write socket index to the
2217 Curl_transfer() call below, as we're not ready to actually upload any
2222 case HTTPREQ_POST_FORM:
2223 if(!http->sendit || conn->bits.authneg) {
2224 /* nothing to post! */
2225 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2229 result = Curl_add_buffer_send(req_buffer, conn,
2230 &data->info.request_size, 0, FIRSTSOCKET);
2232 failf(data, "Failed sending POST request");
2234 /* setup variables for the upcoming transfer */
2235 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2240 if(Curl_FormInit(&http->form, http->sendit)) {
2241 failf(data, "Internal HTTP POST error!");
2242 return CURLE_HTTP_POST_ERROR;
2245 /* Get the currently set callback function pointer and store that in the
2246 form struct since we might want the actual user-provided callback later
2247 on. The conn->fread_func pointer itself will be changed for the
2248 multipart case to the function that returns a multipart formatted
2250 http->form.fread_func = conn->fread_func;
2252 /* Set the read function to read from the generated form data */
2253 conn->fread_func = (curl_read_callback)Curl_FormReader;
2254 conn->fread_in = &http->form;
2256 http->sending = HTTPSEND_BODY;
2258 if(!data->req.upload_chunky) {
2259 /* only add Content-Length if not uploading chunked */
2260 result = Curl_add_bufferf(req_buffer,
2261 "Content-Length: %" FORMAT_OFF_T "\r\n",
2267 result = expect100(data, conn, req_buffer);
2273 /* Get Content-Type: line from Curl_formpostheader.
2276 size_t linelength=0;
2277 contentType = Curl_formpostheader((void *)&http->form,
2280 failf(data, "Could not get Content-Type header line!");
2281 return CURLE_HTTP_POST_ERROR;
2284 result = Curl_add_buffer(req_buffer, contentType, linelength);
2289 /* make the request end in a true CRLF */
2290 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2294 /* set upload size to the progress meter */
2295 Curl_pgrsSetUploadSize(data, http->postsize);
2297 /* fire away the whole request to the server */
2298 result = Curl_add_buffer_send(req_buffer, conn,
2299 &data->info.request_size, 0, FIRSTSOCKET);
2301 failf(data, "Failed sending POST request");
2303 /* setup variables for the upcoming transfer */
2304 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2305 &http->readbytecount, FIRSTSOCKET,
2306 &http->writebytecount);
2309 Curl_formclean(&http->sendit); /* free that whole lot */
2313 /* convert the form data */
2314 result = Curl_convert_form(data, http->sendit);
2316 Curl_formclean(&http->sendit); /* free that whole lot */
2322 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2324 if(conn->bits.authneg)
2327 postsize = data->set.infilesize;
2329 if((postsize != -1) && !data->req.upload_chunky) {
2330 /* only add Content-Length if not uploading chunked */
2331 result = Curl_add_bufferf(req_buffer,
2332 "Content-Length: %" FORMAT_OFF_T "\r\n",
2338 result = expect100(data, conn, req_buffer);
2342 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2346 /* set the upload size to the progress meter */
2347 Curl_pgrsSetUploadSize(data, postsize);
2349 /* this sends the buffer and frees all the buffer resources */
2350 result = Curl_add_buffer_send(req_buffer, conn,
2351 &data->info.request_size, 0, FIRSTSOCKET);
2353 failf(data, "Failed sending PUT request");
2355 /* prepare for transfer */
2356 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2357 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2358 postsize?&http->writebytecount:NULL);
2364 /* this is the simple POST, using x-www-form-urlencoded style */
2366 if(conn->bits.authneg)
2369 /* figure out the size of the postfields */
2370 postsize = (data->set.postfieldsize != -1)?
2371 data->set.postfieldsize:
2372 (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2374 if(!data->req.upload_chunky) {
2375 /* We only set Content-Length and allow a custom Content-Length if
2376 we don't upload data chunked, as RFC2616 forbids us to set both
2377 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2379 if(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length:")) {
2380 /* we allow replacing this header if not during auth negotiation,
2381 although it isn't very wise to actually set your own */
2382 result = Curl_add_bufferf(req_buffer,
2383 "Content-Length: %" FORMAT_OFF_T"\r\n",
2390 if(!Curl_checkheaders(data, "Content-Type:")) {
2391 result = Curl_add_bufferf(req_buffer,
2392 "Content-Type: application/"
2393 "x-www-form-urlencoded\r\n");
2398 /* For really small posts we don't use Expect: headers at all, and for
2399 the somewhat bigger ones we allow the app to disable it. Just make
2400 sure that the expect100header is always set to the preferred value
2402 ptr = Curl_checkheaders(data, "Expect:");
2404 data->state.expect100header =
2405 Curl_compareheader(ptr, "Expect:", "100-continue");
2407 else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2408 result = expect100(data, conn, req_buffer);
2413 data->state.expect100header = FALSE;
2415 if(data->set.postfields) {
2417 if(!data->state.expect100header &&
2418 (postsize < MAX_INITIAL_POST_SIZE)) {
2419 /* if we don't use expect: 100 AND
2420 postsize is less than MAX_INITIAL_POST_SIZE
2422 then append the post data to the HTTP request header. This limit
2423 is no magic limit but only set to prevent really huge POSTs to
2424 get the data duplicated with malloc() and family. */
2426 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2430 if(!data->req.upload_chunky) {
2431 /* We're not sending it 'chunked', append it to the request
2432 already now to reduce the number if send() calls */
2433 result = Curl_add_buffer(req_buffer, data->set.postfields,
2435 included_body = postsize;
2438 /* Append the POST data chunky-style */
2439 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2440 if(CURLE_OK == result)
2441 result = Curl_add_buffer(req_buffer, data->set.postfields,
2443 if(CURLE_OK == result)
2444 result = Curl_add_buffer(req_buffer,
2445 "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2446 /* CR LF 0 CR LF CR LF */
2447 included_body = postsize + 7;
2451 /* Make sure the progress information is accurate */
2452 Curl_pgrsSetUploadSize(data, postsize);
2455 /* A huge POST coming up, do data separate from the request */
2456 http->postsize = postsize;
2457 http->postdata = data->set.postfields;
2459 http->sending = HTTPSEND_BODY;
2461 conn->fread_func = (curl_read_callback)readmoredata;
2462 conn->fread_in = (void *)conn;
2464 /* set the upload size to the progress meter */
2465 Curl_pgrsSetUploadSize(data, http->postsize);
2467 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2473 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2477 if(data->req.upload_chunky && conn->bits.authneg) {
2478 /* Chunky upload is selected and we're negotiating auth still, send
2480 result = Curl_add_buffer(req_buffer,
2481 "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2482 /* CR LF 0 CR LF CR LF */
2487 else if(data->set.postfieldsize) {
2488 /* set the upload size to the progress meter */
2489 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2491 /* set the pointer to mark that we will send the post body using the
2492 read callback, but only if we're not in authenticate
2494 if(!conn->bits.authneg) {
2495 http->postdata = (char *)&http->postdata;
2496 http->postsize = postsize;
2500 /* issue the request */
2501 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2502 (size_t)included_body, FIRSTSOCKET);
2505 failf(data, "Failed sending HTTP POST request");
2507 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2508 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2509 http->postdata?&http->writebytecount:NULL);
2513 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2517 /* issue the request */
2518 result = Curl_add_buffer_send(req_buffer, conn,
2519 &data->info.request_size, 0, FIRSTSOCKET);
2522 failf(data, "Failed sending HTTP request");
2524 /* HTTP GET/HEAD download: */
2525 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2526 http->postdata?FIRSTSOCKET:-1,
2527 http->postdata?&http->writebytecount:NULL);
2532 if(http->writebytecount) {
2533 /* if a request-body has been sent off, we make sure this progress is noted
2535 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2536 if(Curl_pgrsUpdate(conn))
2537 result = CURLE_ABORTED_BY_CALLBACK;
2539 if(http->writebytecount >= postsize) {
2540 /* already sent the entire request body, mark the "upload" as
2542 infof(data, "upload completely sent off: %" FORMAT_OFF_T "out of "
2543 "%" FORMAT_OFF_T " bytes\n",
2544 http->writebytecount, postsize);
2545 data->req.upload_done = TRUE;
2546 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2547 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2557 * Returns TRUE if member of the list matches prefix of string
2560 checkhttpprefix(struct SessionHandle *data,
2563 struct curl_slist *head = data->set.http200aliases;
2565 #ifdef CURL_DOES_CONVERSIONS
2566 /* convert from the network encoding using a scratch area */
2567 char *scratch = strdup(s);
2568 if(NULL == scratch) {
2569 failf (data, "Failed to allocate memory for conversion!");
2570 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2572 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2573 /* Curl_convert_from_network calls failf if unsuccessful */
2575 return FALSE; /* can't return CURLE_foobar so return FALSE */
2578 #endif /* CURL_DOES_CONVERSIONS */
2581 if(checkprefix(head->data, s)) {
2588 if((rc != TRUE) && (checkprefix("HTTP/", s)))
2591 #ifdef CURL_DOES_CONVERSIONS
2593 #endif /* CURL_DOES_CONVERSIONS */
2597 #ifndef CURL_DISABLE_RTSP
2599 checkrtspprefix(struct SessionHandle *data,
2603 #ifdef CURL_DOES_CONVERSIONS
2604 /* convert from the network encoding using a scratch area */
2605 char *scratch = strdup(s);
2606 if(NULL == scratch) {
2607 failf (data, "Failed to allocate memory for conversion!");
2608 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2610 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2611 /* Curl_convert_from_network calls failf if unsuccessful */
2613 return FALSE; /* can't return CURLE_foobar so return FALSE */
2617 (void)data; /* unused */
2618 #endif /* CURL_DOES_CONVERSIONS */
2619 if(checkprefix("RTSP/", s))
2624 #endif /* CURL_DISABLE_RTSP */
2627 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2630 #ifndef CURL_DISABLE_RTSP
2631 if(conn->handler->protocol & CURLPROTO_RTSP)
2632 return checkrtspprefix(data, s);
2635 #endif /* CURL_DISABLE_RTSP */
2637 return checkhttpprefix(data, s);
2641 * header_append() copies a chunk of data to the end of the already received
2642 * header. We make sure that the full string fit in the allocated header
2643 * buffer, or else we enlarge it.
2645 static CURLcode header_append(struct SessionHandle *data,
2646 struct SingleRequest *k,
2649 if(k->hbuflen + length >= data->state.headersize) {
2650 /* We enlarge the header buffer as it is too small */
2655 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2656 /* The reason to have a max limit for this is to avoid the risk of a bad
2657 server feeding libcurl with a never-ending header that will cause
2658 reallocs infinitely */
2659 failf (data, "Avoided giant realloc for header (max is %d)!",
2660 CURL_MAX_HTTP_HEADER);
2661 return CURLE_OUT_OF_MEMORY;
2664 newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2665 hbufp_index = k->hbufp - data->state.headerbuff;
2666 newbuff = realloc(data->state.headerbuff, newsize);
2668 failf (data, "Failed to alloc memory for big header!");
2669 return CURLE_OUT_OF_MEMORY;
2671 data->state.headersize=newsize;
2672 data->state.headerbuff = newbuff;
2673 k->hbufp = data->state.headerbuff + hbufp_index;
2675 memcpy(k->hbufp, k->str_start, length);
2677 k->hbuflen += length;
2685 * Read any HTTP header lines from the server and pass them to the client app.
2687 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2688 struct connectdata *conn,
2693 struct SingleRequest *k = &data->req;
2695 /* header line within buffer loop */
2701 /* str_start is start of line within buf */
2702 k->str_start = k->str;
2704 /* data is in network encoding so use 0x0a instead of '\n' */
2705 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2708 /* Not a complete header line within buffer, append the data to
2709 the end of the headerbuff. */
2710 result = header_append(data, k, *nread);
2714 if(!k->headerline && (k->hbuflen>5)) {
2715 /* make a first check that this looks like a protocol header */
2716 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2717 /* this is not the beginning of a protocol first header line */
2719 k->badheader = HEADER_ALLBAD;
2724 break; /* read more and try again */
2727 /* decrease the size of the remaining (supposed) header line */
2728 rest_length = (k->end_ptr - k->str)+1;
2729 *nread -= (ssize_t)rest_length;
2731 k->str = k->end_ptr + 1; /* move past new line */
2733 full_length = k->str - k->str_start;
2735 result = header_append(data, k, full_length);
2739 k->end_ptr = k->hbufp;
2740 k->p = data->state.headerbuff;
2743 * We now have a FULL header line that p points to
2746 if(!k->headerline) {
2747 /* the first read header */
2748 if((k->hbuflen>5) &&
2749 !checkprotoprefix(data, conn, data->state.headerbuff)) {
2750 /* this is not the beginning of a protocol first header line */
2753 /* since there's more, this is a partial bad header */
2754 k->badheader = HEADER_PARTHEADER;
2756 /* this was all we read so it's all a bad header */
2757 k->badheader = HEADER_ALLBAD;
2758 *nread = (ssize_t)rest_length;
2764 /* headers are in network encoding so
2765 use 0x0a and 0x0d instead of '\n' and '\r' */
2766 if((0x0a == *k->p) || (0x0d == *k->p)) {
2768 /* Zero-length header line means end of headers! */
2770 #ifdef CURL_DOES_CONVERSIONS
2772 *k->p = '\r'; /* replace with CR in host encoding */
2773 k->p++; /* pass the CR byte */
2776 *k->p = '\n'; /* replace with LF in host encoding */
2777 k->p++; /* pass the LF byte */
2781 k->p++; /* pass the \r byte */
2783 k->p++; /* pass the \n byte */
2784 #endif /* CURL_DOES_CONVERSIONS */
2786 if(100 <= k->httpcode && 199 >= k->httpcode) {
2788 * We have made a HTTP PUT or POST and this is 1.1-lingo
2789 * that tells us that the server is OK with this and ready
2790 * to receive the data.
2791 * However, we'll get more headers now so we must get
2792 * back into the header-parsing state!
2795 k->headerline = 0; /* restart the header line counter */
2797 /* if we did wait for this do enable write now! */
2799 k->exp100 = EXP100_SEND_DATA;
2800 k->keepon |= KEEP_SEND;
2804 k->header = FALSE; /* no more header to parse! */
2806 if((k->size == -1) && !k->chunk && !conn->bits.close &&
2807 (conn->httpversion >= 11) &&
2808 !(conn->handler->protocol & CURLPROTO_RTSP)) {
2809 /* On HTTP 1.1, when connection is not to get closed, but no
2810 Content-Length nor Content-Encoding chunked have been
2811 received, according to RFC2616 section 4.4 point 5, we
2812 assume that the server will close the connection to
2813 signal the end of the document. */
2814 infof(data, "no chunk, no close, no size. Assume close to "
2816 conn->bits.close = TRUE;
2821 * When all the headers have been parsed, see if we should give
2822 * up and return an error.
2824 if(http_should_fail(conn)) {
2825 failf (data, "The requested URL returned error: %d",
2827 return CURLE_HTTP_RETURNED_ERROR;
2830 /* now, only output this if the header AND body are requested:
2832 writetype = CLIENTWRITE_HEADER;
2833 if(data->set.include_header)
2834 writetype |= CLIENTWRITE_BODY;
2836 headerlen = k->p - data->state.headerbuff;
2838 result = Curl_client_write(conn, writetype,
2839 data->state.headerbuff,
2844 data->info.header_size += (long)headerlen;
2845 data->req.headerbytecount += (long)headerlen;
2847 data->req.deductheadercount =
2848 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
2850 if(!*stop_reading) {
2851 /* Curl_http_auth_act() checks what authentication methods
2852 * that are available and decides which one (if any) to
2853 * use. It will set 'newurl' if an auth method was picked. */
2854 result = Curl_http_auth_act(conn);
2859 if(k->httpcode >= 300) {
2860 if((!conn->bits.authneg) && !conn->bits.close &&
2861 !conn->bits.rewindaftersend) {
2863 * General treatment of errors when about to send data. Including :
2864 * "417 Expectation Failed", while waiting for 100-continue.
2866 * The check for close above is done simply because of something
2867 * else has already deemed the connection to get closed then
2868 * something else should've considered the big picture and we
2871 * rewindaftersend indicates that something has told libcurl to
2872 * continue sending even if it gets discarded
2875 switch(data->set.httpreq) {
2878 case HTTPREQ_POST_FORM:
2879 /* We got an error response. If this happened before the whole
2880 * request body has been sent we stop sending and mark the
2881 * connection for closure after we've read the entire response.
2883 if(!k->upload_done) {
2884 infof(data, "HTTP error before end of send, stop sending\n");
2885 conn->bits.close = TRUE; /* close after this */
2886 k->upload_done = TRUE;
2887 k->keepon &= ~KEEP_SEND; /* don't send */
2888 if(data->state.expect100header)
2889 k->exp100 = EXP100_FAILED;
2893 default: /* default label present to avoid compiler warnings */
2899 if(conn->bits.rewindaftersend) {
2900 /* We rewind after a complete send, so thus we continue
2902 infof(data, "Keep sending data to get tossed away!\n");
2903 k->keepon |= KEEP_SEND;
2909 * really end-of-headers.
2911 * If we requested a "no body", this is a good time to get
2912 * out and return home.
2914 if(data->set.opt_no_body)
2915 *stop_reading = TRUE;
2917 /* If we know the expected size of this document, we set the
2918 maximum download size to the size of the expected
2919 document or else, we won't know when to stop reading!
2921 Note that we set the download maximum even if we read a
2922 "Connection: close" header, to make sure that
2923 "Content-Length: 0" still prevents us from attempting to
2924 read the (missing) response-body.
2926 /* According to RFC2616 section 4.4, we MUST ignore
2927 Content-Length: headers if we are now receiving data
2928 using chunked Transfer-Encoding.
2931 k->maxdownload = k->size = -1;
2934 /* We do this operation even if no_body is true, since this
2935 data might be retrieved later with curl_easy_getinfo()
2936 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
2938 Curl_pgrsSetDownloadSize(data, k->size);
2939 k->maxdownload = k->size;
2942 /* If max download size is *zero* (nothing) we already
2943 have nothing and can safely return ok now! */
2944 if(0 == k->maxdownload)
2945 *stop_reading = TRUE;
2948 /* we make sure that this socket isn't read more now */
2949 k->keepon &= ~KEEP_RECV;
2952 if(data->set.verbose)
2953 Curl_debug(data, CURLINFO_HEADER_IN,
2954 k->str_start, headerlen, conn);
2955 break; /* exit header line loop */
2958 /* We continue reading headers, so reset the line-based
2959 header parsing variables hbufp && hbuflen */
2960 k->hbufp = data->state.headerbuff;
2966 * Checks for special headers coming up.
2969 if(!k->headerline++) {
2970 /* This is the first header, it MUST be the error code line
2971 or else we consider this to be the body right away! */
2972 int httpversion_major;
2973 int rtspversion_major;
2975 #ifdef CURL_DOES_CONVERSIONS
2976 #define HEADER1 scratch
2977 #define SCRATCHSIZE 21
2979 char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
2980 /* We can't really convert this yet because we
2981 don't know if it's the 1st header line or the body.
2982 So we do a partial conversion into a scratch area,
2983 leaving the data at k->p as-is.
2985 strncpy(&scratch[0], k->p, SCRATCHSIZE);
2986 scratch[SCRATCHSIZE] = 0; /* null terminate */
2987 res = Curl_convert_from_network(data,
2991 /* Curl_convert_from_network calls failf if unsuccessful */
2994 #define HEADER1 k->p /* no conversion needed, just use k->p */
2995 #endif /* CURL_DOES_CONVERSIONS */
2997 if(conn->handler->protocol & CURLPROTO_HTTP) {
2998 nc = sscanf(HEADER1,
3004 conn->httpversion += 10 * httpversion_major;
3007 /* this is the real world, not a Nirvana
3008 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3010 nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3011 conn->httpversion = 10;
3013 /* If user has set option HTTP200ALIASES,
3014 compare header line against list of aliases
3017 if(checkhttpprefix(data, k->p)) {
3020 conn->httpversion = 10;
3025 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3026 nc = sscanf(HEADER1,
3032 conn->rtspversion += 10 * rtspversion_major;
3033 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3036 /* TODO: do we care about the other cases here? */
3042 data->info.httpcode = k->httpcode;
3044 data->info.httpversion = conn->httpversion;
3045 if(!data->state.httpversion ||
3046 data->state.httpversion > conn->httpversion)
3047 /* store the lowest server version we encounter */
3048 data->state.httpversion = conn->httpversion;
3051 * This code executes as part of processing the header. As a
3052 * result, it's not totally clear how to interpret the
3053 * response code yet as that depends on what other headers may
3054 * be present. 401 and 407 may be errors, but may be OK
3055 * depending on how authentication is working. Other codes
3056 * are definitely errors, so give up here.
3058 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3059 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3060 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3062 if(data->state.resume_from &&
3063 (data->set.httpreq==HTTPREQ_GET) &&
3064 (k->httpcode == 416)) {
3065 /* "Requested Range Not Satisfiable", just proceed and
3066 pretend this is no error */
3069 /* serious error, go home! */
3070 failf (data, "The requested URL returned error: %d",
3072 return CURLE_HTTP_RETURNED_ERROR;
3076 if(conn->httpversion == 10) {
3077 /* Default action for HTTP/1.0 must be to close, unless
3078 we get one of those fancy headers that tell us the
3079 server keeps it open for us! */
3080 infof(data, "HTTP 1.0, assume close after body\n");
3081 conn->bits.close = TRUE;
3083 else if(conn->httpversion >= 11 &&
3084 !conn->bits.close) {
3085 /* If HTTP version is >= 1.1 and connection is persistent
3086 server supports pipelining. */
3088 "HTTP 1.1 or later with persistent connection, "
3089 "pipelining supported\n"));
3090 conn->server_supports_pipelining = TRUE;
3093 switch(k->httpcode) {
3095 /* (quote from RFC2616, section 10.2.5): The server has
3096 * fulfilled the request but does not need to return an
3097 * entity-body ... The 204 response MUST NOT include a
3098 * message-body, and thus is always terminated by the first
3099 * empty line after the header fields. */
3102 /* (quote from RFC2616, section 10.3.5): The 304 response
3103 * MUST NOT contain a message-body, and thus is always
3104 * terminated by the first empty line after the header
3106 if(data->set.timecondition)
3107 data->info.timecond = TRUE;
3110 k->ignorecl = TRUE; /* ignore Content-Length headers */
3118 k->header = FALSE; /* this is not a header line */
3123 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3124 /* Curl_convert_from_network calls failf if unsuccessful */
3128 /* Check for Content-Length: header lines to get size */
3129 if(!k->ignorecl && !data->set.ignorecl &&
3130 checkprefix("Content-Length:", k->p)) {
3131 curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3132 if(data->set.max_filesize &&
3133 contentlength > data->set.max_filesize) {
3134 failf(data, "Maximum file size exceeded");
3135 return CURLE_FILESIZE_EXCEEDED;
3137 if(contentlength >= 0) {
3138 k->size = contentlength;
3139 k->maxdownload = k->size;
3140 /* we set the progress download size already at this point
3141 just to make it easier for apps/callbacks to extract this
3142 info as soon as possible */
3143 Curl_pgrsSetDownloadSize(data, k->size);
3146 /* Negative Content-Length is really odd, and we know it
3147 happens for example when older Apache servers send large
3149 conn->bits.close = TRUE;
3150 infof(data, "Negative content-length: %" FORMAT_OFF_T
3151 ", closing after transfer\n", contentlength);
3154 /* check for Content-Type: header lines to get the MIME-type */
3155 else if(checkprefix("Content-Type:", k->p)) {
3156 char *contenttype = copy_header_value(k->p);
3158 return CURLE_OUT_OF_MEMORY;
3160 /* ignore empty data */
3163 Curl_safefree(data->info.contenttype);
3164 data->info.contenttype = contenttype;
3167 else if((conn->httpversion == 10) &&
3168 conn->bits.httpproxy &&
3169 Curl_compareheader(k->p,
3170 "Proxy-Connection:", "keep-alive")) {
3172 * When a HTTP/1.0 reply comes when using a proxy, the
3173 * 'Proxy-Connection: keep-alive' line tells us the
3174 * connection will be kept alive for our pleasure.
3175 * Default action for 1.0 is to close.
3177 conn->bits.close = FALSE; /* don't close when done */
3178 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3180 else if((conn->httpversion == 11) &&
3181 conn->bits.httpproxy &&
3182 Curl_compareheader(k->p,
3183 "Proxy-Connection:", "close")) {
3185 * We get a HTTP/1.1 response from a proxy and it says it'll
3186 * close down after this transfer.
3188 conn->bits.close = TRUE; /* close when done */
3189 infof(data, "HTTP/1.1 proxy connection set close!\n");
3191 else if((conn->httpversion == 10) &&
3192 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3194 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3195 * tells us the connection will be kept alive for our
3196 * pleasure. Default action for 1.0 is to close.
3198 * [RFC2068, section 19.7.1] */
3199 conn->bits.close = FALSE; /* don't close when done */
3200 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3202 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3204 * [RFC 2616, section 8.1.2.1]
3205 * "Connection: close" is HTTP/1.1 language and means that
3206 * the connection will close when this request has been
3209 conn->bits.close = TRUE; /* close when done */
3211 else if(checkprefix("Transfer-Encoding:", k->p)) {
3212 /* One or more encodings. We check for chunked and/or a compression
3215 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3216 * means that the server will send a series of "chunks". Each
3217 * chunk starts with line with info (including size of the
3218 * coming block) (terminated with CRLF), then a block of data
3219 * with the previously mentioned size. There can be any amount
3220 * of chunks, and a chunk-data set to zero signals the
3225 /* Find the first non-space letter */
3229 /* skip whitespaces and commas */
3230 while(*start && (ISSPACE(*start) || (*start == ',')))
3233 if(checkprefix("chunked", start)) {
3234 k->chunk = TRUE; /* chunks coming our way */
3236 /* init our chunky engine */
3237 Curl_httpchunk_init(conn);
3242 if(k->auto_decoding)
3243 /* TODO: we only support the first mentioned compression for now */
3246 if(checkprefix("identity", start)) {
3247 k->auto_decoding = IDENTITY;
3250 else if(checkprefix("deflate", start)) {
3251 k->auto_decoding = DEFLATE;
3254 else if(checkprefix("gzip", start)) {
3255 k->auto_decoding = GZIP;
3258 else if(checkprefix("x-gzip", start)) {
3259 k->auto_decoding = GZIP;
3262 else if(checkprefix("compress", start)) {
3263 k->auto_decoding = COMPRESS;
3266 else if(checkprefix("x-compress", start)) {
3267 k->auto_decoding = COMPRESS;
3277 else if(checkprefix("Content-Encoding:", k->p) &&
3278 data->set.str[STRING_ENCODING]) {
3280 * Process Content-Encoding. Look for the values: identity,
3281 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3282 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3283 * 2616). zlib cannot handle compress. However, errors are
3284 * handled further down when the response body is processed
3288 /* Find the first non-space letter */
3290 while(*start && ISSPACE(*start))
3293 /* Record the content-encoding for later use */
3294 if(checkprefix("identity", start))
3295 k->auto_decoding = IDENTITY;
3296 else if(checkprefix("deflate", start))
3297 k->auto_decoding = DEFLATE;
3298 else if(checkprefix("gzip", start)
3299 || checkprefix("x-gzip", start))
3300 k->auto_decoding = GZIP;
3301 else if(checkprefix("compress", start)
3302 || checkprefix("x-compress", start))
3303 k->auto_decoding = COMPRESS;
3305 else if(checkprefix("Content-Range:", k->p)) {
3306 /* Content-Range: bytes [num]-
3307 Content-Range: bytes: [num]-
3308 Content-Range: [num]-
3310 The second format was added since Sun's webserver
3311 JavaWebServer/1.1.1 obviously sends the header this way!
3312 The third added since some servers use that!
3315 char *ptr = k->p + 14;
3317 /* Move forward until first digit */
3318 while(*ptr && !ISDIGIT(*ptr))
3321 k->offset = curlx_strtoofft(ptr, NULL, 10);
3323 if(data->state.resume_from == k->offset)
3324 /* we asked for a resume and we got it */
3325 k->content_range = TRUE;
3327 #if !defined(CURL_DISABLE_COOKIES)
3328 else if(data->cookies &&
3329 checkprefix("Set-Cookie:", k->p)) {
3330 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3331 CURL_LOCK_ACCESS_SINGLE);
3332 Curl_cookie_add(data,
3333 data->cookies, TRUE, k->p+11,
3334 /* If there is a custom-set Host: name, use it
3335 here, or else use real peer host name. */
3336 conn->allocptr.cookiehost?
3337 conn->allocptr.cookiehost:conn->host.name,
3339 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3342 else if(checkprefix("Last-Modified:", k->p) &&
3343 (data->set.timecondition || data->set.get_filetime) ) {
3344 time_t secs=time(NULL);
3345 k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3347 if(data->set.get_filetime)
3348 data->info.filetime = (long)k->timeofdoc;
3350 else if((checkprefix("WWW-Authenticate:", k->p) &&
3351 (401 == k->httpcode)) ||
3352 (checkprefix("Proxy-authenticate:", k->p) &&
3353 (407 == k->httpcode))) {
3354 result = Curl_http_input_auth(conn, k->httpcode, k->p);
3358 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3359 checkprefix("Location:", k->p) &&
3360 !data->req.location) {
3361 /* this is the URL that the server advises us to use instead */
3362 char *location = copy_header_value(k->p);
3364 return CURLE_OUT_OF_MEMORY;
3366 /* ignore empty data */
3369 data->req.location = location;
3371 if(data->set.http_follow_location) {
3372 DEBUGASSERT(!data->req.newurl);
3373 data->req.newurl = strdup(data->req.location); /* clone */
3374 if(!data->req.newurl)
3375 return CURLE_OUT_OF_MEMORY;
3377 /* some cases of POST and PUT etc needs to rewind the data
3378 stream at this point */
3379 result = http_perhapsrewind(conn);
3385 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3386 result = Curl_rtsp_parseheader(conn, k->p);
3392 * End of header-checks. Write them to the client.
3395 writetype = CLIENTWRITE_HEADER;
3396 if(data->set.include_header)
3397 writetype |= CLIENTWRITE_BODY;
3399 if(data->set.verbose)
3400 Curl_debug(data, CURLINFO_HEADER_IN,
3401 k->p, (size_t)k->hbuflen, conn);
3403 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3407 data->info.header_size += (long)k->hbuflen;
3408 data->req.headerbytecount += (long)k->hbuflen;
3410 /* reset hbufp pointer && hbuflen */
3411 k->hbufp = data->state.headerbuff;
3414 while(!*stop_reading && *k->str); /* header line within buffer */
3416 /* We might have reached the end of the header part here, but
3417 there might be a non-header part left in the end of the read
3423 #endif /* CURL_DISABLE_HTTP */