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 struct SessionHandle *data=conn->data;
241 userp = &conn->allocptr.proxyuserpwd;
242 user = conn->proxyuser;
243 pwd = conn->proxypasswd;
246 userp = &conn->allocptr.userpwd;
251 snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
252 if(Curl_base64_encode(data, data->state.buffer,
253 strlen(data->state.buffer),
254 &authorization) > 0) {
257 *userp = aprintf( "%sAuthorization: Basic %s\r\n",
262 return CURLE_OUT_OF_MEMORY;
265 return CURLE_OUT_OF_MEMORY;
269 /* pickoneauth() selects the most favourable authentication method from the
270 * ones available and the ones we want.
272 * return TRUE if one was picked
274 static bool pickoneauth(struct auth *pick)
277 /* only deal with authentication we want */
278 long avail = pick->avail & pick->want;
281 /* The order of these checks is highly relevant, as this will be the order
282 of preference in case of the existence of multiple accepted types. */
283 if(avail & CURLAUTH_GSSNEGOTIATE)
284 pick->picked = CURLAUTH_GSSNEGOTIATE;
285 else if(avail & CURLAUTH_DIGEST)
286 pick->picked = CURLAUTH_DIGEST;
287 else if(avail & CURLAUTH_NTLM)
288 pick->picked = CURLAUTH_NTLM;
289 else if(avail & CURLAUTH_NTLM_SSO)
290 pick->picked = CURLAUTH_NTLM_SSO;
291 else if(avail & CURLAUTH_BASIC)
292 pick->picked = CURLAUTH_BASIC;
294 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
297 pick->avail = CURLAUTH_NONE; /* clear it here */
303 * Curl_http_perhapsrewind()
305 * If we are doing POST or PUT {
306 * If we have more data to send {
307 * If we are doing NTLM {
308 * Keep sending since we must not disconnect
311 * If there is more than just a little data left to send, close
312 * the current connection by force.
315 * If we have sent any data {
316 * If we don't have track of all the data {
317 * call app to tell it to rewind
320 * rewind internally so that the operation can restart fine
325 static CURLcode http_perhapsrewind(struct connectdata *conn)
327 struct SessionHandle *data = conn->data;
328 struct HTTP *http = data->state.proto.http;
329 curl_off_t bytessent;
330 curl_off_t expectsend = -1; /* default is unknown */
333 /* If this is still NULL, we have not reach very far and we can safely
334 skip this rewinding stuff */
337 switch(data->set.httpreq) {
345 bytessent = http->writebytecount;
347 if(conn->bits.authneg)
348 /* This is a state where we are known to be negotiating and we don't send
352 /* figure out how much data we are expected to send */
353 switch(data->set.httpreq) {
355 if(data->set.postfieldsize != -1)
356 expectsend = data->set.postfieldsize;
357 else if(data->set.postfields)
358 expectsend = (curl_off_t)strlen(data->set.postfields);
361 if(data->set.infilesize != -1)
362 expectsend = data->set.infilesize;
364 case HTTPREQ_POST_FORM:
365 expectsend = http->postsize;
372 conn->bits.rewindaftersend = FALSE; /* default */
374 if((expectsend == -1) || (expectsend > bytessent)) {
375 /* There is still data left to send */
376 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
377 (data->state.authhost.picked == CURLAUTH_NTLM) ||
378 (data->state.authproxy.picked == CURLAUTH_NTLM_SSO) ||
379 (data->state.authhost.picked == CURLAUTH_NTLM_SSO)) {
380 if(((expectsend - bytessent) < 2000) ||
381 (conn->ntlm.state != NTLMSTATE_NONE)) {
382 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
383 data left to send, keep on sending. */
385 /* rewind data when completely done sending! */
386 if(!conn->bits.authneg) {
387 conn->bits.rewindaftersend = TRUE;
388 infof(data, "Rewind stream after send\n");
394 /* this is already marked to get closed */
397 infof(data, "NTLM send, close instead of sending %" FORMAT_OFF_T
398 " bytes\n", (curl_off_t)(expectsend - bytessent));
401 /* This is not NTLM or NTLM with many bytes left to send: close
403 conn->bits.close = TRUE;
404 data->req.size = 0; /* don't download any more than 0 bytes */
406 /* There still is data left to send, but this connection is marked for
407 closure so we can safely do the rewind right now */
411 /* we rewind now at once since if we already sent something */
412 return Curl_readrewind(conn);
418 * Curl_http_auth_act() gets called when all HTTP headers have been received
419 * and it checks what authentication methods that are available and decides
420 * which one (if any) to use. It will set 'newurl' if an auth method was
424 CURLcode Curl_http_auth_act(struct connectdata *conn)
426 struct SessionHandle *data = conn->data;
427 bool pickhost = FALSE;
428 bool pickproxy = FALSE;
429 CURLcode code = CURLE_OK;
431 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
432 /* this is a transient response code, ignore */
435 if(data->state.authproblem)
436 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
438 if(conn->bits.user_passwd &&
439 ((data->req.httpcode == 401) ||
440 (conn->bits.authneg && data->req.httpcode < 300))) {
441 pickhost = pickoneauth(&data->state.authhost);
443 data->state.authproblem = TRUE;
445 if(conn->bits.proxy_user_passwd &&
446 ((data->req.httpcode == 407) ||
447 (conn->bits.authneg && data->req.httpcode < 300))) {
448 pickproxy = pickoneauth(&data->state.authproxy);
450 data->state.authproblem = TRUE;
453 if(pickhost || pickproxy) {
454 /* In case this is GSS auth, the newurl field is already allocated so
455 we must make sure to free it before allocating a new one. As figured
456 out in bug #2284386 */
457 Curl_safefree(data->req.newurl);
458 data->req.newurl = strdup(data->change.url); /* clone URL */
459 if(!data->req.newurl)
460 return CURLE_OUT_OF_MEMORY;
462 if((data->set.httpreq != HTTPREQ_GET) &&
463 (data->set.httpreq != HTTPREQ_HEAD) &&
464 !conn->bits.rewindaftersend) {
465 code = http_perhapsrewind(conn);
471 else if((data->req.httpcode < 300) &&
472 (!data->state.authhost.done) &&
473 conn->bits.authneg) {
474 /* no (known) authentication available,
475 authentication is not "done" yet and
476 no authentication seems to be required and
477 we didn't try HEAD or GET */
478 if((data->set.httpreq != HTTPREQ_GET) &&
479 (data->set.httpreq != HTTPREQ_HEAD)) {
480 data->req.newurl = strdup(data->change.url); /* clone URL */
481 if(!data->req.newurl)
482 return CURLE_OUT_OF_MEMORY;
483 data->state.authhost.done = TRUE;
486 if(http_should_fail(conn)) {
487 failf (data, "The requested URL returned error: %d",
489 code = CURLE_HTTP_RETURNED_ERROR;
497 * Output the correct authentication header depending on the auth type
498 * and whether or not it is to a proxy.
501 output_auth_headers(struct connectdata *conn,
502 struct auth *authstatus,
507 struct SessionHandle *data = conn->data;
508 const char *auth=NULL;
509 CURLcode result = CURLE_OK;
510 #ifdef USE_HTTP_NEGOTIATE
511 struct negotiatedata *negdata = proxy?
512 &data->state.proxyneg:&data->state.negotiate;
515 #ifdef CURL_DISABLE_CRYPTO_AUTH
520 #ifdef USE_HTTP_NEGOTIATE
521 negdata->state = GSS_AUTHNONE;
522 if((authstatus->picked == CURLAUTH_GSSNEGOTIATE) &&
523 negdata->context && !GSS_ERROR(negdata->status)) {
524 auth="GSS-Negotiate";
525 result = Curl_output_negotiate(conn, proxy);
528 authstatus->done = TRUE;
529 negdata->state = GSS_AUTHSENT;
534 if(authstatus->picked == CURLAUTH_NTLM) {
536 result = Curl_output_ntlm(conn, proxy);
543 if(authstatus->picked == CURLAUTH_NTLM_SSO) {
545 result = Curl_output_ntlm_sso(conn, proxy);
551 #ifndef CURL_DISABLE_CRYPTO_AUTH
552 if(authstatus->picked == CURLAUTH_DIGEST) {
554 result = Curl_output_digest(conn,
556 (const unsigned char *)request,
557 (const unsigned char *)path);
563 if(authstatus->picked == CURLAUTH_BASIC) {
565 if((proxy && conn->bits.proxy_user_passwd &&
566 !Curl_checkheaders(data, "Proxy-authorization:")) ||
567 (!proxy && conn->bits.user_passwd &&
568 !Curl_checkheaders(data, "Authorization:"))) {
570 result = http_output_basic(conn, proxy);
574 /* NOTE: this function should set 'done' TRUE, as the other auth
575 functions work that way */
576 authstatus->done = TRUE;
580 infof(data, "%s auth using %s with user '%s'\n",
581 proxy?"Proxy":"Server", auth,
582 proxy?(conn->proxyuser?conn->proxyuser:""):
583 (conn->user?conn->user:""));
584 authstatus->multi = (bool)(!authstatus->done);
587 authstatus->multi = FALSE;
593 * Curl_http_output_auth() setups the authentication headers for the
594 * host/proxy and the correct authentication
595 * method. conn->data->state.authdone is set to TRUE when authentication is
598 * @param conn all information about the current connection
599 * @param request pointer to the request keyword
600 * @param path pointer to the requested path
601 * @param proxytunnel boolean if this is the request setting up a "proxy
607 Curl_http_output_auth(struct connectdata *conn,
610 bool proxytunnel) /* TRUE if this is the request setting
611 up the proxy tunnel */
613 CURLcode result = CURLE_OK;
614 struct SessionHandle *data = conn->data;
615 struct auth *authhost;
616 struct auth *authproxy;
620 authhost = &data->state.authhost;
621 authproxy = &data->state.authproxy;
623 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
624 conn->bits.user_passwd)
625 /* continue please */ ;
627 authhost->done = TRUE;
628 authproxy->done = TRUE;
629 return CURLE_OK; /* no authentication with no user or password */
632 if(authhost->want && !authhost->picked)
633 /* The app has selected one or more methods, but none has been picked
634 so far by a server round-trip. Then we set the picked one to the
635 want one, and if this is one single bit it'll be used instantly. */
636 authhost->picked = authhost->want;
638 if(authproxy->want && !authproxy->picked)
639 /* The app has selected one or more methods, but none has been picked so
640 far by a proxy round-trip. Then we set the picked one to the want one,
641 and if this is one single bit it'll be used instantly. */
642 authproxy->picked = authproxy->want;
644 #ifndef CURL_DISABLE_PROXY
645 /* Send proxy authentication header if needed */
646 if(conn->bits.httpproxy &&
647 (conn->bits.tunnel_proxy == proxytunnel)) {
648 result = output_auth_headers(conn, authproxy, request, path, TRUE);
655 #endif /* CURL_DISABLE_PROXY */
656 /* we have no proxy so let's pretend we're done authenticating
658 authproxy->done = TRUE;
660 /* To prevent the user+password to get sent to other than the original
661 host due to a location-follow, we do some weirdo checks here */
662 if(!data->state.this_is_a_follow ||
664 !data->state.first_host ||
665 data->set.http_disable_hostname_check_before_authentication ||
666 Curl_raw_equal(data->state.first_host, conn->host.name)) {
667 result = output_auth_headers(conn, authhost, request, path, FALSE);
670 authhost->done = TRUE;
677 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
678 * headers. They are dealt with both in the transfer.c main loop and in the
679 * proxy CONNECT loop.
682 CURLcode Curl_http_input_auth(struct connectdata *conn,
684 const char *header) /* the first non-space */
687 * This resource requires authentication
689 struct SessionHandle *data = conn->data;
695 if(httpcode == 407) {
696 start = header+strlen("Proxy-authenticate:");
697 availp = &data->info.proxyauthavail;
698 authp = &data->state.authproxy;
701 start = header+strlen("WWW-Authenticate:");
702 availp = &data->info.httpauthavail;
703 authp = &data->state.authhost;
706 /* pass all white spaces */
707 while(*start && ISSPACE(*start))
711 * Here we check if we want the specific single authentication (using ==) and
712 * if we do, we initiate usage of it.
714 * If the provided authentication is wanted as one out of several accepted
715 * types (using &), we OR this authentication type to the authavail
720 * ->picked is first set to the 'want' value (one or more bits) before the
721 * request is sent, and then it is again set _after_ all response 401/407
722 * headers have been received but then only to a single preferred method
727 #ifdef USE_HTTP_NEGOTIATE
728 if(checkprefix("GSS-Negotiate", start) ||
729 checkprefix("Negotiate", start)) {
731 *availp |= CURLAUTH_GSSNEGOTIATE;
732 authp->avail |= CURLAUTH_GSSNEGOTIATE;
734 if(data->state.negotiate.state == GSS_AUTHSENT) {
735 /* if we sent GSS authentication in the outgoing request and we get this
736 back, we're in trouble */
737 infof(data, "Authentication problem. Ignoring this.\n");
738 data->state.authproblem = TRUE;
741 neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
743 DEBUGASSERT(!data->req.newurl);
744 data->req.newurl = strdup(data->change.url);
745 if(!data->req.newurl)
746 return CURLE_OUT_OF_MEMORY;
747 data->state.authproblem = FALSE;
748 /* we received GSS auth info and we dealt with it fine */
749 data->state.negotiate.state = GSS_AUTHRECV;
752 data->state.authproblem = TRUE;
759 /* NTLM support requires the SSL crypto libs */
760 if(checkprefix("NTLM", start)) {
761 *availp |= CURLAUTH_NTLM;
762 authp->avail |= CURLAUTH_NTLM;
763 if(authp->picked == CURLAUTH_NTLM ||
764 authp->picked == CURLAUTH_NTLM_SSO) {
765 /* NTLM authentication is picked and activated */
767 Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
768 if(CURLNTLM_BAD != ntlm) {
769 data->state.authproblem = FALSE;
771 if(authp->picked == CURLAUTH_NTLM_SSO) {
772 *availp &= ~CURLAUTH_NTLM;
773 authp->avail &= ~CURLAUTH_NTLM;
774 *availp |= CURLAUTH_NTLM_SSO;
775 authp->avail |= CURLAUTH_NTLM_SSO;
777 /* Get the challenge-message which will be passed to
778 * ntlm_auth for generating the type 3 message later */
779 while(*start && ISSPACE(*start))
781 if(checkprefix("NTLM", start)) {
782 start += strlen("NTLM");
783 while(*start && ISSPACE(*start))
786 if((conn->challenge_header = strdup(start)) == NULL)
787 return CURLE_OUT_OF_MEMORY;
793 infof(data, "Authentication problem. Ignoring this.\n");
794 data->state.authproblem = TRUE;
800 #ifndef CURL_DISABLE_CRYPTO_AUTH
801 if(checkprefix("Digest", start)) {
802 if((authp->avail & CURLAUTH_DIGEST) != 0) {
803 infof(data, "Ignoring duplicate digest auth header.\n");
807 *availp |= CURLAUTH_DIGEST;
808 authp->avail |= CURLAUTH_DIGEST;
810 /* We call this function on input Digest headers even if Digest
811 * authentication isn't activated yet, as we need to store the
812 * incoming data from this header in case we are gonna use Digest. */
813 dig = Curl_input_digest(conn, (bool)(httpcode == 407), start);
815 if(CURLDIGEST_FINE != dig) {
816 infof(data, "Authentication problem. Ignoring this.\n");
817 data->state.authproblem = TRUE;
823 if(checkprefix("Basic", start)) {
824 *availp |= CURLAUTH_BASIC;
825 authp->avail |= CURLAUTH_BASIC;
826 if(authp->picked == CURLAUTH_BASIC) {
827 /* We asked for Basic authentication but got a 40X back
828 anyway, which basically means our name+password isn't
830 authp->avail = CURLAUTH_NONE;
831 infof(data, "Authentication problem. Ignoring this.\n");
832 data->state.authproblem = TRUE;
840 * http_should_fail() determines whether an HTTP response has gotten us
841 * into an error state or not.
843 * @param conn all information about the current connection
845 * @retval 0 communications should continue
847 * @retval 1 communications should not continue
849 static int http_should_fail(struct connectdata *conn)
851 struct SessionHandle *data;
858 httpcode = data->req.httpcode;
861 ** If we haven't been asked to fail on error,
864 if(!data->set.http_fail_on_error)
868 ** Any code < 400 is never terminal.
873 if(data->state.resume_from &&
874 (data->set.httpreq==HTTPREQ_GET) &&
876 /* "Requested Range Not Satisfiable", just proceed and
877 pretend this is no error */
882 ** Any code >= 400 that's not 401 or 407 is always
885 if((httpcode != 401) &&
890 ** All we have left to deal with is 401 and 407
892 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
895 ** Examine the current authentication state to see if this
896 ** is an error. The idea is for this function to get
897 ** called after processing all the headers in a response
898 ** message. So, if we've been to asked to authenticate a
899 ** particular stage, and we've done it, we're OK. But, if
900 ** we're already completely authenticated, it's not OK to
901 ** get another 401 or 407.
903 ** It is possible for authentication to go stale such that
904 ** the client needs to reauthenticate. Once that info is
905 ** available, use it here.
909 ** Either we're not authenticating, or we're supposed to
910 ** be authenticating something else. This is an error.
912 if((httpcode == 401) && !conn->bits.user_passwd)
914 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
917 return data->state.authproblem;
921 * readmoredata() is a "fread() emulation" to provide POST and/or request
922 * data. It is used when a huge POST is to be made and the entire chunk wasn't
923 * sent in the first send(). This function will then be called from the
924 * transfer.c loop when more data is to be sent to the peer.
926 * Returns the amount of bytes it filled the buffer with.
928 static size_t readmoredata(char *buffer,
933 struct connectdata *conn = (struct connectdata *)userp;
934 struct HTTP *http = conn->data->state.proto.http;
935 size_t fullsize = size * nitems;
937 if(0 == http->postsize)
938 /* nothing to return */
941 /* make sure that a HTTP request is never sent away chunked! */
942 conn->data->req.forbidchunk = (bool)(http->sending == HTTPSEND_REQUEST);
944 if(http->postsize <= (curl_off_t)fullsize) {
945 memcpy(buffer, http->postdata, (size_t)http->postsize);
946 fullsize = (size_t)http->postsize;
948 if(http->backup.postsize) {
949 /* move backup data into focus and continue on that */
950 http->postdata = http->backup.postdata;
951 http->postsize = http->backup.postsize;
952 conn->fread_func = http->backup.fread_func;
953 conn->fread_in = http->backup.fread_in;
955 http->sending++; /* move one step up */
957 http->backup.postsize=0;
965 memcpy(buffer, http->postdata, fullsize);
966 http->postdata += fullsize;
967 http->postsize -= fullsize;
972 /* ------------------------------------------------------------------------- */
973 /* add_buffer functions */
976 * Curl_add_buffer_init() sets up and returns a fine buffer struct
978 Curl_send_buffer *Curl_add_buffer_init(void)
980 return calloc(1, sizeof(Curl_send_buffer));
984 * Curl_add_buffer_send() sends a header buffer and frees all associated
985 * memory. Body data may be appended to the header data if desired.
989 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
990 struct connectdata *conn,
992 /* add the number of sent bytes to this
996 /* how much of the buffer contains body data */
997 size_t included_body_bytes,
1005 struct HTTP *http = conn->data->state.proto.http;
1007 curl_socket_t sockfd;
1010 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1012 sockfd = conn->sock[socketindex];
1014 /* The looping below is required since we use non-blocking sockets, but due
1015 to the circumstances we will just loop and try again and again etc */
1018 size = in->size_used;
1020 headersize = size - included_body_bytes; /* the initial part that isn't body
1023 DEBUGASSERT(size > included_body_bytes);
1025 res = Curl_convert_to_network(conn->data, ptr, headersize);
1026 /* Curl_convert_to_network calls failf if unsuccessful */
1028 /* conversion failed, free memory and return to the caller */
1035 if(conn->handler->flags & PROTOPT_SSL) {
1036 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1037 when we speak HTTPS, as if only a fraction of it is sent now, this data
1038 needs to fit into the normal read-callback buffer later on and that
1039 buffer is using this size.
1042 sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
1044 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1045 library when we attempt to re-send this buffer. Sending the same data
1046 is not enough, we must use the exact same address. For this reason, we
1047 must copy the data to the uploadbuffer first, since that is the buffer
1048 we will be using if this send is retried later.
1050 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1051 ptr = conn->data->state.uploadbuffer;
1056 res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1058 if(CURLE_OK == res) {
1060 * Note that we may not send the entire chunk at once, and we have a set
1061 * number of data bytes at the end of the big buffer (out of which we may
1062 * only send away a part).
1064 /* how much of the header that was sent */
1065 size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
1066 size_t bodylen = amount - headlen;
1068 if(conn->data->set.verbose) {
1069 /* this data _may_ contain binary stuff */
1070 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1071 if((size_t)amount > headlen) {
1072 /* there was body data sent beyond the initial header part, pass that
1073 on to the debug callback too */
1074 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1075 ptr+headlen, bodylen, conn);
1079 /* since we sent a piece of the body here, up the byte counter for it
1081 http->writebytecount += bodylen;
1083 /* 'amount' can never be a very large value here so typecasting it so a
1084 signed 31 bit value should not cause problems even if ssize_t is
1086 *bytes_written += (long)amount;
1089 if((size_t)amount != size) {
1090 /* The whole request could not be sent in one system call. We must
1091 queue it up and send it later when we get the chance. We must not
1092 loop here and wait until it might work again. */
1096 ptr = in->buffer + amount;
1098 /* backup the currently set pointers */
1099 http->backup.fread_func = conn->fread_func;
1100 http->backup.fread_in = conn->fread_in;
1101 http->backup.postdata = http->postdata;
1102 http->backup.postsize = http->postsize;
1104 /* set the new pointers for the request-sending */
1105 conn->fread_func = (curl_read_callback)readmoredata;
1106 conn->fread_in = (void *)conn;
1107 http->postdata = ptr;
1108 http->postsize = (curl_off_t)size;
1110 http->send_buffer = in;
1111 http->sending = HTTPSEND_REQUEST;
1115 http->sending = HTTPSEND_BODY;
1116 /* the full buffer was sent, clean up and return */
1119 if((size_t)amount != size)
1120 /* We have no continue-send mechanism now, fail. This can only happen
1121 when this function is used from the CONNECT sending function. We
1122 currently (stupidly) assume that the whole request is always sent
1123 away in the first single chunk.
1127 return CURLE_SEND_ERROR;
1129 conn->writechannel_inuse = FALSE;
1141 * add_bufferf() add the formatted input to the buffer.
1143 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1148 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1152 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1156 /* If we failed, we cleanup the whole buffer and return error */
1160 return CURLE_OUT_OF_MEMORY;
1164 * add_buffer() appends a memory chunk to the existing buffer
1166 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1171 if(~size < in->size_used) {
1172 /* If resulting used size of send buffer would wrap size_t, cleanup
1173 the whole buffer and return error. Otherwise the required buffer
1174 size will fit into a single allocatable memory chunk */
1175 Curl_safefree(in->buffer);
1177 return CURLE_OUT_OF_MEMORY;
1181 ((in->size_used + size) > (in->size_max - 1))) {
1183 /* If current buffer size isn't enough to hold the result, use a
1184 buffer size that doubles the required size. If this new size
1185 would wrap size_t, then just use the largest possible one */
1187 if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
1188 (~(size*2) < (in->size_used*2)))
1189 new_size = (size_t)-1;
1191 new_size = (in->size_used+size)*2;
1194 /* we have a buffer, enlarge the existing one */
1195 new_rb = realloc(in->buffer, new_size);
1197 /* create a new buffer */
1198 new_rb = malloc(new_size);
1201 /* If we failed, we cleanup the whole buffer and return error */
1202 Curl_safefree(in->buffer);
1204 return CURLE_OUT_OF_MEMORY;
1207 in->buffer = new_rb;
1208 in->size_max = new_size;
1210 memcpy(&in->buffer[in->size_used], inptr, size);
1212 in->size_used += size;
1217 /* end of the add_buffer functions */
1218 /* ------------------------------------------------------------------------- */
1223 * Curl_compareheader()
1225 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1226 * Pass headers WITH the colon.
1229 Curl_compareheader(const char *headerline, /* line to check */
1230 const char *header, /* header keyword _with_ colon */
1231 const char *content) /* content string to find */
1233 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1234 * by a colon (":") and the field value. Field names are case-insensitive.
1235 * The field value MAY be preceded by any amount of LWS, though a single SP
1238 size_t hlen = strlen(header);
1244 if(!Curl_raw_nequal(headerline, header, hlen))
1245 return FALSE; /* doesn't start with header */
1247 /* pass the header */
1248 start = &headerline[hlen];
1250 /* pass all white spaces */
1251 while(*start && ISSPACE(*start))
1254 /* find the end of the header line */
1255 end = strchr(start, '\r'); /* lines end with CRLF */
1257 /* in case there's a non-standard compliant line here */
1258 end = strchr(start, '\n');
1261 /* hm, there's no line ending here, use the zero byte! */
1262 end = strchr(start, '\0');
1265 len = end-start; /* length of the content part of the input line */
1266 clen = strlen(content); /* length of the word to find */
1268 /* find the content string in the rest of the line */
1269 for(;len>=clen;len--, start++) {
1270 if(Curl_raw_nequal(start, content, clen))
1271 return TRUE; /* match! */
1274 return FALSE; /* no match */
1278 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1279 * the generic Curl_connect().
1281 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1283 struct SessionHandle *data;
1288 /* We default to persistent connections. We set this already in this connect
1289 function to make the re-use checks properly be able to check this bit. */
1290 conn->bits.close = FALSE;
1292 #ifndef CURL_DISABLE_PROXY
1293 /* If we are not using a proxy and we want a secure connection, perform SSL
1294 * initialization & connection now. If using a proxy with https, then we
1295 * must tell the proxy to CONNECT to the host we want to talk to. Only
1296 * after the connect has occurred, can we start talking SSL
1298 if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
1300 /* either SSL over proxy, or explicitly asked for */
1301 result = Curl_proxyCONNECT(conn, FIRSTSOCKET,
1304 if(CURLE_OK != result)
1308 if(conn->bits.tunnel_connecting) {
1309 /* nothing else to do except wait right now - we're not done here. */
1312 #endif /* CURL_DISABLE_PROXY */
1314 if(conn->given->flags & PROTOPT_SSL) {
1315 /* perform SSL initialization */
1316 if(data->state.used_interface == Curl_if_multi) {
1317 result = https_connecting(conn, done);
1323 result = Curl_ssl_connect(conn, FIRSTSOCKET);
1336 /* this returns the socket to wait for in the DO and DOING state for the multi
1337 interface and then we're always _sending_ a request and thus we wait for
1338 the single socket to become writable only */
1339 static int http_getsock_do(struct connectdata *conn,
1340 curl_socket_t *socks,
1344 (void)numsocks; /* unused, we trust it to be at least 1 */
1345 socks[0] = conn->sock[FIRSTSOCKET];
1346 return GETSOCK_WRITESOCK(0);
1350 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1353 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1355 /* perform SSL initialization for this socket */
1356 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1358 conn->bits.close = TRUE; /* a failed connection is marked for closure
1359 to prevent (bad) re-use or similar */
1364 #if defined(USE_SSLEAY) || defined(USE_GNUTLS)
1365 /* This function is for OpenSSL and GnuTLS only. It should be made to query
1366 the generic SSL layer instead. */
1367 static int https_getsock(struct connectdata *conn,
1368 curl_socket_t *socks,
1371 if(conn->handler->flags & PROTOPT_SSL) {
1372 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1375 return GETSOCK_BLANK;
1377 if(connssl->connecting_state == ssl_connect_2_writing) {
1379 socks[0] = conn->sock[FIRSTSOCKET];
1380 return GETSOCK_WRITESOCK(0);
1382 else if(connssl->connecting_state == ssl_connect_2_reading) {
1384 socks[0] = conn->sock[FIRSTSOCKET];
1385 return GETSOCK_READSOCK(0);
1391 #if defined(USE_NSS) || defined(USE_QSOSSL) || \
1392 defined(USE_POLARSSL) || defined(USE_AXTLS) || defined(USE_CYASSL)
1393 static int https_getsock(struct connectdata *conn,
1394 curl_socket_t *socks,
1400 return GETSOCK_BLANK;
1402 #endif /* USE_AXTLS || USE_POLARSSL || USE_QSOSSL || USE_NSS */
1403 #endif /* USE_SSLEAY || USE_GNUTLS */
1406 * Curl_http_done() gets called from Curl_done() after a single HTTP request
1407 * has been performed.
1410 CURLcode Curl_http_done(struct connectdata *conn,
1411 CURLcode status, bool premature)
1413 struct SessionHandle *data = conn->data;
1414 struct HTTP *http =data->state.proto.http;
1416 Curl_unencode_cleanup(conn);
1418 /* set the proper values (possibly modified on POST) */
1419 conn->fread_func = data->set.fread_func; /* restore */
1420 conn->fread_in = data->set.in; /* restore */
1421 conn->seek_func = data->set.seek_func; /* restore */
1422 conn->seek_client = data->set.seek_client; /* restore */
1427 if(http->send_buffer) {
1428 Curl_send_buffer *buff = http->send_buffer;
1432 http->send_buffer = NULL; /* clear the pointer */
1435 if(HTTPREQ_POST_FORM == data->set.httpreq) {
1436 data->req.bytecount = http->readbytecount + http->writebytecount;
1438 Curl_formclean(&http->sendit); /* Now free that whole lot */
1440 /* a file being uploaded was left opened, close it! */
1441 fclose(http->form.fp);
1442 http->form.fp = NULL;
1445 else if(HTTPREQ_PUT == data->set.httpreq)
1446 data->req.bytecount = http->readbytecount + http->writebytecount;
1448 if(status != CURLE_OK)
1451 if(!premature && /* this check is pointless when DONE is called before the
1452 entire operation is complete */
1453 !conn->bits.retry &&
1454 ((http->readbytecount +
1455 data->req.headerbytecount -
1456 data->req.deductheadercount)) <= 0) {
1457 /* If this connection isn't simply closed to be retried, AND nothing was
1458 read from the HTTP server (that counts), this can't be right so we
1459 return an error here */
1460 failf(data, "Empty reply from server");
1461 return CURLE_GOT_NOTHING;
1468 /* Determine if we should use HTTP 1.1 for this request. Reasons to avoid it
1469 are if the user specifically requested HTTP 1.0, if the server we are
1470 connected to only supports 1.0, or if any server previously contacted to
1471 handle this request only supports 1.0. */
1472 static bool use_http_1_1(const struct SessionHandle *data,
1473 const struct connectdata *conn)
1475 return (bool)((data->set.httpversion == CURL_HTTP_VERSION_1_1) ||
1476 ((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
1477 ((conn->httpversion == 11) ||
1478 ((conn->httpversion != 10) &&
1479 (data->state.httpversion != 10)))));
1482 /* check and possibly add an Expect: header */
1483 static CURLcode expect100(struct SessionHandle *data,
1484 struct connectdata *conn,
1485 Curl_send_buffer *req_buffer)
1487 CURLcode result = CURLE_OK;
1489 data->state.expect100header = FALSE; /* default to false unless it is set
1491 if(use_http_1_1(data, conn)) {
1492 /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
1493 100-continue to the headers which actually speeds up post operations
1494 (as there is one packet coming back from the web server) */
1495 ptr = Curl_checkheaders(data, "Expect:");
1497 data->state.expect100header =
1498 Curl_compareheader(ptr, "Expect:", "100-continue");
1501 result = Curl_add_bufferf(req_buffer,
1502 "Expect: 100-continue\r\n");
1503 if(result == CURLE_OK)
1504 data->state.expect100header = TRUE;
1510 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1511 Curl_send_buffer *req_buffer)
1514 struct curl_slist *headers=conn->data->set.headers;
1517 ptr = strchr(headers->data, ':');
1519 /* we require a colon for this to be a true header */
1521 ptr++; /* pass the colon */
1522 while(*ptr && ISSPACE(*ptr))
1526 /* only send this if the contents was non-blank */
1528 if(conn->allocptr.host &&
1529 /* a Host: header was sent already, don't pass on any custom Host:
1530 header as that will produce *two* in the same request! */
1531 checkprefix("Host:", headers->data))
1533 else if(conn->data->set.httpreq == HTTPREQ_POST_FORM &&
1534 /* this header (extended by formdata.c) is sent later */
1535 checkprefix("Content-Type:", headers->data))
1537 else if(conn->bits.authneg &&
1538 /* while doing auth neg, don't allow the custom length since
1539 we will force length zero then */
1540 checkprefix("Content-Length", headers->data))
1542 else if(conn->allocptr.te &&
1543 /* when asking for Transfer-Encoding, don't pass on a custom
1545 checkprefix("Connection", headers->data))
1548 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1555 headers = headers->next;
1560 CURLcode Curl_add_timecondition(struct SessionHandle *data,
1561 Curl_send_buffer *req_buffer)
1563 const struct tm *tm;
1564 char *buf = data->state.buffer;
1565 CURLcode result = CURLE_OK;
1568 result = Curl_gmtime(data->set.timevalue, &keeptime);
1570 failf(data, "Invalid TIMEVALUE\n");
1575 /* The If-Modified-Since header family should have their times set in
1576 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1577 * represented in Greenwich Mean Time (GMT), without exception. For the
1578 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1579 * Time)." (see page 20 of RFC2616).
1582 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1583 snprintf(buf, BUFSIZE-1,
1584 "%s, %02d %s %4d %02d:%02d:%02d GMT",
1585 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1587 Curl_month[tm->tm_mon],
1593 switch(data->set.timecondition) {
1594 case CURL_TIMECOND_IFMODSINCE:
1596 result = Curl_add_bufferf(req_buffer,
1597 "If-Modified-Since: %s\r\n", buf);
1599 case CURL_TIMECOND_IFUNMODSINCE:
1600 result = Curl_add_bufferf(req_buffer,
1601 "If-Unmodified-Since: %s\r\n", buf);
1603 case CURL_TIMECOND_LASTMOD:
1604 result = Curl_add_bufferf(req_buffer,
1605 "Last-Modified: %s\r\n", buf);
1613 * Curl_http() gets called from the generic Curl_do() function when a HTTP
1614 * request is to be performed. This creates and sends a properly constructed
1617 CURLcode Curl_http(struct connectdata *conn, bool *done)
1619 struct SessionHandle *data=conn->data;
1620 CURLcode result=CURLE_OK;
1622 const char *ppath = data->state.path;
1623 bool paste_ftp_userpwd = FALSE;
1624 char ftp_typecode[sizeof("/;type=?")] = "";
1625 const char *host = conn->host.name;
1626 const char *te = ""; /* transfer-encoding */
1628 const char *request;
1629 Curl_HttpReq httpreq = data->set.httpreq;
1630 char *addcookies = NULL;
1631 curl_off_t included_body = 0;
1632 const char *httpstring;
1633 Curl_send_buffer *req_buffer;
1634 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1635 int seekerr = CURL_SEEKFUNC_OK;
1637 /* Always consider the DO phase done after this function call, even if there
1638 may be parts of the request that is not yet sent, since we can deal with
1639 the rest of the request in the PERFORM phase. */
1642 /* If there already is a protocol-specific struct allocated for this
1643 sessionhandle, deal with it */
1644 Curl_reset_reqproto(conn);
1646 if(!data->state.proto.http) {
1647 /* Only allocate this struct if we don't already have it! */
1649 http = calloc(1, sizeof(struct HTTP));
1651 return CURLE_OUT_OF_MEMORY;
1652 data->state.proto.http = http;
1655 http = data->state.proto.http;
1657 if(!data->state.this_is_a_follow) {
1658 /* this is not a followed location, get the original host name */
1659 if(data->state.first_host)
1660 /* Free to avoid leaking memory on multiple requests*/
1661 free(data->state.first_host);
1663 data->state.first_host = strdup(conn->host.name);
1664 if(!data->state.first_host)
1665 return CURLE_OUT_OF_MEMORY;
1667 http->writebytecount = http->readbytecount = 0;
1669 if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
1671 httpreq = HTTPREQ_PUT;
1674 /* Now set the 'request' pointer to the proper request string */
1675 if(data->set.str[STRING_CUSTOMREQUEST])
1676 request = data->set.str[STRING_CUSTOMREQUEST];
1678 if(data->set.opt_no_body)
1681 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1684 case HTTPREQ_POST_FORM:
1690 default: /* this should never happen */
1701 /* The User-Agent string might have been allocated in url.c already, because
1702 it might have been used in the proxy connect, but if we have got a header
1703 with the user-agent string specified, we erase the previously made string
1705 if(Curl_checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
1706 free(conn->allocptr.uagent);
1707 conn->allocptr.uagent=NULL;
1710 /* setup the authentication headers */
1711 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1715 if((data->state.authhost.multi || data->state.authproxy.multi) &&
1716 (httpreq != HTTPREQ_GET) &&
1717 (httpreq != HTTPREQ_HEAD)) {
1718 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1719 with content-length zero as a "probe". */
1720 conn->bits.authneg = TRUE;
1723 conn->bits.authneg = FALSE;
1725 Curl_safefree(conn->allocptr.ref);
1726 if(data->change.referer && !Curl_checkheaders(data, "Referer:"))
1727 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1729 conn->allocptr.ref = NULL;
1731 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie:"))
1732 addcookies = data->set.str[STRING_COOKIE];
1734 if(!Curl_checkheaders(data, "Accept-Encoding:") &&
1735 data->set.str[STRING_ENCODING]) {
1736 Curl_safefree(conn->allocptr.accept_encoding);
1737 conn->allocptr.accept_encoding =
1738 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1739 if(!conn->allocptr.accept_encoding)
1740 return CURLE_OUT_OF_MEMORY;
1744 /* we only consider transfer-encoding magic if libz support is built-in */
1746 if(!Curl_checkheaders(data, "TE:") && data->set.http_transfer_encoding) {
1747 /* When we are to insert a TE: header in the request, we must also insert
1748 TE in a Connection: header, so we need to merge the custom provided
1749 Connection: header and prevent the original to get sent. Note that if
1750 the user has inserted his/hers own TE: header we don't do this magic
1751 but then assume that the user will handle it all! */
1752 char *cptr = Curl_checkheaders(data, "Connection:");
1753 #define TE_HEADER "TE: gzip\r\n"
1755 Curl_safefree(conn->allocptr.te);
1757 /* Create the (updated) Connection: header */
1758 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1759 strdup("Connection: TE\r\n" TE_HEADER);
1761 if(!conn->allocptr.te)
1762 return CURLE_OUT_OF_MEMORY;
1766 ptr = Curl_checkheaders(data, "Transfer-Encoding:");
1768 /* Some kind of TE is requested, check if 'chunked' is chosen */
1769 data->req.upload_chunky =
1770 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1773 if((conn->handler->protocol&CURLPROTO_HTTP) &&
1775 (data->set.infilesize == -1)) {
1776 if(conn->bits.authneg)
1777 /* don't enable chunked during auth neg */
1779 else if(use_http_1_1(data, conn)) {
1780 /* HTTP, upload, unknown file size and not HTTP 1.0 */
1781 data->req.upload_chunky = TRUE;
1784 failf(data, "Chunky upload is not supported by HTTP 1.0");
1785 return CURLE_UPLOAD_FAILED;
1789 /* else, no chunky upload */
1790 data->req.upload_chunky = FALSE;
1793 if(data->req.upload_chunky)
1794 te = "Transfer-Encoding: chunked\r\n";
1797 Curl_safefree(conn->allocptr.host);
1799 ptr = Curl_checkheaders(data, "Host:");
1800 if(ptr && (!data->state.this_is_a_follow ||
1801 Curl_raw_equal(data->state.first_host, conn->host.name))) {
1802 #if !defined(CURL_DISABLE_COOKIES)
1803 /* If we have a given custom Host: header, we extract the host name in
1804 order to possibly use it for cookie reasons later on. We only allow the
1805 custom Host: header if this is NOT a redirect, as setting Host: in the
1806 redirected request is being out on thin ice. Except if the host name
1807 is the same as the first one! */
1808 char *cookiehost = copy_header_value(ptr);
1810 return CURLE_OUT_OF_MEMORY;
1812 /* ignore empty data */
1815 char *colon = strchr(cookiehost, ':');
1817 *colon = 0; /* The host must not include an embedded port number */
1818 Curl_safefree(conn->allocptr.cookiehost);
1819 conn->allocptr.cookiehost = cookiehost;
1823 conn->allocptr.host = NULL;
1826 /* When building Host: headers, we must put the host name within
1827 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
1829 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
1830 (conn->remote_port == PORT_HTTPS)) ||
1831 ((conn->given->protocol&CURLPROTO_HTTP) &&
1832 (conn->remote_port == PORT_HTTP)) )
1833 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
1834 the port number in the host string */
1835 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
1836 conn->bits.ipv6_ip?"[":"",
1838 conn->bits.ipv6_ip?"]":"");
1840 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
1841 conn->bits.ipv6_ip?"[":"",
1843 conn->bits.ipv6_ip?"]":"",
1846 if(!conn->allocptr.host)
1847 /* without Host: we can't make a nice request */
1848 return CURLE_OUT_OF_MEMORY;
1851 #ifndef CURL_DISABLE_PROXY
1852 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
1853 /* Using a proxy but does not tunnel through it */
1855 /* The path sent to the proxy is in fact the entire URL. But if the remote
1856 host is a IDN-name, we must make sure that the request we produce only
1857 uses the encoded host name! */
1858 if(conn->host.dispname != conn->host.name) {
1859 char *url = data->change.url;
1860 ptr = strstr(url, conn->host.dispname);
1862 /* This is where the display name starts in the URL, now replace this
1863 part with the encoded name. TODO: This method of replacing the host
1864 name is rather crude as I believe there's a slight risk that the
1865 user has entered a user name or password that contain the host name
1867 size_t currlen = strlen(conn->host.dispname);
1868 size_t newlen = strlen(conn->host.name);
1869 size_t urllen = strlen(url);
1873 newurl = malloc(urllen + newlen - currlen + 1);
1875 /* copy the part before the host name */
1876 memcpy(newurl, url, ptr - url);
1877 /* append the new host name instead of the old */
1878 memcpy(newurl + (ptr - url), conn->host.name, newlen);
1879 /* append the piece after the host name */
1880 memcpy(newurl + newlen + (ptr - url),
1881 ptr + currlen, /* copy the trailing zero byte too */
1882 urllen - (ptr-url) - currlen + 1);
1883 if(data->change.url_alloc)
1884 free(data->change.url);
1885 data->change.url = newurl;
1886 data->change.url_alloc = TRUE;
1889 return CURLE_OUT_OF_MEMORY;
1892 ppath = data->change.url;
1893 if(checkprefix("ftp://", ppath)) {
1894 if(data->set.proxy_transfer_mode) {
1895 /* when doing ftp, append ;type=<a|i> if not present */
1896 char *type = strstr(ppath, ";type=");
1897 if(type && type[6] && type[7] == 0) {
1898 switch (Curl_raw_toupper(type[6])) {
1908 char *p = ftp_typecode;
1909 /* avoid sending invalid URLs like ftp://example.com;type=i if the
1910 * user specified ftp://example.com without the slash */
1911 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
1914 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
1915 data->set.prefer_ascii ? 'a' : 'i');
1918 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
1919 paste_ftp_userpwd = TRUE;
1922 #endif /* CURL_DISABLE_PROXY */
1924 if(HTTPREQ_POST_FORM == httpreq) {
1925 /* we must build the whole post sequence first, so that we have a size of
1926 the whole transfer before we start to send it */
1927 result = Curl_getformdata(data, &http->sendit, data->set.httppost,
1928 Curl_checkheaders(data, "Content-Type:"),
1934 http->p_accept = Curl_checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n";
1936 if(( (HTTPREQ_POST == httpreq) ||
1937 (HTTPREQ_POST_FORM == httpreq) ||
1938 (HTTPREQ_PUT == httpreq) ) &&
1939 data->state.resume_from) {
1940 /**********************************************************************
1941 * Resuming upload in HTTP means that we PUT or POST and that we have
1942 * got a resume_from value set. The resume value has already created
1943 * a Range: header that will be passed along. We need to "fast forward"
1944 * the file the given number of bytes and decrease the assume upload
1945 * file size before we continue this venture in the dark lands of HTTP.
1946 *********************************************************************/
1948 if(data->state.resume_from < 0 ) {
1950 * This is meant to get the size of the present remote-file by itself.
1951 * We don't support this now. Bail out!
1953 data->state.resume_from = 0;
1956 if(data->state.resume_from && !data->state.this_is_a_follow) {
1957 /* do we still game? */
1959 /* Now, let's read off the proper amount of bytes from the
1961 if(conn->seek_func) {
1962 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1966 if(seekerr != CURL_SEEKFUNC_OK) {
1967 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
1968 failf(data, "Could not seek stream");
1969 return CURLE_READ_ERROR;
1971 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
1973 curl_off_t passed=0;
1975 size_t readthisamountnow =
1976 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
1977 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
1979 size_t actuallyread =
1980 data->set.fread_func(data->state.buffer, 1, readthisamountnow,
1983 passed += actuallyread;
1984 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
1985 /* this checks for greater-than only to make sure that the
1986 CURL_READFUNC_ABORT return code still aborts */
1987 failf(data, "Could only read %" FORMAT_OFF_T
1988 " bytes from the input",
1990 return CURLE_READ_ERROR;
1992 } while(passed < data->state.resume_from);
1996 /* now, decrease the size of the read */
1997 if(data->set.infilesize>0) {
1998 data->set.infilesize -= data->state.resume_from;
2000 if(data->set.infilesize <= 0) {
2001 failf(data, "File already completely uploaded");
2002 return CURLE_PARTIAL_FILE;
2005 /* we've passed, proceed as normal */
2008 if(data->state.use_range) {
2010 * A range is selected. We use different headers whether we're downloading
2011 * or uploading and we always let customized headers override our internal
2012 * ones if any such are specified.
2014 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2015 !Curl_checkheaders(data, "Range:")) {
2016 /* if a line like this was already allocated, free the previous one */
2017 if(conn->allocptr.rangeline)
2018 free(conn->allocptr.rangeline);
2019 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2022 else if((httpreq != HTTPREQ_GET) &&
2023 !Curl_checkheaders(data, "Content-Range:")) {
2025 /* if a line like this was already allocated, free the previous one */
2026 if(conn->allocptr.rangeline)
2027 free(conn->allocptr.rangeline);
2029 if(data->set.set_resume_from < 0) {
2030 /* Upload resume was asked for, but we don't know the size of the
2031 remote part so we tell the server (and act accordingly) that we
2032 upload the whole file (again) */
2033 conn->allocptr.rangeline =
2034 aprintf("Content-Range: bytes 0-%" FORMAT_OFF_T
2035 "/%" FORMAT_OFF_T "\r\n",
2036 data->set.infilesize - 1, data->set.infilesize);
2039 else if(data->state.resume_from) {
2040 /* This is because "resume" was selected */
2041 curl_off_t total_expected_size=
2042 data->state.resume_from + data->set.infilesize;
2043 conn->allocptr.rangeline =
2044 aprintf("Content-Range: bytes %s%" FORMAT_OFF_T
2045 "/%" FORMAT_OFF_T "\r\n",
2046 data->state.range, total_expected_size-1,
2047 total_expected_size);
2050 /* Range was selected and then we just pass the incoming range and
2051 append total size */
2052 conn->allocptr.rangeline =
2053 aprintf("Content-Range: bytes %s/%" FORMAT_OFF_T "\r\n",
2054 data->state.range, data->set.infilesize);
2056 if(!conn->allocptr.rangeline)
2057 return CURLE_OUT_OF_MEMORY;
2061 /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2063 httpstring= use_http_1_1(data, conn)?"1.1":"1.0";
2065 /* initialize a dynamic send-buffer */
2066 req_buffer = Curl_add_buffer_init();
2069 return CURLE_OUT_OF_MEMORY;
2071 /* add the main request stuff */
2072 /* GET/HEAD/POST/PUT */
2073 result = Curl_add_bufferf(req_buffer, "%s ", request);
2078 if(paste_ftp_userpwd)
2079 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2080 conn->user, conn->passwd,
2081 ppath + sizeof("ftp://") - 1);
2083 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2087 result = Curl_add_bufferf(req_buffer,
2088 "%s" /* ftp typecode (;type=x) */
2089 " HTTP/%s\r\n" /* HTTP version */
2090 "%s" /* proxyuserpwd */
2093 "%s" /* user agent */
2097 "%s" /* accept-encoding */
2099 "%s" /* Proxy-Connection */
2100 "%s",/* transfer-encoding */
2104 conn->allocptr.proxyuserpwd?
2105 conn->allocptr.proxyuserpwd:"",
2106 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2107 (data->state.use_range && conn->allocptr.rangeline)?
2108 conn->allocptr.rangeline:"",
2109 (data->set.str[STRING_USERAGENT] &&
2110 *data->set.str[STRING_USERAGENT] && conn->allocptr.uagent)?
2111 conn->allocptr.uagent:"",
2112 (conn->allocptr.host?conn->allocptr.host:""), /* Host: host */
2113 http->p_accept?http->p_accept:"",
2114 conn->allocptr.te?conn->allocptr.te:"",
2115 (data->set.str[STRING_ENCODING] &&
2116 *data->set.str[STRING_ENCODING] &&
2117 conn->allocptr.accept_encoding)?
2118 conn->allocptr.accept_encoding:"",
2119 (data->change.referer && conn->allocptr.ref)?
2120 conn->allocptr.ref:"" /* Referer: <data> */,
2121 (conn->bits.httpproxy &&
2122 !conn->bits.tunnel_proxy &&
2123 !Curl_checkheaders(data, "Proxy-Connection:"))?
2124 "Proxy-Connection: Keep-Alive\r\n":"",
2129 * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
2130 * with basic and digest, it will be freed anyway by the next request
2133 Curl_safefree (conn->allocptr.userpwd);
2134 conn->allocptr.userpwd = NULL;
2139 #if !defined(CURL_DISABLE_COOKIES)
2140 if(data->cookies || addcookies) {
2141 struct Cookie *co=NULL; /* no cookies from start */
2145 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2146 co = Curl_cookie_getlist(data->cookies,
2147 conn->allocptr.cookiehost?
2148 conn->allocptr.cookiehost:host,
2150 (bool)(conn->handler->protocol&CURLPROTO_HTTPS?
2152 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2155 struct Cookie *store=co;
2156 /* now loop through all cookies that matched */
2160 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2164 result = Curl_add_bufferf(req_buffer,
2165 "%s%s=%s", count?"; ":"",
2166 co->name, co->value);
2171 co = co->next; /* next cookie please */
2173 Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2175 if(addcookies && (CURLE_OK == result)) {
2177 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2178 if(CURLE_OK == result) {
2179 result = Curl_add_bufferf(req_buffer, "%s%s",
2185 if(count && (CURLE_OK == result))
2186 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2193 if(data->set.timecondition) {
2194 result = Curl_add_timecondition(data, req_buffer);
2199 result = Curl_add_custom_headers(conn, req_buffer);
2203 http->postdata = NULL; /* nothing to post at this point */
2204 Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
2206 /* If 'authdone' is FALSE, we must not set the write socket index to the
2207 Curl_transfer() call below, as we're not ready to actually upload any
2212 case HTTPREQ_POST_FORM:
2213 if(!http->sendit || conn->bits.authneg) {
2214 /* nothing to post! */
2215 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2219 result = Curl_add_buffer_send(req_buffer, conn,
2220 &data->info.request_size, 0, FIRSTSOCKET);
2222 failf(data, "Failed sending POST request");
2224 /* setup variables for the upcoming transfer */
2225 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2230 if(Curl_FormInit(&http->form, http->sendit)) {
2231 failf(data, "Internal HTTP POST error!");
2232 return CURLE_HTTP_POST_ERROR;
2235 /* Get the currently set callback function pointer and store that in the
2236 form struct since we might want the actual user-provided callback later
2237 on. The conn->fread_func pointer itself will be changed for the
2238 multipart case to the function that returns a multipart formatted
2240 http->form.fread_func = conn->fread_func;
2242 /* Set the read function to read from the generated form data */
2243 conn->fread_func = (curl_read_callback)Curl_FormReader;
2244 conn->fread_in = &http->form;
2246 http->sending = HTTPSEND_BODY;
2248 if(!data->req.upload_chunky) {
2249 /* only add Content-Length if not uploading chunked */
2250 result = Curl_add_bufferf(req_buffer,
2251 "Content-Length: %" FORMAT_OFF_T "\r\n",
2257 result = expect100(data, conn, req_buffer);
2263 /* Get Content-Type: line from Curl_formpostheader.
2266 size_t linelength=0;
2267 contentType = Curl_formpostheader((void *)&http->form,
2270 failf(data, "Could not get Content-Type header line!");
2271 return CURLE_HTTP_POST_ERROR;
2274 result = Curl_add_buffer(req_buffer, contentType, linelength);
2279 /* make the request end in a true CRLF */
2280 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2284 /* set upload size to the progress meter */
2285 Curl_pgrsSetUploadSize(data, http->postsize);
2287 /* fire away the whole request to the server */
2288 result = Curl_add_buffer_send(req_buffer, conn,
2289 &data->info.request_size, 0, FIRSTSOCKET);
2291 failf(data, "Failed sending POST request");
2293 /* setup variables for the upcoming transfer */
2294 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2295 &http->readbytecount, FIRSTSOCKET,
2296 &http->writebytecount);
2299 Curl_formclean(&http->sendit); /* free that whole lot */
2303 /* convert the form data */
2304 result = Curl_convert_form(data, http->sendit);
2306 Curl_formclean(&http->sendit); /* free that whole lot */
2312 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2314 if(conn->bits.authneg)
2317 postsize = data->set.infilesize;
2319 if((postsize != -1) && !data->req.upload_chunky) {
2320 /* only add Content-Length if not uploading chunked */
2321 result = Curl_add_bufferf(req_buffer,
2322 "Content-Length: %" FORMAT_OFF_T "\r\n",
2328 result = expect100(data, conn, req_buffer);
2332 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2336 /* set the upload size to the progress meter */
2337 Curl_pgrsSetUploadSize(data, postsize);
2339 /* this sends the buffer and frees all the buffer resources */
2340 result = Curl_add_buffer_send(req_buffer, conn,
2341 &data->info.request_size, 0, FIRSTSOCKET);
2343 failf(data, "Failed sending PUT request");
2345 /* prepare for transfer */
2346 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2347 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2348 postsize?&http->writebytecount:NULL);
2354 /* this is the simple POST, using x-www-form-urlencoded style */
2356 if(conn->bits.authneg)
2359 /* figure out the size of the postfields */
2360 postsize = (data->set.postfieldsize != -1)?
2361 data->set.postfieldsize:
2362 (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2364 if(!data->req.upload_chunky) {
2365 /* We only set Content-Length and allow a custom Content-Length if
2366 we don't upload data chunked, as RFC2616 forbids us to set both
2367 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2369 if(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length:")) {
2370 /* we allow replacing this header if not during auth negotiation,
2371 although it isn't very wise to actually set your own */
2372 result = Curl_add_bufferf(req_buffer,
2373 "Content-Length: %" FORMAT_OFF_T"\r\n",
2380 if(!Curl_checkheaders(data, "Content-Type:")) {
2381 result = Curl_add_bufferf(req_buffer,
2382 "Content-Type: application/"
2383 "x-www-form-urlencoded\r\n");
2388 /* For really small posts we don't use Expect: headers at all, and for
2389 the somewhat bigger ones we allow the app to disable it. Just make
2390 sure that the expect100header is always set to the preferred value
2392 ptr = Curl_checkheaders(data, "Expect:");
2394 data->state.expect100header =
2395 Curl_compareheader(ptr, "Expect:", "100-continue");
2397 else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2398 result = expect100(data, conn, req_buffer);
2403 data->state.expect100header = FALSE;
2405 if(data->set.postfields) {
2407 if(!data->state.expect100header &&
2408 (postsize < MAX_INITIAL_POST_SIZE)) {
2409 /* if we don't use expect: 100 AND
2410 postsize is less than MAX_INITIAL_POST_SIZE
2412 then append the post data to the HTTP request header. This limit
2413 is no magic limit but only set to prevent really huge POSTs to
2414 get the data duplicated with malloc() and family. */
2416 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2420 if(!data->req.upload_chunky) {
2421 /* We're not sending it 'chunked', append it to the request
2422 already now to reduce the number if send() calls */
2423 result = Curl_add_buffer(req_buffer, data->set.postfields,
2425 included_body = postsize;
2428 /* Append the POST data chunky-style */
2429 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2430 if(CURLE_OK == result)
2431 result = Curl_add_buffer(req_buffer, data->set.postfields,
2433 if(CURLE_OK == result)
2434 result = Curl_add_buffer(req_buffer,
2435 "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2436 /* CR LF 0 CR LF CR LF */
2437 included_body = postsize + 7;
2441 /* Make sure the progress information is accurate */
2442 Curl_pgrsSetUploadSize(data, postsize);
2445 /* A huge POST coming up, do data separate from the request */
2446 http->postsize = postsize;
2447 http->postdata = data->set.postfields;
2449 http->sending = HTTPSEND_BODY;
2451 conn->fread_func = (curl_read_callback)readmoredata;
2452 conn->fread_in = (void *)conn;
2454 /* set the upload size to the progress meter */
2455 Curl_pgrsSetUploadSize(data, http->postsize);
2457 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2463 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2467 if(data->req.upload_chunky && conn->bits.authneg) {
2468 /* Chunky upload is selected and we're negotiating auth still, send
2470 result = Curl_add_buffer(req_buffer,
2471 "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2472 /* CR LF 0 CR LF CR LF */
2477 else if(data->set.postfieldsize) {
2478 /* set the upload size to the progress meter */
2479 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2481 /* set the pointer to mark that we will send the post body using the
2482 read callback, but only if we're not in authenticate
2484 if(!conn->bits.authneg) {
2485 http->postdata = (char *)&http->postdata;
2486 http->postsize = postsize;
2490 /* issue the request */
2491 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2492 (size_t)included_body, FIRSTSOCKET);
2495 failf(data, "Failed sending HTTP POST request");
2497 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2498 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2499 http->postdata?&http->writebytecount:NULL);
2503 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2507 /* issue the request */
2508 result = Curl_add_buffer_send(req_buffer, conn,
2509 &data->info.request_size, 0, FIRSTSOCKET);
2512 failf(data, "Failed sending HTTP request");
2514 /* HTTP GET/HEAD download: */
2515 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2516 http->postdata?FIRSTSOCKET:-1,
2517 http->postdata?&http->writebytecount:NULL);
2522 if(http->writebytecount) {
2523 /* if a request-body has been sent off, we make sure this progress is noted
2525 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2526 if(Curl_pgrsUpdate(conn))
2527 result = CURLE_ABORTED_BY_CALLBACK;
2529 if(http->writebytecount >= postsize) {
2530 /* already sent the entire request body, mark the "upload" as
2532 infof(data, "upload completely sent off: %" FORMAT_OFF_T "out of "
2533 "%" FORMAT_OFF_T " bytes\n",
2534 http->writebytecount, postsize);
2535 data->req.upload_done = TRUE;
2536 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2537 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2547 * Returns TRUE if member of the list matches prefix of string
2550 checkhttpprefix(struct SessionHandle *data,
2553 struct curl_slist *head = data->set.http200aliases;
2555 #ifdef CURL_DOES_CONVERSIONS
2556 /* convert from the network encoding using a scratch area */
2557 char *scratch = strdup(s);
2558 if(NULL == scratch) {
2559 failf (data, "Failed to allocate memory for conversion!");
2560 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2562 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2563 /* Curl_convert_from_network calls failf if unsuccessful */
2565 return FALSE; /* can't return CURLE_foobar so return FALSE */
2568 #endif /* CURL_DOES_CONVERSIONS */
2571 if(checkprefix(head->data, s)) {
2578 if((rc != TRUE) && (checkprefix("HTTP/", s)))
2581 #ifdef CURL_DOES_CONVERSIONS
2583 #endif /* CURL_DOES_CONVERSIONS */
2587 #ifndef CURL_DISABLE_RTSP
2589 checkrtspprefix(struct SessionHandle *data,
2593 #ifdef CURL_DOES_CONVERSIONS
2594 /* convert from the network encoding using a scratch area */
2595 char *scratch = strdup(s);
2596 if(NULL == scratch) {
2597 failf (data, "Failed to allocate memory for conversion!");
2598 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2600 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2601 /* Curl_convert_from_network calls failf if unsuccessful */
2603 return FALSE; /* can't return CURLE_foobar so return FALSE */
2607 (void)data; /* unused */
2608 #endif /* CURL_DOES_CONVERSIONS */
2609 if(checkprefix("RTSP/", s))
2614 #endif /* CURL_DISABLE_RTSP */
2617 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2620 #ifndef CURL_DISABLE_RTSP
2621 if(conn->handler->protocol & CURLPROTO_RTSP)
2622 return checkrtspprefix(data, s);
2625 #endif /* CURL_DISABLE_RTSP */
2627 return checkhttpprefix(data, s);
2631 * header_append() copies a chunk of data to the end of the already received
2632 * header. We make sure that the full string fit in the allocated header
2633 * buffer, or else we enlarge it.
2635 static CURLcode header_append(struct SessionHandle *data,
2636 struct SingleRequest *k,
2639 if(k->hbuflen + length >= data->state.headersize) {
2640 /* We enlarge the header buffer as it is too small */
2645 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2646 /* The reason to have a max limit for this is to avoid the risk of a bad
2647 server feeding libcurl with a never-ending header that will cause
2648 reallocs infinitely */
2649 failf (data, "Avoided giant realloc for header (max is %d)!",
2650 CURL_MAX_HTTP_HEADER);
2651 return CURLE_OUT_OF_MEMORY;
2654 newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2655 hbufp_index = k->hbufp - data->state.headerbuff;
2656 newbuff = realloc(data->state.headerbuff, newsize);
2658 failf (data, "Failed to alloc memory for big header!");
2659 return CURLE_OUT_OF_MEMORY;
2661 data->state.headersize=newsize;
2662 data->state.headerbuff = newbuff;
2663 k->hbufp = data->state.headerbuff + hbufp_index;
2665 memcpy(k->hbufp, k->str_start, length);
2667 k->hbuflen += length;
2675 * Read any HTTP header lines from the server and pass them to the client app.
2677 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2678 struct connectdata *conn,
2683 struct SingleRequest *k = &data->req;
2685 /* header line within buffer loop */
2691 /* str_start is start of line within buf */
2692 k->str_start = k->str;
2694 /* data is in network encoding so use 0x0a instead of '\n' */
2695 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2698 /* Not a complete header line within buffer, append the data to
2699 the end of the headerbuff. */
2700 result = header_append(data, k, *nread);
2704 if(!k->headerline && (k->hbuflen>5)) {
2705 /* make a first check that this looks like a protocol header */
2706 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2707 /* this is not the beginning of a protocol first header line */
2709 k->badheader = HEADER_ALLBAD;
2714 break; /* read more and try again */
2717 /* decrease the size of the remaining (supposed) header line */
2718 rest_length = (k->end_ptr - k->str)+1;
2719 *nread -= (ssize_t)rest_length;
2721 k->str = k->end_ptr + 1; /* move past new line */
2723 full_length = k->str - k->str_start;
2725 result = header_append(data, k, full_length);
2729 k->end_ptr = k->hbufp;
2730 k->p = data->state.headerbuff;
2733 * We now have a FULL header line that p points to
2736 if(!k->headerline) {
2737 /* the first read header */
2738 if((k->hbuflen>5) &&
2739 !checkprotoprefix(data, conn, data->state.headerbuff)) {
2740 /* this is not the beginning of a protocol first header line */
2743 /* since there's more, this is a partial bad header */
2744 k->badheader = HEADER_PARTHEADER;
2746 /* this was all we read so it's all a bad header */
2747 k->badheader = HEADER_ALLBAD;
2748 *nread = (ssize_t)rest_length;
2754 /* headers are in network encoding so
2755 use 0x0a and 0x0d instead of '\n' and '\r' */
2756 if((0x0a == *k->p) || (0x0d == *k->p)) {
2758 /* Zero-length header line means end of headers! */
2760 #ifdef CURL_DOES_CONVERSIONS
2762 *k->p = '\r'; /* replace with CR in host encoding */
2763 k->p++; /* pass the CR byte */
2766 *k->p = '\n'; /* replace with LF in host encoding */
2767 k->p++; /* pass the LF byte */
2771 k->p++; /* pass the \r byte */
2773 k->p++; /* pass the \n byte */
2774 #endif /* CURL_DOES_CONVERSIONS */
2776 if(100 <= k->httpcode && 199 >= k->httpcode) {
2778 * We have made a HTTP PUT or POST and this is 1.1-lingo
2779 * that tells us that the server is OK with this and ready
2780 * to receive the data.
2781 * However, we'll get more headers now so we must get
2782 * back into the header-parsing state!
2785 k->headerline = 0; /* restart the header line counter */
2787 /* if we did wait for this do enable write now! */
2789 k->exp100 = EXP100_SEND_DATA;
2790 k->keepon |= KEEP_SEND;
2794 k->header = FALSE; /* no more header to parse! */
2796 if((k->size == -1) && !k->chunk && !conn->bits.close &&
2797 (conn->httpversion >= 11) &&
2798 !(conn->handler->protocol & CURLPROTO_RTSP)) {
2799 /* On HTTP 1.1, when connection is not to get closed, but no
2800 Content-Length nor Content-Encoding chunked have been
2801 received, according to RFC2616 section 4.4 point 5, we
2802 assume that the server will close the connection to
2803 signal the end of the document. */
2804 infof(data, "no chunk, no close, no size. Assume close to "
2806 conn->bits.close = TRUE;
2811 * When all the headers have been parsed, see if we should give
2812 * up and return an error.
2814 if(http_should_fail(conn)) {
2815 failf (data, "The requested URL returned error: %d",
2817 return CURLE_HTTP_RETURNED_ERROR;
2820 /* now, only output this if the header AND body are requested:
2822 writetype = CLIENTWRITE_HEADER;
2823 if(data->set.include_header)
2824 writetype |= CLIENTWRITE_BODY;
2826 headerlen = k->p - data->state.headerbuff;
2828 result = Curl_client_write(conn, writetype,
2829 data->state.headerbuff,
2834 data->info.header_size += (long)headerlen;
2835 data->req.headerbytecount += (long)headerlen;
2837 data->req.deductheadercount =
2838 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
2840 if(!*stop_reading) {
2841 /* Curl_http_auth_act() checks what authentication methods
2842 * that are available and decides which one (if any) to
2843 * use. It will set 'newurl' if an auth method was picked. */
2844 result = Curl_http_auth_act(conn);
2849 if(k->httpcode >= 300) {
2850 if((!conn->bits.authneg) && !conn->bits.close &&
2851 !conn->bits.rewindaftersend) {
2853 * General treatment of errors when about to send data. Including :
2854 * "417 Expectation Failed", while waiting for 100-continue.
2856 * The check for close above is done simply because of something
2857 * else has already deemed the connection to get closed then
2858 * something else should've considered the big picture and we
2861 * rewindaftersend indicates that something has told libcurl to
2862 * continue sending even if it gets discarded
2865 switch(data->set.httpreq) {
2868 case HTTPREQ_POST_FORM:
2869 /* We got an error response. If this happened before the whole
2870 * request body has been sent we stop sending and mark the
2871 * connection for closure after we've read the entire response.
2873 if(!k->upload_done) {
2874 infof(data, "HTTP error before end of send, stop sending\n");
2875 conn->bits.close = TRUE; /* close after this */
2876 k->upload_done = TRUE;
2877 k->keepon &= ~KEEP_SEND; /* don't send */
2878 if(data->state.expect100header)
2879 k->exp100 = EXP100_FAILED;
2883 default: /* default label present to avoid compiler warnings */
2889 if(conn->bits.rewindaftersend) {
2890 /* We rewind after a complete send, so thus we continue
2892 infof(data, "Keep sending data to get tossed away!\n");
2893 k->keepon |= KEEP_SEND;
2899 * really end-of-headers.
2901 * If we requested a "no body", this is a good time to get
2902 * out and return home.
2904 if(data->set.opt_no_body)
2905 *stop_reading = TRUE;
2907 /* If we know the expected size of this document, we set the
2908 maximum download size to the size of the expected
2909 document or else, we won't know when to stop reading!
2911 Note that we set the download maximum even if we read a
2912 "Connection: close" header, to make sure that
2913 "Content-Length: 0" still prevents us from attempting to
2914 read the (missing) response-body.
2916 /* According to RFC2616 section 4.4, we MUST ignore
2917 Content-Length: headers if we are now receiving data
2918 using chunked Transfer-Encoding.
2921 k->maxdownload = k->size = -1;
2924 /* We do this operation even if no_body is true, since this
2925 data might be retrieved later with curl_easy_getinfo()
2926 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
2928 Curl_pgrsSetDownloadSize(data, k->size);
2929 k->maxdownload = k->size;
2932 /* If max download size is *zero* (nothing) we already
2933 have nothing and can safely return ok now! */
2934 if(0 == k->maxdownload)
2935 *stop_reading = TRUE;
2938 /* we make sure that this socket isn't read more now */
2939 k->keepon &= ~KEEP_RECV;
2942 if(data->set.verbose)
2943 Curl_debug(data, CURLINFO_HEADER_IN,
2944 k->str_start, headerlen, conn);
2945 break; /* exit header line loop */
2948 /* We continue reading headers, so reset the line-based
2949 header parsing variables hbufp && hbuflen */
2950 k->hbufp = data->state.headerbuff;
2956 * Checks for special headers coming up.
2959 if(!k->headerline++) {
2960 /* This is the first header, it MUST be the error code line
2961 or else we consider this to be the body right away! */
2962 int httpversion_major;
2963 int rtspversion_major;
2965 #ifdef CURL_DOES_CONVERSIONS
2966 #define HEADER1 scratch
2967 #define SCRATCHSIZE 21
2969 char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
2970 /* We can't really convert this yet because we
2971 don't know if it's the 1st header line or the body.
2972 So we do a partial conversion into a scratch area,
2973 leaving the data at k->p as-is.
2975 strncpy(&scratch[0], k->p, SCRATCHSIZE);
2976 scratch[SCRATCHSIZE] = 0; /* null terminate */
2977 res = Curl_convert_from_network(data,
2981 /* Curl_convert_from_network calls failf if unsuccessful */
2984 #define HEADER1 k->p /* no conversion needed, just use k->p */
2985 #endif /* CURL_DOES_CONVERSIONS */
2987 if(conn->handler->protocol & CURLPROTO_HTTP) {
2988 nc = sscanf(HEADER1,
2994 conn->httpversion += 10 * httpversion_major;
2997 /* this is the real world, not a Nirvana
2998 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3000 nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3001 conn->httpversion = 10;
3003 /* If user has set option HTTP200ALIASES,
3004 compare header line against list of aliases
3007 if(checkhttpprefix(data, k->p)) {
3010 conn->httpversion = 10;
3015 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3016 nc = sscanf(HEADER1,
3022 conn->rtspversion += 10 * rtspversion_major;
3023 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3026 /* TODO: do we care about the other cases here? */
3032 data->info.httpcode = k->httpcode;
3034 data->info.httpversion = conn->httpversion;
3035 if(!data->state.httpversion ||
3036 data->state.httpversion > conn->httpversion)
3037 /* store the lowest server version we encounter */
3038 data->state.httpversion = conn->httpversion;
3041 * This code executes as part of processing the header. As a
3042 * result, it's not totally clear how to interpret the
3043 * response code yet as that depends on what other headers may
3044 * be present. 401 and 407 may be errors, but may be OK
3045 * depending on how authentication is working. Other codes
3046 * are definitely errors, so give up here.
3048 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3049 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3050 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3052 if(data->state.resume_from &&
3053 (data->set.httpreq==HTTPREQ_GET) &&
3054 (k->httpcode == 416)) {
3055 /* "Requested Range Not Satisfiable", just proceed and
3056 pretend this is no error */
3059 /* serious error, go home! */
3060 failf (data, "The requested URL returned error: %d",
3062 return CURLE_HTTP_RETURNED_ERROR;
3066 if(conn->httpversion == 10) {
3067 /* Default action for HTTP/1.0 must be to close, unless
3068 we get one of those fancy headers that tell us the
3069 server keeps it open for us! */
3070 infof(data, "HTTP 1.0, assume close after body\n");
3071 conn->bits.close = TRUE;
3073 else if(conn->httpversion >= 11 &&
3074 !conn->bits.close) {
3075 /* If HTTP version is >= 1.1 and connection is persistent
3076 server supports pipelining. */
3078 "HTTP 1.1 or later with persistent connection, "
3079 "pipelining supported\n"));
3080 conn->server_supports_pipelining = TRUE;
3083 switch(k->httpcode) {
3085 /* (quote from RFC2616, section 10.2.5): The server has
3086 * fulfilled the request but does not need to return an
3087 * entity-body ... The 204 response MUST NOT include a
3088 * message-body, and thus is always terminated by the first
3089 * empty line after the header fields. */
3092 /* (quote from RFC2616, section 10.3.5): The 304 response
3093 * MUST NOT contain a message-body, and thus is always
3094 * terminated by the first empty line after the header
3096 if(data->set.timecondition)
3097 data->info.timecond = TRUE;
3100 k->ignorecl = TRUE; /* ignore Content-Length headers */
3108 k->header = FALSE; /* this is not a header line */
3113 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3114 /* Curl_convert_from_network calls failf if unsuccessful */
3118 /* Check for Content-Length: header lines to get size */
3119 if(!k->ignorecl && !data->set.ignorecl &&
3120 checkprefix("Content-Length:", k->p)) {
3121 curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3122 if(data->set.max_filesize &&
3123 contentlength > data->set.max_filesize) {
3124 failf(data, "Maximum file size exceeded");
3125 return CURLE_FILESIZE_EXCEEDED;
3127 if(contentlength >= 0) {
3128 k->size = contentlength;
3129 k->maxdownload = k->size;
3130 /* we set the progress download size already at this point
3131 just to make it easier for apps/callbacks to extract this
3132 info as soon as possible */
3133 Curl_pgrsSetDownloadSize(data, k->size);
3136 /* Negative Content-Length is really odd, and we know it
3137 happens for example when older Apache servers send large
3139 conn->bits.close = TRUE;
3140 infof(data, "Negative content-length: %" FORMAT_OFF_T
3141 ", closing after transfer\n", contentlength);
3144 /* check for Content-Type: header lines to get the MIME-type */
3145 else if(checkprefix("Content-Type:", k->p)) {
3146 char *contenttype = copy_header_value(k->p);
3148 return CURLE_OUT_OF_MEMORY;
3150 /* ignore empty data */
3153 Curl_safefree(data->info.contenttype);
3154 data->info.contenttype = contenttype;
3157 else if((conn->httpversion == 10) &&
3158 conn->bits.httpproxy &&
3159 Curl_compareheader(k->p,
3160 "Proxy-Connection:", "keep-alive")) {
3162 * When a HTTP/1.0 reply comes when using a proxy, the
3163 * 'Proxy-Connection: keep-alive' line tells us the
3164 * connection will be kept alive for our pleasure.
3165 * Default action for 1.0 is to close.
3167 conn->bits.close = FALSE; /* don't close when done */
3168 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3170 else if((conn->httpversion == 11) &&
3171 conn->bits.httpproxy &&
3172 Curl_compareheader(k->p,
3173 "Proxy-Connection:", "close")) {
3175 * We get a HTTP/1.1 response from a proxy and it says it'll
3176 * close down after this transfer.
3178 conn->bits.close = TRUE; /* close when done */
3179 infof(data, "HTTP/1.1 proxy connection set close!\n");
3181 else if((conn->httpversion == 10) &&
3182 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3184 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3185 * tells us the connection will be kept alive for our
3186 * pleasure. Default action for 1.0 is to close.
3188 * [RFC2068, section 19.7.1] */
3189 conn->bits.close = FALSE; /* don't close when done */
3190 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3192 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3194 * [RFC 2616, section 8.1.2.1]
3195 * "Connection: close" is HTTP/1.1 language and means that
3196 * the connection will close when this request has been
3199 conn->bits.close = TRUE; /* close when done */
3201 else if(checkprefix("Transfer-Encoding:", k->p)) {
3202 /* One or more encodings. We check for chunked and/or a compression
3205 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3206 * means that the server will send a series of "chunks". Each
3207 * chunk starts with line with info (including size of the
3208 * coming block) (terminated with CRLF), then a block of data
3209 * with the previously mentioned size. There can be any amount
3210 * of chunks, and a chunk-data set to zero signals the
3215 /* Find the first non-space letter */
3219 /* skip whitespaces and commas */
3220 while(*start && (ISSPACE(*start) || (*start == ',')))
3223 if(checkprefix("chunked", start)) {
3224 k->chunk = TRUE; /* chunks coming our way */
3226 /* init our chunky engine */
3227 Curl_httpchunk_init(conn);
3232 if(k->auto_decoding)
3233 /* TODO: we only support the first mentioned compression for now */
3236 if(checkprefix("identity", start)) {
3237 k->auto_decoding = IDENTITY;
3240 else if(checkprefix("deflate", start)) {
3241 k->auto_decoding = DEFLATE;
3244 else if(checkprefix("gzip", start)) {
3245 k->auto_decoding = GZIP;
3248 else if(checkprefix("x-gzip", start)) {
3249 k->auto_decoding = GZIP;
3252 else if(checkprefix("compress", start)) {
3253 k->auto_decoding = COMPRESS;
3256 else if(checkprefix("x-compress", start)) {
3257 k->auto_decoding = COMPRESS;
3267 else if(checkprefix("Content-Encoding:", k->p) &&
3268 data->set.str[STRING_ENCODING]) {
3270 * Process Content-Encoding. Look for the values: identity,
3271 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3272 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3273 * 2616). zlib cannot handle compress. However, errors are
3274 * handled further down when the response body is processed
3278 /* Find the first non-space letter */
3280 while(*start && ISSPACE(*start))
3283 /* Record the content-encoding for later use */
3284 if(checkprefix("identity", start))
3285 k->auto_decoding = IDENTITY;
3286 else if(checkprefix("deflate", start))
3287 k->auto_decoding = DEFLATE;
3288 else if(checkprefix("gzip", start)
3289 || checkprefix("x-gzip", start))
3290 k->auto_decoding = GZIP;
3291 else if(checkprefix("compress", start)
3292 || checkprefix("x-compress", start))
3293 k->auto_decoding = COMPRESS;
3295 else if(checkprefix("Content-Range:", k->p)) {
3296 /* Content-Range: bytes [num]-
3297 Content-Range: bytes: [num]-
3298 Content-Range: [num]-
3300 The second format was added since Sun's webserver
3301 JavaWebServer/1.1.1 obviously sends the header this way!
3302 The third added since some servers use that!
3305 char *ptr = k->p + 14;
3307 /* Move forward until first digit */
3308 while(*ptr && !ISDIGIT(*ptr))
3311 k->offset = curlx_strtoofft(ptr, NULL, 10);
3313 if(data->state.resume_from == k->offset)
3314 /* we asked for a resume and we got it */
3315 k->content_range = TRUE;
3317 #if !defined(CURL_DISABLE_COOKIES)
3318 else if(data->cookies &&
3319 checkprefix("Set-Cookie:", k->p)) {
3320 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3321 CURL_LOCK_ACCESS_SINGLE);
3322 Curl_cookie_add(data,
3323 data->cookies, TRUE, k->p+11,
3324 /* If there is a custom-set Host: name, use it
3325 here, or else use real peer host name. */
3326 conn->allocptr.cookiehost?
3327 conn->allocptr.cookiehost:conn->host.name,
3329 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3332 else if(checkprefix("Last-Modified:", k->p) &&
3333 (data->set.timecondition || data->set.get_filetime) ) {
3334 time_t secs=time(NULL);
3335 k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3337 if(data->set.get_filetime)
3338 data->info.filetime = (long)k->timeofdoc;
3340 else if((checkprefix("WWW-Authenticate:", k->p) &&
3341 (401 == k->httpcode)) ||
3342 (checkprefix("Proxy-authenticate:", k->p) &&
3343 (407 == k->httpcode))) {
3344 result = Curl_http_input_auth(conn, k->httpcode, k->p);
3348 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3349 checkprefix("Location:", k->p) &&
3350 !data->req.location) {
3351 /* this is the URL that the server advises us to use instead */
3352 char *location = copy_header_value(k->p);
3354 return CURLE_OUT_OF_MEMORY;
3356 /* ignore empty data */
3359 data->req.location = location;
3361 if(data->set.http_follow_location) {
3362 DEBUGASSERT(!data->req.newurl);
3363 data->req.newurl = strdup(data->req.location); /* clone */
3364 if(!data->req.newurl)
3365 return CURLE_OUT_OF_MEMORY;
3367 /* some cases of POST and PUT etc needs to rewind the data
3368 stream at this point */
3369 result = http_perhapsrewind(conn);
3375 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3376 result = Curl_rtsp_parseheader(conn, k->p);
3382 * End of header-checks. Write them to the client.
3385 writetype = CLIENTWRITE_HEADER;
3386 if(data->set.include_header)
3387 writetype |= CLIENTWRITE_BODY;
3389 if(data->set.verbose)
3390 Curl_debug(data, CURLINFO_HEADER_IN,
3391 k->p, (size_t)k->hbuflen, conn);
3393 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3397 data->info.header_size += (long)k->hbuflen;
3398 data->req.headerbytecount += (long)k->hbuflen;
3400 /* reset hbufp pointer && hbuflen */
3401 k->hbufp = data->state.headerbuff;
3404 while(!*stop_reading && *k->str); /* header line within buffer */
3406 /* We might have reached the end of the header part here, but
3407 there might be a non-header part left in the end of the read
3413 #endif /* CURL_DISABLE_HTTP */