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_WB)
296 pick->picked = CURLAUTH_NTLM_WB;
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_WB) ||
385 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
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);
548 #ifdef NTLM_WB_ENABLED
549 if(authstatus->picked == CURLAUTH_NTLM_WB) {
551 result = Curl_output_ntlm_wb(conn, proxy);
557 #ifndef CURL_DISABLE_CRYPTO_AUTH
558 if(authstatus->picked == CURLAUTH_DIGEST) {
560 result = Curl_output_digest(conn,
562 (const unsigned char *)request,
563 (const unsigned char *)path);
569 if(authstatus->picked == CURLAUTH_BASIC) {
571 if((proxy && conn->bits.proxy_user_passwd &&
572 !Curl_checkheaders(data, "Proxy-authorization:")) ||
573 (!proxy && conn->bits.user_passwd &&
574 !Curl_checkheaders(data, "Authorization:"))) {
576 result = http_output_basic(conn, proxy);
580 /* NOTE: this function should set 'done' TRUE, as the other auth
581 functions work that way */
582 authstatus->done = TRUE;
586 infof(data, "%s auth using %s with user '%s'\n",
587 proxy?"Proxy":"Server", auth,
588 proxy?(conn->proxyuser?conn->proxyuser:""):
589 (conn->user?conn->user:""));
590 authstatus->multi = (bool)(!authstatus->done);
593 authstatus->multi = FALSE;
599 * Curl_http_output_auth() setups the authentication headers for the
600 * host/proxy and the correct authentication
601 * method. conn->data->state.authdone is set to TRUE when authentication is
604 * @param conn all information about the current connection
605 * @param request pointer to the request keyword
606 * @param path pointer to the requested path
607 * @param proxytunnel boolean if this is the request setting up a "proxy
613 Curl_http_output_auth(struct connectdata *conn,
616 bool proxytunnel) /* TRUE if this is the request setting
617 up the proxy tunnel */
619 CURLcode result = CURLE_OK;
620 struct SessionHandle *data = conn->data;
621 struct auth *authhost;
622 struct auth *authproxy;
626 authhost = &data->state.authhost;
627 authproxy = &data->state.authproxy;
629 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
630 conn->bits.user_passwd)
631 /* continue please */ ;
633 authhost->done = TRUE;
634 authproxy->done = TRUE;
635 return CURLE_OK; /* no authentication with no user or password */
638 if(authhost->want && !authhost->picked)
639 /* The app has selected one or more methods, but none has been picked
640 so far by a server round-trip. Then we set the picked one to the
641 want one, and if this is one single bit it'll be used instantly. */
642 authhost->picked = authhost->want;
644 if(authproxy->want && !authproxy->picked)
645 /* The app has selected one or more methods, but none has been picked so
646 far by a proxy round-trip. Then we set the picked one to the want one,
647 and if this is one single bit it'll be used instantly. */
648 authproxy->picked = authproxy->want;
650 #ifndef CURL_DISABLE_PROXY
651 /* Send proxy authentication header if needed */
652 if(conn->bits.httpproxy &&
653 (conn->bits.tunnel_proxy == proxytunnel)) {
654 result = output_auth_headers(conn, authproxy, request, path, TRUE);
661 #endif /* CURL_DISABLE_PROXY */
662 /* we have no proxy so let's pretend we're done authenticating
664 authproxy->done = TRUE;
666 /* To prevent the user+password to get sent to other than the original
667 host due to a location-follow, we do some weirdo checks here */
668 if(!data->state.this_is_a_follow ||
670 !data->state.first_host ||
671 data->set.http_disable_hostname_check_before_authentication ||
672 Curl_raw_equal(data->state.first_host, conn->host.name)) {
673 result = output_auth_headers(conn, authhost, request, path, FALSE);
676 authhost->done = TRUE;
683 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
684 * headers. They are dealt with both in the transfer.c main loop and in the
685 * proxy CONNECT loop.
688 CURLcode Curl_http_input_auth(struct connectdata *conn,
690 const char *header) /* the first non-space */
693 * This resource requires authentication
695 struct SessionHandle *data = conn->data;
701 if(httpcode == 407) {
702 start = header+strlen("Proxy-authenticate:");
703 availp = &data->info.proxyauthavail;
704 authp = &data->state.authproxy;
707 start = header+strlen("WWW-Authenticate:");
708 availp = &data->info.httpauthavail;
709 authp = &data->state.authhost;
712 /* pass all white spaces */
713 while(*start && ISSPACE(*start))
717 * Here we check if we want the specific single authentication (using ==) and
718 * if we do, we initiate usage of it.
720 * If the provided authentication is wanted as one out of several accepted
721 * types (using &), we OR this authentication type to the authavail
726 * ->picked is first set to the 'want' value (one or more bits) before the
727 * request is sent, and then it is again set _after_ all response 401/407
728 * headers have been received but then only to a single preferred method
733 #ifdef USE_HTTP_NEGOTIATE
734 if(checkprefix("GSS-Negotiate", start) ||
735 checkprefix("Negotiate", start)) {
737 *availp |= CURLAUTH_GSSNEGOTIATE;
738 authp->avail |= CURLAUTH_GSSNEGOTIATE;
740 if(data->state.negotiate.state == GSS_AUTHSENT) {
741 /* if we sent GSS authentication in the outgoing request and we get this
742 back, we're in trouble */
743 infof(data, "Authentication problem. Ignoring this.\n");
744 data->state.authproblem = TRUE;
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, (bool)(httpcode == 407), 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 Digest. */
819 dig = Curl_input_digest(conn, (bool)(httpcode == 407), start);
821 if(CURLDIGEST_FINE != dig) {
822 infof(data, "Authentication problem. Ignoring this.\n");
823 data->state.authproblem = TRUE;
829 if(checkprefix("Basic", start)) {
830 *availp |= CURLAUTH_BASIC;
831 authp->avail |= CURLAUTH_BASIC;
832 if(authp->picked == CURLAUTH_BASIC) {
833 /* We asked for Basic authentication but got a 40X back
834 anyway, which basically means our name+password isn't
836 authp->avail = CURLAUTH_NONE;
837 infof(data, "Authentication problem. Ignoring this.\n");
838 data->state.authproblem = TRUE;
846 * http_should_fail() determines whether an HTTP response has gotten us
847 * into an error state or not.
849 * @param conn all information about the current connection
851 * @retval 0 communications should continue
853 * @retval 1 communications should not continue
855 static int http_should_fail(struct connectdata *conn)
857 struct SessionHandle *data;
864 httpcode = data->req.httpcode;
867 ** If we haven't been asked to fail on error,
870 if(!data->set.http_fail_on_error)
874 ** Any code < 400 is never terminal.
879 if(data->state.resume_from &&
880 (data->set.httpreq==HTTPREQ_GET) &&
882 /* "Requested Range Not Satisfiable", just proceed and
883 pretend this is no error */
888 ** Any code >= 400 that's not 401 or 407 is always
891 if((httpcode != 401) &&
896 ** All we have left to deal with is 401 and 407
898 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
901 ** Examine the current authentication state to see if this
902 ** is an error. The idea is for this function to get
903 ** called after processing all the headers in a response
904 ** message. So, if we've been to asked to authenticate a
905 ** particular stage, and we've done it, we're OK. But, if
906 ** we're already completely authenticated, it's not OK to
907 ** get another 401 or 407.
909 ** It is possible for authentication to go stale such that
910 ** the client needs to reauthenticate. Once that info is
911 ** available, use it here.
915 ** Either we're not authenticating, or we're supposed to
916 ** be authenticating something else. This is an error.
918 if((httpcode == 401) && !conn->bits.user_passwd)
920 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
923 return data->state.authproblem;
927 * readmoredata() is a "fread() emulation" to provide POST and/or request
928 * data. It is used when a huge POST is to be made and the entire chunk wasn't
929 * sent in the first send(). This function will then be called from the
930 * transfer.c loop when more data is to be sent to the peer.
932 * Returns the amount of bytes it filled the buffer with.
934 static size_t readmoredata(char *buffer,
939 struct connectdata *conn = (struct connectdata *)userp;
940 struct HTTP *http = conn->data->state.proto.http;
941 size_t fullsize = size * nitems;
943 if(0 == http->postsize)
944 /* nothing to return */
947 /* make sure that a HTTP request is never sent away chunked! */
948 conn->data->req.forbidchunk = (bool)(http->sending == HTTPSEND_REQUEST);
950 if(http->postsize <= (curl_off_t)fullsize) {
951 memcpy(buffer, http->postdata, (size_t)http->postsize);
952 fullsize = (size_t)http->postsize;
954 if(http->backup.postsize) {
955 /* move backup data into focus and continue on that */
956 http->postdata = http->backup.postdata;
957 http->postsize = http->backup.postsize;
958 conn->fread_func = http->backup.fread_func;
959 conn->fread_in = http->backup.fread_in;
961 http->sending++; /* move one step up */
963 http->backup.postsize=0;
971 memcpy(buffer, http->postdata, fullsize);
972 http->postdata += fullsize;
973 http->postsize -= fullsize;
978 /* ------------------------------------------------------------------------- */
979 /* add_buffer functions */
982 * Curl_add_buffer_init() sets up and returns a fine buffer struct
984 Curl_send_buffer *Curl_add_buffer_init(void)
986 return calloc(1, sizeof(Curl_send_buffer));
990 * Curl_add_buffer_send() sends a header buffer and frees all associated
991 * memory. Body data may be appended to the header data if desired.
995 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
996 struct connectdata *conn,
998 /* add the number of sent bytes to this
1000 long *bytes_written,
1002 /* how much of the buffer contains body data */
1003 size_t included_body_bytes,
1011 struct HTTP *http = conn->data->state.proto.http;
1013 curl_socket_t sockfd;
1016 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1018 sockfd = conn->sock[socketindex];
1020 /* The looping below is required since we use non-blocking sockets, but due
1021 to the circumstances we will just loop and try again and again etc */
1024 size = in->size_used;
1026 headersize = size - included_body_bytes; /* the initial part that isn't body
1029 DEBUGASSERT(size > included_body_bytes);
1031 res = Curl_convert_to_network(conn->data, ptr, headersize);
1032 /* Curl_convert_to_network calls failf if unsuccessful */
1034 /* conversion failed, free memory and return to the caller */
1041 if(conn->handler->flags & PROTOPT_SSL) {
1042 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1043 when we speak HTTPS, as if only a fraction of it is sent now, this data
1044 needs to fit into the normal read-callback buffer later on and that
1045 buffer is using this size.
1048 sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
1050 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1051 library when we attempt to re-send this buffer. Sending the same data
1052 is not enough, we must use the exact same address. For this reason, we
1053 must copy the data to the uploadbuffer first, since that is the buffer
1054 we will be using if this send is retried later.
1056 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1057 ptr = conn->data->state.uploadbuffer;
1062 res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1064 if(CURLE_OK == res) {
1066 * Note that we may not send the entire chunk at once, and we have a set
1067 * number of data bytes at the end of the big buffer (out of which we may
1068 * only send away a part).
1070 /* how much of the header that was sent */
1071 size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
1072 size_t bodylen = amount - headlen;
1074 if(conn->data->set.verbose) {
1075 /* this data _may_ contain binary stuff */
1076 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1077 if((size_t)amount > headlen) {
1078 /* there was body data sent beyond the initial header part, pass that
1079 on to the debug callback too */
1080 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1081 ptr+headlen, bodylen, conn);
1085 /* since we sent a piece of the body here, up the byte counter for it
1087 http->writebytecount += bodylen;
1089 /* 'amount' can never be a very large value here so typecasting it so a
1090 signed 31 bit value should not cause problems even if ssize_t is
1092 *bytes_written += (long)amount;
1095 if((size_t)amount != size) {
1096 /* The whole request could not be sent in one system call. We must
1097 queue it up and send it later when we get the chance. We must not
1098 loop here and wait until it might work again. */
1102 ptr = in->buffer + amount;
1104 /* backup the currently set pointers */
1105 http->backup.fread_func = conn->fread_func;
1106 http->backup.fread_in = conn->fread_in;
1107 http->backup.postdata = http->postdata;
1108 http->backup.postsize = http->postsize;
1110 /* set the new pointers for the request-sending */
1111 conn->fread_func = (curl_read_callback)readmoredata;
1112 conn->fread_in = (void *)conn;
1113 http->postdata = ptr;
1114 http->postsize = (curl_off_t)size;
1116 http->send_buffer = in;
1117 http->sending = HTTPSEND_REQUEST;
1121 http->sending = HTTPSEND_BODY;
1122 /* the full buffer was sent, clean up and return */
1125 if((size_t)amount != size)
1126 /* We have no continue-send mechanism now, fail. This can only happen
1127 when this function is used from the CONNECT sending function. We
1128 currently (stupidly) assume that the whole request is always sent
1129 away in the first single chunk.
1133 return CURLE_SEND_ERROR;
1135 conn->writechannel_inuse = FALSE;
1147 * add_bufferf() add the formatted input to the buffer.
1149 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1154 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1158 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1162 /* If we failed, we cleanup the whole buffer and return error */
1166 return CURLE_OUT_OF_MEMORY;
1170 * add_buffer() appends a memory chunk to the existing buffer
1172 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1177 if(~size < in->size_used) {
1178 /* If resulting used size of send buffer would wrap size_t, cleanup
1179 the whole buffer and return error. Otherwise the required buffer
1180 size will fit into a single allocatable memory chunk */
1181 Curl_safefree(in->buffer);
1183 return CURLE_OUT_OF_MEMORY;
1187 ((in->size_used + size) > (in->size_max - 1))) {
1189 /* If current buffer size isn't enough to hold the result, use a
1190 buffer size that doubles the required size. If this new size
1191 would wrap size_t, then just use the largest possible one */
1193 if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
1194 (~(size*2) < (in->size_used*2)))
1195 new_size = (size_t)-1;
1197 new_size = (in->size_used+size)*2;
1200 /* we have a buffer, enlarge the existing one */
1201 new_rb = realloc(in->buffer, new_size);
1203 /* create a new buffer */
1204 new_rb = malloc(new_size);
1207 /* If we failed, we cleanup the whole buffer and return error */
1208 Curl_safefree(in->buffer);
1210 return CURLE_OUT_OF_MEMORY;
1213 in->buffer = new_rb;
1214 in->size_max = new_size;
1216 memcpy(&in->buffer[in->size_used], inptr, size);
1218 in->size_used += size;
1223 /* end of the add_buffer functions */
1224 /* ------------------------------------------------------------------------- */
1229 * Curl_compareheader()
1231 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1232 * Pass headers WITH the colon.
1235 Curl_compareheader(const char *headerline, /* line to check */
1236 const char *header, /* header keyword _with_ colon */
1237 const char *content) /* content string to find */
1239 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1240 * by a colon (":") and the field value. Field names are case-insensitive.
1241 * The field value MAY be preceded by any amount of LWS, though a single SP
1244 size_t hlen = strlen(header);
1250 if(!Curl_raw_nequal(headerline, header, hlen))
1251 return FALSE; /* doesn't start with header */
1253 /* pass the header */
1254 start = &headerline[hlen];
1256 /* pass all white spaces */
1257 while(*start && ISSPACE(*start))
1260 /* find the end of the header line */
1261 end = strchr(start, '\r'); /* lines end with CRLF */
1263 /* in case there's a non-standard compliant line here */
1264 end = strchr(start, '\n');
1267 /* hm, there's no line ending here, use the zero byte! */
1268 end = strchr(start, '\0');
1271 len = end-start; /* length of the content part of the input line */
1272 clen = strlen(content); /* length of the word to find */
1274 /* find the content string in the rest of the line */
1275 for(;len>=clen;len--, start++) {
1276 if(Curl_raw_nequal(start, content, clen))
1277 return TRUE; /* match! */
1280 return FALSE; /* no match */
1284 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1285 * the generic Curl_connect().
1287 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1289 struct SessionHandle *data;
1294 /* We default to persistent connections. We set this already in this connect
1295 function to make the re-use checks properly be able to check this bit. */
1296 conn->bits.close = FALSE;
1298 #ifndef CURL_DISABLE_PROXY
1299 /* If we are not using a proxy and we want a secure connection, perform SSL
1300 * initialization & connection now. If using a proxy with https, then we
1301 * must tell the proxy to CONNECT to the host we want to talk to. Only
1302 * after the connect has occurred, can we start talking SSL
1304 if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
1306 /* either SSL over proxy, or explicitly asked for */
1307 result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
1310 if(CURLE_OK != result)
1314 if(conn->bits.tunnel_connecting) {
1315 /* nothing else to do except wait right now - we're not done here. */
1318 #endif /* CURL_DISABLE_PROXY */
1320 if(conn->given->flags & PROTOPT_SSL) {
1321 /* perform SSL initialization */
1322 if(data->state.used_interface == Curl_if_multi) {
1323 result = https_connecting(conn, done);
1329 result = Curl_ssl_connect(conn, FIRSTSOCKET);
1342 /* this returns the socket to wait for in the DO and DOING state for the multi
1343 interface and then we're always _sending_ a request and thus we wait for
1344 the single socket to become writable only */
1345 static int http_getsock_do(struct connectdata *conn,
1346 curl_socket_t *socks,
1350 (void)numsocks; /* unused, we trust it to be at least 1 */
1351 socks[0] = conn->sock[FIRSTSOCKET];
1352 return GETSOCK_WRITESOCK(0);
1356 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1359 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1361 /* perform SSL initialization for this socket */
1362 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1364 conn->bits.close = TRUE; /* a failed connection is marked for closure
1365 to prevent (bad) re-use or similar */
1370 #if defined(USE_SSLEAY) || defined(USE_GNUTLS)
1371 /* This function is for OpenSSL and GnuTLS only. It should be made to query
1372 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);
1397 #if defined(USE_NSS) || defined(USE_QSOSSL) || \
1398 defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_CYASSL)
1399 static int https_getsock(struct connectdata *conn,
1400 curl_socket_t *socks,
1406 return GETSOCK_BLANK;
1408 #endif /* USE_AXTLS || USE_POLARSSL || USE_QSOSSL || USE_NSS */
1409 #endif /* USE_SSLEAY || USE_GNUTLS */
1412 * Curl_http_done() gets called from Curl_done() after a single HTTP request
1413 * has been performed.
1416 CURLcode Curl_http_done(struct connectdata *conn,
1417 CURLcode status, bool premature)
1419 struct SessionHandle *data = conn->data;
1420 struct HTTP *http =data->state.proto.http;
1422 Curl_unencode_cleanup(conn);
1424 /* set the proper values (possibly modified on POST) */
1425 conn->fread_func = data->set.fread_func; /* restore */
1426 conn->fread_in = data->set.in; /* restore */
1427 conn->seek_func = data->set.seek_func; /* restore */
1428 conn->seek_client = data->set.seek_client; /* restore */
1433 if(http->send_buffer) {
1434 Curl_send_buffer *buff = http->send_buffer;
1438 http->send_buffer = NULL; /* clear the pointer */
1441 if(HTTPREQ_POST_FORM == data->set.httpreq) {
1442 data->req.bytecount = http->readbytecount + http->writebytecount;
1444 Curl_formclean(&http->sendit); /* Now free that whole lot */
1446 /* a file being uploaded was left opened, close it! */
1447 fclose(http->form.fp);
1448 http->form.fp = NULL;
1451 else if(HTTPREQ_PUT == data->set.httpreq)
1452 data->req.bytecount = http->readbytecount + http->writebytecount;
1454 if(status != CURLE_OK)
1457 if(!premature && /* this check is pointless when DONE is called before the
1458 entire operation is complete */
1459 !conn->bits.retry &&
1460 ((http->readbytecount +
1461 data->req.headerbytecount -
1462 data->req.deductheadercount)) <= 0) {
1463 /* If this connection isn't simply closed to be retried, AND nothing was
1464 read from the HTTP server (that counts), this can't be right so we
1465 return an error here */
1466 failf(data, "Empty reply from server");
1467 return CURLE_GOT_NOTHING;
1474 /* Determine if we should use HTTP 1.1 for this request. Reasons to avoid it
1475 are if the user specifically requested HTTP 1.0, if the server we are
1476 connected to only supports 1.0, or if any server previously contacted to
1477 handle this request only supports 1.0. */
1478 static bool use_http_1_1(const struct SessionHandle *data,
1479 const struct connectdata *conn)
1481 return (bool)((data->set.httpversion == CURL_HTTP_VERSION_1_1) ||
1482 ((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
1483 ((conn->httpversion == 11) ||
1484 ((conn->httpversion != 10) &&
1485 (data->state.httpversion != 10)))));
1488 /* check and possibly add an Expect: header */
1489 static CURLcode expect100(struct SessionHandle *data,
1490 struct connectdata *conn,
1491 Curl_send_buffer *req_buffer)
1493 CURLcode result = CURLE_OK;
1495 data->state.expect100header = FALSE; /* default to false unless it is set
1497 if(use_http_1_1(data, conn)) {
1498 /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
1499 100-continue to the headers which actually speeds up post operations
1500 (as there is one packet coming back from the web server) */
1501 ptr = Curl_checkheaders(data, "Expect:");
1503 data->state.expect100header =
1504 Curl_compareheader(ptr, "Expect:", "100-continue");
1507 result = Curl_add_bufferf(req_buffer,
1508 "Expect: 100-continue\r\n");
1509 if(result == CURLE_OK)
1510 data->state.expect100header = TRUE;
1516 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1517 Curl_send_buffer *req_buffer)
1520 struct curl_slist *headers=conn->data->set.headers;
1523 ptr = strchr(headers->data, ':');
1525 /* we require a colon for this to be a true header */
1527 ptr++; /* pass the colon */
1528 while(*ptr && ISSPACE(*ptr))
1532 /* only send this if the contents was non-blank */
1534 if(conn->allocptr.host &&
1535 /* a Host: header was sent already, don't pass on any custom Host:
1536 header as that will produce *two* in the same request! */
1537 checkprefix("Host:", headers->data))
1539 else if(conn->data->set.httpreq == HTTPREQ_POST_FORM &&
1540 /* this header (extended by formdata.c) is sent later */
1541 checkprefix("Content-Type:", headers->data))
1543 else if(conn->bits.authneg &&
1544 /* while doing auth neg, don't allow the custom length since
1545 we will force length zero then */
1546 checkprefix("Content-Length", headers->data))
1548 else if(conn->allocptr.te &&
1549 /* when asking for Transfer-Encoding, don't pass on a custom
1551 checkprefix("Connection", headers->data))
1554 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1561 headers = headers->next;
1566 CURLcode Curl_add_timecondition(struct SessionHandle *data,
1567 Curl_send_buffer *req_buffer)
1569 const struct tm *tm;
1570 char *buf = data->state.buffer;
1571 CURLcode result = CURLE_OK;
1574 result = Curl_gmtime(data->set.timevalue, &keeptime);
1576 failf(data, "Invalid TIMEVALUE\n");
1581 /* The If-Modified-Since header family should have their times set in
1582 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1583 * represented in Greenwich Mean Time (GMT), without exception. For the
1584 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1585 * Time)." (see page 20 of RFC2616).
1588 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1589 snprintf(buf, BUFSIZE-1,
1590 "%s, %02d %s %4d %02d:%02d:%02d GMT",
1591 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1593 Curl_month[tm->tm_mon],
1599 switch(data->set.timecondition) {
1600 case CURL_TIMECOND_IFMODSINCE:
1602 result = Curl_add_bufferf(req_buffer,
1603 "If-Modified-Since: %s\r\n", buf);
1605 case CURL_TIMECOND_IFUNMODSINCE:
1606 result = Curl_add_bufferf(req_buffer,
1607 "If-Unmodified-Since: %s\r\n", buf);
1609 case CURL_TIMECOND_LASTMOD:
1610 result = Curl_add_bufferf(req_buffer,
1611 "Last-Modified: %s\r\n", buf);
1619 * Curl_http() gets called from the generic Curl_do() function when a HTTP
1620 * request is to be performed. This creates and sends a properly constructed
1623 CURLcode Curl_http(struct connectdata *conn, bool *done)
1625 struct SessionHandle *data=conn->data;
1626 CURLcode result=CURLE_OK;
1628 const char *ppath = data->state.path;
1629 bool paste_ftp_userpwd = FALSE;
1630 char ftp_typecode[sizeof("/;type=?")] = "";
1631 const char *host = conn->host.name;
1632 const char *te = ""; /* transfer-encoding */
1634 const char *request;
1635 Curl_HttpReq httpreq = data->set.httpreq;
1636 char *addcookies = NULL;
1637 curl_off_t included_body = 0;
1638 const char *httpstring;
1639 Curl_send_buffer *req_buffer;
1640 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1641 int seekerr = CURL_SEEKFUNC_OK;
1643 /* Always consider the DO phase done after this function call, even if there
1644 may be parts of the request that is not yet sent, since we can deal with
1645 the rest of the request in the PERFORM phase. */
1648 /* If there already is a protocol-specific struct allocated for this
1649 sessionhandle, deal with it */
1650 Curl_reset_reqproto(conn);
1652 if(!data->state.proto.http) {
1653 /* Only allocate this struct if we don't already have it! */
1655 http = calloc(1, sizeof(struct HTTP));
1657 return CURLE_OUT_OF_MEMORY;
1658 data->state.proto.http = http;
1661 http = data->state.proto.http;
1663 if(!data->state.this_is_a_follow) {
1664 /* this is not a followed location, get the original host name */
1665 if(data->state.first_host)
1666 /* Free to avoid leaking memory on multiple requests*/
1667 free(data->state.first_host);
1669 data->state.first_host = strdup(conn->host.name);
1670 if(!data->state.first_host)
1671 return CURLE_OUT_OF_MEMORY;
1673 http->writebytecount = http->readbytecount = 0;
1675 if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
1677 httpreq = HTTPREQ_PUT;
1680 /* Now set the 'request' pointer to the proper request string */
1681 if(data->set.str[STRING_CUSTOMREQUEST])
1682 request = data->set.str[STRING_CUSTOMREQUEST];
1684 if(data->set.opt_no_body)
1687 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1690 case HTTPREQ_POST_FORM:
1696 default: /* this should never happen */
1707 /* The User-Agent string might have been allocated in url.c already, because
1708 it might have been used in the proxy connect, but if we have got a header
1709 with the user-agent string specified, we erase the previously made string
1711 if(Curl_checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
1712 free(conn->allocptr.uagent);
1713 conn->allocptr.uagent=NULL;
1716 /* setup the authentication headers */
1717 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1721 if((data->state.authhost.multi || data->state.authproxy.multi) &&
1722 (httpreq != HTTPREQ_GET) &&
1723 (httpreq != HTTPREQ_HEAD)) {
1724 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1725 with content-length zero as a "probe". */
1726 conn->bits.authneg = TRUE;
1729 conn->bits.authneg = FALSE;
1731 Curl_safefree(conn->allocptr.ref);
1732 if(data->change.referer && !Curl_checkheaders(data, "Referer:"))
1733 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1735 conn->allocptr.ref = NULL;
1737 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie:"))
1738 addcookies = data->set.str[STRING_COOKIE];
1740 if(!Curl_checkheaders(data, "Accept-Encoding:") &&
1741 data->set.str[STRING_ENCODING]) {
1742 Curl_safefree(conn->allocptr.accept_encoding);
1743 conn->allocptr.accept_encoding =
1744 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1745 if(!conn->allocptr.accept_encoding)
1746 return CURLE_OUT_OF_MEMORY;
1750 /* we only consider transfer-encoding magic if libz support is built-in */
1752 if(!Curl_checkheaders(data, "TE:") && data->set.http_transfer_encoding) {
1753 /* When we are to insert a TE: header in the request, we must also insert
1754 TE in a Connection: header, so we need to merge the custom provided
1755 Connection: header and prevent the original to get sent. Note that if
1756 the user has inserted his/hers own TE: header we don't do this magic
1757 but then assume that the user will handle it all! */
1758 char *cptr = Curl_checkheaders(data, "Connection:");
1759 #define TE_HEADER "TE: gzip\r\n"
1761 Curl_safefree(conn->allocptr.te);
1763 /* Create the (updated) Connection: header */
1764 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1765 strdup("Connection: TE\r\n" TE_HEADER);
1767 if(!conn->allocptr.te)
1768 return CURLE_OUT_OF_MEMORY;
1772 ptr = Curl_checkheaders(data, "Transfer-Encoding:");
1774 /* Some kind of TE is requested, check if 'chunked' is chosen */
1775 data->req.upload_chunky =
1776 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1779 if((conn->handler->protocol&CURLPROTO_HTTP) &&
1781 (data->set.infilesize == -1)) {
1782 if(conn->bits.authneg)
1783 /* don't enable chunked during auth neg */
1785 else if(use_http_1_1(data, conn)) {
1786 /* HTTP, upload, unknown file size and not HTTP 1.0 */
1787 data->req.upload_chunky = TRUE;
1790 failf(data, "Chunky upload is not supported by HTTP 1.0");
1791 return CURLE_UPLOAD_FAILED;
1795 /* else, no chunky upload */
1796 data->req.upload_chunky = FALSE;
1799 if(data->req.upload_chunky)
1800 te = "Transfer-Encoding: chunked\r\n";
1803 Curl_safefree(conn->allocptr.host);
1805 ptr = Curl_checkheaders(data, "Host:");
1806 if(ptr && (!data->state.this_is_a_follow ||
1807 Curl_raw_equal(data->state.first_host, conn->host.name))) {
1808 #if !defined(CURL_DISABLE_COOKIES)
1809 /* If we have a given custom Host: header, we extract the host name in
1810 order to possibly use it for cookie reasons later on. We only allow the
1811 custom Host: header if this is NOT a redirect, as setting Host: in the
1812 redirected request is being out on thin ice. Except if the host name
1813 is the same as the first one! */
1814 char *cookiehost = copy_header_value(ptr);
1816 return CURLE_OUT_OF_MEMORY;
1818 /* ignore empty data */
1821 char *colon = strchr(cookiehost, ':');
1823 *colon = 0; /* The host must not include an embedded port number */
1824 Curl_safefree(conn->allocptr.cookiehost);
1825 conn->allocptr.cookiehost = cookiehost;
1829 conn->allocptr.host = NULL;
1832 /* When building Host: headers, we must put the host name within
1833 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
1835 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
1836 (conn->remote_port == PORT_HTTPS)) ||
1837 ((conn->given->protocol&CURLPROTO_HTTP) &&
1838 (conn->remote_port == PORT_HTTP)) )
1839 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
1840 the port number in the host string */
1841 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
1842 conn->bits.ipv6_ip?"[":"",
1844 conn->bits.ipv6_ip?"]":"");
1846 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
1847 conn->bits.ipv6_ip?"[":"",
1849 conn->bits.ipv6_ip?"]":"",
1852 if(!conn->allocptr.host)
1853 /* without Host: we can't make a nice request */
1854 return CURLE_OUT_OF_MEMORY;
1857 #ifndef CURL_DISABLE_PROXY
1858 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
1859 /* Using a proxy but does not tunnel through it */
1861 /* The path sent to the proxy is in fact the entire URL. But if the remote
1862 host is a IDN-name, we must make sure that the request we produce only
1863 uses the encoded host name! */
1864 if(conn->host.dispname != conn->host.name) {
1865 char *url = data->change.url;
1866 ptr = strstr(url, conn->host.dispname);
1868 /* This is where the display name starts in the URL, now replace this
1869 part with the encoded name. TODO: This method of replacing the host
1870 name is rather crude as I believe there's a slight risk that the
1871 user has entered a user name or password that contain the host name
1873 size_t currlen = strlen(conn->host.dispname);
1874 size_t newlen = strlen(conn->host.name);
1875 size_t urllen = strlen(url);
1879 newurl = malloc(urllen + newlen - currlen + 1);
1881 /* copy the part before the host name */
1882 memcpy(newurl, url, ptr - url);
1883 /* append the new host name instead of the old */
1884 memcpy(newurl + (ptr - url), conn->host.name, newlen);
1885 /* append the piece after the host name */
1886 memcpy(newurl + newlen + (ptr - url),
1887 ptr + currlen, /* copy the trailing zero byte too */
1888 urllen - (ptr-url) - currlen + 1);
1889 if(data->change.url_alloc)
1890 free(data->change.url);
1891 data->change.url = newurl;
1892 data->change.url_alloc = TRUE;
1895 return CURLE_OUT_OF_MEMORY;
1898 ppath = data->change.url;
1899 if(checkprefix("ftp://", ppath)) {
1900 if(data->set.proxy_transfer_mode) {
1901 /* when doing ftp, append ;type=<a|i> if not present */
1902 char *type = strstr(ppath, ";type=");
1903 if(type && type[6] && type[7] == 0) {
1904 switch (Curl_raw_toupper(type[6])) {
1914 char *p = ftp_typecode;
1915 /* avoid sending invalid URLs like ftp://example.com;type=i if the
1916 * user specified ftp://example.com without the slash */
1917 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
1920 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
1921 data->set.prefer_ascii ? 'a' : 'i');
1924 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
1925 paste_ftp_userpwd = TRUE;
1928 #endif /* CURL_DISABLE_PROXY */
1930 if(HTTPREQ_POST_FORM == httpreq) {
1931 /* we must build the whole post sequence first, so that we have a size of
1932 the whole transfer before we start to send it */
1933 result = Curl_getformdata(data, &http->sendit, data->set.httppost,
1934 Curl_checkheaders(data, "Content-Type:"),
1940 http->p_accept = Curl_checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n";
1942 if(( (HTTPREQ_POST == httpreq) ||
1943 (HTTPREQ_POST_FORM == httpreq) ||
1944 (HTTPREQ_PUT == httpreq) ) &&
1945 data->state.resume_from) {
1946 /**********************************************************************
1947 * Resuming upload in HTTP means that we PUT or POST and that we have
1948 * got a resume_from value set. The resume value has already created
1949 * a Range: header that will be passed along. We need to "fast forward"
1950 * the file the given number of bytes and decrease the assume upload
1951 * file size before we continue this venture in the dark lands of HTTP.
1952 *********************************************************************/
1954 if(data->state.resume_from < 0 ) {
1956 * This is meant to get the size of the present remote-file by itself.
1957 * We don't support this now. Bail out!
1959 data->state.resume_from = 0;
1962 if(data->state.resume_from && !data->state.this_is_a_follow) {
1963 /* do we still game? */
1965 /* Now, let's read off the proper amount of bytes from the
1967 if(conn->seek_func) {
1968 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1972 if(seekerr != CURL_SEEKFUNC_OK) {
1973 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1974 failf(data, "Could not seek stream");
1975 return CURLE_READ_ERROR;
1977 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1979 curl_off_t passed=0;
1981 size_t readthisamountnow =
1982 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1983 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1985 size_t actuallyread =
1986 data->set.fread_func(data->state.buffer, 1, readthisamountnow,
1989 passed += actuallyread;
1990 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1991 /* this checks for greater-than only to make sure that the
1992 CURL_READFUNC_ABORT return code still aborts */
1993 failf(data, "Could only read %" FORMAT_OFF_T
1994 " bytes from the input",
1996 return CURLE_READ_ERROR;
1998 } while(passed < data->state.resume_from);
2002 /* now, decrease the size of the read */
2003 if(data->set.infilesize>0) {
2004 data->set.infilesize -= data->state.resume_from;
2006 if(data->set.infilesize <= 0) {
2007 failf(data, "File already completely uploaded");
2008 return CURLE_PARTIAL_FILE;
2011 /* we've passed, proceed as normal */
2014 if(data->state.use_range) {
2016 * A range is selected. We use different headers whether we're downloading
2017 * or uploading and we always let customized headers override our internal
2018 * ones if any such are specified.
2020 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2021 !Curl_checkheaders(data, "Range:")) {
2022 /* if a line like this was already allocated, free the previous one */
2023 if(conn->allocptr.rangeline)
2024 free(conn->allocptr.rangeline);
2025 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2028 else if((httpreq != HTTPREQ_GET) &&
2029 !Curl_checkheaders(data, "Content-Range:")) {
2031 /* if a line like this was already allocated, free the previous one */
2032 if(conn->allocptr.rangeline)
2033 free(conn->allocptr.rangeline);
2035 if(data->set.set_resume_from < 0) {
2036 /* Upload resume was asked for, but we don't know the size of the
2037 remote part so we tell the server (and act accordingly) that we
2038 upload the whole file (again) */
2039 conn->allocptr.rangeline =
2040 aprintf("Content-Range: bytes 0-%" FORMAT_OFF_T
2041 "/%" FORMAT_OFF_T "\r\n",
2042 data->set.infilesize - 1, data->set.infilesize);
2045 else if(data->state.resume_from) {
2046 /* This is because "resume" was selected */
2047 curl_off_t total_expected_size=
2048 data->state.resume_from + data->set.infilesize;
2049 conn->allocptr.rangeline =
2050 aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
2051 "/%" FORMAT_OFF_T "\r\n",
2052 data->state.range, total_expected_size-1,
2053 total_expected_size);
2056 /* Range was selected and then we just pass the incoming range and
2057 append total size */
2058 conn->allocptr.rangeline =
2059 aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
2060 data->state.range, data->set.infilesize);
2062 if(!conn->allocptr.rangeline)
2063 return CURLE_OUT_OF_MEMORY;
2067 /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2069 httpstring= use_http_1_1(data, conn)?"1.1":"1.0";
2071 /* initialize a dynamic send-buffer */
2072 req_buffer = Curl_add_buffer_init();
2075 return CURLE_OUT_OF_MEMORY;
2077 /* add the main request stuff */
2078 /* GET/HEAD/POST/PUT */
2079 result = Curl_add_bufferf(req_buffer, "%s ", request);
2084 if(paste_ftp_userpwd)
2085 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2086 conn->user, conn->passwd,
2087 ppath + sizeof("ftp://") - 1);
2089 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2093 result = Curl_add_bufferf(req_buffer,
2094 "%s" /* ftp typecode (;type=x) */
2095 " HTTP/%s\r\n" /* HTTP version */
2096 "%s" /* proxyuserpwd */
2099 "%s" /* user agent */
2103 "%s" /* accept-encoding */
2105 "%s" /* Proxy-Connection */
2106 "%s",/* transfer-encoding */
2110 conn->allocptr.proxyuserpwd?
2111 conn->allocptr.proxyuserpwd:"",
2112 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2113 (data->state.use_range && conn->allocptr.rangeline)?
2114 conn->allocptr.rangeline:"",
2115 (data->set.str[STRING_USERAGENT] &&
2116 *data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)?
2117 conn->allocptr.uagent:"",
2118 (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
2119 http->p_accept?http->p_accept:"",
2120 conn->allocptr.te?conn->allocptr.te:"",
2121 (data->set.str[STRING_ENCODING] &&
2122 *data->set.str[STRING_ENCODING] &&
2123 conn->allocptr.accept_encoding)?
2124 conn->allocptr.accept_encoding:"",
2125 (data->change.referer && conn->allocptr.ref)?
2126 conn->allocptr.ref:"" /* Referer: <data> */,
2127 (conn->bits.httpproxy &&
2128 !conn->bits.tunnel_proxy &&
2129 !Curl_checkheaders(data, "Proxy-Connection:"))?
2130 "Proxy-Connection: Keep-Alive\r\n":"",
2135 * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
2136 * with basic and digest, it will be freed anyway by the next request
2139 Curl_safefree (conn->allocptr.userpwd);
2140 conn->allocptr.userpwd = NULL;
2145 #if !defined(CURL_DISABLE_COOKIES)
2146 if(data->cookies || addcookies) {
2147 struct Cookie *co=NULL; /* no cookies from start */
2151 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2152 co = Curl_cookie_getlist(data->cookies,
2153 conn->allocptr.cookiehost?
2154 conn->allocptr.cookiehost:host,
2156 (bool)(conn->handler->protocol&CURLPROTO_HTTPS?
2158 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2161 struct Cookie *store=co;
2162 /* now loop through all cookies that matched */
2166 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2170 result = Curl_add_bufferf(req_buffer,
2171 "%s%s=%s", count?"; ":"",
2172 co->name, co->value);
2177 co = co->next; /* next cookie please */
2179 Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2181 if(addcookies && (CURLE_OK == result)) {
2183 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2184 if(CURLE_OK == result) {
2185 result = Curl_add_bufferf(req_buffer, "%s%s",
2191 if(count && (CURLE_OK == result))
2192 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2199 if(data->set.timecondition) {
2200 result = Curl_add_timecondition(data, req_buffer);
2205 result = Curl_add_custom_headers(conn, req_buffer);
2209 http->postdata = NULL; /* nothing to post at this point */
2210 Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
2212 /* If 'authdone' is FALSE, we must not set the write socket index to the
2213 Curl_transfer() call below, as we're not ready to actually upload any
2218 case HTTPREQ_POST_FORM:
2219 if(!http->sendit || conn->bits.authneg) {
2220 /* nothing to post! */
2221 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2225 result = Curl_add_buffer_send(req_buffer, conn,
2226 &data->info.request_size, 0, FIRSTSOCKET);
2228 failf(data, "Failed sending POST request");
2230 /* setup variables for the upcoming transfer */
2231 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2236 if(Curl_FormInit(&http->form, http->sendit)) {
2237 failf(data, "Internal HTTP POST error!");
2238 return CURLE_HTTP_POST_ERROR;
2241 /* Get the currently set callback function pointer and store that in the
2242 form struct since we might want the actual user-provided callback later
2243 on. The conn->fread_func pointer itself will be changed for the
2244 multipart case to the function that returns a multipart formatted
2246 http->form.fread_func = conn->fread_func;
2248 /* Set the read function to read from the generated form data */
2249 conn->fread_func = (curl_read_callback)Curl_FormReader;
2250 conn->fread_in = &http->form;
2252 http->sending = HTTPSEND_BODY;
2254 if(!data->req.upload_chunky) {
2255 /* only add Content-Length if not uploading chunked */
2256 result = Curl_add_bufferf(req_buffer,
2257 "Content-Length: %" FORMAT_OFF_T "\r\n",
2263 result = expect100(data, conn, req_buffer);
2269 /* Get Content-Type: line from Curl_formpostheader.
2272 size_t linelength=0;
2273 contentType = Curl_formpostheader((void *)&http->form,
2276 failf(data, "Could not get Content-Type header line!");
2277 return CURLE_HTTP_POST_ERROR;
2280 result = Curl_add_buffer(req_buffer, contentType, linelength);
2285 /* make the request end in a true CRLF */
2286 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2290 /* set upload size to the progress meter */
2291 Curl_pgrsSetUploadSize(data, http->postsize);
2293 /* fire away the whole request to the server */
2294 result = Curl_add_buffer_send(req_buffer, conn,
2295 &data->info.request_size, 0, FIRSTSOCKET);
2297 failf(data, "Failed sending POST request");
2299 /* setup variables for the upcoming transfer */
2300 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2301 &http->readbytecount, FIRSTSOCKET,
2302 &http->writebytecount);
2305 Curl_formclean(&http->sendit); /* free that whole lot */
2309 /* convert the form data */
2310 result = Curl_convert_form(data, http->sendit);
2312 Curl_formclean(&http->sendit); /* free that whole lot */
2318 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2320 if(conn->bits.authneg)
2323 postsize = data->set.infilesize;
2325 if((postsize != -1) && !data->req.upload_chunky) {
2326 /* only add Content-Length if not uploading chunked */
2327 result = Curl_add_bufferf(req_buffer,
2328 "Content-Length: %" FORMAT_OFF_T "\r\n",
2334 result = expect100(data, conn, req_buffer);
2338 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2342 /* set the upload size to the progress meter */
2343 Curl_pgrsSetUploadSize(data, postsize);
2345 /* this sends the buffer and frees all the buffer resources */
2346 result = Curl_add_buffer_send(req_buffer, conn,
2347 &data->info.request_size, 0, FIRSTSOCKET);
2349 failf(data, "Failed sending PUT request");
2351 /* prepare for transfer */
2352 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2353 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2354 postsize?&http->writebytecount:NULL);
2360 /* this is the simple POST, using x-www-form-urlencoded style */
2362 if(conn->bits.authneg)
2365 /* figure out the size of the postfields */
2366 postsize = (data->set.postfieldsize != -1)?
2367 data->set.postfieldsize:
2368 (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2370 if(!data->req.upload_chunky) {
2371 /* We only set Content-Length and allow a custom Content-Length if
2372 we don't upload data chunked, as RFC2616 forbids us to set both
2373 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2375 if(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length:")) {
2376 /* we allow replacing this header if not during auth negotiation,
2377 although it isn't very wise to actually set your own */
2378 result = Curl_add_bufferf(req_buffer,
2379 "Content-Length: %" FORMAT_OFF_T"\r\n",
2386 if(!Curl_checkheaders(data, "Content-Type:")) {
2387 result = Curl_add_bufferf(req_buffer,
2388 "Content-Type: application/"
2389 "x-www-form-urlencoded\r\n");
2394 /* For really small posts we don't use Expect: headers at all, and for
2395 the somewhat bigger ones we allow the app to disable it. Just make
2396 sure that the expect100header is always set to the preferred value
2398 ptr = Curl_checkheaders(data, "Expect:");
2400 data->state.expect100header =
2401 Curl_compareheader(ptr, "Expect:", "100-continue");
2403 else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2404 result = expect100(data, conn, req_buffer);
2409 data->state.expect100header = FALSE;
2411 if(data->set.postfields) {
2413 if(!data->state.expect100header &&
2414 (postsize < MAX_INITIAL_POST_SIZE)) {
2415 /* if we don't use expect: 100 AND
2416 postsize is less than MAX_INITIAL_POST_SIZE
2418 then append the post data to the HTTP request header. This limit
2419 is no magic limit but only set to prevent really huge POSTs to
2420 get the data duplicated with malloc() and family. */
2422 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2426 if(!data->req.upload_chunky) {
2427 /* We're not sending it 'chunked', append it to the request
2428 already now to reduce the number if send() calls */
2429 result = Curl_add_buffer(req_buffer, data->set.postfields,
2431 included_body = postsize;
2434 /* Append the POST data chunky-style */
2435 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2436 if(CURLE_OK == result)
2437 result = Curl_add_buffer(req_buffer, data->set.postfields,
2439 if(CURLE_OK == result)
2440 result = Curl_add_buffer(req_buffer,
2441 "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2442 /* CR LF 0 CR LF CR LF */
2443 included_body = postsize + 7;
2447 /* Make sure the progress information is accurate */
2448 Curl_pgrsSetUploadSize(data, postsize);
2451 /* A huge POST coming up, do data separate from the request */
2452 http->postsize = postsize;
2453 http->postdata = data->set.postfields;
2455 http->sending = HTTPSEND_BODY;
2457 conn->fread_func = (curl_read_callback)readmoredata;
2458 conn->fread_in = (void *)conn;
2460 /* set the upload size to the progress meter */
2461 Curl_pgrsSetUploadSize(data, http->postsize);
2463 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2469 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2473 if(data->req.upload_chunky && conn->bits.authneg) {
2474 /* Chunky upload is selected and we're negotiating auth still, send
2476 result = Curl_add_buffer(req_buffer,
2477 "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2478 /* CR LF 0 CR LF CR LF */
2483 else if(data->set.postfieldsize) {
2484 /* set the upload size to the progress meter */
2485 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2487 /* set the pointer to mark that we will send the post body using the
2488 read callback, but only if we're not in authenticate
2490 if(!conn->bits.authneg) {
2491 http->postdata = (char *)&http->postdata;
2492 http->postsize = postsize;
2496 /* issue the request */
2497 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2498 (size_t)included_body, FIRSTSOCKET);
2501 failf(data, "Failed sending HTTP POST request");
2503 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2504 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2505 http->postdata?&http->writebytecount:NULL);
2509 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2513 /* issue the request */
2514 result = Curl_add_buffer_send(req_buffer, conn,
2515 &data->info.request_size, 0, FIRSTSOCKET);
2518 failf(data, "Failed sending HTTP request");
2520 /* HTTP GET/HEAD download: */
2521 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2522 http->postdata?FIRSTSOCKET:-1,
2523 http->postdata?&http->writebytecount:NULL);
2528 if(http->writebytecount) {
2529 /* if a request-body has been sent off, we make sure this progress is noted
2531 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2532 if(Curl_pgrsUpdate(conn))
2533 result = CURLE_ABORTED_BY_CALLBACK;
2535 if(http->writebytecount >= postsize) {
2536 /* already sent the entire request body, mark the "upload" as
2538 infof(data, "upload completely sent off: %" FORMAT_OFF_T "out of "
2539 "%" FORMAT_OFF_T " bytes\n",
2540 http->writebytecount, postsize);
2541 data->req.upload_done = TRUE;
2542 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2543 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2553 * Returns TRUE if member of the list matches prefix of string
2556 checkhttpprefix(struct SessionHandle *data,
2559 struct curl_slist *head = data->set.http200aliases;
2561 #ifdef CURL_DOES_CONVERSIONS
2562 /* convert from the network encoding using a scratch area */
2563 char *scratch = strdup(s);
2564 if(NULL == scratch) {
2565 failf (data, "Failed to allocate memory for conversion!");
2566 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2568 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2569 /* Curl_convert_from_network calls failf if unsuccessful */
2571 return FALSE; /* can't return CURLE_foobar so return FALSE */
2574 #endif /* CURL_DOES_CONVERSIONS */
2577 if(checkprefix(head->data, s)) {
2584 if((rc != TRUE) && (checkprefix("HTTP/", s)))
2587 #ifdef CURL_DOES_CONVERSIONS
2589 #endif /* CURL_DOES_CONVERSIONS */
2593 #ifndef CURL_DISABLE_RTSP
2595 checkrtspprefix(struct SessionHandle *data,
2599 #ifdef CURL_DOES_CONVERSIONS
2600 /* convert from the network encoding using a scratch area */
2601 char *scratch = strdup(s);
2602 if(NULL == scratch) {
2603 failf (data, "Failed to allocate memory for conversion!");
2604 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2606 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2607 /* Curl_convert_from_network calls failf if unsuccessful */
2609 return FALSE; /* can't return CURLE_foobar so return FALSE */
2613 (void)data; /* unused */
2614 #endif /* CURL_DOES_CONVERSIONS */
2615 if(checkprefix("RTSP/", s))
2620 #endif /* CURL_DISABLE_RTSP */
2623 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2626 #ifndef CURL_DISABLE_RTSP
2627 if(conn->handler->protocol & CURLPROTO_RTSP)
2628 return checkrtspprefix(data, s);
2631 #endif /* CURL_DISABLE_RTSP */
2633 return checkhttpprefix(data, s);
2637 * header_append() copies a chunk of data to the end of the already received
2638 * header. We make sure that the full string fit in the allocated header
2639 * buffer, or else we enlarge it.
2641 static CURLcode header_append(struct SessionHandle *data,
2642 struct SingleRequest *k,
2645 if(k->hbuflen + length >= data->state.headersize) {
2646 /* We enlarge the header buffer as it is too small */
2651 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2652 /* The reason to have a max limit for this is to avoid the risk of a bad
2653 server feeding libcurl with a never-ending header that will cause
2654 reallocs infinitely */
2655 failf (data, "Avoided giant realloc for header (max is %d)!",
2656 CURL_MAX_HTTP_HEADER);
2657 return CURLE_OUT_OF_MEMORY;
2660 newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2661 hbufp_index = k->hbufp - data->state.headerbuff;
2662 newbuff = realloc(data->state.headerbuff, newsize);
2664 failf (data, "Failed to alloc memory for big header!");
2665 return CURLE_OUT_OF_MEMORY;
2667 data->state.headersize=newsize;
2668 data->state.headerbuff = newbuff;
2669 k->hbufp = data->state.headerbuff + hbufp_index;
2671 memcpy(k->hbufp, k->str_start, length);
2673 k->hbuflen += length;
2681 * Read any HTTP header lines from the server and pass them to the client app.
2683 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2684 struct connectdata *conn,
2689 struct SingleRequest *k = &data->req;
2691 /* header line within buffer loop */
2697 /* str_start is start of line within buf */
2698 k->str_start = k->str;
2700 /* data is in network encoding so use 0x0a instead of '\n' */
2701 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2704 /* Not a complete header line within buffer, append the data to
2705 the end of the headerbuff. */
2706 result = header_append(data, k, *nread);
2710 if(!k->headerline && (k->hbuflen>5)) {
2711 /* make a first check that this looks like a protocol header */
2712 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2713 /* this is not the beginning of a protocol first header line */
2715 k->badheader = HEADER_ALLBAD;
2720 break; /* read more and try again */
2723 /* decrease the size of the remaining (supposed) header line */
2724 rest_length = (k->end_ptr - k->str)+1;
2725 *nread -= (ssize_t)rest_length;
2727 k->str = k->end_ptr + 1; /* move past new line */
2729 full_length = k->str - k->str_start;
2731 result = header_append(data, k, full_length);
2735 k->end_ptr = k->hbufp;
2736 k->p = data->state.headerbuff;
2739 * We now have a FULL header line that p points to
2742 if(!k->headerline) {
2743 /* the first read header */
2744 if((k->hbuflen>5) &&
2745 !checkprotoprefix(data, conn, data->state.headerbuff)) {
2746 /* this is not the beginning of a protocol first header line */
2749 /* since there's more, this is a partial bad header */
2750 k->badheader = HEADER_PARTHEADER;
2752 /* this was all we read so it's all a bad header */
2753 k->badheader = HEADER_ALLBAD;
2754 *nread = (ssize_t)rest_length;
2760 /* headers are in network encoding so
2761 use 0x0a and 0x0d instead of '\n' and '\r' */
2762 if((0x0a == *k->p) || (0x0d == *k->p)) {
2764 /* Zero-length header line means end of headers! */
2766 #ifdef CURL_DOES_CONVERSIONS
2768 *k->p = '\r'; /* replace with CR in host encoding */
2769 k->p++; /* pass the CR byte */
2772 *k->p = '\n'; /* replace with LF in host encoding */
2773 k->p++; /* pass the LF byte */
2777 k->p++; /* pass the \r byte */
2779 k->p++; /* pass the \n byte */
2780 #endif /* CURL_DOES_CONVERSIONS */
2782 if(100 <= k->httpcode && 199 >= k->httpcode) {
2784 * We have made a HTTP PUT or POST and this is 1.1-lingo
2785 * that tells us that the server is OK with this and ready
2786 * to receive the data.
2787 * However, we'll get more headers now so we must get
2788 * back into the header-parsing state!
2791 k->headerline = 0; /* restart the header line counter */
2793 /* if we did wait for this do enable write now! */
2795 k->exp100 = EXP100_SEND_DATA;
2796 k->keepon |= KEEP_SEND;
2800 k->header = FALSE; /* no more header to parse! */
2802 if((k->size == -1) && !k->chunk && !conn->bits.close &&
2803 (conn->httpversion >= 11) &&
2804 !(conn->handler->protocol & CURLPROTO_RTSP)) {
2805 /* On HTTP 1.1, when connection is not to get closed, but no
2806 Content-Length nor Content-Encoding chunked have been
2807 received, according to RFC2616 section 4.4 point 5, we
2808 assume that the server will close the connection to
2809 signal the end of the document. */
2810 infof(data, "no chunk, no close, no size. Assume close to "
2812 conn->bits.close = TRUE;
2817 * When all the headers have been parsed, see if we should give
2818 * up and return an error.
2820 if(http_should_fail(conn)) {
2821 failf (data, "The requested URL returned error: %d",
2823 return CURLE_HTTP_RETURNED_ERROR;
2826 /* now, only output this if the header AND body are requested:
2828 writetype = CLIENTWRITE_HEADER;
2829 if(data->set.include_header)
2830 writetype |= CLIENTWRITE_BODY;
2832 headerlen = k->p - data->state.headerbuff;
2834 result = Curl_client_write(conn, writetype,
2835 data->state.headerbuff,
2840 data->info.header_size += (long)headerlen;
2841 data->req.headerbytecount += (long)headerlen;
2843 data->req.deductheadercount =
2844 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
2846 if(!*stop_reading) {
2847 /* Curl_http_auth_act() checks what authentication methods
2848 * that are available and decides which one (if any) to
2849 * use. It will set 'newurl' if an auth method was picked. */
2850 result = Curl_http_auth_act(conn);
2855 if(k->httpcode >= 300) {
2856 if((!conn->bits.authneg) && !conn->bits.close &&
2857 !conn->bits.rewindaftersend) {
2859 * General treatment of errors when about to send data. Including :
2860 * "417 Expectation Failed", while waiting for 100-continue.
2862 * The check for close above is done simply because of something
2863 * else has already deemed the connection to get closed then
2864 * something else should've considered the big picture and we
2867 * rewindaftersend indicates that something has told libcurl to
2868 * continue sending even if it gets discarded
2871 switch(data->set.httpreq) {
2874 case HTTPREQ_POST_FORM:
2875 /* We got an error response. If this happened before the whole
2876 * request body has been sent we stop sending and mark the
2877 * connection for closure after we've read the entire response.
2879 if(!k->upload_done) {
2880 infof(data, "HTTP error before end of send, stop sending\n");
2881 conn->bits.close = TRUE; /* close after this */
2882 k->upload_done = TRUE;
2883 k->keepon &= ~KEEP_SEND; /* don't send */
2884 if(data->state.expect100header)
2885 k->exp100 = EXP100_FAILED;
2889 default: /* default label present to avoid compiler warnings */
2895 if(conn->bits.rewindaftersend) {
2896 /* We rewind after a complete send, so thus we continue
2898 infof(data, "Keep sending data to get tossed away!\n");
2899 k->keepon |= KEEP_SEND;
2905 * really end-of-headers.
2907 * If we requested a "no body", this is a good time to get
2908 * out and return home.
2910 if(data->set.opt_no_body)
2911 *stop_reading = TRUE;
2913 /* If we know the expected size of this document, we set the
2914 maximum download size to the size of the expected
2915 document or else, we won't know when to stop reading!
2917 Note that we set the download maximum even if we read a
2918 "Connection: close" header, to make sure that
2919 "Content-Length: 0" still prevents us from attempting to
2920 read the (missing) response-body.
2922 /* According to RFC2616 section 4.4, we MUST ignore
2923 Content-Length: headers if we are now receiving data
2924 using chunked Transfer-Encoding.
2927 k->maxdownload = k->size = -1;
2930 /* We do this operation even if no_body is true, since this
2931 data might be retrieved later with curl_easy_getinfo()
2932 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
2934 Curl_pgrsSetDownloadSize(data, k->size);
2935 k->maxdownload = k->size;
2938 /* If max download size is *zero* (nothing) we already
2939 have nothing and can safely return ok now! */
2940 if(0 == k->maxdownload)
2941 *stop_reading = TRUE;
2944 /* we make sure that this socket isn't read more now */
2945 k->keepon &= ~KEEP_RECV;
2948 if(data->set.verbose)
2949 Curl_debug(data, CURLINFO_HEADER_IN,
2950 k->str_start, headerlen, conn);
2951 break; /* exit header line loop */
2954 /* We continue reading headers, so reset the line-based
2955 header parsing variables hbufp && hbuflen */
2956 k->hbufp = data->state.headerbuff;
2962 * Checks for special headers coming up.
2965 if(!k->headerline++) {
2966 /* This is the first header, it MUST be the error code line
2967 or else we consider this to be the body right away! */
2968 int httpversion_major;
2969 int rtspversion_major;
2971 #ifdef CURL_DOES_CONVERSIONS
2972 #define HEADER1 scratch
2973 #define SCRATCHSIZE 21
2975 char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
2976 /* We can't really convert this yet because we
2977 don't know if it's the 1st header line or the body.
2978 So we do a partial conversion into a scratch area,
2979 leaving the data at k->p as-is.
2981 strncpy(&scratch[0], k->p, SCRATCHSIZE);
2982 scratch[SCRATCHSIZE] = 0; /* null terminate */
2983 res = Curl_convert_from_network(data,
2987 /* Curl_convert_from_network calls failf if unsuccessful */
2990 #define HEADER1 k->p /* no conversion needed, just use k->p */
2991 #endif /* CURL_DOES_CONVERSIONS */
2993 if(conn->handler->protocol & CURLPROTO_HTTP) {
2994 nc = sscanf(HEADER1,
3000 conn->httpversion += 10 * httpversion_major;
3003 /* this is the real world, not a Nirvana
3004 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3006 nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3007 conn->httpversion = 10;
3009 /* If user has set option HTTP200ALIASES,
3010 compare header line against list of aliases
3013 if(checkhttpprefix(data, k->p)) {
3016 conn->httpversion = 10;
3021 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3022 nc = sscanf(HEADER1,
3028 conn->rtspversion += 10 * rtspversion_major;
3029 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3032 /* TODO: do we care about the other cases here? */
3038 data->info.httpcode = k->httpcode;
3040 data->info.httpversion = conn->httpversion;
3041 if(!data->state.httpversion ||
3042 data->state.httpversion > conn->httpversion)
3043 /* store the lowest server version we encounter */
3044 data->state.httpversion = conn->httpversion;
3047 * This code executes as part of processing the header. As a
3048 * result, it's not totally clear how to interpret the
3049 * response code yet as that depends on what other headers may
3050 * be present. 401 and 407 may be errors, but may be OK
3051 * depending on how authentication is working. Other codes
3052 * are definitely errors, so give up here.
3054 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3055 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3056 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3058 if(data->state.resume_from &&
3059 (data->set.httpreq==HTTPREQ_GET) &&
3060 (k->httpcode == 416)) {
3061 /* "Requested Range Not Satisfiable", just proceed and
3062 pretend this is no error */
3065 /* serious error, go home! */
3066 failf (data, "The requested URL returned error: %d",
3068 return CURLE_HTTP_RETURNED_ERROR;
3072 if(conn->httpversion == 10) {
3073 /* Default action for HTTP/1.0 must be to close, unless
3074 we get one of those fancy headers that tell us the
3075 server keeps it open for us! */
3076 infof(data, "HTTP 1.0, assume close after body\n");
3077 conn->bits.close = TRUE;
3079 else if(conn->httpversion >= 11 &&
3080 !conn->bits.close) {
3081 /* If HTTP version is >= 1.1 and connection is persistent
3082 server supports pipelining. */
3084 "HTTP 1.1 or later with persistent connection, "
3085 "pipelining supported\n"));
3086 conn->server_supports_pipelining = TRUE;
3089 switch(k->httpcode) {
3091 /* (quote from RFC2616, section 10.2.5): The server has
3092 * fulfilled the request but does not need to return an
3093 * entity-body ... The 204 response MUST NOT include a
3094 * message-body, and thus is always terminated by the first
3095 * empty line after the header fields. */
3098 /* (quote from RFC2616, section 10.3.5): The 304 response
3099 * MUST NOT contain a message-body, and thus is always
3100 * terminated by the first empty line after the header
3102 if(data->set.timecondition)
3103 data->info.timecond = TRUE;
3106 k->ignorecl = TRUE; /* ignore Content-Length headers */
3114 k->header = FALSE; /* this is not a header line */
3119 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3120 /* Curl_convert_from_network calls failf if unsuccessful */
3124 /* Check for Content-Length: header lines to get size */
3125 if(!k->ignorecl && !data->set.ignorecl &&
3126 checkprefix("Content-Length:", k->p)) {
3127 curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3128 if(data->set.max_filesize &&
3129 contentlength > data->set.max_filesize) {
3130 failf(data, "Maximum file size exceeded");
3131 return CURLE_FILESIZE_EXCEEDED;
3133 if(contentlength >= 0) {
3134 k->size = contentlength;
3135 k->maxdownload = k->size;
3136 /* we set the progress download size already at this point
3137 just to make it easier for apps/callbacks to extract this
3138 info as soon as possible */
3139 Curl_pgrsSetDownloadSize(data, k->size);
3142 /* Negative Content-Length is really odd, and we know it
3143 happens for example when older Apache servers send large
3145 conn->bits.close = TRUE;
3146 infof(data, "Negative content-length: %" FORMAT_OFF_T
3147 ", closing after transfer\n", contentlength);
3150 /* check for Content-Type: header lines to get the MIME-type */
3151 else if(checkprefix("Content-Type:", k->p)) {
3152 char *contenttype = copy_header_value(k->p);
3154 return CURLE_OUT_OF_MEMORY;
3156 /* ignore empty data */
3159 Curl_safefree(data->info.contenttype);
3160 data->info.contenttype = contenttype;
3163 else if((conn->httpversion == 10) &&
3164 conn->bits.httpproxy &&
3165 Curl_compareheader(k->p,
3166 "Proxy-Connection:", "keep-alive")) {
3168 * When a HTTP/1.0 reply comes when using a proxy, the
3169 * 'Proxy-Connection: keep-alive' line tells us the
3170 * connection will be kept alive for our pleasure.
3171 * Default action for 1.0 is to close.
3173 conn->bits.close = FALSE; /* don't close when done */
3174 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3176 else if((conn->httpversion == 11) &&
3177 conn->bits.httpproxy &&
3178 Curl_compareheader(k->p,
3179 "Proxy-Connection:", "close")) {
3181 * We get a HTTP/1.1 response from a proxy and it says it'll
3182 * close down after this transfer.
3184 conn->bits.close = TRUE; /* close when done */
3185 infof(data, "HTTP/1.1 proxy connection set close!\n");
3187 else if((conn->httpversion == 10) &&
3188 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3190 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3191 * tells us the connection will be kept alive for our
3192 * pleasure. Default action for 1.0 is to close.
3194 * [RFC2068, section 19.7.1] */
3195 conn->bits.close = FALSE; /* don't close when done */
3196 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3198 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3200 * [RFC 2616, section 8.1.2.1]
3201 * "Connection: close" is HTTP/1.1 language and means that
3202 * the connection will close when this request has been
3205 conn->bits.close = TRUE; /* close when done */
3207 else if(checkprefix("Transfer-Encoding:", k->p)) {
3208 /* One or more encodings. We check for chunked and/or a compression
3211 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3212 * means that the server will send a series of "chunks". Each
3213 * chunk starts with line with info (including size of the
3214 * coming block) (terminated with CRLF), then a block of data
3215 * with the previously mentioned size. There can be any amount
3216 * of chunks, and a chunk-data set to zero signals the
3221 /* Find the first non-space letter */
3225 /* skip whitespaces and commas */
3226 while(*start && (ISSPACE(*start) || (*start == ',')))
3229 if(checkprefix("chunked", start)) {
3230 k->chunk = TRUE; /* chunks coming our way */
3232 /* init our chunky engine */
3233 Curl_httpchunk_init(conn);
3238 if(k->auto_decoding)
3239 /* TODO: we only support the first mentioned compression for now */
3242 if(checkprefix("identity", start)) {
3243 k->auto_decoding = IDENTITY;
3246 else if(checkprefix("deflate", start)) {
3247 k->auto_decoding = DEFLATE;
3250 else if(checkprefix("gzip", start)) {
3251 k->auto_decoding = GZIP;
3254 else if(checkprefix("x-gzip", start)) {
3255 k->auto_decoding = GZIP;
3258 else if(checkprefix("compress", start)) {
3259 k->auto_decoding = COMPRESS;
3262 else if(checkprefix("x-compress", start)) {
3263 k->auto_decoding = COMPRESS;
3273 else if(checkprefix("Content-Encoding:", k->p) &&
3274 data->set.str[STRING_ENCODING]) {
3276 * Process Content-Encoding. Look for the values: identity,
3277 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3278 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3279 * 2616). zlib cannot handle compress. However, errors are
3280 * handled further down when the response body is processed
3284 /* Find the first non-space letter */
3286 while(*start && ISSPACE(*start))
3289 /* Record the content-encoding for later use */
3290 if(checkprefix("identity", start))
3291 k->auto_decoding = IDENTITY;
3292 else if(checkprefix("deflate", start))
3293 k->auto_decoding = DEFLATE;
3294 else if(checkprefix("gzip", start)
3295 || checkprefix("x-gzip", start))
3296 k->auto_decoding = GZIP;
3297 else if(checkprefix("compress", start)
3298 || checkprefix("x-compress", start))
3299 k->auto_decoding = COMPRESS;
3301 else if(checkprefix("Content-Range:", k->p)) {
3302 /* Content-Range: bytes [num]-
3303 Content-Range: bytes: [num]-
3304 Content-Range: [num]-
3306 The second format was added since Sun's webserver
3307 JavaWebServer/1.1.1 obviously sends the header this way!
3308 The third added since some servers use that!
3311 char *ptr = k->p + 14;
3313 /* Move forward until first digit */
3314 while(*ptr && !ISDIGIT(*ptr))
3317 k->offset = curlx_strtoofft(ptr, NULL, 10);
3319 if(data->state.resume_from == k->offset)
3320 /* we asked for a resume and we got it */
3321 k->content_range = TRUE;
3323 #if !defined(CURL_DISABLE_COOKIES)
3324 else if(data->cookies &&
3325 checkprefix("Set-Cookie:", k->p)) {
3326 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3327 CURL_LOCK_ACCESS_SINGLE);
3328 Curl_cookie_add(data,
3329 data->cookies, TRUE, k->p+11,
3330 /* If there is a custom-set Host: name, use it
3331 here, or else use real peer host name. */
3332 conn->allocptr.cookiehost?
3333 conn->allocptr.cookiehost:conn->host.name,
3335 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3338 else if(checkprefix("Last-Modified:", k->p) &&
3339 (data->set.timecondition || data->set.get_filetime) ) {
3340 time_t secs=time(NULL);
3341 k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3343 if(data->set.get_filetime)
3344 data->info.filetime = (long)k->timeofdoc;
3346 else if((checkprefix("WWW-Authenticate:", k->p) &&
3347 (401 == k->httpcode)) ||
3348 (checkprefix("Proxy-authenticate:", k->p) &&
3349 (407 == k->httpcode))) {
3350 result = Curl_http_input_auth(conn, k->httpcode, k->p);
3354 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3355 checkprefix("Location:", k->p) &&
3356 !data->req.location) {
3357 /* this is the URL that the server advises us to use instead */
3358 char *location = copy_header_value(k->p);
3360 return CURLE_OUT_OF_MEMORY;
3362 /* ignore empty data */
3365 data->req.location = location;
3367 if(data->set.http_follow_location) {
3368 DEBUGASSERT(!data->req.newurl);
3369 data->req.newurl = strdup(data->req.location); /* clone */
3370 if(!data->req.newurl)
3371 return CURLE_OUT_OF_MEMORY;
3373 /* some cases of POST and PUT etc needs to rewind the data
3374 stream at this point */
3375 result = http_perhapsrewind(conn);
3381 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3382 result = Curl_rtsp_parseheader(conn, k->p);
3388 * End of header-checks. Write them to the client.
3391 writetype = CLIENTWRITE_HEADER;
3392 if(data->set.include_header)
3393 writetype |= CLIENTWRITE_BODY;
3395 if(data->set.verbose)
3396 Curl_debug(data, CURLINFO_HEADER_IN,
3397 k->p, (size_t)k->hbuflen, conn);
3399 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3403 data->info.header_size += (long)k->hbuflen;
3404 data->req.headerbytecount += (long)k->hbuflen;
3406 /* reset hbufp pointer && hbuflen */
3407 k->hbufp = data->state.headerbuff;
3410 while(!*stop_reading && *k->str); /* header line within buffer */
3412 /* We might have reached the end of the header part here, but
3413 there might be a non-header part left in the end of the read
3419 #endif /* CURL_DISABLE_HTTP */