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
26 /* -- WIN32 approved -- */
37 #ifdef HAVE_SYS_SOCKET_H
38 #include <sys/socket.h>
40 #ifdef HAVE_NETINET_IN_H
41 #include <netinet/in.h>
43 #ifdef HAVE_SYS_TIME_H
48 #ifdef TIME_WITH_SYS_TIME
59 #ifdef HAVE_ARPA_INET_H
60 #include <arpa/inet.h>
65 #ifdef HAVE_SYS_IOCTL_H
66 #include <sys/ioctl.h>
69 #ifdef HAVE_SYS_PARAM_H
70 #include <sys/param.h>
76 #include <curl/curl.h>
81 #include "curl_base64.h"
85 #include "http_digest.h"
86 #include "http_ntlm.h"
87 #include "http_negotiate.h"
92 #include "curl_memory.h"
94 #include "parsedate.h" /* for the week day and month names */
95 #include "strtoofft.h"
98 #include "content_encoding.h"
99 #include "http_proxy.h"
100 #include "warnless.h"
101 #include "non-ascii.h"
103 #define _MPRINTF_REPLACE /* use our functions only */
104 #include <curl/mprintf.h>
106 /* The last #include file should be: */
107 #include "memdebug.h"
110 * Forward declarations.
113 static int http_getsock_do(struct connectdata *conn,
114 curl_socket_t *socks,
116 static int http_should_fail(struct connectdata *conn);
119 static CURLcode https_connecting(struct connectdata *conn, bool *done);
120 static int https_getsock(struct connectdata *conn,
121 curl_socket_t *socks,
124 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
128 * HTTP handler interface.
130 const struct Curl_handler Curl_handler_http = {
132 ZERO_NULL, /* setup_connection */
133 Curl_http, /* do_it */
134 Curl_http_done, /* done */
135 ZERO_NULL, /* do_more */
136 Curl_http_connect, /* connect_it */
137 ZERO_NULL, /* connecting */
138 ZERO_NULL, /* doing */
139 ZERO_NULL, /* proto_getsock */
140 http_getsock_do, /* doing_getsock */
141 ZERO_NULL, /* perform_getsock */
142 ZERO_NULL, /* disconnect */
143 ZERO_NULL, /* readwrite */
144 PORT_HTTP, /* defport */
145 CURLPROTO_HTTP, /* protocol */
146 PROTOPT_NONE /* flags */
151 * HTTPS handler interface.
153 const struct Curl_handler Curl_handler_https = {
154 "HTTPS", /* scheme */
155 ZERO_NULL, /* setup_connection */
156 Curl_http, /* do_it */
157 Curl_http_done, /* done */
158 ZERO_NULL, /* do_more */
159 Curl_http_connect, /* connect_it */
160 https_connecting, /* connecting */
161 ZERO_NULL, /* doing */
162 https_getsock, /* proto_getsock */
163 http_getsock_do, /* doing_getsock */
164 ZERO_NULL, /* perform_getsock */
165 ZERO_NULL, /* disconnect */
166 ZERO_NULL, /* readwrite */
167 PORT_HTTPS, /* defport */
168 CURLPROTO_HTTP | CURLPROTO_HTTPS, /* protocol */
169 PROTOPT_SSL /* flags */
175 * checkheaders() checks the linked list of custom HTTP headers for a
176 * particular header (prefix).
178 * Returns a pointer to the first matching header or NULL if none matched.
180 char *Curl_checkheaders(struct SessionHandle *data, const char *thisheader)
182 struct curl_slist *head;
183 size_t thislen = strlen(thisheader);
185 for(head = data->set.headers; head; head=head->next) {
186 if(Curl_raw_nequal(head->data, thisheader, thislen))
193 * Strip off leading and trailing whitespace from the value in the
194 * given HTTP header line and return a strdupped copy. Returns NULL in
195 * case of allocation failure. Returns an empty string if the header value
196 * consists entirely of whitespace.
198 static char *copy_header_value(const char *h)
207 /* Find the end of the header name */
208 while(*h && (*h != ':'))
212 /* Skip over colon */
215 /* Find the first non-space letter */
217 while(*start && ISSPACE(*start))
220 /* data is in the host encoding so
221 use '\r' and '\n' instead of 0x0d and 0x0a */
222 end = strchr(start, '\r');
224 end = strchr(start, '\n');
226 end = strchr(start, '\0');
230 /* skip all trailing space letters */
231 while((end > start) && ISSPACE(*end))
234 /* get length of the type */
237 value = malloc(len + 1);
241 memcpy(value, start, len);
242 value[len] = 0; /* zero terminate */
248 * http_output_basic() sets up an Authorization: header (or the proxy version)
249 * for HTTP Basic authentication.
253 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
256 struct SessionHandle *data=conn->data;
262 userp = &conn->allocptr.proxyuserpwd;
263 user = conn->proxyuser;
264 pwd = conn->proxypasswd;
267 userp = &conn->allocptr.userpwd;
272 snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
273 if(Curl_base64_encode(data, data->state.buffer,
274 strlen(data->state.buffer),
275 &authorization) > 0) {
278 *userp = aprintf( "%sAuthorization: Basic %s\r\n",
283 return CURLE_OUT_OF_MEMORY;
286 return CURLE_OUT_OF_MEMORY;
290 /* pickoneauth() selects the most favourable authentication method from the
291 * ones available and the ones we want.
293 * return TRUE if one was picked
295 static bool pickoneauth(struct auth *pick)
298 /* only deal with authentication we want */
299 long avail = pick->avail & pick->want;
302 /* The order of these checks is highly relevant, as this will be the order
303 of preference in case of the existence of multiple accepted types. */
304 if(avail & CURLAUTH_GSSNEGOTIATE)
305 pick->picked = CURLAUTH_GSSNEGOTIATE;
306 else if(avail & CURLAUTH_DIGEST)
307 pick->picked = CURLAUTH_DIGEST;
308 else if(avail & CURLAUTH_NTLM)
309 pick->picked = CURLAUTH_NTLM;
310 else if(avail & CURLAUTH_BASIC)
311 pick->picked = CURLAUTH_BASIC;
313 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
316 pick->avail = CURLAUTH_NONE; /* clear it here */
322 * Curl_http_perhapsrewind()
324 * If we are doing POST or PUT {
325 * If we have more data to send {
326 * If we are doing NTLM {
327 * Keep sending since we must not disconnect
330 * If there is more than just a little data left to send, close
331 * the current connection by force.
334 * If we have sent any data {
335 * If we don't have track of all the data {
336 * call app to tell it to rewind
339 * rewind internally so that the operation can restart fine
344 static CURLcode http_perhapsrewind(struct connectdata *conn)
346 struct SessionHandle *data = conn->data;
347 struct HTTP *http = data->state.proto.http;
348 curl_off_t bytessent;
349 curl_off_t expectsend = -1; /* default is unknown */
352 /* If this is still NULL, we have not reach very far and we can safely
353 skip this rewinding stuff */
356 switch(data->set.httpreq) {
364 bytessent = http->writebytecount;
366 if(conn->bits.authneg)
367 /* This is a state where we are known to be negotiating and we don't send
371 /* figure out how much data we are expected to send */
372 switch(data->set.httpreq) {
374 if(data->set.postfieldsize != -1)
375 expectsend = data->set.postfieldsize;
376 else if(data->set.postfields)
377 expectsend = (curl_off_t)strlen(data->set.postfields);
380 if(data->set.infilesize != -1)
381 expectsend = data->set.infilesize;
383 case HTTPREQ_POST_FORM:
384 expectsend = http->postsize;
391 conn->bits.rewindaftersend = FALSE; /* default */
393 if((expectsend == -1) || (expectsend > bytessent)) {
394 /* There is still data left to send */
395 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
396 (data->state.authhost.picked == CURLAUTH_NTLM)) {
397 if(((expectsend - bytessent) < 2000) ||
398 (conn->ntlm.state != NTLMSTATE_NONE)) {
399 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
400 data left to send, keep on sending. */
402 /* rewind data when completely done sending! */
403 if(!conn->bits.authneg)
404 conn->bits.rewindaftersend = TRUE;
409 /* this is already marked to get closed */
412 infof(data, "NTLM send, close instead of sending %" FORMAT_OFF_T
413 " bytes\n", (curl_off_t)(expectsend - bytessent));
416 /* This is not NTLM or NTLM with many bytes left to send: close
418 conn->bits.close = TRUE;
419 data->req.size = 0; /* don't download any more than 0 bytes */
421 /* There still is data left to send, but this connection is marked for
422 closure so we can safely do the rewind right now */
426 /* we rewind now at once since if we already sent something */
427 return Curl_readrewind(conn);
433 * Curl_http_auth_act() gets called when all HTTP headers have been received
434 * and it checks what authentication methods that are available and decides
435 * which one (if any) to use. It will set 'newurl' if an auth method was
439 CURLcode Curl_http_auth_act(struct connectdata *conn)
441 struct SessionHandle *data = conn->data;
442 bool pickhost = FALSE;
443 bool pickproxy = FALSE;
444 CURLcode code = CURLE_OK;
446 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
447 /* this is a transient response code, ignore */
450 if(data->state.authproblem)
451 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
453 if(conn->bits.user_passwd &&
454 ((data->req.httpcode == 401) ||
455 (conn->bits.authneg && data->req.httpcode < 300))) {
456 pickhost = pickoneauth(&data->state.authhost);
458 data->state.authproblem = TRUE;
460 if(conn->bits.proxy_user_passwd &&
461 ((data->req.httpcode == 407) ||
462 (conn->bits.authneg && data->req.httpcode < 300))) {
463 pickproxy = pickoneauth(&data->state.authproxy);
465 data->state.authproblem = TRUE;
468 if(pickhost || pickproxy) {
469 /* In case this is GSS auth, the newurl field is already allocated so
470 we must make sure to free it before allocating a new one. As figured
471 out in bug #2284386 */
472 Curl_safefree(data->req.newurl);
473 data->req.newurl = strdup(data->change.url); /* clone URL */
474 if(!data->req.newurl)
475 return CURLE_OUT_OF_MEMORY;
477 if((data->set.httpreq != HTTPREQ_GET) &&
478 (data->set.httpreq != HTTPREQ_HEAD) &&
479 !conn->bits.rewindaftersend) {
480 code = http_perhapsrewind(conn);
486 else if((data->req.httpcode < 300) &&
487 (!data->state.authhost.done) &&
488 conn->bits.authneg) {
489 /* no (known) authentication available,
490 authentication is not "done" yet and
491 no authentication seems to be required and
492 we didn't try HEAD or GET */
493 if((data->set.httpreq != HTTPREQ_GET) &&
494 (data->set.httpreq != HTTPREQ_HEAD)) {
495 data->req.newurl = strdup(data->change.url); /* clone URL */
496 if(!data->req.newurl)
497 return CURLE_OUT_OF_MEMORY;
498 data->state.authhost.done = TRUE;
501 if(http_should_fail(conn)) {
502 failf (data, "The requested URL returned error: %d",
504 code = CURLE_HTTP_RETURNED_ERROR;
512 * Output the correct authentication header depending on the auth type
513 * and whether or not it is to a proxy.
516 output_auth_headers(struct connectdata *conn,
517 struct auth *authstatus,
522 struct SessionHandle *data = conn->data;
523 const char *auth=NULL;
524 CURLcode result = CURLE_OK;
525 #ifdef USE_HTTP_NEGOTIATE
526 struct negotiatedata *negdata = proxy?
527 &data->state.proxyneg:&data->state.negotiate;
530 #ifdef CURL_DISABLE_CRYPTO_AUTH
535 #ifdef USE_HTTP_NEGOTIATE
536 negdata->state = GSS_AUTHNONE;
537 if((authstatus->picked == CURLAUTH_GSSNEGOTIATE) &&
538 negdata->context && !GSS_ERROR(negdata->status)) {
539 auth="GSS-Negotiate";
540 result = Curl_output_negotiate(conn, proxy);
543 authstatus->done = TRUE;
544 negdata->state = GSS_AUTHSENT;
549 if(authstatus->picked == CURLAUTH_NTLM) {
551 result = Curl_output_ntlm(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 /* NTLM authentication is picked and activated */
772 Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
774 if(CURLNTLM_BAD != ntlm)
775 data->state.authproblem = FALSE;
777 infof(data, "Authentication problem. Ignoring this.\n");
778 data->state.authproblem = TRUE;
784 #ifndef CURL_DISABLE_CRYPTO_AUTH
785 if(checkprefix("Digest", start)) {
786 if((authp->avail & CURLAUTH_DIGEST) != 0) {
787 infof(data, "Ignoring duplicate digest auth header.\n");
791 *availp |= CURLAUTH_DIGEST;
792 authp->avail |= CURLAUTH_DIGEST;
794 /* We call this function on input Digest headers even if Digest
795 * authentication isn't activated yet, as we need to store the
796 * incoming data from this header in case we are gonna use Digest. */
797 dig = Curl_input_digest(conn, (bool)(httpcode == 407), start);
799 if(CURLDIGEST_FINE != dig) {
800 infof(data, "Authentication problem. Ignoring this.\n");
801 data->state.authproblem = TRUE;
807 if(checkprefix("Basic", start)) {
808 *availp |= CURLAUTH_BASIC;
809 authp->avail |= CURLAUTH_BASIC;
810 if(authp->picked == CURLAUTH_BASIC) {
811 /* We asked for Basic authentication but got a 40X back
812 anyway, which basically means our name+password isn't
814 authp->avail = CURLAUTH_NONE;
815 infof(data, "Authentication problem. Ignoring this.\n");
816 data->state.authproblem = TRUE;
824 * http_should_fail() determines whether an HTTP response has gotten us
825 * into an error state or not.
827 * @param conn all information about the current connection
829 * @retval 0 communications should continue
831 * @retval 1 communications should not continue
833 static int http_should_fail(struct connectdata *conn)
835 struct SessionHandle *data;
842 httpcode = data->req.httpcode;
845 ** If we haven't been asked to fail on error,
848 if(!data->set.http_fail_on_error)
852 ** Any code < 400 is never terminal.
857 if(data->state.resume_from &&
858 (data->set.httpreq==HTTPREQ_GET) &&
860 /* "Requested Range Not Satisfiable", just proceed and
861 pretend this is no error */
866 ** Any code >= 400 that's not 401 or 407 is always
869 if((httpcode != 401) &&
874 ** All we have left to deal with is 401 and 407
876 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
879 ** Examine the current authentication state to see if this
880 ** is an error. The idea is for this function to get
881 ** called after processing all the headers in a response
882 ** message. So, if we've been to asked to authenticate a
883 ** particular stage, and we've done it, we're OK. But, if
884 ** we're already completely authenticated, it's not OK to
885 ** get another 401 or 407.
887 ** It is possible for authentication to go stale such that
888 ** the client needs to reauthenticate. Once that info is
889 ** available, use it here.
893 ** Either we're not authenticating, or we're supposed to
894 ** be authenticating something else. This is an error.
896 if((httpcode == 401) && !conn->bits.user_passwd)
898 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
901 return data->state.authproblem;
905 * readmoredata() is a "fread() emulation" to provide POST and/or request
906 * data. It is used when a huge POST is to be made and the entire chunk wasn't
907 * sent in the first send(). This function will then be called from the
908 * transfer.c loop when more data is to be sent to the peer.
910 * Returns the amount of bytes it filled the buffer with.
912 static size_t readmoredata(char *buffer,
917 struct connectdata *conn = (struct connectdata *)userp;
918 struct HTTP *http = conn->data->state.proto.http;
919 size_t fullsize = size * nitems;
921 if(0 == http->postsize)
922 /* nothing to return */
925 /* make sure that a HTTP request is never sent away chunked! */
926 conn->data->req.forbidchunk = (bool)(http->sending == HTTPSEND_REQUEST);
928 if(http->postsize <= (curl_off_t)fullsize) {
929 memcpy(buffer, http->postdata, (size_t)http->postsize);
930 fullsize = (size_t)http->postsize;
932 if(http->backup.postsize) {
933 /* move backup data into focus and continue on that */
934 http->postdata = http->backup.postdata;
935 http->postsize = http->backup.postsize;
936 conn->fread_func = http->backup.fread_func;
937 conn->fread_in = http->backup.fread_in;
939 http->sending++; /* move one step up */
941 http->backup.postsize=0;
949 memcpy(buffer, http->postdata, fullsize);
950 http->postdata += fullsize;
951 http->postsize -= fullsize;
956 /* ------------------------------------------------------------------------- */
957 /* add_buffer functions */
960 * Curl_add_buffer_init() sets up and returns a fine buffer struct
962 Curl_send_buffer *Curl_add_buffer_init(void)
964 return calloc(1, sizeof(Curl_send_buffer));
968 * Curl_add_buffer_send() sends a header buffer and frees all associated
969 * memory. Body data may be appended to the header data if desired.
973 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
974 struct connectdata *conn,
976 /* add the number of sent bytes to this
980 /* how much of the buffer contains body data */
981 size_t included_body_bytes,
989 struct HTTP *http = conn->data->state.proto.http;
991 curl_socket_t sockfd;
994 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
996 sockfd = conn->sock[socketindex];
998 /* The looping below is required since we use non-blocking sockets, but due
999 to the circumstances we will just loop and try again and again etc */
1002 size = in->size_used;
1004 headersize = size - included_body_bytes; /* the initial part that isn't body
1007 DEBUGASSERT(size > included_body_bytes);
1009 res = Curl_convert_to_network(conn->data, ptr, headersize);
1010 /* Curl_convert_to_network calls failf if unsuccessful */
1012 /* conversion failed, free memory and return to the caller */
1019 if(conn->handler->flags & PROTOPT_SSL) {
1020 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1021 when we speak HTTPS, as if only a fraction of it is sent now, this data
1022 needs to fit into the normal read-callback buffer later on and that
1023 buffer is using this size.
1026 sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
1028 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1029 library when we attempt to re-send this buffer. Sending the same data
1030 is not enough, we must use the exact same address. For this reason, we
1031 must copy the data to the uploadbuffer first, since that is the buffer
1032 we will be using if this send is retried later.
1034 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1035 ptr = conn->data->state.uploadbuffer;
1040 res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1042 if(CURLE_OK == res) {
1044 * Note that we may not send the entire chunk at once, and we have a set
1045 * number of data bytes at the end of the big buffer (out of which we may
1046 * only send away a part).
1048 /* how much of the header that was sent */
1049 size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
1050 size_t bodylen = amount - headlen;
1052 if(conn->data->set.verbose) {
1053 /* this data _may_ contain binary stuff */
1054 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1055 if((size_t)amount > headlen) {
1056 /* there was body data sent beyond the initial header part, pass that
1057 on to the debug callback too */
1058 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1059 ptr+headlen, bodylen, conn);
1063 /* since we sent a piece of the body here, up the byte counter for it
1065 http->writebytecount += bodylen;
1067 /* 'amount' can never be a very large value here so typecasting it so a
1068 signed 31 bit value should not cause problems even if ssize_t is
1070 *bytes_written += (long)amount;
1073 if((size_t)amount != size) {
1074 /* The whole request could not be sent in one system call. We must
1075 queue it up and send it later when we get the chance. We must not
1076 loop here and wait until it might work again. */
1080 ptr = in->buffer + amount;
1082 /* backup the currently set pointers */
1083 http->backup.fread_func = conn->fread_func;
1084 http->backup.fread_in = conn->fread_in;
1085 http->backup.postdata = http->postdata;
1086 http->backup.postsize = http->postsize;
1088 /* set the new pointers for the request-sending */
1089 conn->fread_func = (curl_read_callback)readmoredata;
1090 conn->fread_in = (void *)conn;
1091 http->postdata = ptr;
1092 http->postsize = (curl_off_t)size;
1094 http->send_buffer = in;
1095 http->sending = HTTPSEND_REQUEST;
1099 http->sending = HTTPSEND_BODY;
1100 /* the full buffer was sent, clean up and return */
1103 if((size_t)amount != size)
1104 /* We have no continue-send mechanism now, fail. This can only happen
1105 when this function is used from the CONNECT sending function. We
1106 currently (stupidly) assume that the whole request is always sent
1107 away in the first single chunk.
1111 return CURLE_SEND_ERROR;
1113 conn->writechannel_inuse = FALSE;
1125 * add_bufferf() add the formatted input to the buffer.
1127 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1132 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1136 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1140 /* If we failed, we cleanup the whole buffer and return error */
1144 return CURLE_OUT_OF_MEMORY;
1148 * add_buffer() appends a memory chunk to the existing buffer
1150 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1155 if(~size < in->size_used) {
1156 /* If resulting used size of send buffer would wrap size_t, cleanup
1157 the whole buffer and return error. Otherwise the required buffer
1158 size will fit into a single allocatable memory chunk */
1159 Curl_safefree(in->buffer);
1161 return CURLE_OUT_OF_MEMORY;
1165 ((in->size_used + size) > (in->size_max - 1))) {
1167 /* If current buffer size isn't enough to hold the result, use a
1168 buffer size that doubles the required size. If this new size
1169 would wrap size_t, then just use the largest possible one */
1171 if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
1172 (~(size*2) < (in->size_used*2)))
1173 new_size = (size_t)-1;
1175 new_size = (in->size_used+size)*2;
1178 /* we have a buffer, enlarge the existing one */
1179 new_rb = realloc(in->buffer, new_size);
1181 /* create a new buffer */
1182 new_rb = malloc(new_size);
1185 /* If we failed, we cleanup the whole buffer and return error */
1186 Curl_safefree(in->buffer);
1188 return CURLE_OUT_OF_MEMORY;
1191 in->buffer = new_rb;
1192 in->size_max = new_size;
1194 memcpy(&in->buffer[in->size_used], inptr, size);
1196 in->size_used += size;
1201 /* end of the add_buffer functions */
1202 /* ------------------------------------------------------------------------- */
1207 * Curl_compareheader()
1209 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1210 * Pass headers WITH the colon.
1213 Curl_compareheader(const char *headerline, /* line to check */
1214 const char *header, /* header keyword _with_ colon */
1215 const char *content) /* content string to find */
1217 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1218 * by a colon (":") and the field value. Field names are case-insensitive.
1219 * The field value MAY be preceded by any amount of LWS, though a single SP
1222 size_t hlen = strlen(header);
1228 if(!Curl_raw_nequal(headerline, header, hlen))
1229 return FALSE; /* doesn't start with header */
1231 /* pass the header */
1232 start = &headerline[hlen];
1234 /* pass all white spaces */
1235 while(*start && ISSPACE(*start))
1238 /* find the end of the header line */
1239 end = strchr(start, '\r'); /* lines end with CRLF */
1241 /* in case there's a non-standard compliant line here */
1242 end = strchr(start, '\n');
1245 /* hm, there's no line ending here, use the zero byte! */
1246 end = strchr(start, '\0');
1249 len = end-start; /* length of the content part of the input line */
1250 clen = strlen(content); /* length of the word to find */
1252 /* find the content string in the rest of the line */
1253 for(;len>=clen;len--, start++) {
1254 if(Curl_raw_nequal(start, content, clen))
1255 return TRUE; /* match! */
1258 return FALSE; /* no match */
1262 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1263 * the generic Curl_connect().
1265 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1267 struct SessionHandle *data;
1272 /* We default to persistent connections. We set this already in this connect
1273 function to make the re-use checks properly be able to check this bit. */
1274 conn->bits.close = FALSE;
1276 #ifndef CURL_DISABLE_PROXY
1277 /* If we are not using a proxy and we want a secure connection, perform SSL
1278 * initialization & connection now. If using a proxy with https, then we
1279 * must tell the proxy to CONNECT to the host we want to talk to. Only
1280 * after the connect has occurred, can we start talking SSL
1282 if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
1284 /* either SSL over proxy, or explicitly asked for */
1285 result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
1288 if(CURLE_OK != result)
1292 if(conn->bits.tunnel_connecting) {
1293 /* nothing else to do except wait right now - we're not done here. */
1296 #endif /* CURL_DISABLE_PROXY */
1298 if(conn->given->flags & PROTOPT_SSL) {
1299 /* perform SSL initialization */
1300 if(data->state.used_interface == Curl_if_multi) {
1301 result = https_connecting(conn, done);
1307 result = Curl_ssl_connect(conn, FIRSTSOCKET);
1320 /* this returns the socket to wait for in the DO and DOING state for the multi
1321 interface and then we're always _sending_ a request and thus we wait for
1322 the single socket to become writable only */
1323 static int http_getsock_do(struct connectdata *conn,
1324 curl_socket_t *socks,
1328 (void)numsocks; /* unused, we trust it to be at least 1 */
1329 socks[0] = conn->sock[FIRSTSOCKET];
1330 return GETSOCK_WRITESOCK(0);
1334 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1337 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1339 /* perform SSL initialization for this socket */
1340 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1342 conn->bits.close = TRUE; /* a failed connection is marked for closure
1343 to prevent (bad) re-use or similar */
1348 #if defined(USE_SSLEAY) || defined(USE_GNUTLS)
1349 /* This function is for OpenSSL and GnuTLS only. It should be made to query
1350 the generic SSL layer instead. */
1351 static int https_getsock(struct connectdata *conn,
1352 curl_socket_t *socks,
1355 if(conn->handler->flags & PROTOPT_SSL) {
1356 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1359 return GETSOCK_BLANK;
1361 if(connssl->connecting_state == ssl_connect_2_writing) {
1363 socks[0] = conn->sock[FIRSTSOCKET];
1364 return GETSOCK_WRITESOCK(0);
1366 else if(connssl->connecting_state == ssl_connect_2_reading) {
1368 socks[0] = conn->sock[FIRSTSOCKET];
1369 return GETSOCK_READSOCK(0);
1375 #if defined(USE_NSS) || defined(USE_QSOSSL) || \
1376 defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_CYASSL)
1377 static int https_getsock(struct connectdata *conn,
1378 curl_socket_t *socks,
1384 return GETSOCK_BLANK;
1386 #endif /* USE_AXTLS || USE_POLARSSL || USE_QSOSSL || USE_NSS */
1387 #endif /* USE_SSLEAY || USE_GNUTLS */
1390 * Curl_http_done() gets called from Curl_done() after a single HTTP request
1391 * has been performed.
1394 CURLcode Curl_http_done(struct connectdata *conn,
1395 CURLcode status, bool premature)
1397 struct SessionHandle *data = conn->data;
1398 struct HTTP *http =data->state.proto.http;
1400 Curl_unencode_cleanup(conn);
1402 /* set the proper values (possibly modified on POST) */
1403 conn->fread_func = data->set.fread_func; /* restore */
1404 conn->fread_in = data->set.in; /* restore */
1405 conn->seek_func = data->set.seek_func; /* restore */
1406 conn->seek_client = data->set.seek_client; /* restore */
1411 if(http->send_buffer) {
1412 Curl_send_buffer *buff = http->send_buffer;
1416 http->send_buffer = NULL; /* clear the pointer */
1419 if(HTTPREQ_POST_FORM == data->set.httpreq) {
1420 data->req.bytecount = http->readbytecount + http->writebytecount;
1422 Curl_formclean(&http->sendit); /* Now free that whole lot */
1424 /* a file being uploaded was left opened, close it! */
1425 fclose(http->form.fp);
1426 http->form.fp = NULL;
1429 else if(HTTPREQ_PUT == data->set.httpreq)
1430 data->req.bytecount = http->readbytecount + http->writebytecount;
1432 if(status != CURLE_OK)
1435 if(!premature && /* this check is pointless when DONE is called before the
1436 entire operation is complete */
1437 !conn->bits.retry &&
1438 ((http->readbytecount +
1439 data->req.headerbytecount -
1440 data->req.deductheadercount)) <= 0) {
1441 /* If this connection isn't simply closed to be retried, AND nothing was
1442 read from the HTTP server (that counts), this can't be right so we
1443 return an error here */
1444 failf(data, "Empty reply from server");
1445 return CURLE_GOT_NOTHING;
1452 /* Determine if we should use HTTP 1.1 for this request. Reasons to avoid it
1453 are if the user specifically requested HTTP 1.0, if the server we are
1454 connected to only supports 1.0, or if any server previously contacted to
1455 handle this request only supports 1.0. */
1456 static bool use_http_1_1(const struct SessionHandle *data,
1457 const struct connectdata *conn)
1459 return (bool)((data->set.httpversion == CURL_HTTP_VERSION_1_1) ||
1460 ((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
1461 ((conn->httpversion == 11) ||
1462 ((conn->httpversion != 10) &&
1463 (data->state.httpversion != 10)))));
1466 /* check and possibly add an Expect: header */
1467 static CURLcode expect100(struct SessionHandle *data,
1468 struct connectdata *conn,
1469 Curl_send_buffer *req_buffer)
1471 CURLcode result = CURLE_OK;
1473 data->state.expect100header = FALSE; /* default to false unless it is set
1475 if(use_http_1_1(data, conn)) {
1476 /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
1477 100-continue to the headers which actually speeds up post operations
1478 (as there is one packet coming back from the web server) */
1479 ptr = Curl_checkheaders(data, "Expect:");
1481 data->state.expect100header =
1482 Curl_compareheader(ptr, "Expect:", "100-continue");
1485 result = Curl_add_bufferf(req_buffer,
1486 "Expect: 100-continue\r\n");
1487 if(result == CURLE_OK)
1488 data->state.expect100header = TRUE;
1494 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1495 Curl_send_buffer *req_buffer)
1498 struct curl_slist *headers=conn->data->set.headers;
1501 ptr = strchr(headers->data, ':');
1503 /* we require a colon for this to be a true header */
1505 ptr++; /* pass the colon */
1506 while(*ptr && ISSPACE(*ptr))
1510 /* only send this if the contents was non-blank */
1512 if(conn->allocptr.host &&
1513 /* a Host: header was sent already, don't pass on any custom Host:
1514 header as that will produce *two* in the same request! */
1515 checkprefix("Host:", headers->data))
1517 else if(conn->data->set.httpreq == HTTPREQ_POST_FORM &&
1518 /* this header (extended by formdata.c) is sent later */
1519 checkprefix("Content-Type:", headers->data))
1521 else if(conn->bits.authneg &&
1522 /* while doing auth neg, don't allow the custom length since
1523 we will force length zero then */
1524 checkprefix("Content-Length", headers->data))
1526 else if(conn->allocptr.te &&
1527 /* when asking for Transfer-Encoding, don't pass on a custom
1529 checkprefix("Connection", headers->data))
1532 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1539 headers = headers->next;
1544 CURLcode Curl_add_timecondition(struct SessionHandle *data,
1545 Curl_send_buffer *req_buffer)
1547 const struct tm *tm;
1548 char *buf = data->state.buffer;
1549 CURLcode result = CURLE_OK;
1552 result = Curl_gmtime(data->set.timevalue, &keeptime);
1554 failf(data, "Invalid TIMEVALUE\n");
1559 /* The If-Modified-Since header family should have their times set in
1560 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1561 * represented in Greenwich Mean Time (GMT), without exception. For the
1562 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1563 * Time)." (see page 20 of RFC2616).
1566 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1567 snprintf(buf, BUFSIZE-1,
1568 "%s, %02d %s %4d %02d:%02d:%02d GMT",
1569 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1571 Curl_month[tm->tm_mon],
1577 switch(data->set.timecondition) {
1578 case CURL_TIMECOND_IFMODSINCE:
1580 result = Curl_add_bufferf(req_buffer,
1581 "If-Modified-Since: %s\r\n", buf);
1583 case CURL_TIMECOND_IFUNMODSINCE:
1584 result = Curl_add_bufferf(req_buffer,
1585 "If-Unmodified-Since: %s\r\n", buf);
1587 case CURL_TIMECOND_LASTMOD:
1588 result = Curl_add_bufferf(req_buffer,
1589 "Last-Modified: %s\r\n", buf);
1597 * Curl_http() gets called from the generic Curl_do() function when a HTTP
1598 * request is to be performed. This creates and sends a properly constructed
1601 CURLcode Curl_http(struct connectdata *conn, bool *done)
1603 struct SessionHandle *data=conn->data;
1604 CURLcode result=CURLE_OK;
1606 const char *ppath = data->state.path;
1607 bool paste_ftp_userpwd = FALSE;
1608 char ftp_typecode[sizeof("/;type=?")] = "";
1609 const char *host = conn->host.name;
1610 const char *te = ""; /* transfer-encoding */
1612 const char *request;
1613 Curl_HttpReq httpreq = data->set.httpreq;
1614 char *addcookies = NULL;
1615 curl_off_t included_body = 0;
1616 const char *httpstring;
1617 Curl_send_buffer *req_buffer;
1618 curl_off_t postsize; /* off_t type to be able to hold a large file size */
1619 int seekerr = CURL_SEEKFUNC_OK;
1621 /* Always consider the DO phase done after this function call, even if there
1622 may be parts of the request that is not yet sent, since we can deal with
1623 the rest of the request in the PERFORM phase. */
1626 /* If there already is a protocol-specific struct allocated for this
1627 sessionhandle, deal with it */
1628 Curl_reset_reqproto(conn);
1630 if(!data->state.proto.http) {
1631 /* Only allocate this struct if we don't already have it! */
1633 http = calloc(1, sizeof(struct HTTP));
1635 return CURLE_OUT_OF_MEMORY;
1636 data->state.proto.http = http;
1639 http = data->state.proto.http;
1641 if(!data->state.this_is_a_follow) {
1642 /* this is not a followed location, get the original host name */
1643 if(data->state.first_host)
1644 /* Free to avoid leaking memory on multiple requests*/
1645 free(data->state.first_host);
1647 data->state.first_host = strdup(conn->host.name);
1648 if(!data->state.first_host)
1649 return CURLE_OUT_OF_MEMORY;
1652 if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
1654 httpreq = HTTPREQ_PUT;
1657 /* Now set the 'request' pointer to the proper request string */
1658 if(data->set.str[STRING_CUSTOMREQUEST])
1659 request = data->set.str[STRING_CUSTOMREQUEST];
1661 if(data->set.opt_no_body)
1664 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1667 case HTTPREQ_POST_FORM:
1673 default: /* this should never happen */
1684 /* The User-Agent string might have been allocated in url.c already, because
1685 it might have been used in the proxy connect, but if we have got a header
1686 with the user-agent string specified, we erase the previously made string
1688 if(Curl_checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
1689 free(conn->allocptr.uagent);
1690 conn->allocptr.uagent=NULL;
1693 /* setup the authentication headers */
1694 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1698 if((data->state.authhost.multi || data->state.authproxy.multi) &&
1699 (httpreq != HTTPREQ_GET) &&
1700 (httpreq != HTTPREQ_HEAD)) {
1701 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1702 with content-length zero as a "probe". */
1703 conn->bits.authneg = TRUE;
1706 conn->bits.authneg = FALSE;
1708 Curl_safefree(conn->allocptr.ref);
1709 if(data->change.referer && !Curl_checkheaders(data, "Referer:"))
1710 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1712 conn->allocptr.ref = NULL;
1714 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie:"))
1715 addcookies = data->set.str[STRING_COOKIE];
1717 if(!Curl_checkheaders(data, "Accept-Encoding:") &&
1718 data->set.str[STRING_ENCODING]) {
1719 Curl_safefree(conn->allocptr.accept_encoding);
1720 conn->allocptr.accept_encoding =
1721 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1722 if(!conn->allocptr.accept_encoding)
1723 return CURLE_OUT_OF_MEMORY;
1727 /* we only consider transfer-encoding magic if libz support is built-in */
1729 if(!Curl_checkheaders(data, "TE:") && data->set.http_transfer_encoding) {
1730 /* When we are to insert a TE: header in the request, we must also insert
1731 TE in a Connection: header, so we need to merge the custom provided
1732 Connection: header and prevent the original to get sent. Note that if
1733 the user has inserted his/hers own TE: header we don't do this magic
1734 but then assume that the user will handle it all! */
1735 char *cptr = Curl_checkheaders(data, "Connection:");
1736 #define TE_HEADER "TE: gzip\r\n"
1738 Curl_safefree(conn->allocptr.te);
1740 /* Create the (updated) Connection: header */
1741 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1742 strdup("Connection: TE\r\n" TE_HEADER);
1744 if(!conn->allocptr.te)
1745 return CURLE_OUT_OF_MEMORY;
1749 ptr = Curl_checkheaders(data, "Transfer-Encoding:");
1751 /* Some kind of TE is requested, check if 'chunked' is chosen */
1752 data->req.upload_chunky =
1753 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1756 if((conn->handler->protocol&CURLPROTO_HTTP) &&
1758 (data->set.infilesize == -1)) {
1759 if(conn->bits.authneg)
1760 /* don't enable chunked during auth neg */
1762 else if(use_http_1_1(data, conn)) {
1763 /* HTTP, upload, unknown file size and not HTTP 1.0 */
1764 data->req.upload_chunky = TRUE;
1767 failf(data, "Chunky upload is not supported by HTTP 1.0");
1768 return CURLE_UPLOAD_FAILED;
1772 /* else, no chunky upload */
1773 data->req.upload_chunky = FALSE;
1776 if(data->req.upload_chunky)
1777 te = "Transfer-Encoding: chunked\r\n";
1780 Curl_safefree(conn->allocptr.host);
1782 ptr = Curl_checkheaders(data, "Host:");
1783 if(ptr && (!data->state.this_is_a_follow ||
1784 Curl_raw_equal(data->state.first_host, conn->host.name))) {
1785 #if !defined(CURL_DISABLE_COOKIES)
1786 /* If we have a given custom Host: header, we extract the host name in
1787 order to possibly use it for cookie reasons later on. We only allow the
1788 custom Host: header if this is NOT a redirect, as setting Host: in the
1789 redirected request is being out on thin ice. Except if the host name
1790 is the same as the first one! */
1791 char *cookiehost = copy_header_value(ptr);
1793 return CURLE_OUT_OF_MEMORY;
1795 /* ignore empty data */
1798 char *colon = strchr(cookiehost, ':');
1800 *colon = 0; /* The host must not include an embedded port number */
1801 Curl_safefree(conn->allocptr.cookiehost);
1802 conn->allocptr.cookiehost = cookiehost;
1806 conn->allocptr.host = NULL;
1809 /* When building Host: headers, we must put the host name within
1810 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
1812 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
1813 (conn->remote_port == PORT_HTTPS)) ||
1814 ((conn->given->protocol&CURLPROTO_HTTP) &&
1815 (conn->remote_port == PORT_HTTP)) )
1816 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
1817 the port number in the host string */
1818 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
1819 conn->bits.ipv6_ip?"[":"",
1821 conn->bits.ipv6_ip?"]":"");
1823 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
1824 conn->bits.ipv6_ip?"[":"",
1826 conn->bits.ipv6_ip?"]":"",
1829 if(!conn->allocptr.host)
1830 /* without Host: we can't make a nice request */
1831 return CURLE_OUT_OF_MEMORY;
1834 #ifndef CURL_DISABLE_PROXY
1835 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
1836 /* Using a proxy but does not tunnel through it */
1838 /* The path sent to the proxy is in fact the entire URL. But if the remote
1839 host is a IDN-name, we must make sure that the request we produce only
1840 uses the encoded host name! */
1841 if(conn->host.dispname != conn->host.name) {
1842 char *url = data->change.url;
1843 ptr = strstr(url, conn->host.dispname);
1845 /* This is where the display name starts in the URL, now replace this
1846 part with the encoded name. TODO: This method of replacing the host
1847 name is rather crude as I believe there's a slight risk that the
1848 user has entered a user name or password that contain the host name
1850 size_t currlen = strlen(conn->host.dispname);
1851 size_t newlen = strlen(conn->host.name);
1852 size_t urllen = strlen(url);
1856 newurl = malloc(urllen + newlen - currlen + 1);
1858 /* copy the part before the host name */
1859 memcpy(newurl, url, ptr - url);
1860 /* append the new host name instead of the old */
1861 memcpy(newurl + (ptr - url), conn->host.name, newlen);
1862 /* append the piece after the host name */
1863 memcpy(newurl + newlen + (ptr - url),
1864 ptr + currlen, /* copy the trailing zero byte too */
1865 urllen - (ptr-url) - currlen + 1);
1866 if(data->change.url_alloc)
1867 free(data->change.url);
1868 data->change.url = newurl;
1869 data->change.url_alloc = TRUE;
1872 return CURLE_OUT_OF_MEMORY;
1875 ppath = data->change.url;
1876 if(checkprefix("ftp://", ppath)) {
1877 if(data->set.proxy_transfer_mode) {
1878 /* when doing ftp, append ;type=<a|i> if not present */
1879 char *type = strstr(ppath, ";type=");
1880 if(type && type[6] && type[7] == 0) {
1881 switch (Curl_raw_toupper(type[6])) {
1891 char *p = ftp_typecode;
1892 /* avoid sending invalid URLs like ftp://example.com;type=i if the
1893 * user specified ftp://example.com without the slash */
1894 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
1897 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
1898 data->set.prefer_ascii ? 'a' : 'i');
1901 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
1902 paste_ftp_userpwd = TRUE;
1905 #endif /* CURL_DISABLE_PROXY */
1907 if(HTTPREQ_POST_FORM == httpreq) {
1908 /* we must build the whole post sequence first, so that we have a size of
1909 the whole transfer before we start to send it */
1910 result = Curl_getformdata(data, &http->sendit, data->set.httppost,
1911 Curl_checkheaders(data, "Content-Type:"),
1917 http->p_accept = Curl_checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n";
1919 if(( (HTTPREQ_POST == httpreq) ||
1920 (HTTPREQ_POST_FORM == httpreq) ||
1921 (HTTPREQ_PUT == httpreq) ) &&
1922 data->state.resume_from) {
1923 /**********************************************************************
1924 * Resuming upload in HTTP means that we PUT or POST and that we have
1925 * got a resume_from value set. The resume value has already created
1926 * a Range: header that will be passed along. We need to "fast forward"
1927 * the file the given number of bytes and decrease the assume upload
1928 * file size before we continue this venture in the dark lands of HTTP.
1929 *********************************************************************/
1931 if(data->state.resume_from < 0 ) {
1933 * This is meant to get the size of the present remote-file by itself.
1934 * We don't support this now. Bail out!
1936 data->state.resume_from = 0;
1939 if(data->state.resume_from && !data->state.this_is_a_follow) {
1940 /* do we still game? */
1942 /* Now, let's read off the proper amount of bytes from the
1944 if(conn->seek_func) {
1945 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1949 if(seekerr != CURL_SEEKFUNC_OK) {
1950 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1951 failf(data, "Could not seek stream");
1952 return CURLE_READ_ERROR;
1954 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1956 curl_off_t passed=0;
1958 size_t readthisamountnow =
1959 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1960 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1962 size_t actuallyread =
1963 data->set.fread_func(data->state.buffer, 1, readthisamountnow,
1966 passed += actuallyread;
1967 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1968 /* this checks for greater-than only to make sure that the
1969 CURL_READFUNC_ABORT return code still aborts */
1970 failf(data, "Could only read %" FORMAT_OFF_T
1971 " bytes from the input",
1973 return CURLE_READ_ERROR;
1975 } while(passed < data->state.resume_from);
1979 /* now, decrease the size of the read */
1980 if(data->set.infilesize>0) {
1981 data->set.infilesize -= data->state.resume_from;
1983 if(data->set.infilesize <= 0) {
1984 failf(data, "File already completely uploaded");
1985 return CURLE_PARTIAL_FILE;
1988 /* we've passed, proceed as normal */
1991 if(data->state.use_range) {
1993 * A range is selected. We use different headers whether we're downloading
1994 * or uploading and we always let customized headers override our internal
1995 * ones if any such are specified.
1997 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
1998 !Curl_checkheaders(data, "Range:")) {
1999 /* if a line like this was already allocated, free the previous one */
2000 if(conn->allocptr.rangeline)
2001 free(conn->allocptr.rangeline);
2002 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2005 else if((httpreq != HTTPREQ_GET) &&
2006 !Curl_checkheaders(data, "Content-Range:")) {
2008 /* if a line like this was already allocated, free the previous one */
2009 if(conn->allocptr.rangeline)
2010 free(conn->allocptr.rangeline);
2012 if(data->set.set_resume_from < 0) {
2013 /* Upload resume was asked for, but we don't know the size of the
2014 remote part so we tell the server (and act accordingly) that we
2015 upload the whole file (again) */
2016 conn->allocptr.rangeline =
2017 aprintf("Content-Range: bytes 0-%" FORMAT_OFF_T
2018 "/%" FORMAT_OFF_T "\r\n",
2019 data->set.infilesize - 1, data->set.infilesize);
2022 else if(data->state.resume_from) {
2023 /* This is because "resume" was selected */
2024 curl_off_t total_expected_size=
2025 data->state.resume_from + data->set.infilesize;
2026 conn->allocptr.rangeline =
2027 aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
2028 "/%" FORMAT_OFF_T "\r\n",
2029 data->state.range, total_expected_size-1,
2030 total_expected_size);
2033 /* Range was selected and then we just pass the incoming range and
2034 append total size */
2035 conn->allocptr.rangeline =
2036 aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
2037 data->state.range, data->set.infilesize);
2039 if(!conn->allocptr.rangeline)
2040 return CURLE_OUT_OF_MEMORY;
2044 /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2046 httpstring= use_http_1_1(data, conn)?"1.1":"1.0";
2048 /* initialize a dynamic send-buffer */
2049 req_buffer = Curl_add_buffer_init();
2052 return CURLE_OUT_OF_MEMORY;
2054 /* add the main request stuff */
2055 /* GET/HEAD/POST/PUT */
2056 result = Curl_add_bufferf(req_buffer, "%s ", request);
2061 if(paste_ftp_userpwd)
2062 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2063 conn->user, conn->passwd,
2064 ppath + sizeof("ftp://") - 1);
2066 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2070 result = Curl_add_bufferf(req_buffer,
2071 "%s" /* ftp typecode (;type=x) */
2072 " HTTP/%s\r\n" /* HTTP version */
2073 "%s" /* proxyuserpwd */
2076 "%s" /* user agent */
2080 "%s" /* accept-encoding */
2082 "%s" /* Proxy-Connection */
2083 "%s",/* transfer-encoding */
2087 conn->allocptr.proxyuserpwd?
2088 conn->allocptr.proxyuserpwd:"",
2089 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2090 (data->state.use_range && conn->allocptr.rangeline)?
2091 conn->allocptr.rangeline:"",
2092 (data->set.str[STRING_USERAGENT] &&
2093 *data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)?
2094 conn->allocptr.uagent:"",
2095 (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
2096 http->p_accept?http->p_accept:"",
2097 conn->allocptr.te?conn->allocptr.te:"",
2098 (data->set.str[STRING_ENCODING] &&
2099 *data->set.str[STRING_ENCODING] &&
2100 conn->allocptr.accept_encoding)?
2101 conn->allocptr.accept_encoding:"",
2102 (data->change.referer && conn->allocptr.ref)?
2103 conn->allocptr.ref:"" /* Referer: <data> */,
2104 (conn->bits.httpproxy &&
2105 !conn->bits.tunnel_proxy &&
2106 !Curl_checkheaders(data, "Proxy-Connection:"))?
2107 "Proxy-Connection: Keep-Alive\r\n":"",
2112 * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
2113 * with basic and digest, it will be freed anyway by the next request
2116 Curl_safefree (conn->allocptr.userpwd);
2117 conn->allocptr.userpwd = NULL;
2122 #if !defined(CURL_DISABLE_COOKIES)
2123 if(data->cookies || addcookies) {
2124 struct Cookie *co=NULL; /* no cookies from start */
2128 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2129 co = Curl_cookie_getlist(data->cookies,
2130 conn->allocptr.cookiehost?
2131 conn->allocptr.cookiehost:host,
2133 (bool)(conn->handler->protocol&CURLPROTO_HTTPS?
2135 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2138 struct Cookie *store=co;
2139 /* now loop through all cookies that matched */
2143 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2147 result = Curl_add_bufferf(req_buffer,
2148 "%s%s=%s", count?"; ":"",
2149 co->name, co->value);
2154 co = co->next; /* next cookie please */
2156 Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2158 if(addcookies && (CURLE_OK == result)) {
2160 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2161 if(CURLE_OK == result) {
2162 result = Curl_add_bufferf(req_buffer, "%s%s",
2168 if(count && (CURLE_OK == result))
2169 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2176 if(data->set.timecondition) {
2177 result = Curl_add_timecondition(data, req_buffer);
2182 result = Curl_add_custom_headers(conn, req_buffer);
2186 http->postdata = NULL; /* nothing to post at this point */
2187 Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
2189 /* If 'authdone' is FALSE, we must not set the write socket index to the
2190 Curl_transfer() call below, as we're not ready to actually upload any
2195 case HTTPREQ_POST_FORM:
2196 if(!http->sendit || conn->bits.authneg) {
2197 /* nothing to post! */
2198 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2202 result = Curl_add_buffer_send(req_buffer, conn,
2203 &data->info.request_size, 0, FIRSTSOCKET);
2205 failf(data, "Failed sending POST request");
2207 /* setup variables for the upcoming transfer */
2208 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2213 if(Curl_FormInit(&http->form, http->sendit)) {
2214 failf(data, "Internal HTTP POST error!");
2215 return CURLE_HTTP_POST_ERROR;
2218 /* Get the currently set callback function pointer and store that in the
2219 form struct since we might want the actual user-provided callback later
2220 on. The conn->fread_func pointer itself will be changed for the
2221 multipart case to the function that returns a multipart formatted
2223 http->form.fread_func = conn->fread_func;
2225 /* Set the read function to read from the generated form data */
2226 conn->fread_func = (curl_read_callback)Curl_FormReader;
2227 conn->fread_in = &http->form;
2229 http->sending = HTTPSEND_BODY;
2231 if(!data->req.upload_chunky) {
2232 /* only add Content-Length if not uploading chunked */
2233 result = Curl_add_bufferf(req_buffer,
2234 "Content-Length: %" FORMAT_OFF_T "\r\n",
2240 result = expect100(data, conn, req_buffer);
2246 /* Get Content-Type: line from Curl_formpostheader.
2249 size_t linelength=0;
2250 contentType = Curl_formpostheader((void *)&http->form,
2253 failf(data, "Could not get Content-Type header line!");
2254 return CURLE_HTTP_POST_ERROR;
2257 result = Curl_add_buffer(req_buffer, contentType, linelength);
2262 /* make the request end in a true CRLF */
2263 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2267 /* set upload size to the progress meter */
2268 Curl_pgrsSetUploadSize(data, http->postsize);
2270 /* fire away the whole request to the server */
2271 result = Curl_add_buffer_send(req_buffer, conn,
2272 &data->info.request_size, 0, FIRSTSOCKET);
2274 failf(data, "Failed sending POST request");
2276 /* setup variables for the upcoming transfer */
2277 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2278 &http->readbytecount, FIRSTSOCKET,
2279 &http->writebytecount);
2282 Curl_formclean(&http->sendit); /* free that whole lot */
2286 /* convert the form data */
2287 result = Curl_convert_form(data, http->sendit);
2289 Curl_formclean(&http->sendit); /* free that whole lot */
2295 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2297 if(conn->bits.authneg)
2300 postsize = data->set.infilesize;
2302 if((postsize != -1) && !data->req.upload_chunky) {
2303 /* only add Content-Length if not uploading chunked */
2304 result = Curl_add_bufferf(req_buffer,
2305 "Content-Length: %" FORMAT_OFF_T "\r\n",
2311 result = expect100(data, conn, req_buffer);
2315 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2319 /* set the upload size to the progress meter */
2320 Curl_pgrsSetUploadSize(data, postsize);
2322 /* this sends the buffer and frees all the buffer resources */
2323 result = Curl_add_buffer_send(req_buffer, conn,
2324 &data->info.request_size, 0, FIRSTSOCKET);
2326 failf(data, "Failed sending PUT request");
2328 /* prepare for transfer */
2329 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2330 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2331 postsize?&http->writebytecount:NULL);
2337 /* this is the simple POST, using x-www-form-urlencoded style */
2339 if(conn->bits.authneg)
2342 /* figure out the size of the postfields */
2343 postsize = (data->set.postfieldsize != -1)?
2344 data->set.postfieldsize:
2345 (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2347 if(!data->req.upload_chunky) {
2348 /* We only set Content-Length and allow a custom Content-Length if
2349 we don't upload data chunked, as RFC2616 forbids us to set both
2350 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2352 if(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length:")) {
2353 /* we allow replacing this header if not during auth negotiation,
2354 although it isn't very wise to actually set your own */
2355 result = Curl_add_bufferf(req_buffer,
2356 "Content-Length: %" FORMAT_OFF_T"\r\n",
2363 if(!Curl_checkheaders(data, "Content-Type:")) {
2364 result = Curl_add_bufferf(req_buffer,
2365 "Content-Type: application/"
2366 "x-www-form-urlencoded\r\n");
2371 /* For really small posts we don't use Expect: headers at all, and for
2372 the somewhat bigger ones we allow the app to disable it. Just make
2373 sure that the expect100header is always set to the preferred value
2375 ptr = Curl_checkheaders(data, "Expect:");
2377 data->state.expect100header =
2378 Curl_compareheader(ptr, "Expect:", "100-continue");
2380 else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2381 result = expect100(data, conn, req_buffer);
2386 data->state.expect100header = FALSE;
2388 if(data->set.postfields) {
2390 if(!data->state.expect100header &&
2391 (postsize < MAX_INITIAL_POST_SIZE)) {
2392 /* if we don't use expect: 100 AND
2393 postsize is less than MAX_INITIAL_POST_SIZE
2395 then append the post data to the HTTP request header. This limit
2396 is no magic limit but only set to prevent really huge POSTs to
2397 get the data duplicated with malloc() and family. */
2399 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2403 if(!data->req.upload_chunky) {
2404 /* We're not sending it 'chunked', append it to the request
2405 already now to reduce the number if send() calls */
2406 result = Curl_add_buffer(req_buffer, data->set.postfields,
2408 included_body = postsize;
2411 /* Append the POST data chunky-style */
2412 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2413 if(CURLE_OK == result)
2414 result = Curl_add_buffer(req_buffer, data->set.postfields,
2416 if(CURLE_OK == result)
2417 result = Curl_add_buffer(req_buffer,
2418 "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2419 /* CR LF 0 CR LF CR LF */
2420 included_body = postsize + 7;
2424 /* Make sure the progress information is accurate */
2425 Curl_pgrsSetUploadSize(data, postsize);
2428 /* A huge POST coming up, do data separate from the request */
2429 http->postsize = postsize;
2430 http->postdata = data->set.postfields;
2432 http->sending = HTTPSEND_BODY;
2434 conn->fread_func = (curl_read_callback)readmoredata;
2435 conn->fread_in = (void *)conn;
2437 /* set the upload size to the progress meter */
2438 Curl_pgrsSetUploadSize(data, http->postsize);
2440 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2446 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2450 if(data->req.upload_chunky && conn->bits.authneg) {
2451 /* Chunky upload is selected and we're negotiating auth still, send
2453 result = Curl_add_buffer(req_buffer,
2454 "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2455 /* CR LF 0 CR LF CR LF */
2460 else if(data->set.postfieldsize) {
2461 /* set the upload size to the progress meter */
2462 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2464 /* set the pointer to mark that we will send the post body using the
2465 read callback, but only if we're not in authenticate
2467 if(!conn->bits.authneg) {
2468 http->postdata = (char *)&http->postdata;
2469 http->postsize = postsize;
2473 /* issue the request */
2474 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2475 (size_t)included_body, FIRSTSOCKET);
2478 failf(data, "Failed sending HTTP POST request");
2480 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2481 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2482 http->postdata?&http->writebytecount:NULL);
2486 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2490 /* issue the request */
2491 result = Curl_add_buffer_send(req_buffer, conn,
2492 &data->info.request_size, 0, FIRSTSOCKET);
2495 failf(data, "Failed sending HTTP request");
2497 /* HTTP GET/HEAD download: */
2498 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2499 http->postdata?FIRSTSOCKET:-1,
2500 http->postdata?&http->writebytecount:NULL);
2505 if(http->writebytecount) {
2506 /* if a request-body has been sent off, we make sure this progress is noted
2508 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2509 if(Curl_pgrsUpdate(conn))
2510 result = CURLE_ABORTED_BY_CALLBACK;
2519 * Returns TRUE if member of the list matches prefix of string
2522 checkhttpprefix(struct SessionHandle *data,
2525 struct curl_slist *head = data->set.http200aliases;
2527 #ifdef CURL_DOES_CONVERSIONS
2528 /* convert from the network encoding using a scratch area */
2529 char *scratch = strdup(s);
2530 if(NULL == scratch) {
2531 failf (data, "Failed to allocate memory for conversion!");
2532 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2534 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2535 /* Curl_convert_from_network calls failf if unsuccessful */
2537 return FALSE; /* can't return CURLE_foobar so return FALSE */
2540 #endif /* CURL_DOES_CONVERSIONS */
2543 if(checkprefix(head->data, s)) {
2550 if((rc != TRUE) && (checkprefix("HTTP/", s)))
2553 #ifdef CURL_DOES_CONVERSIONS
2555 #endif /* CURL_DOES_CONVERSIONS */
2559 #ifndef CURL_DISABLE_RTSP
2561 checkrtspprefix(struct SessionHandle *data,
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 */
2579 (void)data; /* unused */
2580 #endif /* CURL_DOES_CONVERSIONS */
2581 if(checkprefix("RTSP/", s))
2586 #endif /* CURL_DISABLE_RTSP */
2589 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2592 #ifndef CURL_DISABLE_RTSP
2593 if(conn->handler->protocol & CURLPROTO_RTSP)
2594 return checkrtspprefix(data, s);
2597 #endif /* CURL_DISABLE_RTSP */
2599 return checkhttpprefix(data, s);
2603 * header_append() copies a chunk of data to the end of the already received
2604 * header. We make sure that the full string fit in the allocated header
2605 * buffer, or else we enlarge it.
2607 static CURLcode header_append(struct SessionHandle *data,
2608 struct SingleRequest *k,
2611 if(k->hbuflen + length >= data->state.headersize) {
2612 /* We enlarge the header buffer as it is too small */
2617 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2618 /* The reason to have a max limit for this is to avoid the risk of a bad
2619 server feeding libcurl with a never-ending header that will cause
2620 reallocs infinitely */
2621 failf (data, "Avoided giant realloc for header (max is %d)!",
2622 CURL_MAX_HTTP_HEADER);
2623 return CURLE_OUT_OF_MEMORY;
2626 newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2627 hbufp_index = k->hbufp - data->state.headerbuff;
2628 newbuff = realloc(data->state.headerbuff, newsize);
2630 failf (data, "Failed to alloc memory for big header!");
2631 return CURLE_OUT_OF_MEMORY;
2633 data->state.headersize=newsize;
2634 data->state.headerbuff = newbuff;
2635 k->hbufp = data->state.headerbuff + hbufp_index;
2637 memcpy(k->hbufp, k->str_start, length);
2639 k->hbuflen += length;
2647 * Read any HTTP header lines from the server and pass them to the client app.
2649 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2650 struct connectdata *conn,
2655 struct SingleRequest *k = &data->req;
2657 /* header line within buffer loop */
2663 /* str_start is start of line within buf */
2664 k->str_start = k->str;
2666 /* data is in network encoding so use 0x0a instead of '\n' */
2667 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2670 /* Not a complete header line within buffer, append the data to
2671 the end of the headerbuff. */
2672 result = header_append(data, k, *nread);
2676 if(!k->headerline && (k->hbuflen>5)) {
2677 /* make a first check that this looks like a protocol header */
2678 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2679 /* this is not the beginning of a protocol first header line */
2681 k->badheader = HEADER_ALLBAD;
2686 break; /* read more and try again */
2689 /* decrease the size of the remaining (supposed) header line */
2690 rest_length = (k->end_ptr - k->str)+1;
2691 *nread -= (ssize_t)rest_length;
2693 k->str = k->end_ptr + 1; /* move past new line */
2695 full_length = k->str - k->str_start;
2697 result = header_append(data, k, full_length);
2701 k->end_ptr = k->hbufp;
2702 k->p = data->state.headerbuff;
2705 * We now have a FULL header line that p points to
2708 if(!k->headerline) {
2709 /* the first read header */
2710 if((k->hbuflen>5) &&
2711 !checkprotoprefix(data, conn, data->state.headerbuff)) {
2712 /* this is not the beginning of a protocol first header line */
2715 /* since there's more, this is a partial bad header */
2716 k->badheader = HEADER_PARTHEADER;
2718 /* this was all we read so it's all a bad header */
2719 k->badheader = HEADER_ALLBAD;
2720 *nread = (ssize_t)rest_length;
2726 /* headers are in network encoding so
2727 use 0x0a and 0x0d instead of '\n' and '\r' */
2728 if((0x0a == *k->p) || (0x0d == *k->p)) {
2730 /* Zero-length header line means end of headers! */
2732 #ifdef CURL_DOES_CONVERSIONS
2734 *k->p = '\r'; /* replace with CR in host encoding */
2735 k->p++; /* pass the CR byte */
2738 *k->p = '\n'; /* replace with LF in host encoding */
2739 k->p++; /* pass the LF byte */
2743 k->p++; /* pass the \r byte */
2745 k->p++; /* pass the \n byte */
2746 #endif /* CURL_DOES_CONVERSIONS */
2748 if(100 <= k->httpcode && 199 >= k->httpcode) {
2750 * We have made a HTTP PUT or POST and this is 1.1-lingo
2751 * that tells us that the server is OK with this and ready
2752 * to receive the data.
2753 * However, we'll get more headers now so we must get
2754 * back into the header-parsing state!
2757 k->headerline = 0; /* restart the header line counter */
2759 /* if we did wait for this do enable write now! */
2761 k->exp100 = EXP100_SEND_DATA;
2762 k->keepon |= KEEP_SEND;
2766 k->header = FALSE; /* no more header to parse! */
2768 if((k->size == -1) && !k->chunk && !conn->bits.close &&
2769 (conn->httpversion >= 11) &&
2770 !(conn->handler->protocol & CURLPROTO_RTSP)) {
2771 /* On HTTP 1.1, when connection is not to get closed, but no
2772 Content-Length nor Content-Encoding chunked have been
2773 received, according to RFC2616 section 4.4 point 5, we
2774 assume that the server will close the connection to
2775 signal the end of the document. */
2776 infof(data, "no chunk, no close, no size. Assume close to "
2778 conn->bits.close = TRUE;
2782 if(417 == k->httpcode) {
2784 * we got: "417 Expectation Failed" this means:
2785 * we have made a HTTP call and our Expect Header
2786 * seems to cause a problem => abort the write operations
2787 * (or prevent them from starting).
2789 k->exp100 = EXP100_FAILED;
2790 k->keepon &= ~KEEP_SEND;
2794 * When all the headers have been parsed, see if we should give
2795 * up and return an error.
2797 if(http_should_fail(conn)) {
2798 failf (data, "The requested URL returned error: %d",
2800 return CURLE_HTTP_RETURNED_ERROR;
2803 /* now, only output this if the header AND body are requested:
2805 writetype = CLIENTWRITE_HEADER;
2806 if(data->set.include_header)
2807 writetype |= CLIENTWRITE_BODY;
2809 headerlen = k->p - data->state.headerbuff;
2811 result = Curl_client_write(conn, writetype,
2812 data->state.headerbuff,
2817 data->info.header_size += (long)headerlen;
2818 data->req.headerbytecount += (long)headerlen;
2820 data->req.deductheadercount =
2821 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
2823 if(!*stop_reading) {
2824 /* Curl_http_auth_act() checks what authentication methods
2825 * that are available and decides which one (if any) to
2826 * use. It will set 'newurl' if an auth method was picked. */
2827 result = Curl_http_auth_act(conn);
2832 if(conn->bits.rewindaftersend) {
2833 /* We rewind after a complete send, so thus we continue
2835 infof(data, "Keep sending data to get tossed away!\n");
2836 k->keepon |= KEEP_SEND;
2842 * really end-of-headers.
2844 * If we requested a "no body", this is a good time to get
2845 * out and return home.
2847 if(data->set.opt_no_body)
2848 *stop_reading = TRUE;
2850 /* If we know the expected size of this document, we set the
2851 maximum download size to the size of the expected
2852 document or else, we won't know when to stop reading!
2854 Note that we set the download maximum even if we read a
2855 "Connection: close" header, to make sure that
2856 "Content-Length: 0" still prevents us from attempting to
2857 read the (missing) response-body.
2859 /* According to RFC2616 section 4.4, we MUST ignore
2860 Content-Length: headers if we are now receiving data
2861 using chunked Transfer-Encoding.
2864 k->maxdownload = k->size = -1;
2867 /* We do this operation even if no_body is true, since this
2868 data might be retrieved later with curl_easy_getinfo()
2869 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
2871 Curl_pgrsSetDownloadSize(data, k->size);
2872 k->maxdownload = k->size;
2875 /* If max download size is *zero* (nothing) we already
2876 have nothing and can safely return ok now! */
2877 if(0 == k->maxdownload)
2878 *stop_reading = TRUE;
2881 /* we make sure that this socket isn't read more now */
2882 k->keepon &= ~KEEP_RECV;
2885 if(data->set.verbose)
2886 Curl_debug(data, CURLINFO_HEADER_IN,
2887 k->str_start, headerlen, conn);
2888 break; /* exit header line loop */
2891 /* We continue reading headers, so reset the line-based
2892 header parsing variables hbufp && hbuflen */
2893 k->hbufp = data->state.headerbuff;
2899 * Checks for special headers coming up.
2902 if(!k->headerline++) {
2903 /* This is the first header, it MUST be the error code line
2904 or else we consider this to be the body right away! */
2905 int httpversion_major;
2906 int rtspversion_major;
2908 #ifdef CURL_DOES_CONVERSIONS
2909 #define HEADER1 scratch
2910 #define SCRATCHSIZE 21
2912 char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
2913 /* We can't really convert this yet because we
2914 don't know if it's the 1st header line or the body.
2915 So we do a partial conversion into a scratch area,
2916 leaving the data at k->p as-is.
2918 strncpy(&scratch[0], k->p, SCRATCHSIZE);
2919 scratch[SCRATCHSIZE] = 0; /* null terminate */
2920 res = Curl_convert_from_network(data,
2924 /* Curl_convert_from_network calls failf if unsuccessful */
2927 #define HEADER1 k->p /* no conversion needed, just use k->p */
2928 #endif /* CURL_DOES_CONVERSIONS */
2930 if(conn->handler->protocol & CURLPROTO_HTTP) {
2931 nc = sscanf(HEADER1,
2937 conn->httpversion += 10 * httpversion_major;
2940 /* this is the real world, not a Nirvana
2941 NCSA 1.5.x returns this crap when asked for HTTP/1.1
2943 nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
2944 conn->httpversion = 10;
2946 /* If user has set option HTTP200ALIASES,
2947 compare header line against list of aliases
2950 if(checkhttpprefix(data, k->p)) {
2953 conn->httpversion = 10;
2958 else if(conn->handler->protocol & CURLPROTO_RTSP) {
2959 nc = sscanf(HEADER1,
2965 conn->rtspversion += 10 * rtspversion_major;
2966 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
2969 /* TODO: do we care about the other cases here? */
2975 data->info.httpcode = k->httpcode;
2977 data->info.httpversion = conn->httpversion;
2978 if(!data->state.httpversion ||
2979 data->state.httpversion > conn->httpversion)
2980 /* store the lowest server version we encounter */
2981 data->state.httpversion = conn->httpversion;
2984 * This code executes as part of processing the header. As a
2985 * result, it's not totally clear how to interpret the
2986 * response code yet as that depends on what other headers may
2987 * be present. 401 and 407 may be errors, but may be OK
2988 * depending on how authentication is working. Other codes
2989 * are definitely errors, so give up here.
2991 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
2992 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
2993 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
2995 if(data->state.resume_from &&
2996 (data->set.httpreq==HTTPREQ_GET) &&
2997 (k->httpcode == 416)) {
2998 /* "Requested Range Not Satisfiable", just proceed and
2999 pretend this is no error */
3002 /* serious error, go home! */
3003 failf (data, "The requested URL returned error: %d",
3005 return CURLE_HTTP_RETURNED_ERROR;
3009 if(conn->httpversion == 10) {
3010 /* Default action for HTTP/1.0 must be to close, unless
3011 we get one of those fancy headers that tell us the
3012 server keeps it open for us! */
3013 infof(data, "HTTP 1.0, assume close after body\n");
3014 conn->bits.close = TRUE;
3016 else if(conn->httpversion >= 11 &&
3017 !conn->bits.close) {
3018 /* If HTTP version is >= 1.1 and connection is persistent
3019 server supports pipelining. */
3021 "HTTP 1.1 or later with persistent connection, "
3022 "pipelining supported\n"));
3023 conn->server_supports_pipelining = TRUE;
3026 switch(k->httpcode) {
3028 /* (quote from RFC2616, section 10.2.5): The server has
3029 * fulfilled the request but does not need to return an
3030 * entity-body ... The 204 response MUST NOT include a
3031 * message-body, and thus is always terminated by the first
3032 * empty line after the header fields. */
3035 /* (quote from RFC2616, section 10.3.5): The 304 response
3036 * MUST NOT contain a message-body, and thus is always
3037 * terminated by the first empty line after the header
3039 if(data->set.timecondition)
3040 data->info.timecond = TRUE;
3043 k->ignorecl = TRUE; /* ignore Content-Length headers */
3051 k->header = FALSE; /* this is not a header line */
3056 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3057 /* Curl_convert_from_network calls failf if unsuccessful */
3061 /* Check for Content-Length: header lines to get size */
3062 if(!k->ignorecl && !data->set.ignorecl &&
3063 checkprefix("Content-Length:", k->p)) {
3064 curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3065 if(data->set.max_filesize &&
3066 contentlength > data->set.max_filesize) {
3067 failf(data, "Maximum file size exceeded");
3068 return CURLE_FILESIZE_EXCEEDED;
3070 if(contentlength >= 0) {
3071 k->size = contentlength;
3072 k->maxdownload = k->size;
3073 /* we set the progress download size already at this point
3074 just to make it easier for apps/callbacks to extract this
3075 info as soon as possible */
3076 Curl_pgrsSetDownloadSize(data, k->size);
3079 /* Negative Content-Length is really odd, and we know it
3080 happens for example when older Apache servers send large
3082 conn->bits.close = TRUE;
3083 infof(data, "Negative content-length: %" FORMAT_OFF_T
3084 ", closing after transfer\n", contentlength);
3087 /* check for Content-Type: header lines to get the MIME-type */
3088 else if(checkprefix("Content-Type:", k->p)) {
3089 char *contenttype = copy_header_value(k->p);
3091 return CURLE_OUT_OF_MEMORY;
3093 /* ignore empty data */
3096 Curl_safefree(data->info.contenttype);
3097 data->info.contenttype = contenttype;
3100 else if((conn->httpversion == 10) &&
3101 conn->bits.httpproxy &&
3102 Curl_compareheader(k->p,
3103 "Proxy-Connection:", "keep-alive")) {
3105 * When a HTTP/1.0 reply comes when using a proxy, the
3106 * 'Proxy-Connection: keep-alive' line tells us the
3107 * connection will be kept alive for our pleasure.
3108 * Default action for 1.0 is to close.
3110 conn->bits.close = FALSE; /* don't close when done */
3111 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3113 else if((conn->httpversion == 11) &&
3114 conn->bits.httpproxy &&
3115 Curl_compareheader(k->p,
3116 "Proxy-Connection:", "close")) {
3118 * We get a HTTP/1.1 response from a proxy and it says it'll
3119 * close down after this transfer.
3121 conn->bits.close = TRUE; /* close when done */
3122 infof(data, "HTTP/1.1 proxy connection set close!\n");
3124 else if((conn->httpversion == 10) &&
3125 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3127 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3128 * tells us the connection will be kept alive for our
3129 * pleasure. Default action for 1.0 is to close.
3131 * [RFC2068, section 19.7.1] */
3132 conn->bits.close = FALSE; /* don't close when done */
3133 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3135 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3137 * [RFC 2616, section 8.1.2.1]
3138 * "Connection: close" is HTTP/1.1 language and means that
3139 * the connection will close when this request has been
3142 conn->bits.close = TRUE; /* close when done */
3144 else if(checkprefix("Transfer-Encoding:", k->p)) {
3145 /* One or more encodings. We check for chunked and/or a compression
3148 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3149 * means that the server will send a series of "chunks". Each
3150 * chunk starts with line with info (including size of the
3151 * coming block) (terminated with CRLF), then a block of data
3152 * with the previously mentioned size. There can be any amount
3153 * of chunks, and a chunk-data set to zero signals the
3158 /* Find the first non-space letter */
3162 /* skip whitespaces and commas */
3163 while(*start && (ISSPACE(*start) || (*start == ',')))
3166 if(checkprefix("chunked", start)) {
3167 k->chunk = TRUE; /* chunks coming our way */
3169 /* init our chunky engine */
3170 Curl_httpchunk_init(conn);
3175 if(k->auto_decoding)
3176 /* TODO: we only support the first mentioned compression for now */
3179 if(checkprefix("identity", start)) {
3180 k->auto_decoding = IDENTITY;
3183 else if(checkprefix("deflate", start)) {
3184 k->auto_decoding = DEFLATE;
3187 else if(checkprefix("gzip", start)) {
3188 k->auto_decoding = GZIP;
3191 else if(checkprefix("x-gzip", start)) {
3192 k->auto_decoding = GZIP;
3195 else if(checkprefix("compress", start)) {
3196 k->auto_decoding = COMPRESS;
3199 else if(checkprefix("x-compress", start)) {
3200 k->auto_decoding = COMPRESS;
3210 else if(checkprefix("Content-Encoding:", k->p) &&
3211 data->set.str[STRING_ENCODING]) {
3213 * Process Content-Encoding. Look for the values: identity,
3214 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3215 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3216 * 2616). zlib cannot handle compress. However, errors are
3217 * handled further down when the response body is processed
3221 /* Find the first non-space letter */
3223 while(*start && ISSPACE(*start))
3226 /* Record the content-encoding for later use */
3227 if(checkprefix("identity", start))
3228 k->auto_decoding = IDENTITY;
3229 else if(checkprefix("deflate", start))
3230 k->auto_decoding = DEFLATE;
3231 else if(checkprefix("gzip", start)
3232 || checkprefix("x-gzip", start))
3233 k->auto_decoding = GZIP;
3234 else if(checkprefix("compress", start)
3235 || checkprefix("x-compress", start))
3236 k->auto_decoding = COMPRESS;
3238 else if(checkprefix("Content-Range:", k->p)) {
3239 /* Content-Range: bytes [num]-
3240 Content-Range: bytes: [num]-
3241 Content-Range: [num]-
3243 The second format was added since Sun's webserver
3244 JavaWebServer/1.1.1 obviously sends the header this way!
3245 The third added since some servers use that!
3248 char *ptr = k->p + 14;
3250 /* Move forward until first digit */
3251 while(*ptr && !ISDIGIT(*ptr))
3254 k->offset = curlx_strtoofft(ptr, NULL, 10);
3256 if(data->state.resume_from == k->offset)
3257 /* we asked for a resume and we got it */
3258 k->content_range = TRUE;
3260 #if !defined(CURL_DISABLE_COOKIES)
3261 else if(data->cookies &&
3262 checkprefix("Set-Cookie:", k->p)) {
3263 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3264 CURL_LOCK_ACCESS_SINGLE);
3265 Curl_cookie_add(data,
3266 data->cookies, TRUE, k->p+11,
3267 /* If there is a custom-set Host: name, use it
3268 here, or else use real peer host name. */
3269 conn->allocptr.cookiehost?
3270 conn->allocptr.cookiehost:conn->host.name,
3272 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3275 else if(checkprefix("Last-Modified:", k->p) &&
3276 (data->set.timecondition || data->set.get_filetime) ) {
3277 time_t secs=time(NULL);
3278 k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3280 if(data->set.get_filetime)
3281 data->info.filetime = (long)k->timeofdoc;
3283 else if((checkprefix("WWW-Authenticate:", k->p) &&
3284 (401 == k->httpcode)) ||
3285 (checkprefix("Proxy-authenticate:", k->p) &&
3286 (407 == k->httpcode))) {
3287 result = Curl_http_input_auth(conn, k->httpcode, k->p);
3291 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3292 checkprefix("Location:", k->p) &&
3293 !data->req.location) {
3294 /* this is the URL that the server advises us to use instead */
3295 char *location = copy_header_value(k->p);
3297 return CURLE_OUT_OF_MEMORY;
3299 /* ignore empty data */
3302 data->req.location = location;
3304 if(data->set.http_follow_location) {
3305 DEBUGASSERT(!data->req.newurl);
3306 data->req.newurl = strdup(data->req.location); /* clone */
3307 if(!data->req.newurl)
3308 return CURLE_OUT_OF_MEMORY;
3310 /* some cases of POST and PUT etc needs to rewind the data
3311 stream at this point */
3312 result = http_perhapsrewind(conn);
3318 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3319 result = Curl_rtsp_parseheader(conn, k->p);
3325 * End of header-checks. Write them to the client.
3328 writetype = CLIENTWRITE_HEADER;
3329 if(data->set.include_header)
3330 writetype |= CLIENTWRITE_BODY;
3332 if(data->set.verbose)
3333 Curl_debug(data, CURLINFO_HEADER_IN,
3334 k->p, (size_t)k->hbuflen, conn);
3336 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3340 data->info.header_size += (long)k->hbuflen;
3341 data->req.headerbytecount += (long)k->hbuflen;
3343 /* reset hbufp pointer && hbuflen */
3344 k->hbufp = data->state.headerbuff;
3347 while(!*stop_reading && *k->str); /* header line within buffer */
3349 /* We might have reached the end of the header part here, but
3350 there might be a non-header part left in the end of the read
3356 #endif /* CURL_DISABLE_HTTP */