1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2016, 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 https://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #ifndef CURL_DISABLE_HTTP
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
34 #ifdef HAVE_ARPA_INET_H
35 #include <arpa/inet.h>
40 #ifdef HAVE_SYS_IOCTL_H
41 #include <sys/ioctl.h>
44 #ifdef HAVE_SYS_PARAM_H
45 #include <sys/param.h>
49 #include <curl/curl.h>
54 #include "curl_base64.h"
57 #include "vtls/vtls.h"
58 #include "http_digest.h"
59 #include "curl_ntlm.h"
60 #include "curl_ntlm_wb.h"
61 #include "http_negotiate.h"
67 #include "parsedate.h" /* for the week day and month names */
68 #include "strtoofft.h"
71 #include "content_encoding.h"
72 #include "http_proxy.h"
74 #include "non-ascii.h"
75 #include "conncache.h"
79 #include "curl_printf.h"
81 /* The last #include files should be: */
82 #include "curl_memory.h"
86 * Forward declarations.
89 static int http_getsock_do(struct connectdata *conn,
92 static int http_should_fail(struct connectdata *conn);
95 static CURLcode https_connecting(struct connectdata *conn, bool *done);
96 static int https_getsock(struct connectdata *conn,
100 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
104 * HTTP handler interface.
106 const struct Curl_handler Curl_handler_http = {
108 Curl_http_setup_conn, /* setup_connection */
109 Curl_http, /* do_it */
110 Curl_http_done, /* done */
111 ZERO_NULL, /* do_more */
112 Curl_http_connect, /* connect_it */
113 ZERO_NULL, /* connecting */
114 ZERO_NULL, /* doing */
115 ZERO_NULL, /* proto_getsock */
116 http_getsock_do, /* doing_getsock */
117 ZERO_NULL, /* domore_getsock */
118 ZERO_NULL, /* perform_getsock */
119 ZERO_NULL, /* disconnect */
120 ZERO_NULL, /* readwrite */
121 PORT_HTTP, /* defport */
122 CURLPROTO_HTTP, /* protocol */
123 PROTOPT_CREDSPERREQUEST /* flags */
128 * HTTPS handler interface.
130 const struct Curl_handler Curl_handler_https = {
131 "HTTPS", /* scheme */
132 Curl_http_setup_conn, /* setup_connection */
133 Curl_http, /* do_it */
134 Curl_http_done, /* done */
135 ZERO_NULL, /* do_more */
136 Curl_http_connect, /* connect_it */
137 https_connecting, /* connecting */
138 ZERO_NULL, /* doing */
139 https_getsock, /* proto_getsock */
140 http_getsock_do, /* doing_getsock */
141 ZERO_NULL, /* domore_getsock */
142 ZERO_NULL, /* perform_getsock */
143 ZERO_NULL, /* disconnect */
144 ZERO_NULL, /* readwrite */
145 PORT_HTTPS, /* defport */
146 CURLPROTO_HTTPS, /* protocol */
147 PROTOPT_SSL | PROTOPT_CREDSPERREQUEST /* flags */
152 CURLcode Curl_http_setup_conn(struct connectdata *conn)
154 /* allocate the HTTP-specific struct for the SessionHandle, only to survive
155 during this request */
157 DEBUGASSERT(conn->data->req.protop == NULL);
159 http = calloc(1, sizeof(struct HTTP));
161 return CURLE_OUT_OF_MEMORY;
163 conn->data->req.protop = http;
165 Curl_http2_setup_conn(conn);
166 Curl_http2_setup_req(conn->data);
172 * checkheaders() checks the linked list of custom HTTP headers for a
173 * particular header (prefix).
175 * Returns a pointer to the first matching header or NULL if none matched.
177 char *Curl_checkheaders(const struct connectdata *conn,
178 const char *thisheader)
180 struct curl_slist *head;
181 size_t thislen = strlen(thisheader);
182 struct SessionHandle *data = conn->data;
184 for(head = data->set.headers;head; head=head->next) {
185 if(Curl_raw_nequal(head->data, thisheader, thislen))
192 * checkProxyHeaders() checks the linked list of custom proxy headers
193 * if proxy headers are not available, then it will lookup into http header
196 * It takes a connectdata struct as input instead of the SessionHandle simply
197 * to know if this is a proxy request or not, as it then might check a
198 * different header list.
201 char *Curl_checkProxyheaders(const struct connectdata *conn,
202 const char *thisheader)
204 struct curl_slist *head;
205 size_t thislen = strlen(thisheader);
206 struct SessionHandle *data = conn->data;
208 for(head = (conn->bits.proxy && data->set.sep_headers)?
209 data->set.proxyheaders:data->set.headers;
210 head; head=head->next) {
211 if(Curl_raw_nequal(head->data, thisheader, thislen))
218 * Strip off leading and trailing whitespace from the value in the
219 * given HTTP header line and return a strdupped copy. Returns NULL in
220 * case of allocation failure. Returns an empty string if the header value
221 * consists entirely of whitespace.
223 char *Curl_copy_header_value(const char *header)
232 /* Find the end of the header name */
233 while(*header && (*header != ':'))
237 /* Skip over colon */
240 /* Find the first non-space letter */
242 while(*start && ISSPACE(*start))
245 /* data is in the host encoding so
246 use '\r' and '\n' instead of 0x0d and 0x0a */
247 end = strchr(start, '\r');
249 end = strchr(start, '\n');
251 end = strchr(start, '\0');
255 /* skip all trailing space letters */
256 while((end > start) && ISSPACE(*end))
259 /* get length of the type */
260 len = end - start + 1;
262 value = malloc(len + 1);
266 memcpy(value, start, len);
267 value[len] = 0; /* zero terminate */
273 * http_output_basic() sets up an Authorization: header (or the proxy version)
274 * for HTTP Basic authentication.
278 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
281 char *authorization = NULL;
282 struct SessionHandle *data = conn->data;
289 userp = &conn->allocptr.proxyuserpwd;
290 user = conn->proxyuser;
291 pwd = conn->proxypasswd;
294 userp = &conn->allocptr.userpwd;
299 snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
301 result = Curl_base64_encode(data,
302 data->state.buffer, strlen(data->state.buffer),
303 &authorization, &size);
308 return CURLE_REMOTE_ACCESS_DENIED;
311 *userp = aprintf("%sAuthorization: Basic %s\r\n",
316 return CURLE_OUT_OF_MEMORY;
321 /* pickoneauth() selects the most favourable authentication method from the
322 * ones available and the ones we want.
324 * return TRUE if one was picked
326 static bool pickoneauth(struct auth *pick)
329 /* only deal with authentication we want */
330 unsigned long avail = pick->avail & pick->want;
333 /* The order of these checks is highly relevant, as this will be the order
334 of preference in case of the existence of multiple accepted types. */
335 if(avail & CURLAUTH_NEGOTIATE)
336 pick->picked = CURLAUTH_NEGOTIATE;
337 else if(avail & CURLAUTH_DIGEST)
338 pick->picked = CURLAUTH_DIGEST;
339 else if(avail & CURLAUTH_NTLM)
340 pick->picked = CURLAUTH_NTLM;
341 else if(avail & CURLAUTH_NTLM_WB)
342 pick->picked = CURLAUTH_NTLM_WB;
343 else if(avail & CURLAUTH_BASIC)
344 pick->picked = CURLAUTH_BASIC;
346 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
349 pick->avail = CURLAUTH_NONE; /* clear it here */
355 * Curl_http_perhapsrewind()
357 * If we are doing POST or PUT {
358 * If we have more data to send {
359 * If we are doing NTLM {
360 * Keep sending since we must not disconnect
363 * If there is more than just a little data left to send, close
364 * the current connection by force.
367 * If we have sent any data {
368 * If we don't have track of all the data {
369 * call app to tell it to rewind
372 * rewind internally so that the operation can restart fine
377 static CURLcode http_perhapsrewind(struct connectdata *conn)
379 struct SessionHandle *data = conn->data;
380 struct HTTP *http = data->req.protop;
381 curl_off_t bytessent;
382 curl_off_t expectsend = -1; /* default is unknown */
385 /* If this is still NULL, we have not reach very far and we can safely
386 skip this rewinding stuff */
389 switch(data->set.httpreq) {
397 bytessent = http->writebytecount;
399 if(conn->bits.authneg) {
400 /* This is a state where we are known to be negotiating and we don't send
404 else if(!conn->bits.protoconnstart) {
405 /* HTTP CONNECT in progress: there is no body */
409 /* figure out how much data we are expected to send */
410 switch(data->set.httpreq) {
412 if(data->state.infilesize != -1)
413 expectsend = data->state.infilesize;
414 else if(data->set.postfields)
415 expectsend = (curl_off_t)strlen(data->set.postfields);
418 if(data->state.infilesize != -1)
419 expectsend = data->state.infilesize;
421 case HTTPREQ_POST_FORM:
422 expectsend = http->postsize;
429 conn->bits.rewindaftersend = FALSE; /* default */
431 if((expectsend == -1) || (expectsend > bytessent)) {
432 #if defined(USE_NTLM)
433 /* There is still data left to send */
434 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
435 (data->state.authhost.picked == CURLAUTH_NTLM) ||
436 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
437 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
438 if(((expectsend - bytessent) < 2000) ||
439 (conn->ntlm.state != NTLMSTATE_NONE) ||
440 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
441 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
442 data left to send, keep on sending. */
444 /* rewind data when completely done sending! */
445 if(!conn->bits.authneg) {
446 conn->bits.rewindaftersend = TRUE;
447 infof(data, "Rewind stream after send\n");
454 /* this is already marked to get closed */
457 infof(data, "NTLM send, close instead of sending %"
458 CURL_FORMAT_CURL_OFF_T " bytes\n",
459 (curl_off_t)(expectsend - bytessent));
463 /* This is not NTLM or many bytes left to send: close */
464 connclose(conn, "Mid-auth HTTP and much data left to send");
465 data->req.size = 0; /* don't download any more than 0 bytes */
467 /* There still is data left to send, but this connection is marked for
468 closure so we can safely do the rewind right now */
472 /* we rewind now at once since if we already sent something */
473 return Curl_readrewind(conn);
479 * Curl_http_auth_act() gets called when all HTTP headers have been received
480 * and it checks what authentication methods that are available and decides
481 * which one (if any) to use. It will set 'newurl' if an auth method was
485 CURLcode Curl_http_auth_act(struct connectdata *conn)
487 struct SessionHandle *data = conn->data;
488 bool pickhost = FALSE;
489 bool pickproxy = FALSE;
490 CURLcode result = CURLE_OK;
492 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
493 /* this is a transient response code, ignore */
496 if(data->state.authproblem)
497 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
499 if(conn->bits.user_passwd &&
500 ((data->req.httpcode == 401) ||
501 (conn->bits.authneg && data->req.httpcode < 300))) {
502 pickhost = pickoneauth(&data->state.authhost);
504 data->state.authproblem = TRUE;
506 if(conn->bits.proxy_user_passwd &&
507 ((data->req.httpcode == 407) ||
508 (conn->bits.authneg && data->req.httpcode < 300))) {
509 pickproxy = pickoneauth(&data->state.authproxy);
511 data->state.authproblem = TRUE;
514 if(pickhost || pickproxy) {
515 /* In case this is GSS auth, the newurl field is already allocated so
516 we must make sure to free it before allocating a new one. As figured
517 out in bug #2284386 */
518 Curl_safefree(data->req.newurl);
519 data->req.newurl = strdup(data->change.url); /* clone URL */
520 if(!data->req.newurl)
521 return CURLE_OUT_OF_MEMORY;
523 if((data->set.httpreq != HTTPREQ_GET) &&
524 (data->set.httpreq != HTTPREQ_HEAD) &&
525 !conn->bits.rewindaftersend) {
526 result = http_perhapsrewind(conn);
532 else if((data->req.httpcode < 300) &&
533 (!data->state.authhost.done) &&
534 conn->bits.authneg) {
535 /* no (known) authentication available,
536 authentication is not "done" yet and
537 no authentication seems to be required and
538 we didn't try HEAD or GET */
539 if((data->set.httpreq != HTTPREQ_GET) &&
540 (data->set.httpreq != HTTPREQ_HEAD)) {
541 data->req.newurl = strdup(data->change.url); /* clone URL */
542 if(!data->req.newurl)
543 return CURLE_OUT_OF_MEMORY;
544 data->state.authhost.done = TRUE;
547 if(http_should_fail(conn)) {
548 failf (data, "The requested URL returned error: %d",
550 result = CURLE_HTTP_RETURNED_ERROR;
558 * Output the correct authentication header depending on the auth type
559 * and whether or not it is to a proxy.
562 output_auth_headers(struct connectdata *conn,
563 struct auth *authstatus,
568 const char *auth = NULL;
569 CURLcode result = CURLE_OK;
570 #if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
571 struct SessionHandle *data = conn->data;
574 struct negotiatedata *negdata = proxy ?
575 &data->state.proxyneg : &data->state.negotiate;
578 #ifdef CURL_DISABLE_CRYPTO_AUTH
584 negdata->state = GSS_AUTHNONE;
585 if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
586 negdata->context && !GSS_ERROR(negdata->status)) {
588 result = Curl_output_negotiate(conn, proxy);
591 authstatus->done = TRUE;
592 negdata->state = GSS_AUTHSENT;
597 if(authstatus->picked == CURLAUTH_NTLM) {
599 result = Curl_output_ntlm(conn, proxy);
605 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
606 if(authstatus->picked == CURLAUTH_NTLM_WB) {
608 result = Curl_output_ntlm_wb(conn, proxy);
614 #ifndef CURL_DISABLE_CRYPTO_AUTH
615 if(authstatus->picked == CURLAUTH_DIGEST) {
617 result = Curl_output_digest(conn,
619 (const unsigned char *)request,
620 (const unsigned char *)path);
626 if(authstatus->picked == CURLAUTH_BASIC) {
628 if((proxy && conn->bits.proxy_user_passwd &&
629 !Curl_checkProxyheaders(conn, "Proxy-authorization:")) ||
630 (!proxy && conn->bits.user_passwd &&
631 !Curl_checkheaders(conn, "Authorization:"))) {
633 result = http_output_basic(conn, proxy);
637 /* NOTE: this function should set 'done' TRUE, as the other auth
638 functions work that way */
639 authstatus->done = TRUE;
643 infof(data, "%s auth using %s with user '%s'\n",
644 proxy?"Proxy":"Server", auth,
645 proxy?(conn->proxyuser?conn->proxyuser:""):
646 (conn->user?conn->user:""));
647 authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
650 authstatus->multi = FALSE;
656 * Curl_http_output_auth() setups the authentication headers for the
657 * host/proxy and the correct authentication
658 * method. conn->data->state.authdone is set to TRUE when authentication is
661 * @param conn all information about the current connection
662 * @param request pointer to the request keyword
663 * @param path pointer to the requested path
664 * @param proxytunnel boolean if this is the request setting up a "proxy
670 Curl_http_output_auth(struct connectdata *conn,
673 bool proxytunnel) /* TRUE if this is the request setting
674 up the proxy tunnel */
676 CURLcode result = CURLE_OK;
677 struct SessionHandle *data = conn->data;
678 struct auth *authhost;
679 struct auth *authproxy;
683 authhost = &data->state.authhost;
684 authproxy = &data->state.authproxy;
686 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
687 conn->bits.user_passwd)
688 /* continue please */;
690 authhost->done = TRUE;
691 authproxy->done = TRUE;
692 return CURLE_OK; /* no authentication with no user or password */
695 if(authhost->want && !authhost->picked)
696 /* The app has selected one or more methods, but none has been picked
697 so far by a server round-trip. Then we set the picked one to the
698 want one, and if this is one single bit it'll be used instantly. */
699 authhost->picked = authhost->want;
701 if(authproxy->want && !authproxy->picked)
702 /* The app has selected one or more methods, but none has been picked so
703 far by a proxy round-trip. Then we set the picked one to the want one,
704 and if this is one single bit it'll be used instantly. */
705 authproxy->picked = authproxy->want;
707 #ifndef CURL_DISABLE_PROXY
708 /* Send proxy authentication header if needed */
709 if(conn->bits.httpproxy &&
710 (conn->bits.tunnel_proxy == proxytunnel)) {
711 result = output_auth_headers(conn, authproxy, request, path, TRUE);
718 #endif /* CURL_DISABLE_PROXY */
719 /* we have no proxy so let's pretend we're done authenticating
721 authproxy->done = TRUE;
723 /* To prevent the user+password to get sent to other than the original
724 host due to a location-follow, we do some weirdo checks here */
725 if(!data->state.this_is_a_follow ||
727 !data->state.first_host ||
728 data->set.http_disable_hostname_check_before_authentication ||
729 Curl_raw_equal(data->state.first_host, conn->host.name)) {
730 result = output_auth_headers(conn, authhost, request, path, FALSE);
733 authhost->done = TRUE;
740 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
741 * headers. They are dealt with both in the transfer.c main loop and in the
742 * proxy CONNECT loop.
745 CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
746 const char *auth) /* the first non-space */
749 * This resource requires authentication
751 struct SessionHandle *data = conn->data;
754 struct negotiatedata *negdata = proxy?
755 &data->state.proxyneg:&data->state.negotiate;
757 unsigned long *availp;
761 availp = &data->info.proxyauthavail;
762 authp = &data->state.authproxy;
765 availp = &data->info.httpauthavail;
766 authp = &data->state.authhost;
770 * Here we check if we want the specific single authentication (using ==) and
771 * if we do, we initiate usage of it.
773 * If the provided authentication is wanted as one out of several accepted
774 * types (using &), we OR this authentication type to the authavail
779 * ->picked is first set to the 'want' value (one or more bits) before the
780 * request is sent, and then it is again set _after_ all response 401/407
781 * headers have been received but then only to a single preferred method
788 if(checkprefix("Negotiate", auth)) {
789 *availp |= CURLAUTH_NEGOTIATE;
790 authp->avail |= CURLAUTH_NEGOTIATE;
792 if(authp->picked == CURLAUTH_NEGOTIATE) {
793 if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
794 CURLcode result = Curl_input_negotiate(conn, proxy, auth);
796 DEBUGASSERT(!data->req.newurl);
797 data->req.newurl = strdup(data->change.url);
798 if(!data->req.newurl)
799 return CURLE_OUT_OF_MEMORY;
800 data->state.authproblem = FALSE;
801 /* we received a GSS auth token and we dealt with it fine */
802 negdata->state = GSS_AUTHRECV;
805 data->state.authproblem = TRUE;
812 /* NTLM support requires the SSL crypto libs */
813 if(checkprefix("NTLM", auth)) {
814 *availp |= CURLAUTH_NTLM;
815 authp->avail |= CURLAUTH_NTLM;
816 if(authp->picked == CURLAUTH_NTLM ||
817 authp->picked == CURLAUTH_NTLM_WB) {
818 /* NTLM authentication is picked and activated */
819 CURLcode result = Curl_input_ntlm(conn, proxy, auth);
821 data->state.authproblem = FALSE;
822 #ifdef NTLM_WB_ENABLED
823 if(authp->picked == CURLAUTH_NTLM_WB) {
824 *availp &= ~CURLAUTH_NTLM;
825 authp->avail &= ~CURLAUTH_NTLM;
826 *availp |= CURLAUTH_NTLM_WB;
827 authp->avail |= CURLAUTH_NTLM_WB;
829 /* Get the challenge-message which will be passed to
830 * ntlm_auth for generating the type 3 message later */
831 while(*auth && ISSPACE(*auth))
833 if(checkprefix("NTLM", auth)) {
834 auth += strlen("NTLM");
835 while(*auth && ISSPACE(*auth))
838 if((conn->challenge_header = strdup(auth)) == NULL)
839 return CURLE_OUT_OF_MEMORY;
845 infof(data, "Authentication problem. Ignoring this.\n");
846 data->state.authproblem = TRUE;
852 #ifndef CURL_DISABLE_CRYPTO_AUTH
853 if(checkprefix("Digest", auth)) {
854 if((authp->avail & CURLAUTH_DIGEST) != 0) {
855 infof(data, "Ignoring duplicate digest auth header.\n");
859 *availp |= CURLAUTH_DIGEST;
860 authp->avail |= CURLAUTH_DIGEST;
862 /* We call this function on input Digest headers even if Digest
863 * authentication isn't activated yet, as we need to store the
864 * incoming data from this header in case we are gonna use
866 result = Curl_input_digest(conn, proxy, auth);
868 infof(data, "Authentication problem. Ignoring this.\n");
869 data->state.authproblem = TRUE;
875 if(checkprefix("Basic", auth)) {
876 *availp |= CURLAUTH_BASIC;
877 authp->avail |= CURLAUTH_BASIC;
878 if(authp->picked == CURLAUTH_BASIC) {
879 /* We asked for Basic authentication but got a 40X back
880 anyway, which basically means our name+password isn't
882 authp->avail = CURLAUTH_NONE;
883 infof(data, "Authentication problem. Ignoring this.\n");
884 data->state.authproblem = TRUE;
888 /* there may be multiple methods on one line, so keep reading */
889 while(*auth && *auth != ',') /* read up to the next comma */
891 if(*auth == ',') /* if we're on a comma, skip it */
893 while(*auth && ISSPACE(*auth))
900 * http_should_fail() determines whether an HTTP response has gotten us
901 * into an error state or not.
903 * @param conn all information about the current connection
905 * @retval 0 communications should continue
907 * @retval 1 communications should not continue
909 static int http_should_fail(struct connectdata *conn)
911 struct SessionHandle *data;
918 httpcode = data->req.httpcode;
921 ** If we haven't been asked to fail on error,
924 if(!data->set.http_fail_on_error)
928 ** Any code < 400 is never terminal.
934 ** Any code >= 400 that's not 401 or 407 is always
937 if((httpcode != 401) &&
942 ** All we have left to deal with is 401 and 407
944 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
947 ** Examine the current authentication state to see if this
948 ** is an error. The idea is for this function to get
949 ** called after processing all the headers in a response
950 ** message. So, if we've been to asked to authenticate a
951 ** particular stage, and we've done it, we're OK. But, if
952 ** we're already completely authenticated, it's not OK to
953 ** get another 401 or 407.
955 ** It is possible for authentication to go stale such that
956 ** the client needs to reauthenticate. Once that info is
957 ** available, use it here.
961 ** Either we're not authenticating, or we're supposed to
962 ** be authenticating something else. This is an error.
964 if((httpcode == 401) && !conn->bits.user_passwd)
966 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
969 return data->state.authproblem;
973 * readmoredata() is a "fread() emulation" to provide POST and/or request
974 * data. It is used when a huge POST is to be made and the entire chunk wasn't
975 * sent in the first send(). This function will then be called from the
976 * transfer.c loop when more data is to be sent to the peer.
978 * Returns the amount of bytes it filled the buffer with.
980 static size_t readmoredata(char *buffer,
985 struct connectdata *conn = (struct connectdata *)userp;
986 struct HTTP *http = conn->data->req.protop;
987 size_t fullsize = size * nitems;
989 if(0 == http->postsize)
990 /* nothing to return */
993 /* make sure that a HTTP request is never sent away chunked! */
994 conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
996 if(http->postsize <= (curl_off_t)fullsize) {
997 memcpy(buffer, http->postdata, (size_t)http->postsize);
998 fullsize = (size_t)http->postsize;
1000 if(http->backup.postsize) {
1001 /* move backup data into focus and continue on that */
1002 http->postdata = http->backup.postdata;
1003 http->postsize = http->backup.postsize;
1004 conn->data->state.fread_func = http->backup.fread_func;
1005 conn->data->state.in = http->backup.fread_in;
1007 http->sending++; /* move one step up */
1009 http->backup.postsize=0;
1017 memcpy(buffer, http->postdata, fullsize);
1018 http->postdata += fullsize;
1019 http->postsize -= fullsize;
1024 /* ------------------------------------------------------------------------- */
1025 /* add_buffer functions */
1028 * Curl_add_buffer_init() sets up and returns a fine buffer struct
1030 Curl_send_buffer *Curl_add_buffer_init(void)
1032 return calloc(1, sizeof(Curl_send_buffer));
1036 * Curl_add_buffer_free() frees all associated resources.
1038 void Curl_add_buffer_free(Curl_send_buffer *buff)
1040 if(buff) /* deal with NULL input */
1046 * Curl_add_buffer_send() sends a header buffer and frees all associated
1047 * memory. Body data may be appended to the header data if desired.
1051 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
1052 struct connectdata *conn,
1054 /* add the number of sent bytes to this
1056 long *bytes_written,
1058 /* how much of the buffer contains body data */
1059 size_t included_body_bytes,
1067 struct HTTP *http = conn->data->req.protop;
1069 curl_socket_t sockfd;
1072 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1074 sockfd = conn->sock[socketindex];
1076 /* The looping below is required since we use non-blocking sockets, but due
1077 to the circumstances we will just loop and try again and again etc */
1080 size = in->size_used;
1082 headersize = size - included_body_bytes; /* the initial part that isn't body
1085 DEBUGASSERT(size > included_body_bytes);
1087 result = Curl_convert_to_network(conn->data, ptr, headersize);
1088 /* Curl_convert_to_network calls failf if unsuccessful */
1090 /* conversion failed, free memory and return to the caller */
1091 Curl_add_buffer_free(in);
1096 if((conn->handler->flags & PROTOPT_SSL) && conn->httpversion != 20) {
1097 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1098 when we speak HTTPS, as if only a fraction of it is sent now, this data
1099 needs to fit into the normal read-callback buffer later on and that
1100 buffer is using this size.
1103 sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
1105 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1106 library when we attempt to re-send this buffer. Sending the same data
1107 is not enough, we must use the exact same address. For this reason, we
1108 must copy the data to the uploadbuffer first, since that is the buffer
1109 we will be using if this send is retried later.
1111 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1112 ptr = conn->data->state.uploadbuffer;
1117 result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1121 * Note that we may not send the entire chunk at once, and we have a set
1122 * number of data bytes at the end of the big buffer (out of which we may
1123 * only send away a part).
1125 /* how much of the header that was sent */
1126 size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
1127 size_t bodylen = amount - headlen;
1129 if(conn->data->set.verbose) {
1130 /* this data _may_ contain binary stuff */
1131 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1133 /* there was body data sent beyond the initial header part, pass that
1134 on to the debug callback too */
1135 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1136 ptr+headlen, bodylen, conn);
1140 /* since we sent a piece of the body here, up the byte counter for it
1142 http->writebytecount += bodylen;
1144 /* 'amount' can never be a very large value here so typecasting it so a
1145 signed 31 bit value should not cause problems even if ssize_t is
1147 *bytes_written += (long)amount;
1150 if((size_t)amount != size) {
1151 /* The whole request could not be sent in one system call. We must
1152 queue it up and send it later when we get the chance. We must not
1153 loop here and wait until it might work again. */
1157 ptr = in->buffer + amount;
1159 /* backup the currently set pointers */
1160 http->backup.fread_func = conn->data->state.fread_func;
1161 http->backup.fread_in = conn->data->state.in;
1162 http->backup.postdata = http->postdata;
1163 http->backup.postsize = http->postsize;
1165 /* set the new pointers for the request-sending */
1166 conn->data->state.fread_func = (curl_read_callback)readmoredata;
1167 conn->data->state.in = (void *)conn;
1168 http->postdata = ptr;
1169 http->postsize = (curl_off_t)size;
1171 http->send_buffer = in;
1172 http->sending = HTTPSEND_REQUEST;
1176 http->sending = HTTPSEND_BODY;
1177 /* the full buffer was sent, clean up and return */
1180 if((size_t)amount != size)
1181 /* We have no continue-send mechanism now, fail. This can only happen
1182 when this function is used from the CONNECT sending function. We
1183 currently (stupidly) assume that the whole request is always sent
1184 away in the first single chunk.
1188 return CURLE_SEND_ERROR;
1190 Curl_pipeline_leave_write(conn);
1193 Curl_add_buffer_free(in);
1200 * add_bufferf() add the formatted input to the buffer.
1202 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1207 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1211 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1215 /* If we failed, we cleanup the whole buffer and return error */
1218 return CURLE_OUT_OF_MEMORY;
1222 * add_buffer() appends a memory chunk to the existing buffer
1224 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1229 if(~size < in->size_used) {
1230 /* If resulting used size of send buffer would wrap size_t, cleanup
1231 the whole buffer and return error. Otherwise the required buffer
1232 size will fit into a single allocatable memory chunk */
1233 Curl_safefree(in->buffer);
1235 return CURLE_OUT_OF_MEMORY;
1239 ((in->size_used + size) > (in->size_max - 1))) {
1241 /* If current buffer size isn't enough to hold the result, use a
1242 buffer size that doubles the required size. If this new size
1243 would wrap size_t, then just use the largest possible one */
1245 if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
1246 (~(size*2) < (in->size_used*2)))
1247 new_size = (size_t)-1;
1249 new_size = (in->size_used+size)*2;
1252 /* we have a buffer, enlarge the existing one */
1253 new_rb = realloc(in->buffer, new_size);
1255 /* create a new buffer */
1256 new_rb = malloc(new_size);
1259 /* If we failed, we cleanup the whole buffer and return error */
1260 Curl_safefree(in->buffer);
1262 return CURLE_OUT_OF_MEMORY;
1265 in->buffer = new_rb;
1266 in->size_max = new_size;
1268 memcpy(&in->buffer[in->size_used], inptr, size);
1270 in->size_used += size;
1275 /* end of the add_buffer functions */
1276 /* ------------------------------------------------------------------------- */
1281 * Curl_compareheader()
1283 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1284 * Pass headers WITH the colon.
1287 Curl_compareheader(const char *headerline, /* line to check */
1288 const char *header, /* header keyword _with_ colon */
1289 const char *content) /* content string to find */
1291 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1292 * by a colon (":") and the field value. Field names are case-insensitive.
1293 * The field value MAY be preceded by any amount of LWS, though a single SP
1296 size_t hlen = strlen(header);
1302 if(!Curl_raw_nequal(headerline, header, hlen))
1303 return FALSE; /* doesn't start with header */
1305 /* pass the header */
1306 start = &headerline[hlen];
1308 /* pass all white spaces */
1309 while(*start && ISSPACE(*start))
1312 /* find the end of the header line */
1313 end = strchr(start, '\r'); /* lines end with CRLF */
1315 /* in case there's a non-standard compliant line here */
1316 end = strchr(start, '\n');
1319 /* hm, there's no line ending here, use the zero byte! */
1320 end = strchr(start, '\0');
1323 len = end-start; /* length of the content part of the input line */
1324 clen = strlen(content); /* length of the word to find */
1326 /* find the content string in the rest of the line */
1327 for(;len>=clen;len--, start++) {
1328 if(Curl_raw_nequal(start, content, clen))
1329 return TRUE; /* match! */
1332 return FALSE; /* no match */
1336 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1337 * the generic Curl_connect().
1339 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1343 /* We default to persistent connections. We set this already in this connect
1344 function to make the re-use checks properly be able to check this bit. */
1345 connkeep(conn, "HTTP default");
1347 /* the CONNECT procedure might not have been completed */
1348 result = Curl_proxy_connect(conn);
1352 if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1353 /* nothing else to do except wait right now - we're not done here. */
1356 if(conn->given->flags & PROTOPT_SSL) {
1357 /* perform SSL initialization */
1358 result = https_connecting(conn, done);
1368 /* this returns the socket to wait for in the DO and DOING state for the multi
1369 interface and then we're always _sending_ a request and thus we wait for
1370 the single socket to become writable only */
1371 static int http_getsock_do(struct connectdata *conn,
1372 curl_socket_t *socks,
1376 (void)numsocks; /* unused, we trust it to be at least 1 */
1377 socks[0] = conn->sock[FIRSTSOCKET];
1378 return GETSOCK_WRITESOCK(0);
1382 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1385 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1387 /* perform SSL initialization for this socket */
1388 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1390 connclose(conn, "Failed HTTPS connection");
1396 #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
1397 defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
1398 defined(USE_MBEDTLS)
1399 /* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
1400 It should be made to query the generic SSL layer instead. */
1401 static int https_getsock(struct connectdata *conn,
1402 curl_socket_t *socks,
1405 if(conn->handler->flags & PROTOPT_SSL) {
1406 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1409 return GETSOCK_BLANK;
1411 if(connssl->connecting_state == ssl_connect_2_writing) {
1413 socks[0] = conn->sock[FIRSTSOCKET];
1414 return GETSOCK_WRITESOCK(0);
1416 else if(connssl->connecting_state == ssl_connect_2_reading) {
1418 socks[0] = conn->sock[FIRSTSOCKET];
1419 return GETSOCK_READSOCK(0);
1426 static int https_getsock(struct connectdata *conn,
1427 curl_socket_t *socks,
1433 return GETSOCK_BLANK;
1435 #endif /* USE_SSL */
1436 #endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */
1439 * Curl_http_done() gets called from Curl_done() after a single HTTP request
1440 * has been performed.
1443 CURLcode Curl_http_done(struct connectdata *conn,
1444 CURLcode status, bool premature)
1446 struct SessionHandle *data = conn->data;
1447 struct HTTP *http = data->req.protop;
1449 struct http_conn *httpc = &conn->proto.httpc;
1452 Curl_unencode_cleanup(conn);
1455 if(data->state.proxyneg.state == GSS_AUTHSENT ||
1456 data->state.negotiate.state == GSS_AUTHSENT) {
1457 /* add forbid re-use if http-code != 401/407 as a WA only needed for
1458 * 401/407 that signal auth failure (empty) otherwise state will be RECV
1459 * with current code */
1460 if((data->req.httpcode != 401) && (data->req.httpcode != 407))
1461 connclose(conn, "Negotiate transfer completed");
1462 Curl_cleanup_negotiate(data);
1466 /* set the proper values (possibly modified on POST) */
1467 conn->seek_func = data->set.seek_func; /* restore */
1468 conn->seek_client = data->set.seek_client; /* restore */
1473 if(http->send_buffer) {
1474 Curl_add_buffer_free(http->send_buffer);
1475 http->send_buffer = NULL; /* clear the pointer */
1479 if(http->header_recvbuf) {
1480 DEBUGF(infof(data, "free header_recvbuf!!\n"));
1481 Curl_add_buffer_free(http->header_recvbuf);
1482 http->header_recvbuf = NULL; /* clear the pointer */
1483 Curl_add_buffer_free(http->trailer_recvbuf);
1484 http->trailer_recvbuf = NULL; /* clear the pointer */
1485 if(http->push_headers) {
1486 /* if they weren't used and then freed before */
1487 for(; http->push_headers_used > 0; --http->push_headers_used) {
1488 free(http->push_headers[http->push_headers_used - 1]);
1490 free(http->push_headers);
1491 http->push_headers = NULL;
1494 if(http->stream_id) {
1495 nghttp2_session_set_stream_user_data(httpc->h2, http->stream_id, 0);
1496 http->stream_id = 0;
1500 if(HTTPREQ_POST_FORM == data->set.httpreq) {
1501 data->req.bytecount = http->readbytecount + http->writebytecount;
1503 Curl_formclean(&http->sendit); /* Now free that whole lot */
1505 /* a file being uploaded was left opened, close it! */
1506 fclose(http->form.fp);
1507 http->form.fp = NULL;
1510 else if(HTTPREQ_PUT == data->set.httpreq)
1511 data->req.bytecount = http->readbytecount + http->writebytecount;
1516 if(!premature && /* this check is pointless when DONE is called before the
1517 entire operation is complete */
1518 !conn->bits.retry &&
1519 !data->set.connect_only &&
1520 ((http->readbytecount +
1521 data->req.headerbytecount -
1522 data->req.deductheadercount)) <= 0) {
1523 /* If this connection isn't simply closed to be retried, AND nothing was
1524 read from the HTTP server (that counts), this can't be right so we
1525 return an error here */
1526 failf(data, "Empty reply from server");
1527 return CURLE_GOT_NOTHING;
1535 * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
1536 * to avoid it include:
1538 * - if the user specifically requested HTTP 1.0
1539 * - if the server we are connected to only supports 1.0
1540 * - if any server previously contacted to handle this request only supports
1543 static bool use_http_1_1plus(const struct SessionHandle *data,
1544 const struct connectdata *conn)
1546 if((data->state.httpversion == 10) || (conn->httpversion == 10))
1548 if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
1549 (conn->httpversion <= 10))
1551 return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
1552 (data->set.httpversion >= CURL_HTTP_VERSION_1_1));
1555 /* check and possibly add an Expect: header */
1556 static CURLcode expect100(struct SessionHandle *data,
1557 struct connectdata *conn,
1558 Curl_send_buffer *req_buffer)
1560 CURLcode result = CURLE_OK;
1562 data->state.expect100header = FALSE; /* default to false unless it is set
1564 if(use_http_1_1plus(data, conn) &&
1565 (conn->httpversion != 20)) {
1566 /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
1567 Expect: 100-continue to the headers which actually speeds up post
1568 operations (as there is one packet coming back from the web server) */
1569 ptr = Curl_checkheaders(conn, "Expect:");
1571 data->state.expect100header =
1572 Curl_compareheader(ptr, "Expect:", "100-continue");
1575 result = Curl_add_bufferf(req_buffer,
1576 "Expect: 100-continue\r\n");
1578 data->state.expect100header = TRUE;
1585 HEADER_SERVER, /* direct to server */
1586 HEADER_PROXY, /* regular request to proxy */
1587 HEADER_CONNECT /* sending CONNECT to a proxy */
1590 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1592 Curl_send_buffer *req_buffer)
1595 struct curl_slist *h[2];
1596 struct curl_slist *headers;
1597 int numlists=1; /* by default */
1598 struct SessionHandle *data = conn->data;
1601 enum proxy_use proxy;
1604 proxy = HEADER_CONNECT;
1606 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
1607 HEADER_PROXY:HEADER_SERVER;
1611 h[0] = data->set.headers;
1614 h[0] = data->set.headers;
1615 if(data->set.sep_headers) {
1616 h[1] = data->set.proxyheaders;
1620 case HEADER_CONNECT:
1621 if(data->set.sep_headers)
1622 h[0] = data->set.proxyheaders;
1624 h[0] = data->set.headers;
1628 /* loop through one or two lists */
1629 for(i=0; i < numlists; i++) {
1633 ptr = strchr(headers->data, ':');
1635 /* we require a colon for this to be a true header */
1637 ptr++; /* pass the colon */
1638 while(*ptr && ISSPACE(*ptr))
1642 /* only send this if the contents was non-blank */
1644 if(conn->allocptr.host &&
1645 /* a Host: header was sent already, don't pass on any custom Host:
1646 header as that will produce *two* in the same request! */
1647 checkprefix("Host:", headers->data))
1649 else if(data->set.httpreq == HTTPREQ_POST_FORM &&
1650 /* this header (extended by formdata.c) is sent later */
1651 checkprefix("Content-Type:", headers->data))
1653 else if(conn->bits.authneg &&
1654 /* while doing auth neg, don't allow the custom length since
1655 we will force length zero then */
1656 checkprefix("Content-Length", headers->data))
1658 else if(conn->allocptr.te &&
1659 /* when asking for Transfer-Encoding, don't pass on a custom
1661 checkprefix("Connection", headers->data))
1664 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1672 ptr = strchr(headers->data, ';');
1675 ptr++; /* pass the semicolon */
1676 while(*ptr && ISSPACE(*ptr))
1680 /* this may be used for something else in the future */
1683 if(*(--ptr) == ';') {
1686 /* send no-value custom header if terminated by semicolon */
1688 result = Curl_add_bufferf(req_buffer, "%s\r\n",
1696 headers = headers->next;
1702 CURLcode Curl_add_timecondition(struct SessionHandle *data,
1703 Curl_send_buffer *req_buffer)
1705 const struct tm *tm;
1706 char *buf = data->state.buffer;
1710 if(data->set.timecondition == CURL_TIMECOND_NONE)
1711 /* no condition was asked for */
1714 result = Curl_gmtime(data->set.timevalue, &keeptime);
1716 failf(data, "Invalid TIMEVALUE");
1721 /* The If-Modified-Since header family should have their times set in
1722 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1723 * represented in Greenwich Mean Time (GMT), without exception. For the
1724 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1725 * Time)." (see page 20 of RFC2616).
1728 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1729 snprintf(buf, BUFSIZE-1,
1730 "%s, %02d %s %4d %02d:%02d:%02d GMT",
1731 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1733 Curl_month[tm->tm_mon],
1739 switch(data->set.timecondition) {
1742 case CURL_TIMECOND_IFMODSINCE:
1743 result = Curl_add_bufferf(req_buffer,
1744 "If-Modified-Since: %s\r\n", buf);
1746 case CURL_TIMECOND_IFUNMODSINCE:
1747 result = Curl_add_bufferf(req_buffer,
1748 "If-Unmodified-Since: %s\r\n", buf);
1750 case CURL_TIMECOND_LASTMOD:
1751 result = Curl_add_bufferf(req_buffer,
1752 "Last-Modified: %s\r\n", buf);
1760 * Curl_http() gets called from the generic Curl_do() function when a HTTP
1761 * request is to be performed. This creates and sends a properly constructed
1764 CURLcode Curl_http(struct connectdata *conn, bool *done)
1766 struct SessionHandle *data = conn->data;
1767 CURLcode result = CURLE_OK;
1769 const char *ppath = data->state.path;
1770 bool paste_ftp_userpwd = FALSE;
1771 char ftp_typecode[sizeof("/;type=?")] = "";
1772 const char *host = conn->host.name;
1773 const char *te = ""; /* transfer-encoding */
1775 const char *request;
1776 Curl_HttpReq httpreq = data->set.httpreq;
1777 #if !defined(CURL_DISABLE_COOKIES)
1778 char *addcookies = NULL;
1780 curl_off_t included_body = 0;
1781 const char *httpstring;
1782 Curl_send_buffer *req_buffer;
1783 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1784 int seekerr = CURL_SEEKFUNC_OK;
1786 /* Always consider the DO phase done after this function call, even if there
1787 may be parts of the request that is not yet sent, since we can deal with
1788 the rest of the request in the PERFORM phase. */
1791 if(conn->httpversion < 20) { /* unless the connection is re-used and already
1793 switch(conn->negnpn) {
1794 case CURL_HTTP_VERSION_2:
1795 conn->httpversion = 20; /* we know we're on HTTP/2 now */
1796 result = Curl_http2_init(conn);
1800 result = Curl_http2_setup(conn);
1804 result = Curl_http2_switched(conn, NULL, 0);
1808 case CURL_HTTP_VERSION_1_1:
1809 /* continue with HTTP/1.1 when explicitly requested */
1812 /* and as fallback */
1817 /* prepare for a http2 request */
1818 result = Curl_http2_setup(conn);
1823 http = data->req.protop;
1825 if(!data->state.this_is_a_follow) {
1826 /* Free to avoid leaking memory on multiple requests*/
1827 free(data->state.first_host);
1829 data->state.first_host = strdup(conn->host.name);
1830 if(!data->state.first_host)
1831 return CURLE_OUT_OF_MEMORY;
1833 http->writebytecount = http->readbytecount = 0;
1835 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
1837 httpreq = HTTPREQ_PUT;
1840 /* Now set the 'request' pointer to the proper request string */
1841 if(data->set.str[STRING_CUSTOMREQUEST])
1842 request = data->set.str[STRING_CUSTOMREQUEST];
1844 if(data->set.opt_no_body)
1847 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1850 case HTTPREQ_POST_FORM:
1856 default: /* this should never happen */
1867 /* The User-Agent string might have been allocated in url.c already, because
1868 it might have been used in the proxy connect, but if we have got a header
1869 with the user-agent string specified, we erase the previously made string
1871 if(Curl_checkheaders(conn, "User-Agent:")) {
1872 free(conn->allocptr.uagent);
1873 conn->allocptr.uagent=NULL;
1876 /* setup the authentication headers */
1877 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1881 if((data->state.authhost.multi || data->state.authproxy.multi) &&
1882 (httpreq != HTTPREQ_GET) &&
1883 (httpreq != HTTPREQ_HEAD)) {
1884 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1885 with content-length zero as a "probe". */
1886 conn->bits.authneg = TRUE;
1889 conn->bits.authneg = FALSE;
1891 Curl_safefree(conn->allocptr.ref);
1892 if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) {
1893 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1894 if(!conn->allocptr.ref)
1895 return CURLE_OUT_OF_MEMORY;
1898 conn->allocptr.ref = NULL;
1900 #if !defined(CURL_DISABLE_COOKIES)
1901 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
1902 addcookies = data->set.str[STRING_COOKIE];
1905 if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
1906 data->set.str[STRING_ENCODING]) {
1907 Curl_safefree(conn->allocptr.accept_encoding);
1908 conn->allocptr.accept_encoding =
1909 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1910 if(!conn->allocptr.accept_encoding)
1911 return CURLE_OUT_OF_MEMORY;
1915 /* we only consider transfer-encoding magic if libz support is built-in */
1917 if(!Curl_checkheaders(conn, "TE:") &&
1918 data->set.http_transfer_encoding) {
1919 /* When we are to insert a TE: header in the request, we must also insert
1920 TE in a Connection: header, so we need to merge the custom provided
1921 Connection: header and prevent the original to get sent. Note that if
1922 the user has inserted his/hers own TE: header we don't do this magic
1923 but then assume that the user will handle it all! */
1924 char *cptr = Curl_checkheaders(conn, "Connection:");
1925 #define TE_HEADER "TE: gzip\r\n"
1927 Curl_safefree(conn->allocptr.te);
1929 /* Create the (updated) Connection: header */
1930 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1931 strdup("Connection: TE\r\n" TE_HEADER);
1933 if(!conn->allocptr.te)
1934 return CURLE_OUT_OF_MEMORY;
1938 if(conn->httpversion == 20)
1939 /* In HTTP2 forbids Transfer-Encoding: chunked */
1942 ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
1944 /* Some kind of TE is requested, check if 'chunked' is chosen */
1945 data->req.upload_chunky =
1946 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1949 if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
1951 (data->state.infilesize == -1)) {
1952 if(conn->bits.authneg)
1953 /* don't enable chunked during auth neg */
1955 else if(use_http_1_1plus(data, conn)) {
1956 /* HTTP, upload, unknown file size and not HTTP 1.0 */
1957 data->req.upload_chunky = TRUE;
1960 failf(data, "Chunky upload is not supported by HTTP 1.0");
1961 return CURLE_UPLOAD_FAILED;
1965 /* else, no chunky upload */
1966 data->req.upload_chunky = FALSE;
1969 if(data->req.upload_chunky)
1970 te = "Transfer-Encoding: chunked\r\n";
1974 Curl_safefree(conn->allocptr.host);
1976 ptr = Curl_checkheaders(conn, "Host:");
1977 if(ptr && (!data->state.this_is_a_follow ||
1978 Curl_raw_equal(data->state.first_host, conn->host.name))) {
1979 #if !defined(CURL_DISABLE_COOKIES)
1980 /* If we have a given custom Host: header, we extract the host name in
1981 order to possibly use it for cookie reasons later on. We only allow the
1982 custom Host: header if this is NOT a redirect, as setting Host: in the
1983 redirected request is being out on thin ice. Except if the host name
1984 is the same as the first one! */
1985 char *cookiehost = Curl_copy_header_value(ptr);
1987 return CURLE_OUT_OF_MEMORY;
1989 /* ignore empty data */
1992 /* If the host begins with '[', we start searching for the port after
1993 the bracket has been closed */
1994 int startsearch = 0;
1995 if(*cookiehost == '[') {
1996 char *closingbracket;
1997 /* since the 'cookiehost' is an allocated memory area that will be
1998 freed later we cannot simply increment the pointer */
1999 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
2000 closingbracket = strchr(cookiehost, ']');
2002 *closingbracket = 0;
2005 char *colon = strchr(cookiehost + startsearch, ':');
2007 *colon = 0; /* The host must not include an embedded port number */
2009 Curl_safefree(conn->allocptr.cookiehost);
2010 conn->allocptr.cookiehost = cookiehost;
2014 if(strcmp("Host:", ptr)) {
2015 conn->allocptr.host = aprintf("%s\r\n", ptr);
2016 if(!conn->allocptr.host)
2017 return CURLE_OUT_OF_MEMORY;
2020 /* when clearing the header */
2021 conn->allocptr.host = NULL;
2024 /* When building Host: headers, we must put the host name within
2025 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
2027 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
2028 (conn->remote_port == PORT_HTTPS)) ||
2029 ((conn->given->protocol&CURLPROTO_HTTP) &&
2030 (conn->remote_port == PORT_HTTP)) )
2031 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
2032 the port number in the host string */
2033 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
2034 conn->bits.ipv6_ip?"[":"",
2036 conn->bits.ipv6_ip?"]":"");
2038 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
2039 conn->bits.ipv6_ip?"[":"",
2041 conn->bits.ipv6_ip?"]":"",
2044 if(!conn->allocptr.host)
2045 /* without Host: we can't make a nice request */
2046 return CURLE_OUT_OF_MEMORY;
2049 #ifndef CURL_DISABLE_PROXY
2050 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
2051 /* Using a proxy but does not tunnel through it */
2053 /* The path sent to the proxy is in fact the entire URL. But if the remote
2054 host is a IDN-name, we must make sure that the request we produce only
2055 uses the encoded host name! */
2056 if(conn->host.dispname != conn->host.name) {
2057 char *url = data->change.url;
2058 ptr = strstr(url, conn->host.dispname);
2060 /* This is where the display name starts in the URL, now replace this
2061 part with the encoded name. TODO: This method of replacing the host
2062 name is rather crude as I believe there's a slight risk that the
2063 user has entered a user name or password that contain the host name
2065 size_t currlen = strlen(conn->host.dispname);
2066 size_t newlen = strlen(conn->host.name);
2067 size_t urllen = strlen(url);
2071 newurl = malloc(urllen + newlen - currlen + 1);
2073 /* copy the part before the host name */
2074 memcpy(newurl, url, ptr - url);
2075 /* append the new host name instead of the old */
2076 memcpy(newurl + (ptr - url), conn->host.name, newlen);
2077 /* append the piece after the host name */
2078 memcpy(newurl + newlen + (ptr - url),
2079 ptr + currlen, /* copy the trailing zero byte too */
2080 urllen - (ptr-url) - currlen + 1);
2081 if(data->change.url_alloc) {
2082 Curl_safefree(data->change.url);
2083 data->change.url_alloc = FALSE;
2085 data->change.url = newurl;
2086 data->change.url_alloc = TRUE;
2089 return CURLE_OUT_OF_MEMORY;
2092 ppath = data->change.url;
2093 if(checkprefix("ftp://", ppath)) {
2094 if(data->set.proxy_transfer_mode) {
2095 /* when doing ftp, append ;type=<a|i> if not present */
2096 char *type = strstr(ppath, ";type=");
2097 if(type && type[6] && type[7] == 0) {
2098 switch (Curl_raw_toupper(type[6])) {
2108 char *p = ftp_typecode;
2109 /* avoid sending invalid URLs like ftp://example.com;type=i if the
2110 * user specified ftp://example.com without the slash */
2111 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
2114 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
2115 data->set.prefer_ascii ? 'a' : 'i');
2118 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
2119 paste_ftp_userpwd = TRUE;
2122 #endif /* CURL_DISABLE_PROXY */
2124 if(HTTPREQ_POST_FORM == httpreq) {
2125 /* we must build the whole post sequence first, so that we have a size of
2126 the whole transfer before we start to send it */
2127 result = Curl_getformdata(data, &http->sendit, data->set.httppost,
2128 Curl_checkheaders(conn, "Content-Type:"),
2134 http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n";
2136 if(( (HTTPREQ_POST == httpreq) ||
2137 (HTTPREQ_POST_FORM == httpreq) ||
2138 (HTTPREQ_PUT == httpreq) ) &&
2139 data->state.resume_from) {
2140 /**********************************************************************
2141 * Resuming upload in HTTP means that we PUT or POST and that we have
2142 * got a resume_from value set. The resume value has already created
2143 * a Range: header that will be passed along. We need to "fast forward"
2144 * the file the given number of bytes and decrease the assume upload
2145 * file size before we continue this venture in the dark lands of HTTP.
2146 *********************************************************************/
2148 if(data->state.resume_from < 0 ) {
2150 * This is meant to get the size of the present remote-file by itself.
2151 * We don't support this now. Bail out!
2153 data->state.resume_from = 0;
2156 if(data->state.resume_from && !data->state.this_is_a_follow) {
2157 /* do we still game? */
2159 /* Now, let's read off the proper amount of bytes from the
2161 if(conn->seek_func) {
2162 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2166 if(seekerr != CURL_SEEKFUNC_OK) {
2167 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2168 failf(data, "Could not seek stream");
2169 return CURLE_READ_ERROR;
2171 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2173 curl_off_t passed=0;
2175 size_t readthisamountnow =
2176 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
2177 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
2179 size_t actuallyread =
2180 data->state.fread_func(data->state.buffer, 1, readthisamountnow,
2183 passed += actuallyread;
2184 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2185 /* this checks for greater-than only to make sure that the
2186 CURL_READFUNC_ABORT return code still aborts */
2187 failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2188 " bytes from the input", passed);
2189 return CURLE_READ_ERROR;
2191 } while(passed < data->state.resume_from);
2195 /* now, decrease the size of the read */
2196 if(data->state.infilesize>0) {
2197 data->state.infilesize -= data->state.resume_from;
2199 if(data->state.infilesize <= 0) {
2200 failf(data, "File already completely uploaded");
2201 return CURLE_PARTIAL_FILE;
2204 /* we've passed, proceed as normal */
2207 if(data->state.use_range) {
2209 * A range is selected. We use different headers whether we're downloading
2210 * or uploading and we always let customized headers override our internal
2211 * ones if any such are specified.
2213 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2214 !Curl_checkheaders(conn, "Range:")) {
2215 /* if a line like this was already allocated, free the previous one */
2216 free(conn->allocptr.rangeline);
2217 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2220 else if((httpreq != HTTPREQ_GET) &&
2221 !Curl_checkheaders(conn, "Content-Range:")) {
2223 /* if a line like this was already allocated, free the previous one */
2224 free(conn->allocptr.rangeline);
2226 if(data->set.set_resume_from < 0) {
2227 /* Upload resume was asked for, but we don't know the size of the
2228 remote part so we tell the server (and act accordingly) that we
2229 upload the whole file (again) */
2230 conn->allocptr.rangeline =
2231 aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2232 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2233 data->state.infilesize - 1, data->state.infilesize);
2236 else if(data->state.resume_from) {
2237 /* This is because "resume" was selected */
2238 curl_off_t total_expected_size=
2239 data->state.resume_from + data->state.infilesize;
2240 conn->allocptr.rangeline =
2241 aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2242 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2243 data->state.range, total_expected_size-1,
2244 total_expected_size);
2247 /* Range was selected and then we just pass the incoming range and
2248 append total size */
2249 conn->allocptr.rangeline =
2250 aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2251 data->state.range, data->state.infilesize);
2253 if(!conn->allocptr.rangeline)
2254 return CURLE_OUT_OF_MEMORY;
2258 /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2260 httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
2262 /* initialize a dynamic send-buffer */
2263 req_buffer = Curl_add_buffer_init();
2266 return CURLE_OUT_OF_MEMORY;
2268 /* add the main request stuff */
2269 /* GET/HEAD/POST/PUT */
2270 result = Curl_add_bufferf(req_buffer, "%s ", request);
2275 if(paste_ftp_userpwd)
2276 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2277 conn->user, conn->passwd,
2278 ppath + sizeof("ftp://") - 1);
2280 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2285 Curl_add_bufferf(req_buffer,
2286 "%s" /* ftp typecode (;type=x) */
2287 " HTTP/%s\r\n" /* HTTP version */
2289 "%s" /* proxyuserpwd */
2292 "%s" /* user agent */
2295 "%s" /* accept-encoding */
2297 "%s",/* transfer-encoding */
2301 (conn->allocptr.host?conn->allocptr.host:""),
2302 conn->allocptr.proxyuserpwd?
2303 conn->allocptr.proxyuserpwd:"",
2304 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2305 (data->state.use_range && conn->allocptr.rangeline)?
2306 conn->allocptr.rangeline:"",
2307 (data->set.str[STRING_USERAGENT] &&
2308 *data->set.str[STRING_USERAGENT] &&
2309 conn->allocptr.uagent)?
2310 conn->allocptr.uagent:"",
2311 http->p_accept?http->p_accept:"",
2312 conn->allocptr.te?conn->allocptr.te:"",
2313 (data->set.str[STRING_ENCODING] &&
2314 *data->set.str[STRING_ENCODING] &&
2315 conn->allocptr.accept_encoding)?
2316 conn->allocptr.accept_encoding:"",
2317 (data->change.referer && conn->allocptr.ref)?
2318 conn->allocptr.ref:"" /* Referer: <data> */,
2322 /* clear userpwd to avoid re-using credentials from re-used connections */
2323 Curl_safefree(conn->allocptr.userpwd);
2326 * Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
2327 * with the connection and shouldn't be repeated over it either.
2329 switch (data->state.authproxy.picked) {
2330 case CURLAUTH_NEGOTIATE:
2332 case CURLAUTH_NTLM_WB:
2333 Curl_safefree(conn->allocptr.proxyuserpwd);
2340 if(!(conn->handler->flags&PROTOPT_SSL) &&
2341 conn->httpversion != 20 &&
2342 (data->set.httpversion == CURL_HTTP_VERSION_2)) {
2343 /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
2345 result = Curl_http2_request_upgrade(req_buffer, conn);
2350 #if !defined(CURL_DISABLE_COOKIES)
2351 if(data->cookies || addcookies) {
2352 struct Cookie *co=NULL; /* no cookies from start */
2356 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2357 co = Curl_cookie_getlist(data->cookies,
2358 conn->allocptr.cookiehost?
2359 conn->allocptr.cookiehost:host,
2361 (conn->handler->protocol&CURLPROTO_HTTPS)?
2363 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2366 struct Cookie *store=co;
2367 /* now loop through all cookies that matched */
2371 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2375 result = Curl_add_bufferf(req_buffer,
2376 "%s%s=%s", count?"; ":"",
2377 co->name, co->value);
2382 co = co->next; /* next cookie please */
2384 Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2386 if(addcookies && !result) {
2388 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2390 result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
2395 if(count && !result)
2396 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2403 result = Curl_add_timecondition(data, req_buffer);
2407 result = Curl_add_custom_headers(conn, FALSE, req_buffer);
2411 http->postdata = NULL; /* nothing to post at this point */
2412 Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
2414 /* If 'authdone' is FALSE, we must not set the write socket index to the
2415 Curl_transfer() call below, as we're not ready to actually upload any
2420 case HTTPREQ_POST_FORM:
2421 if(!http->sendit || conn->bits.authneg) {
2422 /* nothing to post! */
2423 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2427 result = Curl_add_buffer_send(req_buffer, conn,
2428 &data->info.request_size, 0, FIRSTSOCKET);
2430 failf(data, "Failed sending POST request");
2432 /* setup variables for the upcoming transfer */
2433 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2438 if(Curl_FormInit(&http->form, http->sendit)) {
2439 failf(data, "Internal HTTP POST error!");
2440 return CURLE_HTTP_POST_ERROR;
2443 /* Get the currently set callback function pointer and store that in the
2444 form struct since we might want the actual user-provided callback later
2445 on. The data->set.fread_func pointer itself will be changed for the
2446 multipart case to the function that returns a multipart formatted
2448 http->form.fread_func = data->state.fread_func;
2450 /* Set the read function to read from the generated form data */
2451 data->state.fread_func = (curl_read_callback)Curl_FormReader;
2452 data->state.in = &http->form;
2454 http->sending = HTTPSEND_BODY;
2456 if(!data->req.upload_chunky &&
2457 !Curl_checkheaders(conn, "Content-Length:")) {
2458 /* only add Content-Length if not uploading chunked */
2459 result = Curl_add_bufferf(req_buffer,
2460 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2461 "\r\n", http->postsize);
2466 result = expect100(data, conn, req_buffer);
2472 /* Get Content-Type: line from Curl_formpostheader.
2475 size_t linelength=0;
2476 contentType = Curl_formpostheader((void *)&http->form,
2479 failf(data, "Could not get Content-Type header line!");
2480 return CURLE_HTTP_POST_ERROR;
2483 result = Curl_add_buffer(req_buffer, contentType, linelength);
2488 /* make the request end in a true CRLF */
2489 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2493 /* set upload size to the progress meter */
2494 Curl_pgrsSetUploadSize(data, http->postsize);
2496 /* fire away the whole request to the server */
2497 result = Curl_add_buffer_send(req_buffer, conn,
2498 &data->info.request_size, 0, FIRSTSOCKET);
2500 failf(data, "Failed sending POST request");
2502 /* setup variables for the upcoming transfer */
2503 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2504 &http->readbytecount, FIRSTSOCKET,
2505 &http->writebytecount);
2508 Curl_formclean(&http->sendit); /* free that whole lot */
2512 /* convert the form data */
2513 result = Curl_convert_form(data, http->sendit);
2515 Curl_formclean(&http->sendit); /* free that whole lot */
2521 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2523 if(conn->bits.authneg)
2526 postsize = data->state.infilesize;
2528 if((postsize != -1) && !data->req.upload_chunky &&
2529 !Curl_checkheaders(conn, "Content-Length:")) {
2530 /* only add Content-Length if not uploading chunked */
2531 result = Curl_add_bufferf(req_buffer,
2532 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2539 result = expect100(data, conn, req_buffer);
2544 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2548 /* set the upload size to the progress meter */
2549 Curl_pgrsSetUploadSize(data, postsize);
2551 /* this sends the buffer and frees all the buffer resources */
2552 result = Curl_add_buffer_send(req_buffer, conn,
2553 &data->info.request_size, 0, FIRSTSOCKET);
2555 failf(data, "Failed sending PUT request");
2557 /* prepare for transfer */
2558 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2559 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2560 postsize?&http->writebytecount:NULL);
2566 /* this is the simple POST, using x-www-form-urlencoded style */
2568 if(conn->bits.authneg)
2571 /* figure out the size of the postfields */
2572 postsize = (data->state.infilesize != -1)?
2573 data->state.infilesize:
2574 (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2577 /* We only set Content-Length and allow a custom Content-Length if
2578 we don't upload data chunked, as RFC2616 forbids us to set both
2579 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2580 if((postsize != -1) && !data->req.upload_chunky &&
2581 !Curl_checkheaders(conn, "Content-Length:")) {
2582 /* we allow replacing this header if not during auth negotiation,
2583 although it isn't very wise to actually set your own */
2584 result = Curl_add_bufferf(req_buffer,
2585 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2591 if(!Curl_checkheaders(conn, "Content-Type:")) {
2592 result = Curl_add_bufferf(req_buffer,
2593 "Content-Type: application/"
2594 "x-www-form-urlencoded\r\n");
2599 /* For really small posts we don't use Expect: headers at all, and for
2600 the somewhat bigger ones we allow the app to disable it. Just make
2601 sure that the expect100header is always set to the preferred value
2603 ptr = Curl_checkheaders(conn, "Expect:");
2605 data->state.expect100header =
2606 Curl_compareheader(ptr, "Expect:", "100-continue");
2608 else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2609 result = expect100(data, conn, req_buffer);
2614 data->state.expect100header = FALSE;
2616 if(data->set.postfields) {
2618 /* In HTTP2, we send request body in DATA frame regardless of
2620 if(conn->httpversion != 20 &&
2621 !data->state.expect100header &&
2622 (postsize < MAX_INITIAL_POST_SIZE)) {
2623 /* if we don't use expect: 100 AND
2624 postsize is less than MAX_INITIAL_POST_SIZE
2626 then append the post data to the HTTP request header. This limit
2627 is no magic limit but only set to prevent really huge POSTs to
2628 get the data duplicated with malloc() and family. */
2630 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2634 if(!data->req.upload_chunky) {
2635 /* We're not sending it 'chunked', append it to the request
2636 already now to reduce the number if send() calls */
2637 result = Curl_add_buffer(req_buffer, data->set.postfields,
2639 included_body = postsize;
2643 /* Append the POST data chunky-style */
2644 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2646 result = Curl_add_buffer(req_buffer, data->set.postfields,
2649 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2650 included_body = postsize + 2;
2654 result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
2660 /* Make sure the progress information is accurate */
2661 Curl_pgrsSetUploadSize(data, postsize);
2664 /* A huge POST coming up, do data separate from the request */
2665 http->postsize = postsize;
2666 http->postdata = data->set.postfields;
2668 http->sending = HTTPSEND_BODY;
2670 data->state.fread_func = (curl_read_callback)readmoredata;
2671 data->state.in = (void *)conn;
2673 /* set the upload size to the progress meter */
2674 Curl_pgrsSetUploadSize(data, http->postsize);
2676 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2682 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2686 if(data->req.upload_chunky && conn->bits.authneg) {
2687 /* Chunky upload is selected and we're negotiating auth still, send
2689 result = Curl_add_buffer(req_buffer,
2690 "\x30\x0d\x0a\x0d\x0a", 5);
2696 else if(data->state.infilesize) {
2697 /* set the upload size to the progress meter */
2698 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2700 /* set the pointer to mark that we will send the post body using the
2701 read callback, but only if we're not in authenticate
2703 if(!conn->bits.authneg) {
2704 http->postdata = (char *)&http->postdata;
2705 http->postsize = postsize;
2709 /* issue the request */
2710 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2711 (size_t)included_body, FIRSTSOCKET);
2714 failf(data, "Failed sending HTTP POST request");
2716 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2717 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2718 http->postdata?&http->writebytecount:NULL);
2722 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2726 /* issue the request */
2727 result = Curl_add_buffer_send(req_buffer, conn,
2728 &data->info.request_size, 0, FIRSTSOCKET);
2731 failf(data, "Failed sending HTTP request");
2733 /* HTTP GET/HEAD download: */
2734 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2735 http->postdata?FIRSTSOCKET:-1,
2736 http->postdata?&http->writebytecount:NULL);
2741 if(http->writebytecount) {
2742 /* if a request-body has been sent off, we make sure this progress is noted
2744 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2745 if(Curl_pgrsUpdate(conn))
2746 result = CURLE_ABORTED_BY_CALLBACK;
2748 if(http->writebytecount >= postsize) {
2749 /* already sent the entire request body, mark the "upload" as
2751 infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
2752 " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
2753 http->writebytecount, postsize);
2754 data->req.upload_done = TRUE;
2755 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2756 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2766 * Returns TRUE if member of the list matches prefix of string
2769 checkhttpprefix(struct SessionHandle *data,
2772 struct curl_slist *head = data->set.http200aliases;
2774 #ifdef CURL_DOES_CONVERSIONS
2775 /* convert from the network encoding using a scratch area */
2776 char *scratch = strdup(s);
2777 if(NULL == scratch) {
2778 failf (data, "Failed to allocate memory for conversion!");
2779 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2781 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2782 /* Curl_convert_from_network calls failf if unsuccessful */
2784 return FALSE; /* can't return CURLE_foobar so return FALSE */
2787 #endif /* CURL_DOES_CONVERSIONS */
2790 if(checkprefix(head->data, s)) {
2797 if(!rc && (checkprefix("HTTP/", s)))
2800 #ifdef CURL_DOES_CONVERSIONS
2802 #endif /* CURL_DOES_CONVERSIONS */
2806 #ifndef CURL_DISABLE_RTSP
2808 checkrtspprefix(struct SessionHandle *data,
2812 #ifdef CURL_DOES_CONVERSIONS
2813 /* convert from the network encoding using a scratch area */
2814 char *scratch = strdup(s);
2815 if(NULL == scratch) {
2816 failf (data, "Failed to allocate memory for conversion!");
2817 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2819 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2820 /* Curl_convert_from_network calls failf if unsuccessful */
2822 return FALSE; /* can't return CURLE_foobar so return FALSE */
2826 (void)data; /* unused */
2827 #endif /* CURL_DOES_CONVERSIONS */
2828 if(checkprefix("RTSP/", s))
2833 #endif /* CURL_DISABLE_RTSP */
2836 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2839 #ifndef CURL_DISABLE_RTSP
2840 if(conn->handler->protocol & CURLPROTO_RTSP)
2841 return checkrtspprefix(data, s);
2844 #endif /* CURL_DISABLE_RTSP */
2846 return checkhttpprefix(data, s);
2850 * header_append() copies a chunk of data to the end of the already received
2851 * header. We make sure that the full string fit in the allocated header
2852 * buffer, or else we enlarge it.
2854 static CURLcode header_append(struct SessionHandle *data,
2855 struct SingleRequest *k,
2858 if(k->hbuflen + length >= data->state.headersize) {
2859 /* We enlarge the header buffer as it is too small */
2864 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2865 /* The reason to have a max limit for this is to avoid the risk of a bad
2866 server feeding libcurl with a never-ending header that will cause
2867 reallocs infinitely */
2868 failf (data, "Avoided giant realloc for header (max is %d)!",
2869 CURL_MAX_HTTP_HEADER);
2870 return CURLE_OUT_OF_MEMORY;
2873 newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2874 hbufp_index = k->hbufp - data->state.headerbuff;
2875 newbuff = realloc(data->state.headerbuff, newsize);
2877 failf (data, "Failed to alloc memory for big header!");
2878 return CURLE_OUT_OF_MEMORY;
2880 data->state.headersize=newsize;
2881 data->state.headerbuff = newbuff;
2882 k->hbufp = data->state.headerbuff + hbufp_index;
2884 memcpy(k->hbufp, k->str_start, length);
2886 k->hbuflen += length;
2892 static void print_http_error(struct SessionHandle *data)
2894 struct SingleRequest *k = &data->req;
2897 /* make sure that data->req.p points to the HTTP status line */
2898 if(!strncmp(beg, "HTTP", 4)) {
2900 /* skip to HTTP status code */
2901 beg = strchr(beg, ' ');
2904 /* find trailing CR */
2905 char end_char = '\r';
2906 char *end = strchr(beg, end_char);
2908 /* try to find LF (workaround for non-compliant HTTP servers) */
2910 end = strchr(beg, end_char);
2914 /* temporarily replace CR or LF by NUL and print the error message */
2916 failf(data, "The requested URL returned error: %s", beg);
2918 /* restore the previously replaced CR or LF */
2925 /* fall-back to printing the HTTP status code only */
2926 failf(data, "The requested URL returned error: %d", k->httpcode);
2930 * Read any HTTP header lines from the server and pass them to the client app.
2932 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2933 struct connectdata *conn,
2938 struct SingleRequest *k = &data->req;
2940 /* header line within buffer loop */
2946 /* str_start is start of line within buf */
2947 k->str_start = k->str;
2949 /* data is in network encoding so use 0x0a instead of '\n' */
2950 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2953 /* Not a complete header line within buffer, append the data to
2954 the end of the headerbuff. */
2955 result = header_append(data, k, *nread);
2959 if(!k->headerline && (k->hbuflen>5)) {
2960 /* make a first check that this looks like a protocol header */
2961 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2962 /* this is not the beginning of a protocol first header line */
2964 k->badheader = HEADER_ALLBAD;
2969 break; /* read more and try again */
2972 /* decrease the size of the remaining (supposed) header line */
2973 rest_length = (k->end_ptr - k->str)+1;
2974 *nread -= (ssize_t)rest_length;
2976 k->str = k->end_ptr + 1; /* move past new line */
2978 full_length = k->str - k->str_start;
2980 result = header_append(data, k, full_length);
2984 k->end_ptr = k->hbufp;
2985 k->p = data->state.headerbuff;
2988 * We now have a FULL header line that p points to
2991 if(!k->headerline) {
2992 /* the first read header */
2993 if((k->hbuflen>5) &&
2994 !checkprotoprefix(data, conn, data->state.headerbuff)) {
2995 /* this is not the beginning of a protocol first header line */
2998 /* since there's more, this is a partial bad header */
2999 k->badheader = HEADER_PARTHEADER;
3001 /* this was all we read so it's all a bad header */
3002 k->badheader = HEADER_ALLBAD;
3003 *nread = (ssize_t)rest_length;
3009 /* headers are in network encoding so
3010 use 0x0a and 0x0d instead of '\n' and '\r' */
3011 if((0x0a == *k->p) || (0x0d == *k->p)) {
3013 /* Zero-length header line means end of headers! */
3015 #ifdef CURL_DOES_CONVERSIONS
3017 *k->p = '\r'; /* replace with CR in host encoding */
3018 k->p++; /* pass the CR byte */
3021 *k->p = '\n'; /* replace with LF in host encoding */
3022 k->p++; /* pass the LF byte */
3026 k->p++; /* pass the \r byte */
3028 k->p++; /* pass the \n byte */
3029 #endif /* CURL_DOES_CONVERSIONS */
3031 if(100 <= k->httpcode && 199 >= k->httpcode) {
3033 * We have made a HTTP PUT or POST and this is 1.1-lingo
3034 * that tells us that the server is OK with this and ready
3035 * to receive the data.
3036 * However, we'll get more headers now so we must get
3037 * back into the header-parsing state!
3040 k->headerline = 0; /* restart the header line counter */
3042 /* "A user agent MAY ignore unexpected 1xx status responses." */
3043 switch(k->httpcode) {
3045 /* if we did wait for this do enable write now! */
3047 k->exp100 = EXP100_SEND_DATA;
3048 k->keepon |= KEEP_SEND;
3052 /* Switching Protocols */
3053 if(k->upgr101 == UPGR101_REQUESTED) {
3054 infof(data, "Received 101\n");
3055 k->upgr101 = UPGR101_RECEIVED;
3057 /* switch to http2 now. The bytes after response headers
3058 are also processed here, otherwise they are lost. */
3059 result = Curl_http2_switched(conn, k->str, *nread);
3070 k->header = FALSE; /* no more header to parse! */
3072 if((k->size == -1) && !k->chunk && !conn->bits.close &&
3073 (conn->httpversion == 11) &&
3074 !(conn->handler->protocol & CURLPROTO_RTSP) &&
3075 data->set.httpreq != HTTPREQ_HEAD) {
3076 /* On HTTP 1.1, when connection is not to get closed, but no
3077 Content-Length nor Content-Encoding chunked have been
3078 received, according to RFC2616 section 4.4 point 5, we
3079 assume that the server will close the connection to
3080 signal the end of the document. */
3081 infof(data, "no chunk, no close, no size. Assume close to "
3083 connclose(conn, "HTTP: No end-of-message indicator");
3087 /* At this point we have some idea about the fate of the connection.
3088 If we are closing the connection it may result auth failure. */
3089 #if defined(USE_NTLM)
3090 if(conn->bits.close &&
3091 (((data->req.httpcode == 401) &&
3092 (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
3093 ((data->req.httpcode == 407) &&
3094 (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
3095 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
3096 data->state.authproblem = TRUE;
3101 * When all the headers have been parsed, see if we should give
3102 * up and return an error.
3104 if(http_should_fail(conn)) {
3105 failf (data, "The requested URL returned error: %d",
3107 return CURLE_HTTP_RETURNED_ERROR;
3110 /* now, only output this if the header AND body are requested:
3112 writetype = CLIENTWRITE_HEADER;
3113 if(data->set.include_header)
3114 writetype |= CLIENTWRITE_BODY;
3116 headerlen = k->p - data->state.headerbuff;
3118 result = Curl_client_write(conn, writetype,
3119 data->state.headerbuff,
3124 data->info.header_size += (long)headerlen;
3125 data->req.headerbytecount += (long)headerlen;
3127 data->req.deductheadercount =
3128 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
3130 if(!*stop_reading) {
3131 /* Curl_http_auth_act() checks what authentication methods
3132 * that are available and decides which one (if any) to
3133 * use. It will set 'newurl' if an auth method was picked. */
3134 result = Curl_http_auth_act(conn);
3139 if(k->httpcode >= 300) {
3140 if((!conn->bits.authneg) && !conn->bits.close &&
3141 !conn->bits.rewindaftersend) {
3143 * General treatment of errors when about to send data. Including :
3144 * "417 Expectation Failed", while waiting for 100-continue.
3146 * The check for close above is done simply because of something
3147 * else has already deemed the connection to get closed then
3148 * something else should've considered the big picture and we
3151 * rewindaftersend indicates that something has told libcurl to
3152 * continue sending even if it gets discarded
3155 switch(data->set.httpreq) {
3158 case HTTPREQ_POST_FORM:
3159 /* We got an error response. If this happened before the whole
3160 * request body has been sent we stop sending and mark the
3161 * connection for closure after we've read the entire response.
3163 if(!k->upload_done) {
3164 infof(data, "HTTP error before end of send, stop sending\n");
3165 connclose(conn, "Stop sending data before everything sent");
3166 k->upload_done = TRUE;
3167 k->keepon &= ~KEEP_SEND; /* don't send */
3168 if(data->state.expect100header)
3169 k->exp100 = EXP100_FAILED;
3173 default: /* default label present to avoid compiler warnings */
3179 if(conn->bits.rewindaftersend) {
3180 /* We rewind after a complete send, so thus we continue
3182 infof(data, "Keep sending data to get tossed away!\n");
3183 k->keepon |= KEEP_SEND;
3189 * really end-of-headers.
3191 * If we requested a "no body", this is a good time to get
3192 * out and return home.
3194 if(data->set.opt_no_body)
3195 *stop_reading = TRUE;
3196 #ifndef CURL_DISABLE_RTSP
3197 else if((conn->handler->protocol & CURLPROTO_RTSP) &&
3198 (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
3200 /* Respect section 4.4 of rfc2326: If the Content-Length header is
3201 absent, a length 0 must be assumed. It will prevent libcurl from
3202 hanging on DECRIBE request that got refused for whatever
3204 *stop_reading = TRUE;
3207 /* If we know the expected size of this document, we set the
3208 maximum download size to the size of the expected
3209 document or else, we won't know when to stop reading!
3211 Note that we set the download maximum even if we read a
3212 "Connection: close" header, to make sure that
3213 "Content-Length: 0" still prevents us from attempting to
3214 read the (missing) response-body.
3216 /* According to RFC2616 section 4.4, we MUST ignore
3217 Content-Length: headers if we are now receiving data
3218 using chunked Transfer-Encoding.
3221 k->maxdownload = k->size = -1;
3224 /* We do this operation even if no_body is true, since this
3225 data might be retrieved later with curl_easy_getinfo()
3226 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3228 Curl_pgrsSetDownloadSize(data, k->size);
3229 k->maxdownload = k->size;
3232 /* If max download size is *zero* (nothing) we already
3233 have nothing and can safely return ok now! */
3234 if(0 == k->maxdownload)
3235 *stop_reading = TRUE;
3238 /* we make sure that this socket isn't read more now */
3239 k->keepon &= ~KEEP_RECV;
3242 if(data->set.verbose)
3243 Curl_debug(data, CURLINFO_HEADER_IN,
3244 k->str_start, headerlen, conn);
3245 break; /* exit header line loop */
3248 /* We continue reading headers, so reset the line-based
3249 header parsing variables hbufp && hbuflen */
3250 k->hbufp = data->state.headerbuff;
3256 * Checks for special headers coming up.
3259 if(!k->headerline++) {
3260 /* This is the first header, it MUST be the error code line
3261 or else we consider this to be the body right away! */
3262 int httpversion_major;
3263 int rtspversion_major;
3265 #ifdef CURL_DOES_CONVERSIONS
3266 #define HEADER1 scratch
3267 #define SCRATCHSIZE 21
3269 char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
3270 /* We can't really convert this yet because we
3271 don't know if it's the 1st header line or the body.
3272 So we do a partial conversion into a scratch area,
3273 leaving the data at k->p as-is.
3275 strncpy(&scratch[0], k->p, SCRATCHSIZE);
3276 scratch[SCRATCHSIZE] = 0; /* null terminate */
3277 res = Curl_convert_from_network(data,
3281 /* Curl_convert_from_network calls failf if unsuccessful */
3284 #define HEADER1 k->p /* no conversion needed, just use k->p */
3285 #endif /* CURL_DOES_CONVERSIONS */
3287 if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
3289 * https://tools.ietf.org/html/rfc7230#section-3.1.2
3291 * The reponse code is always a three-digit number in HTTP as the spec
3292 * says. We try to allow any number here, but we cannot make
3293 * guarantees on future behaviors since it isn't within the protocol.
3295 nc = sscanf(HEADER1,
3301 conn->httpversion += 10 * httpversion_major;
3303 if(k->upgr101 == UPGR101_RECEIVED) {
3304 /* supposedly upgraded to http2 now */
3305 if(conn->httpversion != 20)
3306 infof(data, "Lying server, not serving HTTP/2\n");
3310 /* this is the real world, not a Nirvana
3311 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3313 nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3314 conn->httpversion = 10;
3316 /* If user has set option HTTP200ALIASES,
3317 compare header line against list of aliases
3320 if(checkhttpprefix(data, k->p)) {
3323 conn->httpversion = 10;
3328 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3329 nc = sscanf(HEADER1,
3335 conn->rtspversion += 10 * rtspversion_major;
3336 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3339 /* TODO: do we care about the other cases here? */
3345 data->info.httpcode = k->httpcode;
3347 data->info.httpversion = conn->httpversion;
3348 if(!data->state.httpversion ||
3349 data->state.httpversion > conn->httpversion)
3350 /* store the lowest server version we encounter */
3351 data->state.httpversion = conn->httpversion;
3354 * This code executes as part of processing the header. As a
3355 * result, it's not totally clear how to interpret the
3356 * response code yet as that depends on what other headers may
3357 * be present. 401 and 407 may be errors, but may be OK
3358 * depending on how authentication is working. Other codes
3359 * are definitely errors, so give up here.
3361 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3362 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3363 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3365 if(data->state.resume_from &&
3366 (data->set.httpreq==HTTPREQ_GET) &&
3367 (k->httpcode == 416)) {
3368 /* "Requested Range Not Satisfiable", just proceed and
3369 pretend this is no error */
3372 /* serious error, go home! */
3373 print_http_error(data);
3374 return CURLE_HTTP_RETURNED_ERROR;
3378 if(conn->httpversion == 10) {
3379 /* Default action for HTTP/1.0 must be to close, unless
3380 we get one of those fancy headers that tell us the
3381 server keeps it open for us! */
3382 infof(data, "HTTP 1.0, assume close after body\n");
3383 connclose(conn, "HTTP/1.0 close after body");
3385 else if(conn->httpversion == 20 ||
3386 (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
3387 DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
3389 /* HTTP/2 cannot blacklist multiplexing since it is a core
3390 functionality of the protocol */
3391 conn->bundle->multiuse = BUNDLE_MULTIPLEX;
3393 else if(conn->httpversion >= 11 &&
3394 !conn->bits.close) {
3395 /* If HTTP version is >= 1.1 and connection is persistent
3396 server supports pipelining. */
3398 "HTTP 1.1 or later with persistent connection, "
3399 "pipelining supported\n"));
3400 /* Activate pipelining if needed */
3402 if(!Curl_pipeline_site_blacklisted(data, conn))
3403 conn->bundle->multiuse = BUNDLE_PIPELINING;
3407 switch(k->httpcode) {
3409 /* (quote from RFC2616, section 10.2.5): The server has
3410 * fulfilled the request but does not need to return an
3411 * entity-body ... The 204 response MUST NOT include a
3412 * message-body, and thus is always terminated by the first
3413 * empty line after the header fields. */
3416 /* (quote from RFC2616, section 10.3.5): The 304 response
3417 * MUST NOT contain a message-body, and thus is always
3418 * terminated by the first empty line after the header
3420 if(data->set.timecondition)
3421 data->info.timecond = TRUE;
3424 k->ignorecl = TRUE; /* ignore Content-Length headers */
3432 k->header = FALSE; /* this is not a header line */
3437 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3438 /* Curl_convert_from_network calls failf if unsuccessful */
3442 /* Check for Content-Length: header lines to get size */
3443 if(!k->ignorecl && !data->set.ignorecl &&
3444 checkprefix("Content-Length:", k->p)) {
3445 curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3446 if(data->set.max_filesize &&
3447 contentlength > data->set.max_filesize) {
3448 failf(data, "Maximum file size exceeded");
3449 return CURLE_FILESIZE_EXCEEDED;
3451 if(contentlength >= 0) {
3452 k->size = contentlength;
3453 k->maxdownload = k->size;
3454 /* we set the progress download size already at this point
3455 just to make it easier for apps/callbacks to extract this
3456 info as soon as possible */
3457 Curl_pgrsSetDownloadSize(data, k->size);
3460 /* Negative Content-Length is really odd, and we know it
3461 happens for example when older Apache servers send large
3463 connclose(conn, "negative content-length");
3464 infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
3465 ", closing after transfer\n", contentlength);
3468 /* check for Content-Type: header lines to get the MIME-type */
3469 else if(checkprefix("Content-Type:", k->p)) {
3470 char *contenttype = Curl_copy_header_value(k->p);
3472 return CURLE_OUT_OF_MEMORY;
3474 /* ignore empty data */
3477 Curl_safefree(data->info.contenttype);
3478 data->info.contenttype = contenttype;
3481 else if(checkprefix("Server:", k->p)) {
3482 if(conn->httpversion < 20) {
3483 /* only do this for non-h2 servers */
3484 char *server_name = Curl_copy_header_value(k->p);
3486 /* Turn off pipelining if the server version is blacklisted */
3487 if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
3488 if(Curl_pipeline_server_blacklisted(data, server_name))
3489 conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
3494 else if((conn->httpversion == 10) &&
3495 conn->bits.httpproxy &&
3496 Curl_compareheader(k->p,
3497 "Proxy-Connection:", "keep-alive")) {
3499 * When a HTTP/1.0 reply comes when using a proxy, the
3500 * 'Proxy-Connection: keep-alive' line tells us the
3501 * connection will be kept alive for our pleasure.
3502 * Default action for 1.0 is to close.
3504 connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
3505 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3507 else if((conn->httpversion == 11) &&
3508 conn->bits.httpproxy &&
3509 Curl_compareheader(k->p,
3510 "Proxy-Connection:", "close")) {
3512 * We get a HTTP/1.1 response from a proxy and it says it'll
3513 * close down after this transfer.
3515 connclose(conn, "Proxy-Connection: asked to close after done");
3516 infof(data, "HTTP/1.1 proxy connection set close!\n");
3518 else if((conn->httpversion == 10) &&
3519 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3521 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3522 * tells us the connection will be kept alive for our
3523 * pleasure. Default action for 1.0 is to close.
3525 * [RFC2068, section 19.7.1] */
3526 connkeep(conn, "Connection keep-alive");
3527 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3529 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3531 * [RFC 2616, section 8.1.2.1]
3532 * "Connection: close" is HTTP/1.1 language and means that
3533 * the connection will close when this request has been
3536 connclose(conn, "Connection: close used");
3538 else if(checkprefix("Transfer-Encoding:", k->p)) {
3539 /* One or more encodings. We check for chunked and/or a compression
3542 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3543 * means that the server will send a series of "chunks". Each
3544 * chunk starts with line with info (including size of the
3545 * coming block) (terminated with CRLF), then a block of data
3546 * with the previously mentioned size. There can be any amount
3547 * of chunks, and a chunk-data set to zero signals the
3552 /* Find the first non-space letter */
3556 /* skip whitespaces and commas */
3557 while(*start && (ISSPACE(*start) || (*start == ',')))
3560 if(checkprefix("chunked", start)) {
3561 k->chunk = TRUE; /* chunks coming our way */
3563 /* init our chunky engine */
3564 Curl_httpchunk_init(conn);
3569 if(k->auto_decoding)
3570 /* TODO: we only support the first mentioned compression for now */
3573 if(checkprefix("identity", start)) {
3574 k->auto_decoding = IDENTITY;
3577 else if(checkprefix("deflate", start)) {
3578 k->auto_decoding = DEFLATE;
3581 else if(checkprefix("gzip", start)) {
3582 k->auto_decoding = GZIP;
3585 else if(checkprefix("x-gzip", start)) {
3586 k->auto_decoding = GZIP;
3596 else if(checkprefix("Content-Encoding:", k->p) &&
3597 data->set.str[STRING_ENCODING]) {
3599 * Process Content-Encoding. Look for the values: identity,
3600 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3601 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3602 * 2616). zlib cannot handle compress. However, errors are
3603 * handled further down when the response body is processed
3607 /* Find the first non-space letter */
3609 while(*start && ISSPACE(*start))
3612 /* Record the content-encoding for later use */
3613 if(checkprefix("identity", start))
3614 k->auto_decoding = IDENTITY;
3615 else if(checkprefix("deflate", start))
3616 k->auto_decoding = DEFLATE;
3617 else if(checkprefix("gzip", start)
3618 || checkprefix("x-gzip", start))
3619 k->auto_decoding = GZIP;
3621 else if(checkprefix("Content-Range:", k->p)) {
3622 /* Content-Range: bytes [num]-
3623 Content-Range: bytes: [num]-
3624 Content-Range: [num]-
3625 Content-Range: [asterisk]/[total]
3627 The second format was added since Sun's webserver
3628 JavaWebServer/1.1.1 obviously sends the header this way!
3629 The third added since some servers use that!
3630 The forth means the requested range was unsatisfied.
3633 char *ptr = k->p + 14;
3635 /* Move forward until first digit or asterisk */
3636 while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
3639 /* if it truly stopped on a digit */
3641 k->offset = curlx_strtoofft(ptr, NULL, 10);
3643 if(data->state.resume_from == k->offset)
3644 /* we asked for a resume and we got it */
3645 k->content_range = TRUE;
3648 data->state.resume_from = 0; /* get everything */
3650 #if !defined(CURL_DISABLE_COOKIES)
3651 else if(data->cookies &&
3652 checkprefix("Set-Cookie:", k->p)) {
3653 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3654 CURL_LOCK_ACCESS_SINGLE);
3655 Curl_cookie_add(data,
3656 data->cookies, TRUE, k->p+11,
3657 /* If there is a custom-set Host: name, use it
3658 here, or else use real peer host name. */
3659 conn->allocptr.cookiehost?
3660 conn->allocptr.cookiehost:conn->host.name,
3662 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3665 else if(checkprefix("Last-Modified:", k->p) &&
3666 (data->set.timecondition || data->set.get_filetime) ) {
3667 time_t secs=time(NULL);
3668 k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3670 if(data->set.get_filetime)
3671 data->info.filetime = (long)k->timeofdoc;
3673 else if((checkprefix("WWW-Authenticate:", k->p) &&
3674 (401 == k->httpcode)) ||
3675 (checkprefix("Proxy-authenticate:", k->p) &&
3676 (407 == k->httpcode))) {
3678 bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3679 char *auth = Curl_copy_header_value(k->p);
3681 return CURLE_OUT_OF_MEMORY;
3683 result = Curl_http_input_auth(conn, proxy, auth);
3690 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3691 checkprefix("Location:", k->p) &&
3692 !data->req.location) {
3693 /* this is the URL that the server advises us to use instead */
3694 char *location = Curl_copy_header_value(k->p);
3696 return CURLE_OUT_OF_MEMORY;
3698 /* ignore empty data */
3701 data->req.location = location;
3703 if(data->set.http_follow_location) {
3704 DEBUGASSERT(!data->req.newurl);
3705 data->req.newurl = strdup(data->req.location); /* clone */
3706 if(!data->req.newurl)
3707 return CURLE_OUT_OF_MEMORY;
3709 /* some cases of POST and PUT etc needs to rewind the data
3710 stream at this point */
3711 result = http_perhapsrewind(conn);
3717 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3718 result = Curl_rtsp_parseheader(conn, k->p);
3724 * End of header-checks. Write them to the client.
3727 writetype = CLIENTWRITE_HEADER;
3728 if(data->set.include_header)
3729 writetype |= CLIENTWRITE_BODY;
3731 if(data->set.verbose)
3732 Curl_debug(data, CURLINFO_HEADER_IN,
3733 k->p, (size_t)k->hbuflen, conn);
3735 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3739 data->info.header_size += (long)k->hbuflen;
3740 data->req.headerbytecount += (long)k->hbuflen;
3742 /* reset hbufp pointer && hbuflen */
3743 k->hbufp = data->state.headerbuff;
3746 while(!*stop_reading && *k->str); /* header line within buffer */
3748 /* We might have reached the end of the header part here, but
3749 there might be a non-header part left in the end of the read
3755 #endif /* CURL_DISABLE_HTTP */