1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2015, 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 "vauth/vauth.h"
58 #include "vtls/vtls.h"
59 #include "http_digest.h"
60 #include "http_ntlm.h"
61 #include "curl_ntlm_wb.h"
62 #include "http_negotiate.h"
68 #include "parsedate.h" /* for the week day and month names */
69 #include "strtoofft.h"
72 #include "content_encoding.h"
73 #include "http_proxy.h"
75 #include "non-ascii.h"
76 #include "conncache.h"
81 /* The last 3 #include files should be in this order */
82 #include "curl_printf.h"
83 #include "curl_memory.h"
87 * Forward declarations.
90 static int http_getsock_do(struct connectdata *conn,
93 static int http_should_fail(struct connectdata *conn);
96 static CURLcode https_connecting(struct connectdata *conn, bool *done);
97 static int https_getsock(struct connectdata *conn,
101 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
105 * HTTP handler interface.
107 const struct Curl_handler Curl_handler_http = {
109 Curl_http_setup_conn, /* setup_connection */
110 Curl_http, /* do_it */
111 Curl_http_done, /* done */
112 ZERO_NULL, /* do_more */
113 Curl_http_connect, /* connect_it */
114 ZERO_NULL, /* connecting */
115 ZERO_NULL, /* doing */
116 ZERO_NULL, /* proto_getsock */
117 http_getsock_do, /* doing_getsock */
118 ZERO_NULL, /* domore_getsock */
119 ZERO_NULL, /* perform_getsock */
120 ZERO_NULL, /* disconnect */
121 ZERO_NULL, /* readwrite */
122 PORT_HTTP, /* defport */
123 CURLPROTO_HTTP, /* protocol */
124 PROTOPT_CREDSPERREQUEST /* flags */
129 * HTTPS handler interface.
131 const struct Curl_handler Curl_handler_https = {
132 "HTTPS", /* scheme */
133 Curl_http_setup_conn, /* setup_connection */
134 Curl_http, /* do_it */
135 Curl_http_done, /* done */
136 ZERO_NULL, /* do_more */
137 Curl_http_connect, /* connect_it */
138 https_connecting, /* connecting */
139 ZERO_NULL, /* doing */
140 https_getsock, /* proto_getsock */
141 http_getsock_do, /* doing_getsock */
142 ZERO_NULL, /* domore_getsock */
143 ZERO_NULL, /* perform_getsock */
144 ZERO_NULL, /* disconnect */
145 ZERO_NULL, /* readwrite */
146 PORT_HTTPS, /* defport */
147 CURLPROTO_HTTPS, /* protocol */
148 PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */
152 CURLcode Curl_http_setup_conn(struct connectdata *conn)
154 /* allocate the HTTP-specific struct for the Curl_easy, 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 Curl_easy *data = conn->data;
184 for(head = data->set.headers;head; head=head->next) {
185 if(Curl_raw_nequal(head->data, thisheader, thislen))
193 * checkProxyHeaders() checks the linked list of custom proxy headers
194 * if proxy headers are not available, then it will lookup into http header
197 * It takes a connectdata struct as input instead of the Curl_easy simply
198 * to know if this is a proxy request or not, as it then might check a
199 * 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 Curl_easy *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))
219 * Strip off leading and trailing whitespace from the value in the
220 * given HTTP header line and return a strdupped copy. Returns NULL in
221 * case of allocation failure. Returns an empty string if the header value
222 * consists entirely of whitespace.
224 char *Curl_copy_header_value(const char *header)
233 /* Find the end of the header name */
234 while(*header && (*header != ':'))
238 /* Skip over colon */
241 /* Find the first non-space letter */
243 while(*start && ISSPACE(*start))
246 /* data is in the host encoding so
247 use '\r' and '\n' instead of 0x0d and 0x0a */
248 end = strchr(start, '\r');
250 end = strchr(start, '\n');
252 end = strchr(start, '\0');
256 /* skip all trailing space letters */
257 while((end > start) && ISSPACE(*end))
260 /* get length of the type */
261 len = end - start + 1;
263 value = malloc(len + 1);
267 memcpy(value, start, len);
268 value[len] = 0; /* zero terminate */
274 * http_output_basic() sets up an Authorization: header (or the proxy version)
275 * for HTTP Basic authentication.
279 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
282 char *authorization = NULL;
283 struct Curl_easy *data = conn->data;
290 userp = &conn->allocptr.proxyuserpwd;
291 user = conn->proxyuser;
292 pwd = conn->proxypasswd;
295 userp = &conn->allocptr.userpwd;
300 snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
302 result = Curl_base64_encode(data,
303 data->state.buffer, strlen(data->state.buffer),
304 &authorization, &size);
309 return CURLE_REMOTE_ACCESS_DENIED;
312 *userp = aprintf("%sAuthorization: Basic %s\r\n",
313 proxy ? "Proxy-" : "",
317 return CURLE_OUT_OF_MEMORY;
322 /* pickoneauth() selects the most favourable authentication method from the
323 * ones available and the ones we want.
325 * return TRUE if one was picked
327 static bool pickoneauth(struct auth *pick)
330 /* only deal with authentication we want */
331 unsigned long avail = pick->avail & pick->want;
334 /* The order of these checks is highly relevant, as this will be the order
335 of preference in case of the existence of multiple accepted types. */
336 if(avail & CURLAUTH_NEGOTIATE)
337 pick->picked = CURLAUTH_NEGOTIATE;
338 else if(avail & CURLAUTH_DIGEST)
339 pick->picked = CURLAUTH_DIGEST;
340 else if(avail & CURLAUTH_NTLM)
341 pick->picked = CURLAUTH_NTLM;
342 else if(avail & CURLAUTH_NTLM_WB)
343 pick->picked = CURLAUTH_NTLM_WB;
344 else if(avail & CURLAUTH_BASIC)
345 pick->picked = CURLAUTH_BASIC;
347 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
350 pick->avail = CURLAUTH_NONE; /* clear it here */
356 * Curl_http_perhapsrewind()
358 * If we are doing POST or PUT {
359 * If we have more data to send {
360 * If we are doing NTLM {
361 * Keep sending since we must not disconnect
364 * If there is more than just a little data left to send, close
365 * the current connection by force.
368 * If we have sent any data {
369 * If we don't have track of all the data {
370 * call app to tell it to rewind
373 * rewind internally so that the operation can restart fine
378 static CURLcode http_perhapsrewind(struct connectdata *conn)
380 struct Curl_easy *data = conn->data;
381 struct HTTP *http = data->req.protop;
382 curl_off_t bytessent;
383 curl_off_t expectsend = -1; /* default is unknown */
386 /* If this is still NULL, we have not reach very far and we can safely
387 skip this rewinding stuff */
390 switch(data->set.httpreq) {
398 bytessent = http->writebytecount;
400 if(conn->bits.authneg) {
401 /* This is a state where we are known to be negotiating and we don't send
405 else if(!conn->bits.protoconnstart) {
406 /* HTTP CONNECT in progress: there is no body */
410 /* figure out how much data we are expected to send */
411 switch(data->set.httpreq) {
413 if(data->state.infilesize != -1)
414 expectsend = data->state.infilesize;
415 else if(data->set.postfields)
416 expectsend = (curl_off_t)strlen(data->set.postfields);
419 if(data->state.infilesize != -1)
420 expectsend = data->state.infilesize;
422 case HTTPREQ_POST_FORM:
423 expectsend = http->postsize;
430 conn->bits.rewindaftersend = FALSE; /* default */
432 if((expectsend == -1) || (expectsend > bytessent)) {
433 #if defined(USE_NTLM)
434 /* There is still data left to send */
435 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
436 (data->state.authhost.picked == CURLAUTH_NTLM) ||
437 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
438 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
439 if(((expectsend - bytessent) < 2000) ||
440 (conn->ntlm.state != NTLMSTATE_NONE) ||
441 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
442 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
443 data left to send, keep on sending. */
445 /* rewind data when completely done sending! */
446 if(!conn->bits.authneg) {
447 conn->bits.rewindaftersend = TRUE;
448 infof(data, "Rewind stream after send\n");
455 /* this is already marked to get closed */
458 infof(data, "NTLM send, close instead of sending %"
459 CURL_FORMAT_CURL_OFF_T " bytes\n",
460 (curl_off_t)(expectsend - bytessent));
464 /* This is not NTLM or many bytes left to send: close */
465 streamclose(conn, "Mid-auth HTTP and much data left to send");
466 data->req.size = 0; /* don't download any more than 0 bytes */
468 /* There still is data left to send, but this connection is marked for
469 closure so we can safely do the rewind right now */
473 /* we rewind now at once since if we already sent something */
474 return Curl_readrewind(conn);
480 * Curl_http_auth_act() gets called when all HTTP headers have been received
481 * and it checks what authentication methods that are available and decides
482 * which one (if any) to use. It will set 'newurl' if an auth method was
486 CURLcode Curl_http_auth_act(struct connectdata *conn)
488 struct Curl_easy *data = conn->data;
489 bool pickhost = FALSE;
490 bool pickproxy = FALSE;
491 CURLcode result = CURLE_OK;
493 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
494 /* this is a transient response code, ignore */
497 if(data->state.authproblem)
498 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
500 if(conn->bits.user_passwd &&
501 ((data->req.httpcode == 401) ||
502 (conn->bits.authneg && data->req.httpcode < 300))) {
503 pickhost = pickoneauth(&data->state.authhost);
505 data->state.authproblem = TRUE;
507 if(conn->bits.proxy_user_passwd &&
508 ((data->req.httpcode == 407) ||
509 (conn->bits.authneg && data->req.httpcode < 300))) {
510 pickproxy = pickoneauth(&data->state.authproxy);
512 data->state.authproblem = TRUE;
515 if(pickhost || pickproxy) {
516 /* In case this is GSS auth, the newurl field is already allocated so
517 we must make sure to free it before allocating a new one. As figured
518 out in bug #2284386 */
519 Curl_safefree(data->req.newurl);
520 data->req.newurl = strdup(data->change.url); /* clone URL */
521 if(!data->req.newurl)
522 return CURLE_OUT_OF_MEMORY;
524 if((data->set.httpreq != HTTPREQ_GET) &&
525 (data->set.httpreq != HTTPREQ_HEAD) &&
526 !conn->bits.rewindaftersend) {
527 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;
557 * Output the correct authentication header depending on the auth type
558 * and whether or not it is to a proxy.
561 output_auth_headers(struct connectdata *conn,
562 struct auth *authstatus,
567 const char *auth = NULL;
568 CURLcode result = CURLE_OK;
569 #if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
570 struct Curl_easy *data = conn->data;
573 struct negotiatedata *negdata = proxy ?
574 &data->state.proxyneg : &data->state.negotiate;
577 #ifdef CURL_DISABLE_CRYPTO_AUTH
583 negdata->state = GSS_AUTHNONE;
584 if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
585 negdata->context && !GSS_ERROR(negdata->status)) {
587 result = Curl_output_negotiate(conn, proxy);
590 authstatus->done = TRUE;
591 negdata->state = GSS_AUTHSENT;
596 if(authstatus->picked == CURLAUTH_NTLM) {
598 result = Curl_output_ntlm(conn, proxy);
604 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
605 if(authstatus->picked == CURLAUTH_NTLM_WB) {
607 result = Curl_output_ntlm_wb(conn, proxy);
613 #ifndef CURL_DISABLE_CRYPTO_AUTH
614 if(authstatus->picked == CURLAUTH_DIGEST) {
616 result = Curl_output_digest(conn,
618 (const unsigned char *)request,
619 (const unsigned char *)path);
625 if(authstatus->picked == CURLAUTH_BASIC) {
627 if((proxy && conn->bits.proxy_user_passwd &&
628 !Curl_checkProxyheaders(conn, "Proxy-authorization:")) ||
629 (!proxy && conn->bits.user_passwd &&
630 !Curl_checkheaders(conn, "Authorization:"))) {
632 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 Curl_easy *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;
739 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
740 * headers. They are dealt with both in the transfer.c main loop and in the
741 * proxy CONNECT loop.
744 CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
745 const char *auth) /* the first non-space */
748 * This resource requires authentication
750 struct Curl_easy *data = conn->data;
753 struct negotiatedata *negdata = proxy?
754 &data->state.proxyneg:&data->state.negotiate;
756 unsigned long *availp;
760 availp = &data->info.proxyauthavail;
761 authp = &data->state.authproxy;
764 availp = &data->info.httpauthavail;
765 authp = &data->state.authhost;
769 * Here we check if we want the specific single authentication (using ==) and
770 * if we do, we initiate usage of it.
772 * If the provided authentication is wanted as one out of several accepted
773 * types (using &), we OR this authentication type to the authavail
778 * ->picked is first set to the 'want' value (one or more bits) before the
779 * request is sent, and then it is again set _after_ all response 401/407
780 * headers have been received but then only to a single preferred method
786 if(checkprefix("Negotiate", auth)) {
787 if((authp->avail & CURLAUTH_NEGOTIATE) ||
788 Curl_auth_is_spnego_supported()) {
789 *availp |= CURLAUTH_NEGOTIATE;
790 authp->avail |= CURLAUTH_NEGOTIATE;
792 if(authp->picked == CURLAUTH_NEGOTIATE) {
793 if(negdata->state == GSS_AUTHSENT ||
794 negdata->state == GSS_AUTHNONE) {
795 CURLcode result = Curl_input_negotiate(conn, proxy, auth);
797 DEBUGASSERT(!data->req.newurl);
798 data->req.newurl = strdup(data->change.url);
799 if(!data->req.newurl)
800 return CURLE_OUT_OF_MEMORY;
801 data->state.authproblem = FALSE;
802 /* we received a GSS auth token and we dealt with it fine */
803 negdata->state = GSS_AUTHRECV;
806 data->state.authproblem = TRUE;
814 /* NTLM support requires the SSL crypto libs */
815 if(checkprefix("NTLM", auth)) {
816 if((authp->avail & CURLAUTH_NTLM) ||
817 (authp->avail & CURLAUTH_NTLM_WB) ||
818 Curl_auth_is_ntlm_supported()) {
819 *availp |= CURLAUTH_NTLM;
820 authp->avail |= CURLAUTH_NTLM;
822 if(authp->picked == CURLAUTH_NTLM ||
823 authp->picked == CURLAUTH_NTLM_WB) {
824 /* NTLM authentication is picked and activated */
825 CURLcode result = Curl_input_ntlm(conn, proxy, auth);
827 data->state.authproblem = FALSE;
828 #ifdef NTLM_WB_ENABLED
829 if(authp->picked == CURLAUTH_NTLM_WB) {
830 *availp &= ~CURLAUTH_NTLM;
831 authp->avail &= ~CURLAUTH_NTLM;
832 *availp |= CURLAUTH_NTLM_WB;
833 authp->avail |= CURLAUTH_NTLM_WB;
835 /* Get the challenge-message which will be passed to
836 * ntlm_auth for generating the type 3 message later */
837 while(*auth && ISSPACE(*auth))
839 if(checkprefix("NTLM", auth)) {
840 auth += strlen("NTLM");
841 while(*auth && ISSPACE(*auth))
844 if((conn->challenge_header = strdup(auth)) == NULL)
845 return CURLE_OUT_OF_MEMORY;
851 infof(data, "Authentication problem. Ignoring this.\n");
852 data->state.authproblem = TRUE;
859 #ifndef CURL_DISABLE_CRYPTO_AUTH
860 if(checkprefix("Digest", auth)) {
861 if((authp->avail & CURLAUTH_DIGEST) != 0)
862 infof(data, "Ignoring duplicate digest auth header.\n");
863 else if(Curl_auth_is_digest_supported()) {
866 *availp |= CURLAUTH_DIGEST;
867 authp->avail |= CURLAUTH_DIGEST;
869 /* We call this function on input Digest headers even if Digest
870 * authentication isn't activated yet, as we need to store the
871 * incoming data from this header in case we are going to use
873 result = Curl_input_digest(conn, proxy, auth);
875 infof(data, "Authentication problem. Ignoring this.\n");
876 data->state.authproblem = TRUE;
882 if(checkprefix("Basic", auth)) {
883 *availp |= CURLAUTH_BASIC;
884 authp->avail |= CURLAUTH_BASIC;
885 if(authp->picked == CURLAUTH_BASIC) {
886 /* We asked for Basic authentication but got a 40X back
887 anyway, which basically means our name+password isn't
889 authp->avail = CURLAUTH_NONE;
890 infof(data, "Authentication problem. Ignoring this.\n");
891 data->state.authproblem = TRUE;
895 /* there may be multiple methods on one line, so keep reading */
896 while(*auth && *auth != ',') /* read up to the next comma */
898 if(*auth == ',') /* if we're on a comma, skip it */
900 while(*auth && ISSPACE(*auth))
908 * http_should_fail() determines whether an HTTP response has gotten us
909 * into an error state or not.
911 * @param conn all information about the current connection
913 * @retval 0 communications should continue
915 * @retval 1 communications should not continue
917 static int http_should_fail(struct connectdata *conn)
919 struct Curl_easy *data;
926 httpcode = data->req.httpcode;
929 ** If we haven't been asked to fail on error,
932 if(!data->set.http_fail_on_error)
936 ** Any code < 400 is never terminal.
942 ** Any code >= 400 that's not 401 or 407 is always
945 if((httpcode != 401) && (httpcode != 407))
949 ** All we have left to deal with is 401 and 407
951 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
954 ** Examine the current authentication state to see if this
955 ** is an error. The idea is for this function to get
956 ** called after processing all the headers in a response
957 ** message. So, if we've been to asked to authenticate a
958 ** particular stage, and we've done it, we're OK. But, if
959 ** we're already completely authenticated, it's not OK to
960 ** get another 401 or 407.
962 ** It is possible for authentication to go stale such that
963 ** the client needs to reauthenticate. Once that info is
964 ** available, use it here.
968 ** Either we're not authenticating, or we're supposed to
969 ** be authenticating something else. This is an error.
971 if((httpcode == 401) && !conn->bits.user_passwd)
973 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
976 return data->state.authproblem;
980 * readmoredata() is a "fread() emulation" to provide POST and/or request
981 * data. It is used when a huge POST is to be made and the entire chunk wasn't
982 * sent in the first send(). This function will then be called from the
983 * transfer.c loop when more data is to be sent to the peer.
985 * Returns the amount of bytes it filled the buffer with.
987 static size_t readmoredata(char *buffer,
992 struct connectdata *conn = (struct connectdata *)userp;
993 struct HTTP *http = conn->data->req.protop;
994 size_t fullsize = size * nitems;
997 /* nothing to return */
1000 /* make sure that a HTTP request is never sent away chunked! */
1001 conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
1003 if(http->postsize <= (curl_off_t)fullsize) {
1004 memcpy(buffer, http->postdata, (size_t)http->postsize);
1005 fullsize = (size_t)http->postsize;
1007 if(http->backup.postsize) {
1008 /* move backup data into focus and continue on that */
1009 http->postdata = http->backup.postdata;
1010 http->postsize = http->backup.postsize;
1011 conn->data->state.fread_func = http->backup.fread_func;
1012 conn->data->state.in = http->backup.fread_in;
1014 http->sending++; /* move one step up */
1016 http->backup.postsize=0;
1024 memcpy(buffer, http->postdata, fullsize);
1025 http->postdata += fullsize;
1026 http->postsize -= fullsize;
1031 /* ------------------------------------------------------------------------- */
1032 /* add_buffer functions */
1035 * Curl_add_buffer_init() sets up and returns a fine buffer struct
1037 Curl_send_buffer *Curl_add_buffer_init(void)
1039 return calloc(1, sizeof(Curl_send_buffer));
1043 * Curl_add_buffer_free() frees all associated resources.
1045 void Curl_add_buffer_free(Curl_send_buffer *buff)
1047 if(buff) /* deal with NULL input */
1053 * Curl_add_buffer_send() sends a header buffer and frees all associated
1054 * memory. Body data may be appended to the header data if desired.
1058 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
1059 struct connectdata *conn,
1061 /* add the number of sent bytes to this
1063 long *bytes_written,
1065 /* how much of the buffer contains body data */
1066 size_t included_body_bytes,
1074 struct HTTP *http = conn->data->req.protop;
1076 curl_socket_t sockfd;
1079 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1081 sockfd = conn->sock[socketindex];
1083 /* The looping below is required since we use non-blocking sockets, but due
1084 to the circumstances we will just loop and try again and again etc */
1087 size = in->size_used;
1089 headersize = size - included_body_bytes; /* the initial part that isn't body
1092 DEBUGASSERT(size > included_body_bytes);
1094 result = Curl_convert_to_network(conn->data, ptr, headersize);
1095 /* Curl_convert_to_network calls failf if unsuccessful */
1097 /* conversion failed, free memory and return to the caller */
1098 Curl_add_buffer_free(in);
1102 if((conn->handler->flags & PROTOPT_SSL) && conn->httpversion != 20) {
1103 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1104 when we speak HTTPS, as if only a fraction of it is sent now, this data
1105 needs to fit into the normal read-callback buffer later on and that
1106 buffer is using this size.
1109 sendsize = (size > CURL_MAX_WRITE_SIZE) ? CURL_MAX_WRITE_SIZE : size;
1111 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1112 library when we attempt to re-send this buffer. Sending the same data
1113 is not enough, we must use the exact same address. For this reason, we
1114 must copy the data to the uploadbuffer first, since that is the buffer
1115 we will be using if this send is retried later.
1117 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1118 ptr = conn->data->state.uploadbuffer;
1123 result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1127 * Note that we may not send the entire chunk at once, and we have a set
1128 * number of data bytes at the end of the big buffer (out of which we may
1129 * only send away a part).
1131 /* how much of the header that was sent */
1132 size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
1133 size_t bodylen = amount - headlen;
1135 if(conn->data->set.verbose) {
1136 /* this data _may_ contain binary stuff */
1137 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1139 /* there was body data sent beyond the initial header part, pass that
1140 on to the debug callback too */
1141 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1142 ptr+headlen, bodylen, conn);
1146 /* 'amount' can never be a very large value here so typecasting it so a
1147 signed 31 bit value should not cause problems even if ssize_t is
1149 *bytes_written += (long)amount;
1152 /* if we sent a piece of the body here, up the byte counter for it
1154 http->writebytecount += bodylen;
1156 if((size_t)amount != size) {
1157 /* The whole request could not be sent in one system call. We must
1158 queue it up and send it later when we get the chance. We must not
1159 loop here and wait until it might work again. */
1163 ptr = in->buffer + amount;
1165 /* backup the currently set pointers */
1166 http->backup.fread_func = conn->data->state.fread_func;
1167 http->backup.fread_in = conn->data->state.in;
1168 http->backup.postdata = http->postdata;
1169 http->backup.postsize = http->postsize;
1171 /* set the new pointers for the request-sending */
1172 conn->data->state.fread_func = (curl_read_callback)readmoredata;
1173 conn->data->state.in = (void *)conn;
1174 http->postdata = ptr;
1175 http->postsize = (curl_off_t)size;
1177 http->send_buffer = in;
1178 http->sending = HTTPSEND_REQUEST;
1182 http->sending = HTTPSEND_BODY;
1183 /* the full buffer was sent, clean up and return */
1186 if((size_t)amount != size)
1187 /* We have no continue-send mechanism now, fail. This can only happen
1188 when this function is used from the CONNECT sending function. We
1189 currently (stupidly) assume that the whole request is always sent
1190 away in the first single chunk.
1194 return CURLE_SEND_ERROR;
1196 Curl_pipeline_leave_write(conn);
1199 Curl_add_buffer_free(in);
1206 * add_bufferf() add the formatted input to the buffer.
1208 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1213 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1217 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1221 /* If we failed, we cleanup the whole buffer and return error */
1224 return CURLE_OUT_OF_MEMORY;
1228 * add_buffer() appends a memory chunk to the existing buffer
1230 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1235 if(~size < in->size_used) {
1236 /* If resulting used size of send buffer would wrap size_t, cleanup
1237 the whole buffer and return error. Otherwise the required buffer
1238 size will fit into a single allocatable memory chunk */
1239 Curl_safefree(in->buffer);
1241 return CURLE_OUT_OF_MEMORY;
1245 ((in->size_used + size) > (in->size_max - 1))) {
1247 /* If current buffer size isn't enough to hold the result, use a
1248 buffer size that doubles the required size. If this new size
1249 would wrap size_t, then just use the largest possible one */
1251 if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
1252 (~(size * 2) < (in->size_used * 2)))
1253 new_size = (size_t)-1;
1255 new_size = (in->size_used+size) * 2;
1258 /* we have a buffer, enlarge the existing one */
1259 new_rb = realloc(in->buffer, new_size);
1261 /* create a new buffer */
1262 new_rb = malloc(new_size);
1265 /* If we failed, we cleanup the whole buffer and return error */
1266 Curl_safefree(in->buffer);
1268 return CURLE_OUT_OF_MEMORY;
1271 in->buffer = new_rb;
1272 in->size_max = new_size;
1274 memcpy(&in->buffer[in->size_used], inptr, size);
1276 in->size_used += size;
1281 /* end of the add_buffer functions */
1282 /* ------------------------------------------------------------------------- */
1287 * Curl_compareheader()
1289 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1290 * Pass headers WITH the colon.
1293 Curl_compareheader(const char *headerline, /* line to check */
1294 const char *header, /* header keyword _with_ colon */
1295 const char *content) /* content string to find */
1297 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1298 * by a colon (":") and the field value. Field names are case-insensitive.
1299 * The field value MAY be preceded by any amount of LWS, though a single SP
1302 size_t hlen = strlen(header);
1308 if(!Curl_raw_nequal(headerline, header, hlen))
1309 return FALSE; /* doesn't start with header */
1311 /* pass the header */
1312 start = &headerline[hlen];
1314 /* pass all white spaces */
1315 while(*start && ISSPACE(*start))
1318 /* find the end of the header line */
1319 end = strchr(start, '\r'); /* lines end with CRLF */
1321 /* in case there's a non-standard compliant line here */
1322 end = strchr(start, '\n');
1325 /* hm, there's no line ending here, use the zero byte! */
1326 end = strchr(start, '\0');
1329 len = end-start; /* length of the content part of the input line */
1330 clen = strlen(content); /* length of the word to find */
1332 /* find the content string in the rest of the line */
1333 for(;len>=clen;len--, start++) {
1334 if(Curl_raw_nequal(start, content, clen))
1335 return TRUE; /* match! */
1338 return FALSE; /* no match */
1342 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1343 * the generic Curl_connect().
1345 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1349 /* We default to persistent connections. We set this already in this connect
1350 function to make the re-use checks properly be able to check this bit. */
1351 connkeep(conn, "HTTP default");
1353 /* the CONNECT procedure might not have been completed */
1354 result = Curl_proxy_connect(conn);
1358 if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1359 /* nothing else to do except wait right now - we're not done here. */
1362 if(conn->given->flags & PROTOPT_SSL) {
1363 /* perform SSL initialization */
1364 result = https_connecting(conn, done);
1374 /* this returns the socket to wait for in the DO and DOING state for the multi
1375 interface and then we're always _sending_ a request and thus we wait for
1376 the single socket to become writable only */
1377 static int http_getsock_do(struct connectdata *conn,
1378 curl_socket_t *socks,
1382 (void)numsocks; /* unused, we trust it to be at least 1 */
1383 socks[0] = conn->sock[FIRSTSOCKET];
1384 return GETSOCK_WRITESOCK(0);
1388 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1391 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1393 /* perform SSL initialization for this socket */
1394 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1396 connclose(conn, "Failed HTTPS connection");
1402 #if defined(USE_OPENSSL) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
1403 defined(USE_DARWINSSL) || defined(USE_POLARSSL) || defined(USE_NSS) || \
1404 defined(USE_MBEDTLS)
1405 /* This function is for OpenSSL, GnuTLS, darwinssl, schannel and polarssl only.
1406 It should be made to query the generic SSL layer instead. */
1407 static int https_getsock(struct connectdata *conn,
1408 curl_socket_t *socks,
1411 if(conn->handler->flags & PROTOPT_SSL) {
1412 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1415 return GETSOCK_BLANK;
1417 if(connssl->connecting_state == ssl_connect_2_writing) {
1419 socks[0] = conn->sock[FIRSTSOCKET];
1420 return GETSOCK_WRITESOCK(0);
1422 else if(connssl->connecting_state == ssl_connect_2_reading) {
1424 socks[0] = conn->sock[FIRSTSOCKET];
1425 return GETSOCK_READSOCK(0);
1433 static int https_getsock(struct connectdata *conn,
1434 curl_socket_t *socks,
1440 return GETSOCK_BLANK;
1442 #endif /* USE_SSL */
1443 #endif /* USE_OPENSSL || USE_GNUTLS || USE_SCHANNEL */
1446 * Curl_http_done() gets called after a single HTTP request has been
1450 CURLcode Curl_http_done(struct connectdata *conn,
1451 CURLcode status, bool premature)
1453 struct Curl_easy *data = conn->data;
1454 struct HTTP *http = data->req.protop;
1456 infof(data, "Curl_http_done: called premature == %d\n", premature);
1458 Curl_unencode_cleanup(conn);
1461 if(data->state.proxyneg.state == GSS_AUTHSENT ||
1462 data->state.negotiate.state == GSS_AUTHSENT) {
1463 /* add forbid re-use if http-code != 401/407 as a WA only needed for
1464 * 401/407 that signal auth failure (empty) otherwise state will be RECV
1465 * with current code.
1466 * Do not close CONNECT_ONLY connections. */
1467 if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
1468 !data->set.connect_only)
1469 streamclose(conn, "Negotiate transfer completed");
1470 Curl_cleanup_negotiate(data);
1474 /* set the proper values (possibly modified on POST) */
1475 conn->seek_func = data->set.seek_func; /* restore */
1476 conn->seek_client = data->set.seek_client; /* restore */
1481 if(http->send_buffer) {
1482 Curl_add_buffer_free(http->send_buffer);
1483 http->send_buffer = NULL; /* clear the pointer */
1486 Curl_http2_done(conn, premature);
1488 if(HTTPREQ_POST_FORM == data->set.httpreq) {
1489 data->req.bytecount = http->readbytecount + http->writebytecount;
1491 Curl_formclean(&http->sendit); /* Now free that whole lot */
1493 /* a file being uploaded was left opened, close it! */
1494 fclose(http->form.fp);
1495 http->form.fp = NULL;
1498 else if(HTTPREQ_PUT == data->set.httpreq)
1499 data->req.bytecount = http->readbytecount + http->writebytecount;
1504 if(!premature && /* this check is pointless when DONE is called before the
1505 entire operation is complete */
1506 !conn->bits.retry &&
1507 !data->set.connect_only &&
1508 (http->readbytecount +
1509 data->req.headerbytecount -
1510 data->req.deductheadercount) <= 0) {
1511 /* If this connection isn't simply closed to be retried, AND nothing was
1512 read from the HTTP server (that counts), this can't be right so we
1513 return an error here */
1514 failf(data, "Empty reply from server");
1515 return CURLE_GOT_NOTHING;
1522 * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
1523 * to avoid it include:
1525 * - if the user specifically requested HTTP 1.0
1526 * - if the server we are connected to only supports 1.0
1527 * - if any server previously contacted to handle this request only supports
1530 static bool use_http_1_1plus(const struct Curl_easy *data,
1531 const struct connectdata *conn)
1533 if((data->state.httpversion == 10) || (conn->httpversion == 10))
1535 if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
1536 (conn->httpversion <= 10))
1538 return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
1539 (data->set.httpversion >= CURL_HTTP_VERSION_1_1));
1542 /* check and possibly add an Expect: header */
1543 static CURLcode expect100(struct Curl_easy *data,
1544 struct connectdata *conn,
1545 Curl_send_buffer *req_buffer)
1547 CURLcode result = CURLE_OK;
1549 data->state.expect100header = FALSE; /* default to false unless it is set
1551 if(use_http_1_1plus(data, conn) &&
1552 (conn->httpversion != 20)) {
1553 /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
1554 Expect: 100-continue to the headers which actually speeds up post
1555 operations (as there is one packet coming back from the web server) */
1556 ptr = Curl_checkheaders(conn, "Expect:");
1558 data->state.expect100header =
1559 Curl_compareheader(ptr, "Expect:", "100-continue");
1562 result = Curl_add_bufferf(req_buffer,
1563 "Expect: 100-continue\r\n");
1565 data->state.expect100header = TRUE;
1573 HEADER_SERVER, /* direct to server */
1574 HEADER_PROXY, /* regular request to proxy */
1575 HEADER_CONNECT /* sending CONNECT to a proxy */
1578 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1580 Curl_send_buffer *req_buffer)
1583 struct curl_slist *h[2];
1584 struct curl_slist *headers;
1585 int numlists=1; /* by default */
1586 struct Curl_easy *data = conn->data;
1589 enum proxy_use proxy;
1592 proxy = HEADER_CONNECT;
1594 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
1595 HEADER_PROXY:HEADER_SERVER;
1599 h[0] = data->set.headers;
1602 h[0] = data->set.headers;
1603 if(data->set.sep_headers) {
1604 h[1] = data->set.proxyheaders;
1608 case HEADER_CONNECT:
1609 if(data->set.sep_headers)
1610 h[0] = data->set.proxyheaders;
1612 h[0] = data->set.headers;
1616 /* loop through one or two lists */
1617 for(i=0; i < numlists; i++) {
1621 ptr = strchr(headers->data, ':');
1623 /* we require a colon for this to be a true header */
1625 ptr++; /* pass the colon */
1626 while(*ptr && ISSPACE(*ptr))
1630 /* only send this if the contents was non-blank */
1632 if(conn->allocptr.host &&
1633 /* a Host: header was sent already, don't pass on any custom Host:
1634 header as that will produce *two* in the same request! */
1635 checkprefix("Host:", headers->data))
1637 else if(data->set.httpreq == HTTPREQ_POST_FORM &&
1638 /* this header (extended by formdata.c) is sent later */
1639 checkprefix("Content-Type:", headers->data))
1641 else if(conn->bits.authneg &&
1642 /* while doing auth neg, don't allow the custom length since
1643 we will force length zero then */
1644 checkprefix("Content-Length", headers->data))
1646 else if(conn->allocptr.te &&
1647 /* when asking for Transfer-Encoding, don't pass on a custom
1649 checkprefix("Connection", headers->data))
1652 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1660 ptr = strchr(headers->data, ';');
1663 ptr++; /* pass the semicolon */
1664 while(*ptr && ISSPACE(*ptr))
1668 /* this may be used for something else in the future */
1671 if(*(--ptr) == ';') {
1674 /* send no-value custom header if terminated by semicolon */
1676 result = Curl_add_bufferf(req_buffer, "%s\r\n",
1684 headers = headers->next;
1691 CURLcode Curl_add_timecondition(struct Curl_easy *data,
1692 Curl_send_buffer *req_buffer)
1694 const struct tm *tm;
1695 char *buf = data->state.buffer;
1699 if(data->set.timecondition == CURL_TIMECOND_NONE)
1700 /* no condition was asked for */
1703 result = Curl_gmtime(data->set.timevalue, &keeptime);
1705 failf(data, "Invalid TIMEVALUE");
1710 /* The If-Modified-Since header family should have their times set in
1711 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1712 * represented in Greenwich Mean Time (GMT), without exception. For the
1713 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1714 * Time)." (see page 20 of RFC2616).
1717 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1718 snprintf(buf, BUFSIZE-1,
1719 "%s, %02d %s %4d %02d:%02d:%02d GMT",
1720 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1722 Curl_month[tm->tm_mon],
1728 switch(data->set.timecondition) {
1731 case CURL_TIMECOND_IFMODSINCE:
1732 result = Curl_add_bufferf(req_buffer,
1733 "If-Modified-Since: %s\r\n", buf);
1735 case CURL_TIMECOND_IFUNMODSINCE:
1736 result = Curl_add_bufferf(req_buffer,
1737 "If-Unmodified-Since: %s\r\n", buf);
1739 case CURL_TIMECOND_LASTMOD:
1740 result = Curl_add_bufferf(req_buffer,
1741 "Last-Modified: %s\r\n", buf);
1749 * Curl_http() gets called from the generic multi_do() function when a HTTP
1750 * request is to be performed. This creates and sends a properly constructed
1753 CURLcode Curl_http(struct connectdata *conn, bool *done)
1755 struct Curl_easy *data = conn->data;
1756 CURLcode result = CURLE_OK;
1758 const char *ppath = data->state.path;
1759 bool paste_ftp_userpwd = FALSE;
1760 char ftp_typecode[sizeof("/;type=?")] = "";
1761 const char *host = conn->host.name;
1762 const char *te = ""; /* transfer-encoding */
1764 const char *request;
1765 Curl_HttpReq httpreq = data->set.httpreq;
1766 #if !defined(CURL_DISABLE_COOKIES)
1767 char *addcookies = NULL;
1769 curl_off_t included_body = 0;
1770 const char *httpstring;
1771 Curl_send_buffer *req_buffer;
1772 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1773 int seekerr = CURL_SEEKFUNC_OK;
1775 /* Always consider the DO phase done after this function call, even if there
1776 may be parts of the request that is not yet sent, since we can deal with
1777 the rest of the request in the PERFORM phase. */
1780 if(conn->httpversion < 20) { /* unless the connection is re-used and already
1782 switch(conn->negnpn) {
1783 case CURL_HTTP_VERSION_2:
1784 conn->httpversion = 20; /* we know we're on HTTP/2 now */
1786 result = Curl_http2_switched(conn, NULL, 0);
1790 case CURL_HTTP_VERSION_1_1:
1791 /* continue with HTTP/1.1 when explicitly requested */
1794 /* Check if user wants to use HTTP/2 with clear TCP*/
1796 if(conn->data->set.httpversion ==
1797 CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
1798 DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
1799 conn->httpversion = 20;
1801 result = Curl_http2_switched(conn, NULL, 0);
1810 /* prepare for a http2 request */
1811 result = Curl_http2_setup(conn);
1816 http = data->req.protop;
1818 if(!data->state.this_is_a_follow) {
1819 /* Free to avoid leaking memory on multiple requests*/
1820 free(data->state.first_host);
1822 data->state.first_host = strdup(conn->host.name);
1823 if(!data->state.first_host)
1824 return CURLE_OUT_OF_MEMORY;
1826 data->state.first_remote_port = conn->remote_port;
1828 http->writebytecount = http->readbytecount = 0;
1830 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
1832 httpreq = HTTPREQ_PUT;
1835 /* Now set the 'request' pointer to the proper request string */
1836 if(data->set.str[STRING_CUSTOMREQUEST])
1837 request = data->set.str[STRING_CUSTOMREQUEST];
1839 if(data->set.opt_no_body)
1842 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1845 case HTTPREQ_POST_FORM:
1851 default: /* this should never happen */
1862 /* The User-Agent string might have been allocated in url.c already, because
1863 it might have been used in the proxy connect, but if we have got a header
1864 with the user-agent string specified, we erase the previously made string
1866 if(Curl_checkheaders(conn, "User-Agent:")) {
1867 free(conn->allocptr.uagent);
1868 conn->allocptr.uagent=NULL;
1871 /* setup the authentication headers */
1872 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1876 if((data->state.authhost.multi || data->state.authproxy.multi) &&
1877 (httpreq != HTTPREQ_GET) &&
1878 (httpreq != HTTPREQ_HEAD)) {
1879 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1880 with content-length zero as a "probe". */
1881 conn->bits.authneg = TRUE;
1884 conn->bits.authneg = FALSE;
1886 Curl_safefree(conn->allocptr.ref);
1887 if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) {
1888 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1889 if(!conn->allocptr.ref)
1890 return CURLE_OUT_OF_MEMORY;
1893 conn->allocptr.ref = NULL;
1895 #if !defined(CURL_DISABLE_COOKIES)
1896 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
1897 addcookies = data->set.str[STRING_COOKIE];
1900 if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
1901 data->set.str[STRING_ENCODING]) {
1902 Curl_safefree(conn->allocptr.accept_encoding);
1903 conn->allocptr.accept_encoding =
1904 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1905 if(!conn->allocptr.accept_encoding)
1906 return CURLE_OUT_OF_MEMORY;
1909 Curl_safefree(conn->allocptr.accept_encoding);
1910 conn->allocptr.accept_encoding = NULL;
1914 /* we only consider transfer-encoding magic if libz support is built-in */
1916 if(!Curl_checkheaders(conn, "TE:") &&
1917 data->set.http_transfer_encoding) {
1918 /* When we are to insert a TE: header in the request, we must also insert
1919 TE in a Connection: header, so we need to merge the custom provided
1920 Connection: header and prevent the original to get sent. Note that if
1921 the user has inserted his/hers own TE: header we don't do this magic
1922 but then assume that the user will handle it all! */
1923 char *cptr = Curl_checkheaders(conn, "Connection:");
1924 #define TE_HEADER "TE: gzip\r\n"
1926 Curl_safefree(conn->allocptr.te);
1928 /* Create the (updated) Connection: header */
1929 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1930 strdup("Connection: TE\r\n" TE_HEADER);
1932 if(!conn->allocptr.te)
1933 return CURLE_OUT_OF_MEMORY;
1937 if(conn->httpversion == 20)
1938 /* In HTTP2 forbids Transfer-Encoding: chunked */
1941 ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
1943 /* Some kind of TE is requested, check if 'chunked' is chosen */
1944 data->req.upload_chunky =
1945 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1948 if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
1950 (data->state.infilesize == -1)) {
1951 if(conn->bits.authneg)
1952 /* don't enable chunked during auth neg */
1954 else if(use_http_1_1plus(data, conn)) {
1955 /* HTTP, upload, unknown file size and not HTTP 1.0 */
1956 data->req.upload_chunky = TRUE;
1959 failf(data, "Chunky upload is not supported by HTTP 1.0");
1960 return CURLE_UPLOAD_FAILED;
1964 /* else, no chunky upload */
1965 data->req.upload_chunky = FALSE;
1968 if(data->req.upload_chunky)
1969 te = "Transfer-Encoding: chunked\r\n";
1973 Curl_safefree(conn->allocptr.host);
1975 ptr = Curl_checkheaders(conn, "Host:");
1976 if(ptr && (!data->state.this_is_a_follow ||
1977 Curl_raw_equal(data->state.first_host, conn->host.name))) {
1978 #if !defined(CURL_DISABLE_COOKIES)
1979 /* If we have a given custom Host: header, we extract the host name in
1980 order to possibly use it for cookie reasons later on. We only allow the
1981 custom Host: header if this is NOT a redirect, as setting Host: in the
1982 redirected request is being out on thin ice. Except if the host name
1983 is the same as the first one! */
1984 char *cookiehost = Curl_copy_header_value(ptr);
1986 return CURLE_OUT_OF_MEMORY;
1988 /* ignore empty data */
1991 /* If the host begins with '[', we start searching for the port after
1992 the bracket has been closed */
1993 int startsearch = 0;
1994 if(*cookiehost == '[') {
1995 char *closingbracket;
1996 /* since the 'cookiehost' is an allocated memory area that will be
1997 freed later we cannot simply increment the pointer */
1998 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
1999 closingbracket = strchr(cookiehost, ']');
2001 *closingbracket = 0;
2004 char *colon = strchr(cookiehost + startsearch, ':');
2006 *colon = 0; /* The host must not include an embedded port number */
2008 Curl_safefree(conn->allocptr.cookiehost);
2009 conn->allocptr.cookiehost = cookiehost;
2013 if(strcmp("Host:", ptr)) {
2014 conn->allocptr.host = aprintf("%s\r\n", ptr);
2015 if(!conn->allocptr.host)
2016 return CURLE_OUT_OF_MEMORY;
2019 /* when clearing the header */
2020 conn->allocptr.host = NULL;
2023 /* When building Host: headers, we must put the host name within
2024 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
2026 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
2027 (conn->remote_port == PORT_HTTPS)) ||
2028 ((conn->given->protocol&CURLPROTO_HTTP) &&
2029 (conn->remote_port == PORT_HTTP)) )
2030 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
2031 the port number in the host string */
2032 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
2033 conn->bits.ipv6_ip?"[":"",
2035 conn->bits.ipv6_ip?"]":"");
2037 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
2038 conn->bits.ipv6_ip?"[":"",
2040 conn->bits.ipv6_ip?"]":"",
2043 if(!conn->allocptr.host)
2044 /* without Host: we can't make a nice request */
2045 return CURLE_OUT_OF_MEMORY;
2048 #ifndef CURL_DISABLE_PROXY
2049 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
2050 /* Using a proxy but does not tunnel through it */
2052 /* The path sent to the proxy is in fact the entire URL. But if the remote
2053 host is a IDN-name, we must make sure that the request we produce only
2054 uses the encoded host name! */
2055 if(conn->host.dispname != conn->host.name) {
2056 char *url = data->change.url;
2057 ptr = strstr(url, conn->host.dispname);
2059 /* This is where the display name starts in the URL, now replace this
2060 part with the encoded name. TODO: This method of replacing the host
2061 name is rather crude as I believe there's a slight risk that the
2062 user has entered a user name or password that contain the host name
2064 size_t currlen = strlen(conn->host.dispname);
2065 size_t newlen = strlen(conn->host.name);
2066 size_t urllen = strlen(url);
2070 newurl = malloc(urllen + newlen - currlen + 1);
2072 /* copy the part before the host name */
2073 memcpy(newurl, url, ptr - url);
2074 /* append the new host name instead of the old */
2075 memcpy(newurl + (ptr - url), conn->host.name, newlen);
2076 /* append the piece after the host name */
2077 memcpy(newurl + newlen + (ptr - url),
2078 ptr + currlen, /* copy the trailing zero byte too */
2079 urllen - (ptr-url) - currlen + 1);
2080 if(data->change.url_alloc) {
2081 Curl_safefree(data->change.url);
2082 data->change.url_alloc = FALSE;
2084 data->change.url = newurl;
2085 data->change.url_alloc = TRUE;
2088 return CURLE_OUT_OF_MEMORY;
2091 ppath = data->change.url;
2092 if(checkprefix("ftp://", ppath)) {
2093 if(data->set.proxy_transfer_mode) {
2094 /* when doing ftp, append ;type=<a|i> if not present */
2095 char *type = strstr(ppath, ";type=");
2096 if(type && type[6] && type[7] == 0) {
2097 switch (Curl_raw_toupper(type[6])) {
2107 char *p = ftp_typecode;
2108 /* avoid sending invalid URLs like ftp://example.com;type=i if the
2109 * user specified ftp://example.com without the slash */
2110 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
2113 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
2114 data->set.prefer_ascii ? 'a' : 'i');
2117 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
2118 paste_ftp_userpwd = TRUE;
2121 #endif /* CURL_DISABLE_PROXY */
2123 if(HTTPREQ_POST_FORM == httpreq) {
2124 /* we must build the whole post sequence first, so that we have a size of
2125 the whole transfer before we start to send it */
2126 result = Curl_getformdata(data, &http->sendit, data->set.httppost,
2127 Curl_checkheaders(conn, "Content-Type:"),
2133 http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n";
2135 if(( (HTTPREQ_POST == httpreq) ||
2136 (HTTPREQ_POST_FORM == httpreq) ||
2137 (HTTPREQ_PUT == httpreq) ) &&
2138 data->state.resume_from) {
2139 /**********************************************************************
2140 * Resuming upload in HTTP means that we PUT or POST and that we have
2141 * got a resume_from value set. The resume value has already created
2142 * a Range: header that will be passed along. We need to "fast forward"
2143 * the file the given number of bytes and decrease the assume upload
2144 * file size before we continue this venture in the dark lands of HTTP.
2145 *********************************************************************/
2147 if(data->state.resume_from < 0) {
2149 * This is meant to get the size of the present remote-file by itself.
2150 * We don't support this now. Bail out!
2152 data->state.resume_from = 0;
2155 if(data->state.resume_from && !data->state.this_is_a_follow) {
2156 /* do we still game? */
2158 /* Now, let's read off the proper amount of bytes from the
2160 if(conn->seek_func) {
2161 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2165 if(seekerr != CURL_SEEKFUNC_OK) {
2166 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2167 failf(data, "Could not seek stream");
2168 return CURLE_READ_ERROR;
2170 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2172 curl_off_t passed=0;
2174 size_t readthisamountnow =
2175 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
2176 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
2178 size_t actuallyread =
2179 data->state.fread_func(data->state.buffer, 1, readthisamountnow,
2182 passed += actuallyread;
2183 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2184 /* this checks for greater-than only to make sure that the
2185 CURL_READFUNC_ABORT return code still aborts */
2186 failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2187 " bytes from the input", passed);
2188 return CURLE_READ_ERROR;
2190 } while(passed < data->state.resume_from);
2194 /* now, decrease the size of the read */
2195 if(data->state.infilesize>0) {
2196 data->state.infilesize -= data->state.resume_from;
2198 if(data->state.infilesize <= 0) {
2199 failf(data, "File already completely uploaded");
2200 return CURLE_PARTIAL_FILE;
2203 /* we've passed, proceed as normal */
2206 if(data->state.use_range) {
2208 * A range is selected. We use different headers whether we're downloading
2209 * or uploading and we always let customized headers override our internal
2210 * ones if any such are specified.
2212 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2213 !Curl_checkheaders(conn, "Range:")) {
2214 /* if a line like this was already allocated, free the previous one */
2215 free(conn->allocptr.rangeline);
2216 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2219 else if((httpreq != HTTPREQ_GET) &&
2220 !Curl_checkheaders(conn, "Content-Range:")) {
2222 /* if a line like this was already allocated, free the previous one */
2223 free(conn->allocptr.rangeline);
2225 if(data->set.set_resume_from < 0) {
2226 /* Upload resume was asked for, but we don't know the size of the
2227 remote part so we tell the server (and act accordingly) that we
2228 upload the whole file (again) */
2229 conn->allocptr.rangeline =
2230 aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2231 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2232 data->state.infilesize - 1, data->state.infilesize);
2235 else if(data->state.resume_from) {
2236 /* This is because "resume" was selected */
2237 curl_off_t total_expected_size=
2238 data->state.resume_from + data->state.infilesize;
2239 conn->allocptr.rangeline =
2240 aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2241 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2242 data->state.range, total_expected_size-1,
2243 total_expected_size);
2246 /* Range was selected and then we just pass the incoming range and
2247 append total size */
2248 conn->allocptr.rangeline =
2249 aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2250 data->state.range, data->state.infilesize);
2252 if(!conn->allocptr.rangeline)
2253 return CURLE_OUT_OF_MEMORY;
2257 /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2259 httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
2261 /* initialize a dynamic send-buffer */
2262 req_buffer = Curl_add_buffer_init();
2265 return CURLE_OUT_OF_MEMORY;
2267 /* add the main request stuff */
2268 /* GET/HEAD/POST/PUT */
2269 result = Curl_add_bufferf(req_buffer, "%s ", request);
2274 if(paste_ftp_userpwd)
2275 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2276 conn->user, conn->passwd,
2277 ppath + sizeof("ftp://") - 1);
2279 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2284 Curl_add_bufferf(req_buffer,
2285 "%s" /* ftp typecode (;type=x) */
2286 " HTTP/%s\r\n" /* HTTP version */
2288 "%s" /* proxyuserpwd */
2291 "%s" /* user agent */
2294 "%s" /* accept-encoding */
2296 "%s" /* Proxy-Connection */
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> */,
2319 (conn->bits.httpproxy &&
2320 !conn->bits.tunnel_proxy &&
2321 !Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
2322 "Proxy-Connection: Keep-Alive\r\n":"",
2326 /* clear userpwd to avoid re-using credentials from re-used connections */
2327 Curl_safefree(conn->allocptr.userpwd);
2330 * Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
2331 * with the connection and shouldn't be repeated over it either.
2333 switch (data->state.authproxy.picked) {
2334 case CURLAUTH_NEGOTIATE:
2336 case CURLAUTH_NTLM_WB:
2337 Curl_safefree(conn->allocptr.proxyuserpwd);
2344 if(!(conn->handler->flags&PROTOPT_SSL) &&
2345 conn->httpversion != 20 &&
2346 (data->set.httpversion == CURL_HTTP_VERSION_2)) {
2347 /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
2349 result = Curl_http2_request_upgrade(req_buffer, conn);
2354 #if !defined(CURL_DISABLE_COOKIES)
2355 if(data->cookies || addcookies) {
2356 struct Cookie *co=NULL; /* no cookies from start */
2360 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2361 co = Curl_cookie_getlist(data->cookies,
2362 conn->allocptr.cookiehost?
2363 conn->allocptr.cookiehost:host,
2365 (conn->handler->protocol&CURLPROTO_HTTPS)?
2367 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2370 struct Cookie *store=co;
2371 /* now loop through all cookies that matched */
2375 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2379 result = Curl_add_bufferf(req_buffer,
2380 "%s%s=%s", count?"; ":"",
2381 co->name, co->value);
2386 co = co->next; /* next cookie please */
2388 Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2390 if(addcookies && !result) {
2392 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2394 result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
2399 if(count && !result)
2400 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2407 result = Curl_add_timecondition(data, req_buffer);
2411 result = Curl_add_custom_headers(conn, FALSE, req_buffer);
2415 http->postdata = NULL; /* nothing to post at this point */
2416 Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
2418 /* If 'authdone' is FALSE, we must not set the write socket index to the
2419 Curl_transfer() call below, as we're not ready to actually upload any
2424 case HTTPREQ_POST_FORM:
2425 if(!http->sendit || conn->bits.authneg) {
2426 /* nothing to post! */
2427 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2431 result = Curl_add_buffer_send(req_buffer, conn,
2432 &data->info.request_size, 0, FIRSTSOCKET);
2434 failf(data, "Failed sending POST request");
2436 /* setup variables for the upcoming transfer */
2437 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2442 if(Curl_FormInit(&http->form, http->sendit)) {
2443 failf(data, "Internal HTTP POST error!");
2444 return CURLE_HTTP_POST_ERROR;
2447 /* Get the currently set callback function pointer and store that in the
2448 form struct since we might want the actual user-provided callback later
2449 on. The data->set.fread_func pointer itself will be changed for the
2450 multipart case to the function that returns a multipart formatted
2452 http->form.fread_func = data->state.fread_func;
2454 /* Set the read function to read from the generated form data */
2455 data->state.fread_func = (curl_read_callback)Curl_FormReader;
2456 data->state.in = &http->form;
2458 http->sending = HTTPSEND_BODY;
2460 if(!data->req.upload_chunky &&
2461 !Curl_checkheaders(conn, "Content-Length:")) {
2462 /* only add Content-Length if not uploading chunked */
2463 result = Curl_add_bufferf(req_buffer,
2464 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2465 "\r\n", http->postsize);
2470 result = expect100(data, conn, req_buffer);
2476 /* Get Content-Type: line from Curl_formpostheader.
2479 size_t linelength=0;
2480 contentType = Curl_formpostheader((void *)&http->form,
2483 failf(data, "Could not get Content-Type header line!");
2484 return CURLE_HTTP_POST_ERROR;
2487 result = Curl_add_buffer(req_buffer, contentType, linelength);
2492 /* make the request end in a true CRLF */
2493 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2497 /* set upload size to the progress meter */
2498 Curl_pgrsSetUploadSize(data, http->postsize);
2500 /* fire away the whole request to the server */
2501 result = Curl_add_buffer_send(req_buffer, conn,
2502 &data->info.request_size, 0, FIRSTSOCKET);
2504 failf(data, "Failed sending POST request");
2506 /* setup variables for the upcoming transfer */
2507 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2508 &http->readbytecount, FIRSTSOCKET,
2509 &http->writebytecount);
2512 Curl_formclean(&http->sendit); /* free that whole lot */
2516 /* convert the form data */
2517 result = Curl_convert_form(data, http->sendit);
2519 Curl_formclean(&http->sendit); /* free that whole lot */
2525 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2527 if(conn->bits.authneg)
2530 postsize = data->state.infilesize;
2532 if((postsize != -1) && !data->req.upload_chunky &&
2533 !Curl_checkheaders(conn, "Content-Length:")) {
2534 /* only add Content-Length if not uploading chunked */
2535 result = Curl_add_bufferf(req_buffer,
2536 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2543 result = expect100(data, conn, req_buffer);
2548 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2552 /* set the upload size to the progress meter */
2553 Curl_pgrsSetUploadSize(data, postsize);
2555 /* this sends the buffer and frees all the buffer resources */
2556 result = Curl_add_buffer_send(req_buffer, conn,
2557 &data->info.request_size, 0, FIRSTSOCKET);
2559 failf(data, "Failed sending PUT request");
2561 /* prepare for transfer */
2562 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2563 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2564 postsize?&http->writebytecount:NULL);
2570 /* this is the simple POST, using x-www-form-urlencoded style */
2572 if(conn->bits.authneg)
2575 /* figure out the size of the postfields */
2576 postsize = (data->state.infilesize != -1)?
2577 data->state.infilesize:
2578 (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2581 /* We only set Content-Length and allow a custom Content-Length if
2582 we don't upload data chunked, as RFC2616 forbids us to set both
2583 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2584 if((postsize != -1) && !data->req.upload_chunky &&
2585 !Curl_checkheaders(conn, "Content-Length:")) {
2586 /* we allow replacing this header if not during auth negotiation,
2587 although it isn't very wise to actually set your own */
2588 result = Curl_add_bufferf(req_buffer,
2589 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2595 if(!Curl_checkheaders(conn, "Content-Type:")) {
2596 result = Curl_add_bufferf(req_buffer,
2597 "Content-Type: application/"
2598 "x-www-form-urlencoded\r\n");
2603 /* For really small posts we don't use Expect: headers at all, and for
2604 the somewhat bigger ones we allow the app to disable it. Just make
2605 sure that the expect100header is always set to the preferred value
2607 ptr = Curl_checkheaders(conn, "Expect:");
2609 data->state.expect100header =
2610 Curl_compareheader(ptr, "Expect:", "100-continue");
2612 else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2613 result = expect100(data, conn, req_buffer);
2618 data->state.expect100header = FALSE;
2620 if(data->set.postfields) {
2622 /* In HTTP2, we send request body in DATA frame regardless of
2624 if(conn->httpversion != 20 &&
2625 !data->state.expect100header &&
2626 (postsize < MAX_INITIAL_POST_SIZE)) {
2627 /* if we don't use expect: 100 AND
2628 postsize is less than MAX_INITIAL_POST_SIZE
2630 then append the post data to the HTTP request header. This limit
2631 is no magic limit but only set to prevent really huge POSTs to
2632 get the data duplicated with malloc() and family. */
2634 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2638 if(!data->req.upload_chunky) {
2639 /* We're not sending it 'chunked', append it to the request
2640 already now to reduce the number if send() calls */
2641 result = Curl_add_buffer(req_buffer, data->set.postfields,
2643 included_body = postsize;
2647 /* Append the POST data chunky-style */
2648 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2650 result = Curl_add_buffer(req_buffer, data->set.postfields,
2653 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2654 included_body = postsize + 2;
2658 result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
2664 /* Make sure the progress information is accurate */
2665 Curl_pgrsSetUploadSize(data, postsize);
2668 /* A huge POST coming up, do data separate from the request */
2669 http->postsize = postsize;
2670 http->postdata = data->set.postfields;
2672 http->sending = HTTPSEND_BODY;
2674 data->state.fread_func = (curl_read_callback)readmoredata;
2675 data->state.in = (void *)conn;
2677 /* set the upload size to the progress meter */
2678 Curl_pgrsSetUploadSize(data, http->postsize);
2680 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2686 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2690 if(data->req.upload_chunky && conn->bits.authneg) {
2691 /* Chunky upload is selected and we're negotiating auth still, send
2693 result = Curl_add_buffer(req_buffer,
2694 "\x30\x0d\x0a\x0d\x0a", 5);
2700 else if(data->state.infilesize) {
2701 /* set the upload size to the progress meter */
2702 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2704 /* set the pointer to mark that we will send the post body using the
2705 read callback, but only if we're not in authenticate
2707 if(!conn->bits.authneg) {
2708 http->postdata = (char *)&http->postdata;
2709 http->postsize = postsize;
2713 /* issue the request */
2714 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2715 (size_t)included_body, FIRSTSOCKET);
2718 failf(data, "Failed sending HTTP POST request");
2720 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2721 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2722 http->postdata?&http->writebytecount:NULL);
2726 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2730 /* issue the request */
2731 result = Curl_add_buffer_send(req_buffer, conn,
2732 &data->info.request_size, 0, FIRSTSOCKET);
2735 failf(data, "Failed sending HTTP request");
2737 /* HTTP GET/HEAD download: */
2738 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2739 http->postdata?FIRSTSOCKET:-1,
2740 http->postdata?&http->writebytecount:NULL);
2745 if(http->writebytecount) {
2746 /* if a request-body has been sent off, we make sure this progress is noted
2748 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2749 if(Curl_pgrsUpdate(conn))
2750 result = CURLE_ABORTED_BY_CALLBACK;
2752 if(http->writebytecount >= postsize) {
2753 /* already sent the entire request body, mark the "upload" as
2755 infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
2756 " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
2757 http->writebytecount, postsize);
2758 data->req.upload_done = TRUE;
2759 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2760 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2770 * Returns TRUE if member of the list matches prefix of string
2773 checkhttpprefix(struct Curl_easy *data,
2776 struct curl_slist *head = data->set.http200aliases;
2778 #ifdef CURL_DOES_CONVERSIONS
2779 /* convert from the network encoding using a scratch area */
2780 char *scratch = strdup(s);
2781 if(NULL == scratch) {
2782 failf (data, "Failed to allocate memory for conversion!");
2783 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2785 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2786 /* Curl_convert_from_network calls failf if unsuccessful */
2788 return FALSE; /* can't return CURLE_foobar so return FALSE */
2791 #endif /* CURL_DOES_CONVERSIONS */
2794 if(checkprefix(head->data, s)) {
2801 if(!rc && (checkprefix("HTTP/", s)))
2804 #ifdef CURL_DOES_CONVERSIONS
2806 #endif /* CURL_DOES_CONVERSIONS */
2810 #ifndef CURL_DISABLE_RTSP
2812 checkrtspprefix(struct Curl_easy *data,
2816 #ifdef CURL_DOES_CONVERSIONS
2817 /* convert from the network encoding using a scratch area */
2818 char *scratch = strdup(s);
2819 if(NULL == scratch) {
2820 failf (data, "Failed to allocate memory for conversion!");
2821 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2823 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2824 /* Curl_convert_from_network calls failf if unsuccessful */
2826 return FALSE; /* can't return CURLE_foobar so return FALSE */
2830 (void)data; /* unused */
2831 #endif /* CURL_DOES_CONVERSIONS */
2832 if(checkprefix("RTSP/", s))
2837 #endif /* CURL_DISABLE_RTSP */
2840 checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
2843 #ifndef CURL_DISABLE_RTSP
2844 if(conn->handler->protocol & CURLPROTO_RTSP)
2845 return checkrtspprefix(data, s);
2848 #endif /* CURL_DISABLE_RTSP */
2850 return checkhttpprefix(data, s);
2854 * header_append() copies a chunk of data to the end of the already received
2855 * header. We make sure that the full string fit in the allocated header
2856 * buffer, or else we enlarge it.
2858 static CURLcode header_append(struct Curl_easy *data,
2859 struct SingleRequest *k,
2862 if(k->hbuflen + length >= data->state.headersize) {
2863 /* We enlarge the header buffer as it is too small */
2868 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2869 /* The reason to have a max limit for this is to avoid the risk of a bad
2870 server feeding libcurl with a never-ending header that will cause
2871 reallocs infinitely */
2872 failf (data, "Avoided giant realloc for header (max is %d)!",
2873 CURL_MAX_HTTP_HEADER);
2874 return CURLE_OUT_OF_MEMORY;
2877 newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2878 hbufp_index = k->hbufp - data->state.headerbuff;
2879 newbuff = realloc(data->state.headerbuff, newsize);
2881 failf (data, "Failed to alloc memory for big header!");
2882 return CURLE_OUT_OF_MEMORY;
2884 data->state.headersize=newsize;
2885 data->state.headerbuff = newbuff;
2886 k->hbufp = data->state.headerbuff + hbufp_index;
2888 memcpy(k->hbufp, k->str_start, length);
2890 k->hbuflen += length;
2896 static void print_http_error(struct Curl_easy *data)
2898 struct SingleRequest *k = &data->req;
2901 /* make sure that data->req.p points to the HTTP status line */
2902 if(!strncmp(beg, "HTTP", 4)) {
2904 /* skip to HTTP status code */
2905 beg = strchr(beg, ' ');
2908 /* find trailing CR */
2909 char end_char = '\r';
2910 char *end = strchr(beg, end_char);
2912 /* try to find LF (workaround for non-compliant HTTP servers) */
2914 end = strchr(beg, end_char);
2918 /* temporarily replace CR or LF by NUL and print the error message */
2920 failf(data, "The requested URL returned error: %s", beg);
2922 /* restore the previously replaced CR or LF */
2929 /* fall-back to printing the HTTP status code only */
2930 failf(data, "The requested URL returned error: %d", k->httpcode);
2934 * Read any HTTP header lines from the server and pass them to the client app.
2936 CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
2937 struct connectdata *conn,
2942 struct SingleRequest *k = &data->req;
2944 /* header line within buffer loop */
2950 /* str_start is start of line within buf */
2951 k->str_start = k->str;
2953 /* data is in network encoding so use 0x0a instead of '\n' */
2954 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2957 /* Not a complete header line within buffer, append the data to
2958 the end of the headerbuff. */
2959 result = header_append(data, k, *nread);
2963 if(!k->headerline && (k->hbuflen>5)) {
2964 /* make a first check that this looks like a protocol header */
2965 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2966 /* this is not the beginning of a protocol first header line */
2968 k->badheader = HEADER_ALLBAD;
2973 break; /* read more and try again */
2976 /* decrease the size of the remaining (supposed) header line */
2977 rest_length = (k->end_ptr - k->str)+1;
2978 *nread -= (ssize_t)rest_length;
2980 k->str = k->end_ptr + 1; /* move past new line */
2982 full_length = k->str - k->str_start;
2984 result = header_append(data, k, full_length);
2988 k->end_ptr = k->hbufp;
2989 k->p = data->state.headerbuff;
2992 * We now have a FULL header line that p points to
2995 if(!k->headerline) {
2996 /* the first read header */
2997 if((k->hbuflen>5) &&
2998 !checkprotoprefix(data, conn, data->state.headerbuff)) {
2999 /* this is not the beginning of a protocol first header line */
3002 /* since there's more, this is a partial bad header */
3003 k->badheader = HEADER_PARTHEADER;
3005 /* this was all we read so it's all a bad header */
3006 k->badheader = HEADER_ALLBAD;
3007 *nread = (ssize_t)rest_length;
3013 /* headers are in network encoding so
3014 use 0x0a and 0x0d instead of '\n' and '\r' */
3015 if((0x0a == *k->p) || (0x0d == *k->p)) {
3017 /* Zero-length header line means end of headers! */
3019 #ifdef CURL_DOES_CONVERSIONS
3021 *k->p = '\r'; /* replace with CR in host encoding */
3022 k->p++; /* pass the CR byte */
3025 *k->p = '\n'; /* replace with LF in host encoding */
3026 k->p++; /* pass the LF byte */
3030 k->p++; /* pass the \r byte */
3032 k->p++; /* pass the \n byte */
3033 #endif /* CURL_DOES_CONVERSIONS */
3035 if(100 <= k->httpcode && 199 >= k->httpcode) {
3036 /* "A user agent MAY ignore unexpected 1xx status responses." */
3037 switch(k->httpcode) {
3040 * We have made a HTTP PUT or POST and this is 1.1-lingo
3041 * that tells us that the server is OK with this and ready
3042 * to receive the data.
3043 * However, we'll get more headers now so we must get
3044 * back into the header-parsing state!
3047 k->headerline = 0; /* restart the header line counter */
3049 /* if we did wait for this do enable write now! */
3050 if(k->exp100 > EXP100_SEND_DATA) {
3051 k->exp100 = EXP100_SEND_DATA;
3052 k->keepon |= KEEP_SEND;
3056 /* Switching Protocols */
3057 if(k->upgr101 == UPGR101_REQUESTED) {
3058 /* Switching to HTTP/2 */
3059 infof(data, "Received 101\n");
3060 k->upgr101 = UPGR101_RECEIVED;
3062 /* we'll get more headers (HTTP/2 response) */
3064 k->headerline = 0; /* restart the header line counter */
3066 /* switch to http2 now. The bytes after response headers
3067 are also processed here, otherwise they are lost. */
3068 result = Curl_http2_switched(conn, k->str, *nread);
3074 /* Switching to another protocol (e.g. WebSocket) */
3075 k->header = FALSE; /* no more header to parse! */
3079 /* the status code 1xx indicates a provisional response, so
3080 we'll get another set of headers */
3082 k->headerline = 0; /* restart the header line counter */
3087 k->header = FALSE; /* no more header to parse! */
3089 if((k->size == -1) && !k->chunk && !conn->bits.close &&
3090 (conn->httpversion == 11) &&
3091 !(conn->handler->protocol & CURLPROTO_RTSP) &&
3092 data->set.httpreq != HTTPREQ_HEAD) {
3093 /* On HTTP 1.1, when connection is not to get closed, but no
3094 Content-Length nor Content-Encoding chunked have been
3095 received, according to RFC2616 section 4.4 point 5, we
3096 assume that the server will close the connection to
3097 signal the end of the document. */
3098 infof(data, "no chunk, no close, no size. Assume close to "
3100 streamclose(conn, "HTTP: No end-of-message indicator");
3104 /* At this point we have some idea about the fate of the connection.
3105 If we are closing the connection it may result auth failure. */
3106 #if defined(USE_NTLM)
3107 if(conn->bits.close &&
3108 (((data->req.httpcode == 401) &&
3109 (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
3110 ((data->req.httpcode == 407) &&
3111 (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
3112 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
3113 data->state.authproblem = TRUE;
3118 * When all the headers have been parsed, see if we should give
3119 * up and return an error.
3121 if(http_should_fail(conn)) {
3122 failf (data, "The requested URL returned error: %d",
3124 return CURLE_HTTP_RETURNED_ERROR;
3127 /* now, only output this if the header AND body are requested:
3129 writetype = CLIENTWRITE_HEADER;
3130 if(data->set.include_header)
3131 writetype |= CLIENTWRITE_BODY;
3133 headerlen = k->p - data->state.headerbuff;
3135 result = Curl_client_write(conn, writetype,
3136 data->state.headerbuff,
3141 data->info.header_size += (long)headerlen;
3142 data->req.headerbytecount += (long)headerlen;
3144 data->req.deductheadercount =
3145 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
3147 /* Curl_http_auth_act() checks what authentication methods
3148 * that are available and decides which one (if any) to
3149 * use. It will set 'newurl' if an auth method was picked. */
3150 result = Curl_http_auth_act(conn);
3155 if(k->httpcode >= 300) {
3156 if((!conn->bits.authneg) && !conn->bits.close &&
3157 !conn->bits.rewindaftersend) {
3159 * General treatment of errors when about to send data. Including :
3160 * "417 Expectation Failed", while waiting for 100-continue.
3162 * The check for close above is done simply because of something
3163 * else has already deemed the connection to get closed then
3164 * something else should've considered the big picture and we
3167 * rewindaftersend indicates that something has told libcurl to
3168 * continue sending even if it gets discarded
3171 switch(data->set.httpreq) {
3174 case HTTPREQ_POST_FORM:
3175 /* We got an error response. If this happened before the whole
3176 * request body has been sent we stop sending and mark the
3177 * connection for closure after we've read the entire response.
3179 if(!k->upload_done) {
3180 infof(data, "HTTP error before end of send, stop sending\n");
3181 streamclose(conn, "Stop sending data before everything sent");
3182 k->upload_done = TRUE;
3183 k->keepon &= ~KEEP_SEND; /* don't send */
3184 if(data->state.expect100header)
3185 k->exp100 = EXP100_FAILED;
3189 default: /* default label present to avoid compiler warnings */
3194 if(conn->bits.rewindaftersend) {
3195 /* We rewind after a complete send, so thus we continue
3197 infof(data, "Keep sending data to get tossed away!\n");
3198 k->keepon |= KEEP_SEND;
3204 * really end-of-headers.
3206 * If we requested a "no body", this is a good time to get
3207 * out and return home.
3209 if(data->set.opt_no_body)
3210 *stop_reading = TRUE;
3211 #ifndef CURL_DISABLE_RTSP
3212 else if((conn->handler->protocol & CURLPROTO_RTSP) &&
3213 (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
3215 /* Respect section 4.4 of rfc2326: If the Content-Length header is
3216 absent, a length 0 must be assumed. It will prevent libcurl from
3217 hanging on DESCRIBE request that got refused for whatever
3219 *stop_reading = TRUE;
3222 /* If we know the expected size of this document, we set the
3223 maximum download size to the size of the expected
3224 document or else, we won't know when to stop reading!
3226 Note that we set the download maximum even if we read a
3227 "Connection: close" header, to make sure that
3228 "Content-Length: 0" still prevents us from attempting to
3229 read the (missing) response-body.
3231 /* According to RFC2616 section 4.4, we MUST ignore
3232 Content-Length: headers if we are now receiving data
3233 using chunked Transfer-Encoding.
3236 k->maxdownload = k->size = -1;
3239 /* We do this operation even if no_body is true, since this
3240 data might be retrieved later with curl_easy_getinfo()
3241 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3243 Curl_pgrsSetDownloadSize(data, k->size);
3244 k->maxdownload = k->size;
3247 /* If max download size is *zero* (nothing) we already
3248 have nothing and can safely return ok now! */
3249 if(0 == k->maxdownload)
3250 *stop_reading = TRUE;
3253 /* we make sure that this socket isn't read more now */
3254 k->keepon &= ~KEEP_RECV;
3257 if(data->set.verbose)
3258 Curl_debug(data, CURLINFO_HEADER_IN,
3259 k->str_start, headerlen, conn);
3260 break; /* exit header line loop */
3263 /* We continue reading headers, so reset the line-based
3264 header parsing variables hbufp && hbuflen */
3265 k->hbufp = data->state.headerbuff;
3271 * Checks for special headers coming up.
3274 if(!k->headerline++) {
3275 /* This is the first header, it MUST be the error code line
3276 or else we consider this to be the body right away! */
3277 int httpversion_major;
3278 int rtspversion_major;
3280 #ifdef CURL_DOES_CONVERSIONS
3281 #define HEADER1 scratch
3282 #define SCRATCHSIZE 21
3284 char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
3285 /* We can't really convert this yet because we
3286 don't know if it's the 1st header line or the body.
3287 So we do a partial conversion into a scratch area,
3288 leaving the data at k->p as-is.
3290 strncpy(&scratch[0], k->p, SCRATCHSIZE);
3291 scratch[SCRATCHSIZE] = 0; /* null terminate */
3292 res = Curl_convert_from_network(data,
3296 /* Curl_convert_from_network calls failf if unsuccessful */
3299 #define HEADER1 k->p /* no conversion needed, just use k->p */
3300 #endif /* CURL_DOES_CONVERSIONS */
3302 if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
3304 * https://tools.ietf.org/html/rfc7230#section-3.1.2
3306 * The reponse code is always a three-digit number in HTTP as the spec
3307 * says. We try to allow any number here, but we cannot make
3308 * guarantees on future behaviors since it isn't within the protocol.
3310 nc = sscanf(HEADER1,
3316 if(nc == 1 && httpversion_major == 2 &&
3317 1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) {
3318 conn->httpversion = 0;
3323 conn->httpversion += 10 * httpversion_major;
3325 if(k->upgr101 == UPGR101_RECEIVED) {
3326 /* supposedly upgraded to http2 now */
3327 if(conn->httpversion != 20)
3328 infof(data, "Lying server, not serving HTTP/2\n");
3332 /* this is the real world, not a Nirvana
3333 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3335 nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3336 conn->httpversion = 10;
3338 /* If user has set option HTTP200ALIASES,
3339 compare header line against list of aliases
3342 if(checkhttpprefix(data, k->p)) {
3345 conn->httpversion = 10;
3350 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3351 nc = sscanf(HEADER1,
3357 conn->rtspversion += 10 * rtspversion_major;
3358 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3361 /* TODO: do we care about the other cases here? */
3367 data->info.httpcode = k->httpcode;
3369 data->info.httpversion = conn->httpversion;
3370 if(!data->state.httpversion ||
3371 data->state.httpversion > conn->httpversion)
3372 /* store the lowest server version we encounter */
3373 data->state.httpversion = conn->httpversion;
3376 * This code executes as part of processing the header. As a
3377 * result, it's not totally clear how to interpret the
3378 * response code yet as that depends on what other headers may
3379 * be present. 401 and 407 may be errors, but may be OK
3380 * depending on how authentication is working. Other codes
3381 * are definitely errors, so give up here.
3383 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3384 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3385 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3387 if(data->state.resume_from &&
3388 (data->set.httpreq==HTTPREQ_GET) &&
3389 (k->httpcode == 416)) {
3390 /* "Requested Range Not Satisfiable", just proceed and
3391 pretend this is no error */
3394 /* serious error, go home! */
3395 print_http_error(data);
3396 return CURLE_HTTP_RETURNED_ERROR;
3400 if(conn->httpversion == 10) {
3401 /* Default action for HTTP/1.0 must be to close, unless
3402 we get one of those fancy headers that tell us the
3403 server keeps it open for us! */
3404 infof(data, "HTTP 1.0, assume close after body\n");
3405 connclose(conn, "HTTP/1.0 close after body");
3407 else if(conn->httpversion == 20 ||
3408 (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
3409 DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
3411 /* HTTP/2 cannot blacklist multiplexing since it is a core
3412 functionality of the protocol */
3413 conn->bundle->multiuse = BUNDLE_MULTIPLEX;
3415 else if(conn->httpversion >= 11 &&
3416 !conn->bits.close) {
3417 /* If HTTP version is >= 1.1 and connection is persistent
3418 server supports pipelining. */
3420 "HTTP 1.1 or later with persistent connection, "
3421 "pipelining supported\n"));
3422 /* Activate pipelining if needed */
3424 if(!Curl_pipeline_site_blacklisted(data, conn))
3425 conn->bundle->multiuse = BUNDLE_PIPELINING;
3429 switch(k->httpcode) {
3431 /* (quote from RFC2616, section 10.2.5): The server has
3432 * fulfilled the request but does not need to return an
3433 * entity-body ... The 204 response MUST NOT include a
3434 * message-body, and thus is always terminated by the first
3435 * empty line after the header fields. */
3438 /* (quote from RFC2616, section 10.3.5): The 304 response
3439 * MUST NOT contain a message-body, and thus is always
3440 * terminated by the first empty line after the header
3442 if(data->set.timecondition)
3443 data->info.timecond = TRUE;
3446 k->ignorecl = TRUE; /* ignore Content-Length headers */
3454 k->header = FALSE; /* this is not a header line */
3459 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3460 /* Curl_convert_from_network calls failf if unsuccessful */
3464 /* Check for Content-Length: header lines to get size */
3465 if(!k->ignorecl && !data->set.ignorecl &&
3466 checkprefix("Content-Length:", k->p)) {
3467 curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3468 if(data->set.max_filesize &&
3469 contentlength > data->set.max_filesize) {
3470 failf(data, "Maximum file size exceeded");
3471 return CURLE_FILESIZE_EXCEEDED;
3473 if(contentlength >= 0) {
3474 k->size = contentlength;
3475 k->maxdownload = k->size;
3476 /* we set the progress download size already at this point
3477 just to make it easier for apps/callbacks to extract this
3478 info as soon as possible */
3479 Curl_pgrsSetDownloadSize(data, k->size);
3482 /* Negative Content-Length is really odd, and we know it
3483 happens for example when older Apache servers send large
3485 streamclose(conn, "negative content-length");
3486 infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
3487 ", closing after transfer\n", contentlength);
3490 /* check for Content-Type: header lines to get the MIME-type */
3491 else if(checkprefix("Content-Type:", k->p)) {
3492 char *contenttype = Curl_copy_header_value(k->p);
3494 return CURLE_OUT_OF_MEMORY;
3496 /* ignore empty data */
3499 Curl_safefree(data->info.contenttype);
3500 data->info.contenttype = contenttype;
3503 else if(checkprefix("Server:", k->p)) {
3504 if(conn->httpversion < 20) {
3505 /* only do this for non-h2 servers */
3506 char *server_name = Curl_copy_header_value(k->p);
3508 /* Turn off pipelining if the server version is blacklisted */
3509 if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
3510 if(Curl_pipeline_server_blacklisted(data, server_name))
3511 conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
3516 else if((conn->httpversion == 10) &&
3517 conn->bits.httpproxy &&
3518 Curl_compareheader(k->p,
3519 "Proxy-Connection:", "keep-alive")) {
3521 * When a HTTP/1.0 reply comes when using a proxy, the
3522 * 'Proxy-Connection: keep-alive' line tells us the
3523 * connection will be kept alive for our pleasure.
3524 * Default action for 1.0 is to close.
3526 connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
3527 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3529 else if((conn->httpversion == 11) &&
3530 conn->bits.httpproxy &&
3531 Curl_compareheader(k->p,
3532 "Proxy-Connection:", "close")) {
3534 * We get a HTTP/1.1 response from a proxy and it says it'll
3535 * close down after this transfer.
3537 connclose(conn, "Proxy-Connection: asked to close after done");
3538 infof(data, "HTTP/1.1 proxy connection set close!\n");
3540 else if((conn->httpversion == 10) &&
3541 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3543 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3544 * tells us the connection will be kept alive for our
3545 * pleasure. Default action for 1.0 is to close.
3547 * [RFC2068, section 19.7.1] */
3548 connkeep(conn, "Connection keep-alive");
3549 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3551 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3553 * [RFC 2616, section 8.1.2.1]
3554 * "Connection: close" is HTTP/1.1 language and means that
3555 * the connection will close when this request has been
3558 streamclose(conn, "Connection: close used");
3560 else if(checkprefix("Transfer-Encoding:", k->p)) {
3561 /* One or more encodings. We check for chunked and/or a compression
3564 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3565 * means that the server will send a series of "chunks". Each
3566 * chunk starts with line with info (including size of the
3567 * coming block) (terminated with CRLF), then a block of data
3568 * with the previously mentioned size. There can be any amount
3569 * of chunks, and a chunk-data set to zero signals the
3574 /* Find the first non-space letter */
3578 /* skip whitespaces and commas */
3579 while(*start && (ISSPACE(*start) || (*start == ',')))
3582 if(checkprefix("chunked", start)) {
3583 k->chunk = TRUE; /* chunks coming our way */
3585 /* init our chunky engine */
3586 Curl_httpchunk_init(conn);
3591 if(k->auto_decoding)
3592 /* TODO: we only support the first mentioned compression for now */
3595 if(checkprefix("identity", start)) {
3596 k->auto_decoding = IDENTITY;
3599 else if(checkprefix("deflate", start)) {
3600 k->auto_decoding = DEFLATE;
3603 else if(checkprefix("gzip", start)) {
3604 k->auto_decoding = GZIP;
3607 else if(checkprefix("x-gzip", start)) {
3608 k->auto_decoding = GZIP;
3618 else if(checkprefix("Content-Encoding:", k->p) &&
3619 data->set.str[STRING_ENCODING]) {
3621 * Process Content-Encoding. Look for the values: identity,
3622 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3623 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3624 * 2616). zlib cannot handle compress. However, errors are
3625 * handled further down when the response body is processed
3629 /* Find the first non-space letter */
3631 while(*start && ISSPACE(*start))
3634 /* Record the content-encoding for later use */
3635 if(checkprefix("identity", start))
3636 k->auto_decoding = IDENTITY;
3637 else if(checkprefix("deflate", start))
3638 k->auto_decoding = DEFLATE;
3639 else if(checkprefix("gzip", start)
3640 || checkprefix("x-gzip", start))
3641 k->auto_decoding = GZIP;
3643 else if(checkprefix("Content-Range:", k->p)) {
3644 /* Content-Range: bytes [num]-
3645 Content-Range: bytes: [num]-
3646 Content-Range: [num]-
3647 Content-Range: [asterisk]/[total]
3649 The second format was added since Sun's webserver
3650 JavaWebServer/1.1.1 obviously sends the header this way!
3651 The third added since some servers use that!
3652 The forth means the requested range was unsatisfied.
3655 char *ptr = k->p + 14;
3657 /* Move forward until first digit or asterisk */
3658 while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
3661 /* if it truly stopped on a digit */
3663 k->offset = curlx_strtoofft(ptr, NULL, 10);
3665 if(data->state.resume_from == k->offset)
3666 /* we asked for a resume and we got it */
3667 k->content_range = TRUE;
3670 data->state.resume_from = 0; /* get everything */
3672 #if !defined(CURL_DISABLE_COOKIES)
3673 else if(data->cookies &&
3674 checkprefix("Set-Cookie:", k->p)) {
3675 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3676 CURL_LOCK_ACCESS_SINGLE);
3677 Curl_cookie_add(data,
3678 data->cookies, TRUE, k->p+11,
3679 /* If there is a custom-set Host: name, use it
3680 here, or else use real peer host name. */
3681 conn->allocptr.cookiehost?
3682 conn->allocptr.cookiehost:conn->host.name,
3684 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3687 else if(checkprefix("Last-Modified:", k->p) &&
3688 (data->set.timecondition || data->set.get_filetime) ) {
3689 time_t secs=time(NULL);
3690 k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3692 if(data->set.get_filetime)
3693 data->info.filetime = (long)k->timeofdoc;
3695 else if((checkprefix("WWW-Authenticate:", k->p) &&
3696 (401 == k->httpcode)) ||
3697 (checkprefix("Proxy-authenticate:", k->p) &&
3698 (407 == k->httpcode))) {
3700 bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3701 char *auth = Curl_copy_header_value(k->p);
3703 return CURLE_OUT_OF_MEMORY;
3705 result = Curl_http_input_auth(conn, proxy, auth);
3712 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3713 checkprefix("Location:", k->p) &&
3714 !data->req.location) {
3715 /* this is the URL that the server advises us to use instead */
3716 char *location = Curl_copy_header_value(k->p);
3718 return CURLE_OUT_OF_MEMORY;
3720 /* ignore empty data */
3723 data->req.location = location;
3725 if(data->set.http_follow_location) {
3726 DEBUGASSERT(!data->req.newurl);
3727 data->req.newurl = strdup(data->req.location); /* clone */
3728 if(!data->req.newurl)
3729 return CURLE_OUT_OF_MEMORY;
3731 /* some cases of POST and PUT etc needs to rewind the data
3732 stream at this point */
3733 result = http_perhapsrewind(conn);
3739 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3740 result = Curl_rtsp_parseheader(conn, k->p);
3746 * End of header-checks. Write them to the client.
3749 writetype = CLIENTWRITE_HEADER;
3750 if(data->set.include_header)
3751 writetype |= CLIENTWRITE_BODY;
3753 if(data->set.verbose)
3754 Curl_debug(data, CURLINFO_HEADER_IN,
3755 k->p, (size_t)k->hbuflen, conn);
3757 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3761 data->info.header_size += (long)k->hbuflen;
3762 data->req.headerbytecount += (long)k->hbuflen;
3764 /* reset hbufp pointer && hbuflen */
3765 k->hbufp = data->state.headerbuff;
3768 while(*k->str); /* header line within buffer */
3770 /* We might have reached the end of the header part here, but
3771 there might be a non-header part left in the end of the read
3777 #endif /* CURL_DISABLE_HTTP */