1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2018, 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>
55 #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"
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 ZERO_NULL, /* connection_check */
123 PORT_HTTP, /* defport */
124 CURLPROTO_HTTP, /* protocol */
125 PROTOPT_CREDSPERREQUEST /* flags */
130 * HTTPS handler interface.
132 const struct Curl_handler Curl_handler_https = {
133 "HTTPS", /* scheme */
134 Curl_http_setup_conn, /* setup_connection */
135 Curl_http, /* do_it */
136 Curl_http_done, /* done */
137 ZERO_NULL, /* do_more */
138 Curl_http_connect, /* connect_it */
139 https_connecting, /* connecting */
140 ZERO_NULL, /* doing */
141 https_getsock, /* proto_getsock */
142 http_getsock_do, /* doing_getsock */
143 ZERO_NULL, /* domore_getsock */
144 ZERO_NULL, /* perform_getsock */
145 ZERO_NULL, /* disconnect */
146 ZERO_NULL, /* readwrite */
147 ZERO_NULL, /* connection_check */
148 PORT_HTTPS, /* defport */
149 CURLPROTO_HTTPS, /* protocol */
150 PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */
154 CURLcode Curl_http_setup_conn(struct connectdata *conn)
156 /* allocate the HTTP-specific struct for the Curl_easy, only to survive
157 during this request */
159 DEBUGASSERT(conn->data->req.protop == NULL);
161 http = calloc(1, sizeof(struct HTTP));
163 return CURLE_OUT_OF_MEMORY;
165 Curl_mime_initpart(&http->form, conn->data);
166 conn->data->req.protop = http;
168 Curl_http2_setup_conn(conn);
169 Curl_http2_setup_req(conn->data);
176 * checkProxyHeaders() checks the linked list of custom proxy headers
177 * if proxy headers are not available, then it will lookup into http header
180 * It takes a connectdata struct as input instead of the Curl_easy simply to
181 * know if this is a proxy request or not, as it then might check a different
182 * header list. Provide the header prefix without colon!.
184 char *Curl_checkProxyheaders(const struct connectdata *conn,
185 const char *thisheader)
187 struct curl_slist *head;
188 size_t thislen = strlen(thisheader);
189 struct Curl_easy *data = conn->data;
191 for(head = (conn->bits.proxy && data->set.sep_headers) ?
192 data->set.proxyheaders : data->set.headers;
193 head; head = head->next) {
194 if(strncasecompare(head->data, thisheader, thislen) &&
195 Curl_headersep(head->data[thislen]))
203 * Strip off leading and trailing whitespace from the value in the
204 * given HTTP header line and return a strdupped copy. Returns NULL in
205 * case of allocation failure. Returns an empty string if the header value
206 * consists entirely of whitespace.
208 char *Curl_copy_header_value(const char *header)
217 /* Find the end of the header name */
218 while(*header && (*header != ':'))
222 /* Skip over colon */
225 /* Find the first non-space letter */
227 while(*start && ISSPACE(*start))
230 /* data is in the host encoding so
231 use '\r' and '\n' instead of 0x0d and 0x0a */
232 end = strchr(start, '\r');
234 end = strchr(start, '\n');
236 end = strchr(start, '\0');
240 /* skip all trailing space letters */
241 while((end > start) && ISSPACE(*end))
244 /* get length of the type */
245 len = end - start + 1;
247 value = malloc(len + 1);
251 memcpy(value, start, len);
252 value[len] = 0; /* zero terminate */
258 * http_output_basic() sets up an Authorization: header (or the proxy version)
259 * for HTTP Basic authentication.
263 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
266 char *authorization = NULL;
267 struct Curl_easy *data = conn->data;
275 userp = &conn->allocptr.proxyuserpwd;
276 user = conn->http_proxy.user;
277 pwd = conn->http_proxy.passwd;
280 userp = &conn->allocptr.userpwd;
285 out = aprintf("%s:%s", user, pwd);
287 return CURLE_OUT_OF_MEMORY;
289 result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
294 result = CURLE_REMOTE_ACCESS_DENIED;
299 *userp = aprintf("%sAuthorization: Basic %s\r\n",
300 proxy ? "Proxy-" : "",
304 result = CURLE_OUT_OF_MEMORY;
313 /* pickoneauth() selects the most favourable authentication method from the
314 * ones available and the ones we want.
316 * return TRUE if one was picked
318 static bool pickoneauth(struct auth *pick)
321 /* only deal with authentication we want */
322 unsigned long avail = pick->avail & pick->want;
325 /* The order of these checks is highly relevant, as this will be the order
326 of preference in case of the existence of multiple accepted types. */
327 if(avail & CURLAUTH_NEGOTIATE)
328 pick->picked = CURLAUTH_NEGOTIATE;
329 else if(avail & CURLAUTH_DIGEST)
330 pick->picked = CURLAUTH_DIGEST;
331 else if(avail & CURLAUTH_NTLM)
332 pick->picked = CURLAUTH_NTLM;
333 else if(avail & CURLAUTH_NTLM_WB)
334 pick->picked = CURLAUTH_NTLM_WB;
335 else if(avail & CURLAUTH_BASIC)
336 pick->picked = CURLAUTH_BASIC;
338 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
341 pick->avail = CURLAUTH_NONE; /* clear it here */
347 * Curl_http_perhapsrewind()
349 * If we are doing POST or PUT {
350 * If we have more data to send {
351 * If we are doing NTLM {
352 * Keep sending since we must not disconnect
355 * If there is more than just a little data left to send, close
356 * the current connection by force.
359 * If we have sent any data {
360 * If we don't have track of all the data {
361 * call app to tell it to rewind
364 * rewind internally so that the operation can restart fine
369 static CURLcode http_perhapsrewind(struct connectdata *conn)
371 struct Curl_easy *data = conn->data;
372 struct HTTP *http = data->req.protop;
373 curl_off_t bytessent;
374 curl_off_t expectsend = -1; /* default is unknown */
377 /* If this is still NULL, we have not reach very far and we can safely
378 skip this rewinding stuff */
381 switch(data->set.httpreq) {
389 bytessent = http->writebytecount;
391 if(conn->bits.authneg) {
392 /* This is a state where we are known to be negotiating and we don't send
396 else if(!conn->bits.protoconnstart) {
397 /* HTTP CONNECT in progress: there is no body */
401 /* figure out how much data we are expected to send */
402 switch(data->set.httpreq) {
404 if(data->state.infilesize != -1)
405 expectsend = data->state.infilesize;
408 if(data->state.infilesize != -1)
409 expectsend = data->state.infilesize;
411 case HTTPREQ_POST_FORM:
412 case HTTPREQ_POST_MIME:
413 expectsend = http->postsize;
420 conn->bits.rewindaftersend = FALSE; /* default */
422 if((expectsend == -1) || (expectsend > bytessent)) {
423 #if defined(USE_NTLM)
424 /* There is still data left to send */
425 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
426 (data->state.authhost.picked == CURLAUTH_NTLM) ||
427 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
428 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
429 if(((expectsend - bytessent) < 2000) ||
430 (conn->ntlm.state != NTLMSTATE_NONE) ||
431 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
432 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
433 data left to send, keep on sending. */
435 /* rewind data when completely done sending! */
436 if(!conn->bits.authneg) {
437 conn->bits.rewindaftersend = TRUE;
438 infof(data, "Rewind stream after send\n");
445 /* this is already marked to get closed */
448 infof(data, "NTLM send, close instead of sending %"
449 CURL_FORMAT_CURL_OFF_T " bytes\n",
450 (curl_off_t)(expectsend - bytessent));
454 /* This is not NTLM or many bytes left to send: close */
455 streamclose(conn, "Mid-auth HTTP and much data left to send");
456 data->req.size = 0; /* don't download any more than 0 bytes */
458 /* There still is data left to send, but this connection is marked for
459 closure so we can safely do the rewind right now */
463 /* we rewind now at once since if we already sent something */
464 return Curl_readrewind(conn);
470 * Curl_http_auth_act() gets called when all HTTP headers have been received
471 * and it checks what authentication methods that are available and decides
472 * which one (if any) to use. It will set 'newurl' if an auth method was
476 CURLcode Curl_http_auth_act(struct connectdata *conn)
478 struct Curl_easy *data = conn->data;
479 bool pickhost = FALSE;
480 bool pickproxy = FALSE;
481 CURLcode result = CURLE_OK;
483 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
484 /* this is a transient response code, ignore */
487 if(data->state.authproblem)
488 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
490 if(conn->bits.user_passwd &&
491 ((data->req.httpcode == 401) ||
492 (conn->bits.authneg && data->req.httpcode < 300))) {
493 pickhost = pickoneauth(&data->state.authhost);
495 data->state.authproblem = TRUE;
497 if(conn->bits.proxy_user_passwd &&
498 ((data->req.httpcode == 407) ||
499 (conn->bits.authneg && data->req.httpcode < 300))) {
500 pickproxy = pickoneauth(&data->state.authproxy);
502 data->state.authproblem = TRUE;
505 if(pickhost || pickproxy) {
506 /* In case this is GSS auth, the newurl field is already allocated so
507 we must make sure to free it before allocating a new one. As figured
508 out in bug #2284386 */
509 Curl_safefree(data->req.newurl);
510 data->req.newurl = strdup(data->change.url); /* clone URL */
511 if(!data->req.newurl)
512 return CURLE_OUT_OF_MEMORY;
514 if((data->set.httpreq != HTTPREQ_GET) &&
515 (data->set.httpreq != HTTPREQ_HEAD) &&
516 !conn->bits.rewindaftersend) {
517 result = http_perhapsrewind(conn);
522 else if((data->req.httpcode < 300) &&
523 (!data->state.authhost.done) &&
524 conn->bits.authneg) {
525 /* no (known) authentication available,
526 authentication is not "done" yet and
527 no authentication seems to be required and
528 we didn't try HEAD or GET */
529 if((data->set.httpreq != HTTPREQ_GET) &&
530 (data->set.httpreq != HTTPREQ_HEAD)) {
531 data->req.newurl = strdup(data->change.url); /* clone URL */
532 if(!data->req.newurl)
533 return CURLE_OUT_OF_MEMORY;
534 data->state.authhost.done = TRUE;
537 if(http_should_fail(conn)) {
538 failf(data, "The requested URL returned error: %d",
540 result = CURLE_HTTP_RETURNED_ERROR;
547 * Output the correct authentication header depending on the auth type
548 * and whether or not it is to a proxy.
551 output_auth_headers(struct connectdata *conn,
552 struct auth *authstatus,
557 const char *auth = NULL;
558 CURLcode result = CURLE_OK;
559 #if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
560 struct Curl_easy *data = conn->data;
563 struct negotiatedata *negdata = proxy ?
564 &data->state.proxyneg : &data->state.negotiate;
567 #ifdef CURL_DISABLE_CRYPTO_AUTH
573 negdata->state = GSS_AUTHNONE;
574 if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
575 negdata->context && !GSS_ERROR(negdata->status)) {
577 result = Curl_output_negotiate(conn, proxy);
580 authstatus->done = TRUE;
581 negdata->state = GSS_AUTHSENT;
586 if(authstatus->picked == CURLAUTH_NTLM) {
588 result = Curl_output_ntlm(conn, proxy);
594 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
595 if(authstatus->picked == CURLAUTH_NTLM_WB) {
597 result = Curl_output_ntlm_wb(conn, proxy);
603 #ifndef CURL_DISABLE_CRYPTO_AUTH
604 if(authstatus->picked == CURLAUTH_DIGEST) {
606 result = Curl_output_digest(conn,
608 (const unsigned char *)request,
609 (const unsigned char *)path);
615 if(authstatus->picked == CURLAUTH_BASIC) {
617 if((proxy && conn->bits.proxy_user_passwd &&
618 !Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
619 (!proxy && conn->bits.user_passwd &&
620 !Curl_checkheaders(conn, "Authorization"))) {
622 result = http_output_basic(conn, proxy);
627 /* NOTE: this function should set 'done' TRUE, as the other auth
628 functions work that way */
629 authstatus->done = TRUE;
633 infof(data, "%s auth using %s with user '%s'\n",
634 proxy ? "Proxy" : "Server", auth,
635 proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
636 (conn->user ? conn->user : ""));
637 authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
640 authstatus->multipass = FALSE;
646 * Curl_http_output_auth() setups the authentication headers for the
647 * host/proxy and the correct authentication
648 * method. conn->data->state.authdone is set to TRUE when authentication is
651 * @param conn all information about the current connection
652 * @param request pointer to the request keyword
653 * @param path pointer to the requested path
654 * @param proxytunnel boolean if this is the request setting up a "proxy
660 Curl_http_output_auth(struct connectdata *conn,
663 bool proxytunnel) /* TRUE if this is the request setting
664 up the proxy tunnel */
666 CURLcode result = CURLE_OK;
667 struct Curl_easy *data = conn->data;
668 struct auth *authhost;
669 struct auth *authproxy;
673 authhost = &data->state.authhost;
674 authproxy = &data->state.authproxy;
676 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
677 conn->bits.user_passwd)
678 /* continue please */;
680 authhost->done = TRUE;
681 authproxy->done = TRUE;
682 return CURLE_OK; /* no authentication with no user or password */
685 if(authhost->want && !authhost->picked)
686 /* The app has selected one or more methods, but none has been picked
687 so far by a server round-trip. Then we set the picked one to the
688 want one, and if this is one single bit it'll be used instantly. */
689 authhost->picked = authhost->want;
691 if(authproxy->want && !authproxy->picked)
692 /* The app has selected one or more methods, but none has been picked so
693 far by a proxy round-trip. Then we set the picked one to the want one,
694 and if this is one single bit it'll be used instantly. */
695 authproxy->picked = authproxy->want;
697 #ifndef CURL_DISABLE_PROXY
698 /* Send proxy authentication header if needed */
699 if(conn->bits.httpproxy &&
700 (conn->bits.tunnel_proxy == proxytunnel)) {
701 result = output_auth_headers(conn, authproxy, request, path, TRUE);
708 #endif /* CURL_DISABLE_PROXY */
709 /* we have no proxy so let's pretend we're done authenticating
711 authproxy->done = TRUE;
713 /* To prevent the user+password to get sent to other than the original
714 host due to a location-follow, we do some weirdo checks here */
715 if(!data->state.this_is_a_follow ||
717 !data->state.first_host ||
718 data->set.allow_auth_to_other_hosts ||
719 strcasecompare(data->state.first_host, conn->host.name)) {
720 result = output_auth_headers(conn, authhost, request, path, FALSE);
723 authhost->done = TRUE;
729 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
730 * headers. They are dealt with both in the transfer.c main loop and in the
731 * proxy CONNECT loop.
734 CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
735 const char *auth) /* the first non-space */
738 * This resource requires authentication
740 struct Curl_easy *data = conn->data;
743 struct negotiatedata *negdata = proxy?
744 &data->state.proxyneg:&data->state.negotiate;
746 unsigned long *availp;
750 availp = &data->info.proxyauthavail;
751 authp = &data->state.authproxy;
754 availp = &data->info.httpauthavail;
755 authp = &data->state.authhost;
759 * Here we check if we want the specific single authentication (using ==) and
760 * if we do, we initiate usage of it.
762 * If the provided authentication is wanted as one out of several accepted
763 * types (using &), we OR this authentication type to the authavail
768 * ->picked is first set to the 'want' value (one or more bits) before the
769 * request is sent, and then it is again set _after_ all response 401/407
770 * headers have been received but then only to a single preferred method
776 if(checkprefix("Negotiate", auth)) {
777 if((authp->avail & CURLAUTH_NEGOTIATE) ||
778 Curl_auth_is_spnego_supported()) {
779 *availp |= CURLAUTH_NEGOTIATE;
780 authp->avail |= CURLAUTH_NEGOTIATE;
782 if(authp->picked == CURLAUTH_NEGOTIATE) {
783 if(negdata->state == GSS_AUTHSENT ||
784 negdata->state == GSS_AUTHNONE) {
785 CURLcode result = Curl_input_negotiate(conn, proxy, auth);
787 DEBUGASSERT(!data->req.newurl);
788 data->req.newurl = strdup(data->change.url);
789 if(!data->req.newurl)
790 return CURLE_OUT_OF_MEMORY;
791 data->state.authproblem = FALSE;
792 /* we received a GSS auth token and we dealt with it fine */
793 negdata->state = GSS_AUTHRECV;
796 data->state.authproblem = TRUE;
804 /* NTLM support requires the SSL crypto libs */
805 if(checkprefix("NTLM", auth)) {
806 if((authp->avail & CURLAUTH_NTLM) ||
807 (authp->avail & CURLAUTH_NTLM_WB) ||
808 Curl_auth_is_ntlm_supported()) {
809 *availp |= CURLAUTH_NTLM;
810 authp->avail |= CURLAUTH_NTLM;
812 if(authp->picked == CURLAUTH_NTLM ||
813 authp->picked == CURLAUTH_NTLM_WB) {
814 /* NTLM authentication is picked and activated */
815 CURLcode result = Curl_input_ntlm(conn, proxy, auth);
817 data->state.authproblem = FALSE;
818 #ifdef NTLM_WB_ENABLED
819 if(authp->picked == CURLAUTH_NTLM_WB) {
820 *availp &= ~CURLAUTH_NTLM;
821 authp->avail &= ~CURLAUTH_NTLM;
822 *availp |= CURLAUTH_NTLM_WB;
823 authp->avail |= CURLAUTH_NTLM_WB;
825 /* Get the challenge-message which will be passed to
826 * ntlm_auth for generating the type 3 message later */
827 while(*auth && ISSPACE(*auth))
829 if(checkprefix("NTLM", auth)) {
830 auth += strlen("NTLM");
831 while(*auth && ISSPACE(*auth))
834 conn->challenge_header = strdup(auth);
835 if(!conn->challenge_header)
836 return CURLE_OUT_OF_MEMORY;
843 infof(data, "Authentication problem. Ignoring this.\n");
844 data->state.authproblem = TRUE;
851 #ifndef CURL_DISABLE_CRYPTO_AUTH
852 if(checkprefix("Digest", auth)) {
853 if((authp->avail & CURLAUTH_DIGEST) != 0)
854 infof(data, "Ignoring duplicate digest auth header.\n");
855 else if(Curl_auth_is_digest_supported()) {
858 *availp |= CURLAUTH_DIGEST;
859 authp->avail |= CURLAUTH_DIGEST;
861 /* We call this function on input Digest headers even if Digest
862 * authentication isn't activated yet, as we need to store the
863 * incoming data from this header in case we are going to use
865 result = Curl_input_digest(conn, proxy, auth);
867 infof(data, "Authentication problem. Ignoring this.\n");
868 data->state.authproblem = TRUE;
874 if(checkprefix("Basic", auth)) {
875 *availp |= CURLAUTH_BASIC;
876 authp->avail |= CURLAUTH_BASIC;
877 if(authp->picked == CURLAUTH_BASIC) {
878 /* We asked for Basic authentication but got a 40X back
879 anyway, which basically means our name+password isn't
881 authp->avail = CURLAUTH_NONE;
882 infof(data, "Authentication problem. Ignoring this.\n");
883 data->state.authproblem = TRUE;
887 /* there may be multiple methods on one line, so keep reading */
888 while(*auth && *auth != ',') /* read up to the next comma */
890 if(*auth == ',') /* if we're on a comma, skip it */
892 while(*auth && ISSPACE(*auth))
900 * http_should_fail() determines whether an HTTP response has gotten us
901 * into an error state or not.
903 * @param conn all information about the current connection
905 * @retval 0 communications should continue
907 * @retval 1 communications should not continue
909 static int http_should_fail(struct connectdata *conn)
911 struct Curl_easy *data;
918 httpcode = data->req.httpcode;
921 ** If we haven't been asked to fail on error,
924 if(!data->set.http_fail_on_error)
928 ** Any code < 400 is never terminal.
934 ** Any code >= 400 that's not 401 or 407 is always
937 if((httpcode != 401) && (httpcode != 407))
941 ** All we have left to deal with is 401 and 407
943 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
946 ** Examine the current authentication state to see if this
947 ** is an error. The idea is for this function to get
948 ** called after processing all the headers in a response
949 ** message. So, if we've been to asked to authenticate a
950 ** particular stage, and we've done it, we're OK. But, if
951 ** we're already completely authenticated, it's not OK to
952 ** get another 401 or 407.
954 ** It is possible for authentication to go stale such that
955 ** the client needs to reauthenticate. Once that info is
956 ** available, use it here.
960 ** Either we're not authenticating, or we're supposed to
961 ** be authenticating something else. This is an error.
963 if((httpcode == 401) && !conn->bits.user_passwd)
965 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
968 return data->state.authproblem;
972 * readmoredata() is a "fread() emulation" to provide POST and/or request
973 * data. It is used when a huge POST is to be made and the entire chunk wasn't
974 * sent in the first send(). This function will then be called from the
975 * transfer.c loop when more data is to be sent to the peer.
977 * Returns the amount of bytes it filled the buffer with.
979 static size_t readmoredata(char *buffer,
984 struct connectdata *conn = (struct connectdata *)userp;
985 struct HTTP *http = conn->data->req.protop;
986 size_t fullsize = size * nitems;
989 /* nothing to return */
992 /* make sure that a HTTP request is never sent away chunked! */
993 conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
995 if(http->postsize <= (curl_off_t)fullsize) {
996 memcpy(buffer, http->postdata, (size_t)http->postsize);
997 fullsize = (size_t)http->postsize;
999 if(http->backup.postsize) {
1000 /* move backup data into focus and continue on that */
1001 http->postdata = http->backup.postdata;
1002 http->postsize = http->backup.postsize;
1003 conn->data->state.fread_func = http->backup.fread_func;
1004 conn->data->state.in = http->backup.fread_in;
1006 http->sending++; /* move one step up */
1008 http->backup.postsize = 0;
1016 memcpy(buffer, http->postdata, fullsize);
1017 http->postdata += fullsize;
1018 http->postsize -= fullsize;
1023 /* ------------------------------------------------------------------------- */
1024 /* add_buffer functions */
1027 * Curl_add_buffer_init() sets up and returns a fine buffer struct
1029 Curl_send_buffer *Curl_add_buffer_init(void)
1031 return calloc(1, sizeof(Curl_send_buffer));
1035 * Curl_add_buffer_free() frees all associated resources.
1037 void Curl_add_buffer_free(Curl_send_buffer *buff)
1039 if(buff) /* deal with NULL input */
1045 * Curl_add_buffer_send() sends a header buffer and frees all associated
1046 * memory. Body data may be appended to the header data if desired.
1050 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
1051 struct connectdata *conn,
1053 /* add the number of sent bytes to this
1055 long *bytes_written,
1057 /* how much of the buffer contains body data */
1058 size_t included_body_bytes,
1066 struct HTTP *http = conn->data->req.protop;
1068 curl_socket_t sockfd;
1071 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1073 sockfd = conn->sock[socketindex];
1075 /* The looping below is required since we use non-blocking sockets, but due
1076 to the circumstances we will just loop and try again and again etc */
1079 size = in->size_used;
1081 headersize = size - included_body_bytes; /* the initial part that isn't body
1084 DEBUGASSERT(size > included_body_bytes);
1086 result = Curl_convert_to_network(conn->data, ptr, headersize);
1087 /* Curl_convert_to_network calls failf if unsuccessful */
1089 /* conversion failed, free memory and return to the caller */
1090 Curl_add_buffer_free(in);
1094 if((conn->handler->flags & PROTOPT_SSL ||
1095 conn->http_proxy.proxytype == CURLPROXY_HTTPS)
1096 && conn->httpversion != 20) {
1097 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1098 when we speak HTTPS, as if only a fraction of it is sent now, this data
1099 needs to fit into the normal read-callback buffer later on and that
1100 buffer is using this size.
1103 sendsize = CURLMIN(size, CURL_MAX_WRITE_SIZE);
1105 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1106 library when we attempt to re-send this buffer. Sending the same data
1107 is not enough, we must use the exact same address. For this reason, we
1108 must copy the data to the uploadbuffer first, since that is the buffer
1109 we will be using if this send is retried later.
1111 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1112 ptr = conn->data->state.uploadbuffer;
1117 result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1121 * Note that we may not send the entire chunk at once, and we have a set
1122 * number of data bytes at the end of the big buffer (out of which we may
1123 * only send away a part).
1125 /* how much of the header that was sent */
1126 size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
1127 size_t bodylen = amount - headlen;
1129 if(conn->data->set.verbose) {
1130 /* this data _may_ contain binary stuff */
1131 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1133 /* there was body data sent beyond the initial header part, pass that
1134 on to the debug callback too */
1135 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1136 ptr + headlen, bodylen, conn);
1140 /* 'amount' can never be a very large value here so typecasting it so a
1141 signed 31 bit value should not cause problems even if ssize_t is
1143 *bytes_written += (long)amount;
1146 /* if we sent a piece of the body here, up the byte counter for it
1148 http->writebytecount += bodylen;
1150 if((size_t)amount != size) {
1151 /* The whole request could not be sent in one system call. We must
1152 queue it up and send it later when we get the chance. We must not
1153 loop here and wait until it might work again. */
1157 ptr = in->buffer + amount;
1159 /* backup the currently set pointers */
1160 http->backup.fread_func = conn->data->state.fread_func;
1161 http->backup.fread_in = conn->data->state.in;
1162 http->backup.postdata = http->postdata;
1163 http->backup.postsize = http->postsize;
1165 /* set the new pointers for the request-sending */
1166 conn->data->state.fread_func = (curl_read_callback)readmoredata;
1167 conn->data->state.in = (void *)conn;
1168 http->postdata = ptr;
1169 http->postsize = (curl_off_t)size;
1171 http->send_buffer = in;
1172 http->sending = HTTPSEND_REQUEST;
1176 http->sending = HTTPSEND_BODY;
1177 /* the full buffer was sent, clean up and return */
1180 if((size_t)amount != size)
1181 /* We have no continue-send mechanism now, fail. This can only happen
1182 when this function is used from the CONNECT sending function. We
1183 currently (stupidly) assume that the whole request is always sent
1184 away in the first single chunk.
1188 return CURLE_SEND_ERROR;
1189 Curl_pipeline_leave_write(conn);
1192 Curl_add_buffer_free(in);
1199 * add_bufferf() add the formatted input to the buffer.
1201 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1206 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1210 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1214 /* If we failed, we cleanup the whole buffer and return error */
1217 return CURLE_OUT_OF_MEMORY;
1221 * add_buffer() appends a memory chunk to the existing buffer
1223 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1228 if(~size < in->size_used) {
1229 /* If resulting used size of send buffer would wrap size_t, cleanup
1230 the whole buffer and return error. Otherwise the required buffer
1231 size will fit into a single allocatable memory chunk */
1232 Curl_safefree(in->buffer);
1234 return CURLE_OUT_OF_MEMORY;
1238 ((in->size_used + size) > (in->size_max - 1))) {
1240 /* If current buffer size isn't enough to hold the result, use a
1241 buffer size that doubles the required size. If this new size
1242 would wrap size_t, then just use the largest possible one */
1244 if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
1245 (~(size * 2) < (in->size_used * 2)))
1246 new_size = (size_t)-1;
1248 new_size = (in->size_used + size) * 2;
1251 /* we have a buffer, enlarge the existing one */
1252 new_rb = Curl_saferealloc(in->buffer, new_size);
1254 /* create a new buffer */
1255 new_rb = malloc(new_size);
1258 /* If we failed, we cleanup the whole buffer and return error */
1260 return CURLE_OUT_OF_MEMORY;
1263 in->buffer = new_rb;
1264 in->size_max = new_size;
1266 memcpy(&in->buffer[in->size_used], inptr, size);
1268 in->size_used += size;
1273 /* end of the add_buffer functions */
1274 /* ------------------------------------------------------------------------- */
1279 * Curl_compareheader()
1281 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1282 * Pass headers WITH the colon.
1285 Curl_compareheader(const char *headerline, /* line to check */
1286 const char *header, /* header keyword _with_ colon */
1287 const char *content) /* content string to find */
1289 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1290 * by a colon (":") and the field value. Field names are case-insensitive.
1291 * The field value MAY be preceded by any amount of LWS, though a single SP
1294 size_t hlen = strlen(header);
1300 if(!strncasecompare(headerline, header, hlen))
1301 return FALSE; /* doesn't start with header */
1303 /* pass the header */
1304 start = &headerline[hlen];
1306 /* pass all white spaces */
1307 while(*start && ISSPACE(*start))
1310 /* find the end of the header line */
1311 end = strchr(start, '\r'); /* lines end with CRLF */
1313 /* in case there's a non-standard compliant line here */
1314 end = strchr(start, '\n');
1317 /* hm, there's no line ending here, use the zero byte! */
1318 end = strchr(start, '\0');
1321 len = end-start; /* length of the content part of the input line */
1322 clen = strlen(content); /* length of the word to find */
1324 /* find the content string in the rest of the line */
1325 for(; len >= clen; len--, start++) {
1326 if(strncasecompare(start, content, clen))
1327 return TRUE; /* match! */
1330 return FALSE; /* no match */
1334 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1335 * the generic Curl_connect().
1337 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1341 /* We default to persistent connections. We set this already in this connect
1342 function to make the re-use checks properly be able to check this bit. */
1343 connkeep(conn, "HTTP default");
1345 /* the CONNECT procedure might not have been completed */
1346 result = Curl_proxy_connect(conn, FIRSTSOCKET);
1350 if(conn->bits.proxy_connect_closed)
1351 /* this is not an error, just part of the connection negotiation */
1354 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
1355 return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
1357 if(Curl_connect_ongoing(conn))
1358 /* nothing else to do except wait right now - we're not done here. */
1361 if(conn->given->protocol & CURLPROTO_HTTPS) {
1362 /* perform SSL initialization */
1363 result = https_connecting(conn, done);
1373 /* this returns the socket to wait for in the DO and DOING state for the multi
1374 interface and then we're always _sending_ a request and thus we wait for
1375 the single socket to become writable only */
1376 static int http_getsock_do(struct connectdata *conn,
1377 curl_socket_t *socks,
1381 (void)numsocks; /* unused, we trust it to be at least 1 */
1382 socks[0] = conn->sock[FIRSTSOCKET];
1383 return GETSOCK_WRITESOCK(0);
1387 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1390 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1392 /* perform SSL initialization for this socket */
1393 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1395 connclose(conn, "Failed HTTPS connection");
1400 static int https_getsock(struct connectdata *conn,
1401 curl_socket_t *socks,
1404 if(conn->handler->flags & PROTOPT_SSL)
1405 return Curl_ssl_getsock(conn, socks, numsocks);
1406 return GETSOCK_BLANK;
1408 #endif /* USE_SSL */
1411 * Curl_http_done() gets called after a single HTTP request has been
1415 CURLcode Curl_http_done(struct connectdata *conn,
1416 CURLcode status, bool premature)
1418 struct Curl_easy *data = conn->data;
1419 struct HTTP *http = data->req.protop;
1421 /* Clear multipass flag. If authentication isn't done yet, then it will get
1422 * a chance to be set back to true when we output the next auth header */
1423 data->state.authhost.multipass = FALSE;
1424 data->state.authproxy.multipass = FALSE;
1426 Curl_unencode_cleanup(conn);
1429 if(data->state.proxyneg.state == GSS_AUTHSENT ||
1430 data->state.negotiate.state == GSS_AUTHSENT) {
1431 /* add forbid re-use if http-code != 401/407 as a WA only needed for
1432 * 401/407 that signal auth failure (empty) otherwise state will be RECV
1433 * with current code.
1434 * Do not close CONNECT_ONLY connections. */
1435 if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
1436 !data->set.connect_only)
1437 streamclose(conn, "Negotiate transfer completed");
1438 Curl_cleanup_negotiate(data);
1442 /* set the proper values (possibly modified on POST) */
1443 conn->seek_func = data->set.seek_func; /* restore */
1444 conn->seek_client = data->set.seek_client; /* restore */
1449 if(http->send_buffer) {
1450 Curl_add_buffer_free(http->send_buffer);
1451 http->send_buffer = NULL; /* clear the pointer */
1454 Curl_http2_done(conn, premature);
1456 Curl_mime_cleanpart(&http->form);
1458 switch(data->set.httpreq) {
1460 case HTTPREQ_POST_FORM:
1461 case HTTPREQ_POST_MIME:
1462 data->req.bytecount = http->readbytecount + http->writebytecount;
1471 if(!premature && /* this check is pointless when DONE is called before the
1472 entire operation is complete */
1473 !conn->bits.retry &&
1474 !data->set.connect_only &&
1475 (http->readbytecount +
1476 data->req.headerbytecount -
1477 data->req.deductheadercount) <= 0) {
1478 /* If this connection isn't simply closed to be retried, AND nothing was
1479 read from the HTTP server (that counts), this can't be right so we
1480 return an error here */
1481 failf(data, "Empty reply from server");
1482 return CURLE_GOT_NOTHING;
1489 * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
1490 * to avoid it include:
1492 * - if the user specifically requested HTTP 1.0
1493 * - if the server we are connected to only supports 1.0
1494 * - if any server previously contacted to handle this request only supports
1497 static bool use_http_1_1plus(const struct Curl_easy *data,
1498 const struct connectdata *conn)
1500 if((data->state.httpversion == 10) || (conn->httpversion == 10))
1502 if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
1503 (conn->httpversion <= 10))
1505 return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
1506 (data->set.httpversion >= CURL_HTTP_VERSION_1_1));
1509 static const char *get_http_string(const struct Curl_easy *data,
1510 const struct connectdata *conn)
1513 if(conn->proto.httpc.h2)
1517 if(use_http_1_1plus(data, conn))
1523 /* check and possibly add an Expect: header */
1524 static CURLcode expect100(struct Curl_easy *data,
1525 struct connectdata *conn,
1526 Curl_send_buffer *req_buffer)
1528 CURLcode result = CURLE_OK;
1530 data->state.expect100header = FALSE; /* default to false unless it is set
1532 if(use_http_1_1plus(data, conn) &&
1533 (conn->httpversion != 20)) {
1534 /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
1535 Expect: 100-continue to the headers which actually speeds up post
1536 operations (as there is one packet coming back from the web server) */
1537 ptr = Curl_checkheaders(conn, "Expect");
1539 data->state.expect100header =
1540 Curl_compareheader(ptr, "Expect:", "100-continue");
1543 result = Curl_add_bufferf(req_buffer,
1544 "Expect: 100-continue\r\n");
1546 data->state.expect100header = TRUE;
1554 HEADER_SERVER, /* direct to server */
1555 HEADER_PROXY, /* regular request to proxy */
1556 HEADER_CONNECT /* sending CONNECT to a proxy */
1559 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1561 Curl_send_buffer *req_buffer)
1564 struct curl_slist *h[2];
1565 struct curl_slist *headers;
1566 int numlists = 1; /* by default */
1567 struct Curl_easy *data = conn->data;
1570 enum proxy_use proxy;
1573 proxy = HEADER_CONNECT;
1575 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
1576 HEADER_PROXY:HEADER_SERVER;
1580 h[0] = data->set.headers;
1583 h[0] = data->set.headers;
1584 if(data->set.sep_headers) {
1585 h[1] = data->set.proxyheaders;
1589 case HEADER_CONNECT:
1590 if(data->set.sep_headers)
1591 h[0] = data->set.proxyheaders;
1593 h[0] = data->set.headers;
1597 /* loop through one or two lists */
1598 for(i = 0; i < numlists; i++) {
1602 char *semicolonp = NULL;
1603 ptr = strchr(headers->data, ':');
1606 /* no colon, semicolon? */
1607 ptr = strchr(headers->data, ';');
1610 ptr++; /* pass the semicolon */
1611 while(*ptr && ISSPACE(*ptr))
1615 /* this may be used for something else in the future */
1619 if(*(--ptr) == ';') {
1620 /* send no-value custom header if terminated by semicolon */
1629 /* we require a colon for this to be a true header */
1631 ptr++; /* pass the colon */
1632 while(*ptr && ISSPACE(*ptr))
1635 if(*ptr || semicolonp) {
1636 /* only send this if the contents was non-blank or done special */
1637 CURLcode result = CURLE_OK;
1639 if(conn->allocptr.host &&
1640 /* a Host: header was sent already, don't pass on any custom Host:
1641 header as that will produce *two* in the same request! */
1642 checkprefix("Host:", headers->data))
1644 else if(data->set.httpreq == HTTPREQ_POST_FORM &&
1645 /* this header (extended by formdata.c) is sent later */
1646 checkprefix("Content-Type:", headers->data))
1648 else if(data->set.httpreq == HTTPREQ_POST_MIME &&
1649 /* this header is sent later */
1650 checkprefix("Content-Type:", headers->data))
1652 else if(conn->bits.authneg &&
1653 /* while doing auth neg, don't allow the custom length since
1654 we will force length zero then */
1655 checkprefix("Content-Length:", headers->data))
1657 else if(conn->allocptr.te &&
1658 /* when asking for Transfer-Encoding, don't pass on a custom
1660 checkprefix("Connection:", headers->data))
1662 else if((conn->httpversion == 20) &&
1663 checkprefix("Transfer-Encoding:", headers->data))
1664 /* HTTP/2 doesn't support chunked requests */
1666 else if(checkprefix("Authorization:", headers->data) &&
1667 /* be careful of sending this potentially sensitive header to
1669 (data->state.this_is_a_follow &&
1670 data->state.first_host &&
1671 !data->set.allow_auth_to_other_hosts &&
1672 !strcasecompare(data->state.first_host, conn->host.name)))
1675 result = Curl_add_bufferf(req_buffer, "%s\r\n", headers->data);
1678 *semicolonp = ';'; /* put back the semicolon */
1683 headers = headers->next;
1690 CURLcode Curl_add_timecondition(struct Curl_easy *data,
1691 Curl_send_buffer *req_buffer)
1693 const struct tm *tm;
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 switch(data->set.timecondition) {
1712 return CURLE_BAD_FUNCTION_ARGUMENT;
1714 case CURL_TIMECOND_IFMODSINCE:
1715 condp = "If-Modified-Since";
1717 case CURL_TIMECOND_IFUNMODSINCE:
1718 condp = "If-Unmodified-Since";
1720 case CURL_TIMECOND_LASTMOD:
1721 condp = "Last-Modified";
1725 /* The If-Modified-Since header family should have their times set in
1726 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1727 * represented in Greenwich Mean Time (GMT), without exception. For the
1728 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1729 * Time)." (see page 20 of RFC2616).
1732 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1733 snprintf(datestr, sizeof(datestr),
1734 "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
1736 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1738 Curl_month[tm->tm_mon],
1744 result = Curl_add_buffer(req_buffer, datestr, strlen(datestr));
1750 * Curl_http() gets called from the generic multi_do() function when a HTTP
1751 * request is to be performed. This creates and sends a properly constructed
1754 CURLcode Curl_http(struct connectdata *conn, bool *done)
1756 struct Curl_easy *data = conn->data;
1757 CURLcode result = CURLE_OK;
1759 const char *ppath = data->state.path;
1760 bool paste_ftp_userpwd = FALSE;
1761 char ftp_typecode[sizeof("/;type=?")] = "";
1762 const char *host = conn->host.name;
1763 const char *te = ""; /* transfer-encoding */
1765 const char *request;
1766 Curl_HttpReq httpreq = data->set.httpreq;
1767 #if !defined(CURL_DISABLE_COOKIES)
1768 char *addcookies = NULL;
1770 curl_off_t included_body = 0;
1771 const char *httpstring;
1772 Curl_send_buffer *req_buffer;
1773 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1774 int seekerr = CURL_SEEKFUNC_CANTSEEK;
1776 /* Always consider the DO phase done after this function call, even if there
1777 may be parts of the request that is not yet sent, since we can deal with
1778 the rest of the request in the PERFORM phase. */
1781 if(conn->httpversion < 20) { /* unless the connection is re-used and already
1783 switch(conn->negnpn) {
1784 case CURL_HTTP_VERSION_2:
1785 conn->httpversion = 20; /* we know we're on HTTP/2 now */
1787 result = Curl_http2_switched(conn, NULL, 0);
1791 case CURL_HTTP_VERSION_1_1:
1792 /* continue with HTTP/1.1 when explicitly requested */
1795 /* Check if user wants to use HTTP/2 with clear TCP*/
1797 if(conn->data->set.httpversion ==
1798 CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
1799 DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
1800 conn->httpversion = 20;
1802 result = Curl_http2_switched(conn, NULL, 0);
1811 /* prepare for a http2 request */
1812 result = Curl_http2_setup(conn);
1817 http = data->req.protop;
1819 if(!data->state.this_is_a_follow) {
1820 /* Free to avoid leaking memory on multiple requests*/
1821 free(data->state.first_host);
1823 data->state.first_host = strdup(conn->host.name);
1824 if(!data->state.first_host)
1825 return CURLE_OUT_OF_MEMORY;
1827 data->state.first_remote_port = conn->remote_port;
1829 http->writebytecount = http->readbytecount = 0;
1831 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
1833 httpreq = HTTPREQ_PUT;
1836 /* Now set the 'request' pointer to the proper request string */
1837 if(data->set.str[STRING_CUSTOMREQUEST])
1838 request = data->set.str[STRING_CUSTOMREQUEST];
1840 if(data->set.opt_no_body)
1843 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1846 case HTTPREQ_POST_FORM:
1847 case HTTPREQ_POST_MIME:
1853 case HTTPREQ_OPTIONS:
1854 request = "OPTIONS";
1856 default: /* this should never happen */
1867 /* The User-Agent string might have been allocated in url.c already, because
1868 it might have been used in the proxy connect, but if we have got a header
1869 with the user-agent string specified, we erase the previously made string
1871 if(Curl_checkheaders(conn, "User-Agent")) {
1872 free(conn->allocptr.uagent);
1873 conn->allocptr.uagent = NULL;
1876 /* setup the authentication headers */
1877 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1881 if((data->state.authhost.multipass || data->state.authproxy.multipass) &&
1882 (httpreq != HTTPREQ_GET) &&
1883 (httpreq != HTTPREQ_HEAD)) {
1884 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1885 with content-length zero as a "probe". */
1886 conn->bits.authneg = TRUE;
1889 conn->bits.authneg = FALSE;
1891 Curl_safefree(conn->allocptr.ref);
1892 if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
1893 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1894 if(!conn->allocptr.ref)
1895 return CURLE_OUT_OF_MEMORY;
1898 conn->allocptr.ref = NULL;
1900 #if !defined(CURL_DISABLE_COOKIES)
1901 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie"))
1902 addcookies = data->set.str[STRING_COOKIE];
1905 if(!Curl_checkheaders(conn, "Accept-Encoding") &&
1906 data->set.str[STRING_ENCODING]) {
1907 Curl_safefree(conn->allocptr.accept_encoding);
1908 conn->allocptr.accept_encoding =
1909 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1910 if(!conn->allocptr.accept_encoding)
1911 return CURLE_OUT_OF_MEMORY;
1914 Curl_safefree(conn->allocptr.accept_encoding);
1915 conn->allocptr.accept_encoding = NULL;
1919 /* we only consider transfer-encoding magic if libz support is built-in */
1921 if(!Curl_checkheaders(conn, "TE") &&
1922 data->set.http_transfer_encoding) {
1923 /* When we are to insert a TE: header in the request, we must also insert
1924 TE in a Connection: header, so we need to merge the custom provided
1925 Connection: header and prevent the original to get sent. Note that if
1926 the user has inserted his/hers own TE: header we don't do this magic
1927 but then assume that the user will handle it all! */
1928 char *cptr = Curl_checkheaders(conn, "Connection");
1929 #define TE_HEADER "TE: gzip\r\n"
1931 Curl_safefree(conn->allocptr.te);
1934 cptr = Curl_copy_header_value(cptr);
1936 return CURLE_OUT_OF_MEMORY;
1939 /* Create the (updated) Connection: header */
1940 conn->allocptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
1941 cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
1944 if(!conn->allocptr.te)
1945 return CURLE_OUT_OF_MEMORY;
1950 case HTTPREQ_POST_MIME:
1951 http->sendit = &data->set.mimepost;
1953 case HTTPREQ_POST_FORM:
1954 /* Convert the form structure into a mime structure. */
1955 Curl_mime_cleanpart(&http->form);
1956 result = Curl_getformdata(data, &http->form, data->set.httppost,
1957 data->state.fread_func);
1960 http->sendit = &http->form;
1963 http->sendit = NULL;
1967 const char *cthdr = Curl_checkheaders(conn, "Content-Type");
1969 /* Read and seek body only. */
1970 http->sendit->flags |= MIME_BODY_ONLY;
1972 /* Prepare the mime structure headers & set content type. */
1975 for(cthdr += 13; *cthdr == ' '; cthdr++)
1977 else if(http->sendit->kind == MIMEKIND_MULTIPART)
1978 cthdr = "multipart/form-data";
1980 curl_mime_headers(http->sendit, data->set.headers, 0);
1981 result = Curl_mime_prepare_headers(http->sendit, cthdr,
1982 NULL, MIMESTRATEGY_FORM);
1983 curl_mime_headers(http->sendit, NULL, 0);
1985 result = Curl_mime_rewind(http->sendit);
1988 http->postsize = Curl_mime_size(http->sendit);
1991 ptr = Curl_checkheaders(conn, "Transfer-Encoding");
1993 /* Some kind of TE is requested, check if 'chunked' is chosen */
1994 data->req.upload_chunky =
1995 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1998 if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
1999 (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
2000 http->postsize < 0) ||
2001 (data->set.upload && data->state.infilesize == -1))) {
2002 if(conn->bits.authneg)
2003 /* don't enable chunked during auth neg */
2005 else if(use_http_1_1plus(data, conn)) {
2006 /* HTTP, upload, unknown file size and not HTTP 1.0 */
2007 data->req.upload_chunky = TRUE;
2010 failf(data, "Chunky upload is not supported by HTTP 1.0");
2011 return CURLE_UPLOAD_FAILED;
2015 /* else, no chunky upload */
2016 data->req.upload_chunky = FALSE;
2019 if(data->req.upload_chunky)
2020 te = "Transfer-Encoding: chunked\r\n";
2023 Curl_safefree(conn->allocptr.host);
2025 ptr = Curl_checkheaders(conn, "Host");
2026 if(ptr && (!data->state.this_is_a_follow ||
2027 strcasecompare(data->state.first_host, conn->host.name))) {
2028 #if !defined(CURL_DISABLE_COOKIES)
2029 /* If we have a given custom Host: header, we extract the host name in
2030 order to possibly use it for cookie reasons later on. We only allow the
2031 custom Host: header if this is NOT a redirect, as setting Host: in the
2032 redirected request is being out on thin ice. Except if the host name
2033 is the same as the first one! */
2034 char *cookiehost = Curl_copy_header_value(ptr);
2036 return CURLE_OUT_OF_MEMORY;
2038 /* ignore empty data */
2041 /* If the host begins with '[', we start searching for the port after
2042 the bracket has been closed */
2043 int startsearch = 0;
2044 if(*cookiehost == '[') {
2045 char *closingbracket;
2046 /* since the 'cookiehost' is an allocated memory area that will be
2047 freed later we cannot simply increment the pointer */
2048 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
2049 closingbracket = strchr(cookiehost, ']');
2051 *closingbracket = 0;
2054 char *colon = strchr(cookiehost + startsearch, ':');
2056 *colon = 0; /* The host must not include an embedded port number */
2058 Curl_safefree(conn->allocptr.cookiehost);
2059 conn->allocptr.cookiehost = cookiehost;
2063 if(strcmp("Host:", ptr)) {
2064 conn->allocptr.host = aprintf("Host:%s\r\n", &ptr[5]);
2065 if(!conn->allocptr.host)
2066 return CURLE_OUT_OF_MEMORY;
2069 /* when clearing the header */
2070 conn->allocptr.host = NULL;
2073 /* When building Host: headers, we must put the host name within
2074 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
2076 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
2077 (conn->remote_port == PORT_HTTPS)) ||
2078 ((conn->given->protocol&CURLPROTO_HTTP) &&
2079 (conn->remote_port == PORT_HTTP)) )
2080 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
2081 the port number in the host string */
2082 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
2083 conn->bits.ipv6_ip?"[":"",
2085 conn->bits.ipv6_ip?"]":"");
2087 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
2088 conn->bits.ipv6_ip?"[":"",
2090 conn->bits.ipv6_ip?"]":"",
2093 if(!conn->allocptr.host)
2094 /* without Host: we can't make a nice request */
2095 return CURLE_OUT_OF_MEMORY;
2098 #ifndef CURL_DISABLE_PROXY
2099 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
2100 /* Using a proxy but does not tunnel through it */
2102 /* The path sent to the proxy is in fact the entire URL. But if the remote
2103 host is a IDN-name, we must make sure that the request we produce only
2104 uses the encoded host name! */
2105 if(conn->host.dispname != conn->host.name) {
2106 char *url = data->change.url;
2107 ptr = strstr(url, conn->host.dispname);
2109 /* This is where the display name starts in the URL, now replace this
2110 part with the encoded name. TODO: This method of replacing the host
2111 name is rather crude as I believe there's a slight risk that the
2112 user has entered a user name or password that contain the host name
2114 size_t currlen = strlen(conn->host.dispname);
2115 size_t newlen = strlen(conn->host.name);
2116 size_t urllen = strlen(url);
2120 newurl = malloc(urllen + newlen - currlen + 1);
2122 /* copy the part before the host name */
2123 memcpy(newurl, url, ptr - url);
2124 /* append the new host name instead of the old */
2125 memcpy(newurl + (ptr - url), conn->host.name, newlen);
2126 /* append the piece after the host name */
2127 memcpy(newurl + newlen + (ptr - url),
2128 ptr + currlen, /* copy the trailing zero byte too */
2129 urllen - (ptr-url) - currlen + 1);
2130 if(data->change.url_alloc) {
2131 Curl_safefree(data->change.url);
2132 data->change.url_alloc = FALSE;
2134 data->change.url = newurl;
2135 data->change.url_alloc = TRUE;
2138 return CURLE_OUT_OF_MEMORY;
2141 ppath = data->change.url;
2142 if(checkprefix("ftp://", ppath)) {
2143 if(data->set.proxy_transfer_mode) {
2144 /* when doing ftp, append ;type=<a|i> if not present */
2145 char *type = strstr(ppath, ";type=");
2146 if(type && type[6] && type[7] == 0) {
2147 switch(Curl_raw_toupper(type[6])) {
2157 char *p = ftp_typecode;
2158 /* avoid sending invalid URLs like ftp://example.com;type=i if the
2159 * user specified ftp://example.com without the slash */
2160 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
2163 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
2164 data->set.prefer_ascii ? 'a' : 'i');
2167 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
2168 paste_ftp_userpwd = TRUE;
2171 #endif /* CURL_DISABLE_PROXY */
2173 http->p_accept = Curl_checkheaders(conn, "Accept")?NULL:"Accept: */*\r\n";
2175 if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) &&
2176 data->state.resume_from) {
2177 /**********************************************************************
2178 * Resuming upload in HTTP means that we PUT or POST and that we have
2179 * got a resume_from value set. The resume value has already created
2180 * a Range: header that will be passed along. We need to "fast forward"
2181 * the file the given number of bytes and decrease the assume upload
2182 * file size before we continue this venture in the dark lands of HTTP.
2183 * Resuming mime/form posting at an offset > 0 has no sense and is ignored.
2184 *********************************************************************/
2186 if(data->state.resume_from < 0) {
2188 * This is meant to get the size of the present remote-file by itself.
2189 * We don't support this now. Bail out!
2191 data->state.resume_from = 0;
2194 if(data->state.resume_from && !data->state.this_is_a_follow) {
2195 /* do we still game? */
2197 /* Now, let's read off the proper amount of bytes from the
2199 if(conn->seek_func) {
2200 Curl_set_in_callback(data, true);
2201 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2203 Curl_set_in_callback(data, false);
2206 if(seekerr != CURL_SEEKFUNC_OK) {
2207 curl_off_t passed = 0;
2209 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2210 failf(data, "Could not seek stream");
2211 return CURLE_READ_ERROR;
2213 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2215 size_t readthisamountnow =
2216 (data->state.resume_from - passed > data->set.buffer_size) ?
2217 (size_t)data->set.buffer_size :
2218 curlx_sotouz(data->state.resume_from - passed);
2220 size_t actuallyread =
2221 data->state.fread_func(data->state.buffer, 1, readthisamountnow,
2224 passed += actuallyread;
2225 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2226 /* this checks for greater-than only to make sure that the
2227 CURL_READFUNC_ABORT return code still aborts */
2228 failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2229 " bytes from the input", passed);
2230 return CURLE_READ_ERROR;
2232 } while(passed < data->state.resume_from);
2235 /* now, decrease the size of the read */
2236 if(data->state.infilesize>0) {
2237 data->state.infilesize -= data->state.resume_from;
2239 if(data->state.infilesize <= 0) {
2240 failf(data, "File already completely uploaded");
2241 return CURLE_PARTIAL_FILE;
2244 /* we've passed, proceed as normal */
2247 if(data->state.use_range) {
2249 * A range is selected. We use different headers whether we're downloading
2250 * or uploading and we always let customized headers override our internal
2251 * ones if any such are specified.
2253 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2254 !Curl_checkheaders(conn, "Range")) {
2255 /* if a line like this was already allocated, free the previous one */
2256 free(conn->allocptr.rangeline);
2257 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2260 else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
2261 !Curl_checkheaders(conn, "Content-Range")) {
2263 /* if a line like this was already allocated, free the previous one */
2264 free(conn->allocptr.rangeline);
2266 if(data->set.set_resume_from < 0) {
2267 /* Upload resume was asked for, but we don't know the size of the
2268 remote part so we tell the server (and act accordingly) that we
2269 upload the whole file (again) */
2270 conn->allocptr.rangeline =
2271 aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2272 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2273 data->state.infilesize - 1, data->state.infilesize);
2276 else if(data->state.resume_from) {
2277 /* This is because "resume" was selected */
2278 curl_off_t total_expected_size =
2279 data->state.resume_from + data->state.infilesize;
2280 conn->allocptr.rangeline =
2281 aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2282 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2283 data->state.range, total_expected_size-1,
2284 total_expected_size);
2287 /* Range was selected and then we just pass the incoming range and
2288 append total size */
2289 conn->allocptr.rangeline =
2290 aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2291 data->state.range, data->state.infilesize);
2293 if(!conn->allocptr.rangeline)
2294 return CURLE_OUT_OF_MEMORY;
2298 httpstring = get_http_string(data, conn);
2300 /* initialize a dynamic send-buffer */
2301 req_buffer = Curl_add_buffer_init();
2304 return CURLE_OUT_OF_MEMORY;
2306 /* add the main request stuff */
2307 /* GET/HEAD/POST/PUT */
2308 result = Curl_add_bufferf(req_buffer, "%s ", request);
2312 if(data->set.str[STRING_TARGET])
2313 ppath = data->set.str[STRING_TARGET];
2316 if(paste_ftp_userpwd)
2317 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2318 conn->user, conn->passwd,
2319 ppath + sizeof("ftp://") - 1);
2321 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2326 Curl_add_bufferf(req_buffer,
2327 "%s" /* ftp typecode (;type=x) */
2328 " HTTP/%s\r\n" /* HTTP version */
2330 "%s" /* proxyuserpwd */
2333 "%s" /* user agent */
2336 "%s" /* accept-encoding */
2338 "%s" /* Proxy-Connection */
2339 "%s",/* transfer-encoding */
2343 (conn->allocptr.host?conn->allocptr.host:""),
2344 conn->allocptr.proxyuserpwd?
2345 conn->allocptr.proxyuserpwd:"",
2346 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2347 (data->state.use_range && conn->allocptr.rangeline)?
2348 conn->allocptr.rangeline:"",
2349 (data->set.str[STRING_USERAGENT] &&
2350 *data->set.str[STRING_USERAGENT] &&
2351 conn->allocptr.uagent)?
2352 conn->allocptr.uagent:"",
2353 http->p_accept?http->p_accept:"",
2354 conn->allocptr.te?conn->allocptr.te:"",
2355 (data->set.str[STRING_ENCODING] &&
2356 *data->set.str[STRING_ENCODING] &&
2357 conn->allocptr.accept_encoding)?
2358 conn->allocptr.accept_encoding:"",
2359 (data->change.referer && conn->allocptr.ref)?
2360 conn->allocptr.ref:"" /* Referer: <data> */,
2361 (conn->bits.httpproxy &&
2362 !conn->bits.tunnel_proxy &&
2363 !Curl_checkProxyheaders(conn, "Proxy-Connection"))?
2364 "Proxy-Connection: Keep-Alive\r\n":"",
2368 /* clear userpwd and proxyuserpwd to avoid re-using old credentials
2369 * from re-used connections */
2370 Curl_safefree(conn->allocptr.userpwd);
2371 Curl_safefree(conn->allocptr.proxyuserpwd);
2376 if(!(conn->handler->flags&PROTOPT_SSL) &&
2377 conn->httpversion != 20 &&
2378 (data->set.httpversion == CURL_HTTP_VERSION_2)) {
2379 /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
2381 result = Curl_http2_request_upgrade(req_buffer, conn);
2386 #if !defined(CURL_DISABLE_COOKIES)
2387 if(data->cookies || addcookies) {
2388 struct Cookie *co = NULL; /* no cookies from start */
2392 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2393 co = Curl_cookie_getlist(data->cookies,
2394 conn->allocptr.cookiehost?
2395 conn->allocptr.cookiehost:host,
2397 (conn->handler->protocol&CURLPROTO_HTTPS)?
2399 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2402 struct Cookie *store = co;
2403 /* now loop through all cookies that matched */
2407 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2411 result = Curl_add_bufferf(req_buffer,
2412 "%s%s=%s", count?"; ":"",
2413 co->name, co->value);
2418 co = co->next; /* next cookie please */
2420 Curl_cookie_freelist(store);
2422 if(addcookies && !result) {
2424 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2426 result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
2431 if(count && !result)
2432 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2439 result = Curl_add_timecondition(data, req_buffer);
2443 result = Curl_add_custom_headers(conn, FALSE, req_buffer);
2447 http->postdata = NULL; /* nothing to post at this point */
2448 Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
2450 /* If 'authdone' is FALSE, we must not set the write socket index to the
2451 Curl_transfer() call below, as we're not ready to actually upload any
2456 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2458 if(conn->bits.authneg)
2461 postsize = data->state.infilesize;
2463 if((postsize != -1) && !data->req.upload_chunky &&
2464 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
2465 /* only add Content-Length if not uploading chunked */
2466 result = Curl_add_bufferf(req_buffer,
2467 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2474 result = expect100(data, conn, req_buffer);
2479 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2483 /* set the upload size to the progress meter */
2484 Curl_pgrsSetUploadSize(data, postsize);
2486 /* this sends the buffer and frees all the buffer resources */
2487 result = Curl_add_buffer_send(req_buffer, conn,
2488 &data->info.request_size, 0, FIRSTSOCKET);
2490 failf(data, "Failed sending PUT request");
2492 /* prepare for transfer */
2493 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2494 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2495 postsize?&http->writebytecount:NULL);
2500 case HTTPREQ_POST_FORM:
2501 case HTTPREQ_POST_MIME:
2502 /* This is form posting using mime data. */
2503 if(conn->bits.authneg) {
2504 /* nothing to post! */
2505 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2509 result = Curl_add_buffer_send(req_buffer, conn,
2510 &data->info.request_size, 0, FIRSTSOCKET);
2512 failf(data, "Failed sending POST request");
2514 /* setup variables for the upcoming transfer */
2515 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2520 postsize = http->postsize;
2522 /* We only set Content-Length and allow a custom Content-Length if
2523 we don't upload data chunked, as RFC2616 forbids us to set both
2524 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2525 if(postsize != -1 && !data->req.upload_chunky &&
2526 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
2527 /* we allow replacing this header if not during auth negotiation,
2528 although it isn't very wise to actually set your own */
2529 result = Curl_add_bufferf(req_buffer,
2530 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2536 /* Output mime-generated headers. */
2538 struct curl_slist *hdr;
2540 for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) {
2541 result = Curl_add_bufferf(req_buffer, "%s\r\n", hdr->data);
2547 /* For really small posts we don't use Expect: headers at all, and for
2548 the somewhat bigger ones we allow the app to disable it. Just make
2549 sure that the expect100header is always set to the preferred value
2551 ptr = Curl_checkheaders(conn, "Expect");
2553 data->state.expect100header =
2554 Curl_compareheader(ptr, "Expect:", "100-continue");
2556 else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
2557 result = expect100(data, conn, req_buffer);
2562 data->state.expect100header = FALSE;
2564 /* make the request end in a true CRLF */
2565 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2569 /* set the upload size to the progress meter */
2570 Curl_pgrsSetUploadSize(data, postsize);
2572 /* Read from mime structure. */
2573 data->state.fread_func = (curl_read_callback) Curl_mime_read;
2574 data->state.in = (void *) http->sendit;
2575 http->sending = HTTPSEND_BODY;
2577 /* this sends the buffer and frees all the buffer resources */
2578 result = Curl_add_buffer_send(req_buffer, conn,
2579 &data->info.request_size, 0, FIRSTSOCKET);
2581 failf(data, "Failed sending POST request");
2583 /* prepare for transfer */
2584 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2585 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2586 postsize?&http->writebytecount:NULL);
2593 /* this is the simple POST, using x-www-form-urlencoded style */
2595 if(conn->bits.authneg)
2598 /* the size of the post body */
2599 postsize = data->state.infilesize;
2601 /* We only set Content-Length and allow a custom Content-Length if
2602 we don't upload data chunked, as RFC2616 forbids us to set both
2603 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2604 if((postsize != -1) && !data->req.upload_chunky &&
2605 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
2606 /* we allow replacing this header if not during auth negotiation,
2607 although it isn't very wise to actually set your own */
2608 result = Curl_add_bufferf(req_buffer,
2609 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2615 if(!Curl_checkheaders(conn, "Content-Type")) {
2616 result = Curl_add_bufferf(req_buffer,
2617 "Content-Type: application/"
2618 "x-www-form-urlencoded\r\n");
2623 /* For really small posts we don't use Expect: headers at all, and for
2624 the somewhat bigger ones we allow the app to disable it. Just make
2625 sure that the expect100header is always set to the preferred value
2627 ptr = Curl_checkheaders(conn, "Expect");
2629 data->state.expect100header =
2630 Curl_compareheader(ptr, "Expect:", "100-continue");
2632 else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
2633 result = expect100(data, conn, req_buffer);
2638 data->state.expect100header = FALSE;
2640 if(data->set.postfields) {
2642 /* In HTTP2, we send request body in DATA frame regardless of
2644 if(conn->httpversion != 20 &&
2645 !data->state.expect100header &&
2646 (postsize < MAX_INITIAL_POST_SIZE)) {
2647 /* if we don't use expect: 100 AND
2648 postsize is less than MAX_INITIAL_POST_SIZE
2650 then append the post data to the HTTP request header. This limit
2651 is no magic limit but only set to prevent really huge POSTs to
2652 get the data duplicated with malloc() and family. */
2654 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2658 if(!data->req.upload_chunky) {
2659 /* We're not sending it 'chunked', append it to the request
2660 already now to reduce the number if send() calls */
2661 result = Curl_add_buffer(req_buffer, data->set.postfields,
2663 included_body = postsize;
2667 /* Append the POST data chunky-style */
2668 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2670 result = Curl_add_buffer(req_buffer, data->set.postfields,
2673 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2674 included_body = postsize + 2;
2678 result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
2684 /* Make sure the progress information is accurate */
2685 Curl_pgrsSetUploadSize(data, postsize);
2688 /* A huge POST coming up, do data separate from the request */
2689 http->postsize = postsize;
2690 http->postdata = data->set.postfields;
2692 http->sending = HTTPSEND_BODY;
2694 data->state.fread_func = (curl_read_callback)readmoredata;
2695 data->state.in = (void *)conn;
2697 /* set the upload size to the progress meter */
2698 Curl_pgrsSetUploadSize(data, http->postsize);
2700 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2706 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2710 if(data->req.upload_chunky && conn->bits.authneg) {
2711 /* Chunky upload is selected and we're negotiating auth still, send
2713 result = Curl_add_buffer(req_buffer,
2714 "\x30\x0d\x0a\x0d\x0a", 5);
2720 else if(data->state.infilesize) {
2721 /* set the upload size to the progress meter */
2722 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2724 /* set the pointer to mark that we will send the post body using the
2725 read callback, but only if we're not in authenticate
2727 if(!conn->bits.authneg) {
2728 http->postdata = (char *)&http->postdata;
2729 http->postsize = postsize;
2733 /* issue the request */
2734 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2735 (size_t)included_body, FIRSTSOCKET);
2738 failf(data, "Failed sending HTTP POST request");
2740 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2741 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2742 http->postdata?&http->writebytecount:NULL);
2746 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2750 /* issue the request */
2751 result = Curl_add_buffer_send(req_buffer, conn,
2752 &data->info.request_size, 0, FIRSTSOCKET);
2755 failf(data, "Failed sending HTTP request");
2757 /* HTTP GET/HEAD download: */
2758 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2759 http->postdata?FIRSTSOCKET:-1,
2760 http->postdata?&http->writebytecount:NULL);
2765 if(http->writebytecount) {
2766 /* if a request-body has been sent off, we make sure this progress is noted
2768 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2769 if(Curl_pgrsUpdate(conn))
2770 result = CURLE_ABORTED_BY_CALLBACK;
2772 if(http->writebytecount >= postsize) {
2773 /* already sent the entire request body, mark the "upload" as
2775 infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
2776 " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
2777 http->writebytecount, postsize);
2778 data->req.upload_done = TRUE;
2779 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2780 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2781 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
2785 if((conn->httpversion == 20) && data->req.upload_chunky)
2786 /* upload_chunky was set above to set up the request in a chunky fashion,
2787 but is disabled here again to avoid that the chunked encoded version is
2788 actually used when sending the request body over h2 */
2789 data->req.upload_chunky = FALSE;
2796 * Returns TRUE if member of the list matches prefix of string
2799 checkhttpprefix(struct Curl_easy *data,
2802 struct curl_slist *head = data->set.http200aliases;
2804 #ifdef CURL_DOES_CONVERSIONS
2805 /* convert from the network encoding using a scratch area */
2806 char *scratch = strdup(s);
2807 if(NULL == scratch) {
2808 failf(data, "Failed to allocate memory for conversion!");
2809 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2811 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
2812 /* Curl_convert_from_network calls failf if unsuccessful */
2814 return FALSE; /* can't return CURLE_foobar so return FALSE */
2817 #endif /* CURL_DOES_CONVERSIONS */
2820 if(checkprefix(head->data, s)) {
2827 if(!rc && (checkprefix("HTTP/", s)))
2830 #ifdef CURL_DOES_CONVERSIONS
2832 #endif /* CURL_DOES_CONVERSIONS */
2836 #ifndef CURL_DISABLE_RTSP
2838 checkrtspprefix(struct Curl_easy *data,
2841 bool result = FALSE;
2843 #ifdef CURL_DOES_CONVERSIONS
2844 /* convert from the network encoding using a scratch area */
2845 char *scratch = strdup(s);
2846 if(NULL == scratch) {
2847 failf(data, "Failed to allocate memory for conversion!");
2848 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2850 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
2851 /* Curl_convert_from_network calls failf if unsuccessful */
2852 result = FALSE; /* can't return CURLE_foobar so return FALSE */
2855 result = checkprefix("RTSP/", scratch)? TRUE: FALSE;
2858 (void)data; /* unused */
2859 result = checkprefix("RTSP/", s)? TRUE: FALSE;
2860 #endif /* CURL_DOES_CONVERSIONS */
2864 #endif /* CURL_DISABLE_RTSP */
2867 checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
2870 #ifndef CURL_DISABLE_RTSP
2871 if(conn->handler->protocol & CURLPROTO_RTSP)
2872 return checkrtspprefix(data, s);
2875 #endif /* CURL_DISABLE_RTSP */
2877 return checkhttpprefix(data, s);
2881 * header_append() copies a chunk of data to the end of the already received
2882 * header. We make sure that the full string fit in the allocated header
2883 * buffer, or else we enlarge it.
2885 static CURLcode header_append(struct Curl_easy *data,
2886 struct SingleRequest *k,
2889 size_t newsize = k->hbuflen + length;
2890 if(newsize > CURL_MAX_HTTP_HEADER) {
2891 /* The reason to have a max limit for this is to avoid the risk of a bad
2892 server feeding libcurl with a never-ending header that will cause
2893 reallocs infinitely */
2894 failf(data, "Rejected %zd bytes header (max is %d)!", newsize,
2895 CURL_MAX_HTTP_HEADER);
2896 return CURLE_OUT_OF_MEMORY;
2898 if(newsize >= data->state.headersize) {
2899 /* We enlarge the header buffer as it is too small */
2903 newsize = CURLMAX((k->hbuflen + length) * 3 / 2, data->state.headersize*2);
2904 hbufp_index = k->hbufp - data->state.headerbuff;
2905 newbuff = realloc(data->state.headerbuff, newsize);
2907 failf(data, "Failed to alloc memory for big header!");
2908 return CURLE_OUT_OF_MEMORY;
2910 data->state.headersize = newsize;
2911 data->state.headerbuff = newbuff;
2912 k->hbufp = data->state.headerbuff + hbufp_index;
2914 memcpy(k->hbufp, k->str_start, length);
2916 k->hbuflen += length;
2922 static void print_http_error(struct Curl_easy *data)
2924 struct SingleRequest *k = &data->req;
2927 /* make sure that data->req.p points to the HTTP status line */
2928 if(!strncmp(beg, "HTTP", 4)) {
2930 /* skip to HTTP status code */
2931 beg = strchr(beg, ' ');
2934 /* find trailing CR */
2935 char end_char = '\r';
2936 char *end = strchr(beg, end_char);
2938 /* try to find LF (workaround for non-compliant HTTP servers) */
2940 end = strchr(beg, end_char);
2944 /* temporarily replace CR or LF by NUL and print the error message */
2946 failf(data, "The requested URL returned error: %s", beg);
2948 /* restore the previously replaced CR or LF */
2955 /* fall-back to printing the HTTP status code only */
2956 failf(data, "The requested URL returned error: %d", k->httpcode);
2960 * Read any HTTP header lines from the server and pass them to the client app.
2962 CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
2963 struct connectdata *conn,
2968 struct SingleRequest *k = &data->req;
2969 ssize_t onread = *nread;
2970 char *ostr = k->str;
2972 /* header line within buffer loop */
2978 /* str_start is start of line within buf */
2979 k->str_start = k->str;
2981 /* data is in network encoding so use 0x0a instead of '\n' */
2982 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2985 /* Not a complete header line within buffer, append the data to
2986 the end of the headerbuff. */
2987 result = header_append(data, k, *nread);
2991 if(!k->headerline && (k->hbuflen>5)) {
2992 /* make a first check that this looks like a protocol header */
2993 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2994 /* this is not the beginning of a protocol first header line */
2996 k->badheader = HEADER_ALLBAD;
3001 break; /* read more and try again */
3004 /* decrease the size of the remaining (supposed) header line */
3005 rest_length = (k->end_ptr - k->str) + 1;
3006 *nread -= (ssize_t)rest_length;
3008 k->str = k->end_ptr + 1; /* move past new line */
3010 full_length = k->str - k->str_start;
3012 result = header_append(data, k, full_length);
3016 k->end_ptr = k->hbufp;
3017 k->p = data->state.headerbuff;
3020 * We now have a FULL header line that p points to
3023 if(!k->headerline) {
3024 /* the first read header */
3025 if((k->hbuflen>5) &&
3026 !checkprotoprefix(data, conn, data->state.headerbuff)) {
3027 /* this is not the beginning of a protocol first header line */
3030 /* since there's more, this is a partial bad header */
3031 k->badheader = HEADER_PARTHEADER;
3033 /* this was all we read so it's all a bad header */
3034 k->badheader = HEADER_ALLBAD;
3043 /* headers are in network encoding so
3044 use 0x0a and 0x0d instead of '\n' and '\r' */
3045 if((0x0a == *k->p) || (0x0d == *k->p)) {
3047 /* Zero-length header line means end of headers! */
3049 #ifdef CURL_DOES_CONVERSIONS
3051 *k->p = '\r'; /* replace with CR in host encoding */
3052 k->p++; /* pass the CR byte */
3055 *k->p = '\n'; /* replace with LF in host encoding */
3056 k->p++; /* pass the LF byte */
3060 k->p++; /* pass the \r byte */
3062 k->p++; /* pass the \n byte */
3063 #endif /* CURL_DOES_CONVERSIONS */
3065 if(100 <= k->httpcode && 199 >= k->httpcode) {
3066 /* "A user agent MAY ignore unexpected 1xx status responses." */
3067 switch(k->httpcode) {
3070 * We have made a HTTP PUT or POST and this is 1.1-lingo
3071 * that tells us that the server is OK with this and ready
3072 * to receive the data.
3073 * However, we'll get more headers now so we must get
3074 * back into the header-parsing state!
3077 k->headerline = 0; /* restart the header line counter */
3079 /* if we did wait for this do enable write now! */
3080 if(k->exp100 > EXP100_SEND_DATA) {
3081 k->exp100 = EXP100_SEND_DATA;
3082 k->keepon |= KEEP_SEND;
3083 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
3087 /* Switching Protocols */
3088 if(k->upgr101 == UPGR101_REQUESTED) {
3089 /* Switching to HTTP/2 */
3090 infof(data, "Received 101\n");
3091 k->upgr101 = UPGR101_RECEIVED;
3093 /* we'll get more headers (HTTP/2 response) */
3095 k->headerline = 0; /* restart the header line counter */
3097 /* switch to http2 now. The bytes after response headers
3098 are also processed here, otherwise they are lost. */
3099 result = Curl_http2_switched(conn, k->str, *nread);
3105 /* Switching to another protocol (e.g. WebSocket) */
3106 k->header = FALSE; /* no more header to parse! */
3110 /* the status code 1xx indicates a provisional response, so
3111 we'll get another set of headers */
3113 k->headerline = 0; /* restart the header line counter */
3118 k->header = FALSE; /* no more header to parse! */
3120 if((k->size == -1) && !k->chunk && !conn->bits.close &&
3121 (conn->httpversion == 11) &&
3122 !(conn->handler->protocol & CURLPROTO_RTSP) &&
3123 data->set.httpreq != HTTPREQ_HEAD) {
3124 /* On HTTP 1.1, when connection is not to get closed, but no
3125 Content-Length nor Transfer-Encoding chunked have been
3126 received, according to RFC2616 section 4.4 point 5, we
3127 assume that the server will close the connection to
3128 signal the end of the document. */
3129 infof(data, "no chunk, no close, no size. Assume close to "
3131 streamclose(conn, "HTTP: No end-of-message indicator");
3135 /* At this point we have some idea about the fate of the connection.
3136 If we are closing the connection it may result auth failure. */
3137 #if defined(USE_NTLM)
3138 if(conn->bits.close &&
3139 (((data->req.httpcode == 401) &&
3140 (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
3141 ((data->req.httpcode == 407) &&
3142 (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
3143 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
3144 data->state.authproblem = TRUE;
3149 * When all the headers have been parsed, see if we should give
3150 * up and return an error.
3152 if(http_should_fail(conn)) {
3153 failf(data, "The requested URL returned error: %d",
3155 return CURLE_HTTP_RETURNED_ERROR;
3158 /* now, only output this if the header AND body are requested:
3160 writetype = CLIENTWRITE_HEADER;
3161 if(data->set.include_header)
3162 writetype |= CLIENTWRITE_BODY;
3164 headerlen = k->p - data->state.headerbuff;
3166 result = Curl_client_write(conn, writetype,
3167 data->state.headerbuff,
3172 data->info.header_size += (long)headerlen;
3173 data->req.headerbytecount += (long)headerlen;
3175 data->req.deductheadercount =
3176 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
3178 /* Curl_http_auth_act() checks what authentication methods
3179 * that are available and decides which one (if any) to
3180 * use. It will set 'newurl' if an auth method was picked. */
3181 result = Curl_http_auth_act(conn);
3186 if(k->httpcode >= 300) {
3187 if((!conn->bits.authneg) && !conn->bits.close &&
3188 !conn->bits.rewindaftersend) {
3190 * General treatment of errors when about to send data. Including :
3191 * "417 Expectation Failed", while waiting for 100-continue.
3193 * The check for close above is done simply because of something
3194 * else has already deemed the connection to get closed then
3195 * something else should've considered the big picture and we
3198 * rewindaftersend indicates that something has told libcurl to
3199 * continue sending even if it gets discarded
3202 switch(data->set.httpreq) {
3205 case HTTPREQ_POST_FORM:
3206 case HTTPREQ_POST_MIME:
3207 /* We got an error response. If this happened before the whole
3208 * request body has been sent we stop sending and mark the
3209 * connection for closure after we've read the entire response.
3211 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
3212 if(!k->upload_done) {
3213 if(data->set.http_keep_sending_on_error) {
3214 infof(data, "HTTP error before end of send, keep sending\n");
3215 if(k->exp100 > EXP100_SEND_DATA) {
3216 k->exp100 = EXP100_SEND_DATA;
3217 k->keepon |= KEEP_SEND;
3221 infof(data, "HTTP error before end of send, stop sending\n");
3222 streamclose(conn, "Stop sending data before everything sent");
3223 k->upload_done = TRUE;
3224 k->keepon &= ~KEEP_SEND; /* don't send */
3225 if(data->state.expect100header)
3226 k->exp100 = EXP100_FAILED;
3231 default: /* default label present to avoid compiler warnings */
3236 if(conn->bits.rewindaftersend) {
3237 /* We rewind after a complete send, so thus we continue
3239 infof(data, "Keep sending data to get tossed away!\n");
3240 k->keepon |= KEEP_SEND;
3246 * really end-of-headers.
3248 * If we requested a "no body", this is a good time to get
3249 * out and return home.
3251 if(data->set.opt_no_body)
3252 *stop_reading = TRUE;
3253 #ifndef CURL_DISABLE_RTSP
3254 else if((conn->handler->protocol & CURLPROTO_RTSP) &&
3255 (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
3257 /* Respect section 4.4 of rfc2326: If the Content-Length header is
3258 absent, a length 0 must be assumed. It will prevent libcurl from
3259 hanging on DESCRIBE request that got refused for whatever
3261 *stop_reading = TRUE;
3264 /* If we know the expected size of this document, we set the
3265 maximum download size to the size of the expected
3266 document or else, we won't know when to stop reading!
3268 Note that we set the download maximum even if we read a
3269 "Connection: close" header, to make sure that
3270 "Content-Length: 0" still prevents us from attempting to
3271 read the (missing) response-body.
3273 /* According to RFC2616 section 4.4, we MUST ignore
3274 Content-Length: headers if we are now receiving data
3275 using chunked Transfer-Encoding.
3278 k->maxdownload = k->size = -1;
3281 /* We do this operation even if no_body is true, since this
3282 data might be retrieved later with curl_easy_getinfo()
3283 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3285 Curl_pgrsSetDownloadSize(data, k->size);
3286 k->maxdownload = k->size;
3289 /* If max download size is *zero* (nothing) we already have
3290 nothing and can safely return ok now! But for HTTP/2, we'd
3291 like to call http2_handle_stream_close to properly close a
3292 stream. In order to do this, we keep reading until we
3293 close the stream. */
3294 if(0 == k->maxdownload
3295 #if defined(USE_NGHTTP2)
3296 && !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
3297 conn->httpversion == 20)
3300 *stop_reading = TRUE;
3303 /* we make sure that this socket isn't read more now */
3304 k->keepon &= ~KEEP_RECV;
3307 if(data->set.verbose)
3308 Curl_debug(data, CURLINFO_HEADER_IN,
3309 k->str_start, headerlen, conn);
3310 break; /* exit header line loop */
3313 /* We continue reading headers, so reset the line-based
3314 header parsing variables hbufp && hbuflen */
3315 k->hbufp = data->state.headerbuff;
3321 * Checks for special headers coming up.
3324 if(!k->headerline++) {
3325 /* This is the first header, it MUST be the error code line
3326 or else we consider this to be the body right away! */
3327 int httpversion_major;
3328 int rtspversion_major;
3330 #ifdef CURL_DOES_CONVERSIONS
3331 #define HEADER1 scratch
3332 #define SCRATCHSIZE 21
3334 char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */
3335 /* We can't really convert this yet because we
3336 don't know if it's the 1st header line or the body.
3337 So we do a partial conversion into a scratch area,
3338 leaving the data at k->p as-is.
3340 strncpy(&scratch[0], k->p, SCRATCHSIZE);
3341 scratch[SCRATCHSIZE] = 0; /* null terminate */
3342 res = Curl_convert_from_network(data,
3346 /* Curl_convert_from_network calls failf if unsuccessful */
3349 #define HEADER1 k->p /* no conversion needed, just use k->p */
3350 #endif /* CURL_DOES_CONVERSIONS */
3352 if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
3354 * https://tools.ietf.org/html/rfc7230#section-3.1.2
3356 * The response code is always a three-digit number in HTTP as the spec
3357 * says. We try to allow any number here, but we cannot make
3358 * guarantees on future behaviors since it isn't within the protocol.
3361 nc = sscanf(HEADER1,
3362 " HTTP/%1d.%1d%c%3d",
3368 if(nc == 1 && httpversion_major == 2 &&
3369 1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) {
3370 conn->httpversion = 0;
3375 if((nc == 4) && (' ' == separator)) {
3376 conn->httpversion += 10 * httpversion_major;
3378 if(k->upgr101 == UPGR101_RECEIVED) {
3379 /* supposedly upgraded to http2 now */
3380 if(conn->httpversion != 20)
3381 infof(data, "Lying server, not serving HTTP/2\n");
3385 /* this is the real world, not a Nirvana
3386 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3388 nc = sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3389 conn->httpversion = 10;
3391 /* If user has set option HTTP200ALIASES,
3392 compare header line against list of aliases
3395 if(checkhttpprefix(data, k->p)) {
3398 conn->httpversion = 10;
3403 failf(data, "Unsupported HTTP version in response\n");
3404 return CURLE_UNSUPPORTED_PROTOCOL;
3407 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3409 nc = sscanf(HEADER1,
3410 " RTSP/%1d.%1d%c%3d",
3415 if((nc == 4) && (' ' == separator)) {
3416 conn->rtspversion += 10 * rtspversion_major;
3417 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3420 /* TODO: do we care about the other cases here? */
3426 data->info.httpcode = k->httpcode;
3428 data->info.httpversion = conn->httpversion;
3429 if(!data->state.httpversion ||
3430 data->state.httpversion > conn->httpversion)
3431 /* store the lowest server version we encounter */
3432 data->state.httpversion = conn->httpversion;
3435 * This code executes as part of processing the header. As a
3436 * result, it's not totally clear how to interpret the
3437 * response code yet as that depends on what other headers may
3438 * be present. 401 and 407 may be errors, but may be OK
3439 * depending on how authentication is working. Other codes
3440 * are definitely errors, so give up here.
3442 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3443 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3444 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3446 if(data->state.resume_from &&
3447 (data->set.httpreq == HTTPREQ_GET) &&
3448 (k->httpcode == 416)) {
3449 /* "Requested Range Not Satisfiable", just proceed and
3450 pretend this is no error */
3453 /* serious error, go home! */
3454 print_http_error(data);
3455 return CURLE_HTTP_RETURNED_ERROR;
3459 if(conn->httpversion == 10) {
3460 /* Default action for HTTP/1.0 must be to close, unless
3461 we get one of those fancy headers that tell us the
3462 server keeps it open for us! */
3463 infof(data, "HTTP 1.0, assume close after body\n");
3464 connclose(conn, "HTTP/1.0 close after body");
3466 else if(conn->httpversion == 20 ||
3467 (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
3468 DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
3470 /* HTTP/2 cannot blacklist multiplexing since it is a core
3471 functionality of the protocol */
3472 conn->bundle->multiuse = BUNDLE_MULTIPLEX;
3474 else if(conn->httpversion >= 11 &&
3475 !conn->bits.close) {
3476 /* If HTTP version is >= 1.1 and connection is persistent
3477 server supports pipelining. */
3479 "HTTP 1.1 or later with persistent connection, "
3480 "pipelining supported\n"));
3481 /* Activate pipelining if needed */
3483 if(!Curl_pipeline_site_blacklisted(data, conn))
3484 conn->bundle->multiuse = BUNDLE_PIPELINING;
3488 switch(k->httpcode) {
3490 /* (quote from RFC2616, section 10.2.5): The server has
3491 * fulfilled the request but does not need to return an
3492 * entity-body ... The 204 response MUST NOT include a
3493 * message-body, and thus is always terminated by the first
3494 * empty line after the header fields. */
3497 /* (quote from RFC2616, section 10.3.5): The 304 response
3498 * MUST NOT contain a message-body, and thus is always
3499 * terminated by the first empty line after the header
3501 if(data->set.timecondition)
3502 data->info.timecond = TRUE;
3505 k->ignorecl = TRUE; /* ignore Content-Length headers */
3513 k->header = FALSE; /* this is not a header line */
3518 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3519 /* Curl_convert_from_network calls failf if unsuccessful */
3523 /* Check for Content-Length: header lines to get size */
3524 if(!k->ignorecl && !data->set.ignorecl &&
3525 checkprefix("Content-Length:", k->p)) {
3526 curl_off_t contentlength;
3527 CURLofft offt = curlx_strtoofft(k->p + 15, NULL, 10, &contentlength);
3529 if(offt == CURL_OFFT_OK) {
3530 if(data->set.max_filesize &&
3531 contentlength > data->set.max_filesize) {
3532 failf(data, "Maximum file size exceeded");
3533 return CURLE_FILESIZE_EXCEEDED;
3535 k->size = contentlength;
3536 k->maxdownload = k->size;
3537 /* we set the progress download size already at this point
3538 just to make it easier for apps/callbacks to extract this
3539 info as soon as possible */
3540 Curl_pgrsSetDownloadSize(data, k->size);
3542 else if(offt == CURL_OFFT_FLOW) {
3544 if(data->set.max_filesize) {
3545 failf(data, "Maximum file size exceeded");
3546 return CURLE_FILESIZE_EXCEEDED;
3548 streamclose(conn, "overflow content-length");
3549 infof(data, "Overflow Content-Length: value!\n");
3552 /* negative or just rubbish - bad HTTP */
3553 failf(data, "Invalid Content-Length: value");
3554 return CURLE_WEIRD_SERVER_REPLY;
3557 /* check for Content-Type: header lines to get the MIME-type */
3558 else if(checkprefix("Content-Type:", k->p)) {
3559 char *contenttype = Curl_copy_header_value(k->p);
3561 return CURLE_OUT_OF_MEMORY;
3563 /* ignore empty data */
3566 Curl_safefree(data->info.contenttype);
3567 data->info.contenttype = contenttype;
3570 else if(checkprefix("Server:", k->p)) {
3571 if(conn->httpversion < 20) {
3572 /* only do this for non-h2 servers */
3573 char *server_name = Curl_copy_header_value(k->p);
3575 /* Turn off pipelining if the server version is blacklisted */
3576 if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
3577 if(Curl_pipeline_server_blacklisted(data, server_name))
3578 conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
3583 else if((conn->httpversion == 10) &&
3584 conn->bits.httpproxy &&
3585 Curl_compareheader(k->p,
3586 "Proxy-Connection:", "keep-alive")) {
3588 * When a HTTP/1.0 reply comes when using a proxy, the
3589 * 'Proxy-Connection: keep-alive' line tells us the
3590 * connection will be kept alive for our pleasure.
3591 * Default action for 1.0 is to close.
3593 connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
3594 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3596 else if((conn->httpversion == 11) &&
3597 conn->bits.httpproxy &&
3598 Curl_compareheader(k->p,
3599 "Proxy-Connection:", "close")) {
3601 * We get a HTTP/1.1 response from a proxy and it says it'll
3602 * close down after this transfer.
3604 connclose(conn, "Proxy-Connection: asked to close after done");
3605 infof(data, "HTTP/1.1 proxy connection set close!\n");
3607 else if((conn->httpversion == 10) &&
3608 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3610 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3611 * tells us the connection will be kept alive for our
3612 * pleasure. Default action for 1.0 is to close.
3614 * [RFC2068, section 19.7.1] */
3615 connkeep(conn, "Connection keep-alive");
3616 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3618 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3620 * [RFC 2616, section 8.1.2.1]
3621 * "Connection: close" is HTTP/1.1 language and means that
3622 * the connection will close when this request has been
3625 streamclose(conn, "Connection: close used");
3627 else if(checkprefix("Transfer-Encoding:", k->p)) {
3628 /* One or more encodings. We check for chunked and/or a compression
3631 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3632 * means that the server will send a series of "chunks". Each
3633 * chunk starts with line with info (including size of the
3634 * coming block) (terminated with CRLF), then a block of data
3635 * with the previously mentioned size. There can be any amount
3636 * of chunks, and a chunk-data set to zero signals the
3639 result = Curl_build_unencoding_stack(conn, k->p + 18, TRUE);
3643 else if(checkprefix("Content-Encoding:", k->p) &&
3644 data->set.str[STRING_ENCODING]) {
3646 * Process Content-Encoding. Look for the values: identity,
3647 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3648 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3649 * 2616). zlib cannot handle compress. However, errors are
3650 * handled further down when the response body is processed
3652 result = Curl_build_unencoding_stack(conn, k->p + 17, FALSE);
3656 else if(checkprefix("Content-Range:", k->p)) {
3657 /* Content-Range: bytes [num]-
3658 Content-Range: bytes: [num]-
3659 Content-Range: [num]-
3660 Content-Range: [asterisk]/[total]
3662 The second format was added since Sun's webserver
3663 JavaWebServer/1.1.1 obviously sends the header this way!
3664 The third added since some servers use that!
3665 The forth means the requested range was unsatisfied.
3668 char *ptr = k->p + 14;
3670 /* Move forward until first digit or asterisk */
3671 while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
3674 /* if it truly stopped on a digit */
3676 if(!curlx_strtoofft(ptr, NULL, 10, &k->offset)) {
3677 if(data->state.resume_from == k->offset)
3678 /* we asked for a resume and we got it */
3679 k->content_range = TRUE;
3683 data->state.resume_from = 0; /* get everything */
3685 #if !defined(CURL_DISABLE_COOKIES)
3686 else if(data->cookies &&
3687 checkprefix("Set-Cookie:", k->p)) {
3688 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3689 CURL_LOCK_ACCESS_SINGLE);
3690 Curl_cookie_add(data,
3691 data->cookies, TRUE, k->p + 11,
3692 /* If there is a custom-set Host: name, use it
3693 here, or else use real peer host name. */
3694 conn->allocptr.cookiehost?
3695 conn->allocptr.cookiehost:conn->host.name,
3697 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3700 else if(checkprefix("Last-Modified:", k->p) &&
3701 (data->set.timecondition || data->set.get_filetime) ) {
3702 time_t secs = time(NULL);
3703 k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"),
3705 if(data->set.get_filetime)
3706 data->info.filetime = k->timeofdoc;
3708 else if((checkprefix("WWW-Authenticate:", k->p) &&
3709 (401 == k->httpcode)) ||
3710 (checkprefix("Proxy-authenticate:", k->p) &&
3711 (407 == k->httpcode))) {
3713 bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3714 char *auth = Curl_copy_header_value(k->p);
3716 return CURLE_OUT_OF_MEMORY;
3718 result = Curl_http_input_auth(conn, proxy, auth);
3725 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3726 checkprefix("Location:", k->p) &&
3727 !data->req.location) {
3728 /* this is the URL that the server advises us to use instead */
3729 char *location = Curl_copy_header_value(k->p);
3731 return CURLE_OUT_OF_MEMORY;
3733 /* ignore empty data */
3736 data->req.location = location;
3738 if(data->set.http_follow_location) {
3739 DEBUGASSERT(!data->req.newurl);
3740 data->req.newurl = strdup(data->req.location); /* clone */
3741 if(!data->req.newurl)
3742 return CURLE_OUT_OF_MEMORY;
3744 /* some cases of POST and PUT etc needs to rewind the data
3745 stream at this point */
3746 result = http_perhapsrewind(conn);
3752 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3753 result = Curl_rtsp_parseheader(conn, k->p);
3759 * End of header-checks. Write them to the client.
3762 writetype = CLIENTWRITE_HEADER;
3763 if(data->set.include_header)
3764 writetype |= CLIENTWRITE_BODY;
3766 if(data->set.verbose)
3767 Curl_debug(data, CURLINFO_HEADER_IN,
3768 k->p, (size_t)k->hbuflen, conn);
3770 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3774 data->info.header_size += (long)k->hbuflen;
3775 data->req.headerbytecount += (long)k->hbuflen;
3777 /* reset hbufp pointer && hbuflen */
3778 k->hbufp = data->state.headerbuff;
3781 while(*k->str); /* header line within buffer */
3783 /* We might have reached the end of the header part here, but
3784 there might be a non-header part left in the end of the read
3790 #endif /* CURL_DISABLE_HTTP */