1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #ifndef CURL_DISABLE_HTTP
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
34 #ifdef HAVE_ARPA_INET_H
35 #include <arpa/inet.h>
40 #ifdef HAVE_SYS_IOCTL_H
41 #include <sys/ioctl.h>
44 #ifdef HAVE_SYS_PARAM_H
45 #include <sys/param.h>
49 #include <curl/curl.h>
54 #include "curl_base64.h"
56 #include "vauth/vauth.h"
57 #include "vtls/vtls.h"
58 #include "http_digest.h"
59 #include "http_ntlm.h"
60 #include "curl_ntlm_wb.h"
61 #include "http_negotiate.h"
67 #include "parsedate.h" /* for the week day and month names */
68 #include "strtoofft.h"
71 #include "content_encoding.h"
72 #include "http_proxy.h"
74 #include "non-ascii.h"
75 #include "conncache.h"
81 /* The last 3 #include files should be in this order */
82 #include "curl_printf.h"
83 #include "curl_memory.h"
87 * Forward declarations.
90 static int http_getsock_do(struct connectdata *conn,
93 static int http_should_fail(struct connectdata *conn);
96 static CURLcode https_connecting(struct connectdata *conn, bool *done);
97 static int https_getsock(struct connectdata *conn,
101 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
105 * HTTP handler interface.
107 const struct Curl_handler Curl_handler_http = {
109 Curl_http_setup_conn, /* setup_connection */
110 Curl_http, /* do_it */
111 Curl_http_done, /* done */
112 ZERO_NULL, /* do_more */
113 Curl_http_connect, /* connect_it */
114 ZERO_NULL, /* connecting */
115 ZERO_NULL, /* doing */
116 ZERO_NULL, /* proto_getsock */
117 http_getsock_do, /* doing_getsock */
118 ZERO_NULL, /* domore_getsock */
119 ZERO_NULL, /* perform_getsock */
120 ZERO_NULL, /* disconnect */
121 ZERO_NULL, /* readwrite */
122 PORT_HTTP, /* defport */
123 CURLPROTO_HTTP, /* protocol */
124 PROTOPT_CREDSPERREQUEST /* flags */
129 * HTTPS handler interface.
131 const struct Curl_handler Curl_handler_https = {
132 "HTTPS", /* scheme */
133 Curl_http_setup_conn, /* setup_connection */
134 Curl_http, /* do_it */
135 Curl_http_done, /* done */
136 ZERO_NULL, /* do_more */
137 Curl_http_connect, /* connect_it */
138 https_connecting, /* connecting */
139 ZERO_NULL, /* doing */
140 https_getsock, /* proto_getsock */
141 http_getsock_do, /* doing_getsock */
142 ZERO_NULL, /* domore_getsock */
143 ZERO_NULL, /* perform_getsock */
144 ZERO_NULL, /* disconnect */
145 ZERO_NULL, /* readwrite */
146 PORT_HTTPS, /* defport */
147 CURLPROTO_HTTPS, /* protocol */
148 PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN /* flags */
152 CURLcode Curl_http_setup_conn(struct connectdata *conn)
154 /* allocate the HTTP-specific struct for the Curl_easy, only to survive
155 during this request */
157 DEBUGASSERT(conn->data->req.protop == NULL);
159 http = calloc(1, sizeof(struct HTTP));
161 return CURLE_OUT_OF_MEMORY;
163 conn->data->req.protop = http;
165 Curl_http2_setup_conn(conn);
166 Curl_http2_setup_req(conn->data);
172 * checkheaders() checks the linked list of custom HTTP headers for a
173 * particular header (prefix).
175 * Returns a pointer to the first matching header or NULL if none matched.
177 char *Curl_checkheaders(const struct connectdata *conn,
178 const char *thisheader)
180 struct curl_slist *head;
181 size_t thislen = strlen(thisheader);
182 struct Curl_easy *data = conn->data;
184 for(head = data->set.headers;head; head=head->next) {
185 if(strncasecompare(head->data, thisheader, thislen))
193 * checkProxyHeaders() checks the linked list of custom proxy headers
194 * if proxy headers are not available, then it will lookup into http header
197 * It takes a connectdata struct as input instead of the Curl_easy simply
198 * to know if this is a proxy request or not, as it then might check a
199 * different header list.
201 char *Curl_checkProxyheaders(const struct connectdata *conn,
202 const char *thisheader)
204 struct curl_slist *head;
205 size_t thislen = strlen(thisheader);
206 struct Curl_easy *data = conn->data;
208 for(head = (conn->bits.proxy && data->set.sep_headers) ?
209 data->set.proxyheaders : data->set.headers;
210 head; head=head->next) {
211 if(strncasecompare(head->data, thisheader, thislen))
219 * Strip off leading and trailing whitespace from the value in the
220 * given HTTP header line and return a strdupped copy. Returns NULL in
221 * case of allocation failure. Returns an empty string if the header value
222 * consists entirely of whitespace.
224 char *Curl_copy_header_value(const char *header)
233 /* Find the end of the header name */
234 while(*header && (*header != ':'))
238 /* Skip over colon */
241 /* Find the first non-space letter */
243 while(*start && ISSPACE(*start))
246 /* data is in the host encoding so
247 use '\r' and '\n' instead of 0x0d and 0x0a */
248 end = strchr(start, '\r');
250 end = strchr(start, '\n');
252 end = strchr(start, '\0');
256 /* skip all trailing space letters */
257 while((end > start) && ISSPACE(*end))
260 /* get length of the type */
261 len = end - start + 1;
263 value = malloc(len + 1);
267 memcpy(value, start, len);
268 value[len] = 0; /* zero terminate */
274 * http_output_basic() sets up an Authorization: header (or the proxy version)
275 * for HTTP Basic authentication.
279 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
282 char *authorization = NULL;
283 struct Curl_easy *data = conn->data;
290 userp = &conn->allocptr.proxyuserpwd;
291 user = conn->http_proxy.user;
292 pwd = conn->http_proxy.passwd;
295 userp = &conn->allocptr.userpwd;
300 snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
303 result = Curl_base64_encode(data,
304 data->state.buffer, strlen(data->state.buffer),
305 &authorization, &size);
310 return CURLE_REMOTE_ACCESS_DENIED;
313 *userp = aprintf("%sAuthorization: Basic %s\r\n",
314 proxy ? "Proxy-" : "",
318 return CURLE_OUT_OF_MEMORY;
323 /* pickoneauth() selects the most favourable authentication method from the
324 * ones available and the ones we want.
326 * return TRUE if one was picked
328 static bool pickoneauth(struct auth *pick)
331 /* only deal with authentication we want */
332 unsigned long avail = pick->avail & pick->want;
335 /* The order of these checks is highly relevant, as this will be the order
336 of preference in case of the existence of multiple accepted types. */
337 if(avail & CURLAUTH_NEGOTIATE)
338 pick->picked = CURLAUTH_NEGOTIATE;
339 else if(avail & CURLAUTH_DIGEST)
340 pick->picked = CURLAUTH_DIGEST;
341 else if(avail & CURLAUTH_NTLM)
342 pick->picked = CURLAUTH_NTLM;
343 else if(avail & CURLAUTH_NTLM_WB)
344 pick->picked = CURLAUTH_NTLM_WB;
345 else if(avail & CURLAUTH_BASIC)
346 pick->picked = CURLAUTH_BASIC;
348 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
351 pick->avail = CURLAUTH_NONE; /* clear it here */
357 * Curl_http_perhapsrewind()
359 * If we are doing POST or PUT {
360 * If we have more data to send {
361 * If we are doing NTLM {
362 * Keep sending since we must not disconnect
365 * If there is more than just a little data left to send, close
366 * the current connection by force.
369 * If we have sent any data {
370 * If we don't have track of all the data {
371 * call app to tell it to rewind
374 * rewind internally so that the operation can restart fine
379 static CURLcode http_perhapsrewind(struct connectdata *conn)
381 struct Curl_easy *data = conn->data;
382 struct HTTP *http = data->req.protop;
383 curl_off_t bytessent;
384 curl_off_t expectsend = -1; /* default is unknown */
387 /* If this is still NULL, we have not reach very far and we can safely
388 skip this rewinding stuff */
391 switch(data->set.httpreq) {
399 bytessent = http->writebytecount;
401 if(conn->bits.authneg) {
402 /* This is a state where we are known to be negotiating and we don't send
406 else if(!conn->bits.protoconnstart) {
407 /* HTTP CONNECT in progress: there is no body */
411 /* figure out how much data we are expected to send */
412 switch(data->set.httpreq) {
414 if(data->state.infilesize != -1)
415 expectsend = data->state.infilesize;
416 else if(data->set.postfields)
417 expectsend = (curl_off_t)strlen(data->set.postfields);
420 if(data->state.infilesize != -1)
421 expectsend = data->state.infilesize;
423 case HTTPREQ_POST_FORM:
424 expectsend = http->postsize;
431 conn->bits.rewindaftersend = FALSE; /* default */
433 if((expectsend == -1) || (expectsend > bytessent)) {
434 #if defined(USE_NTLM)
435 /* There is still data left to send */
436 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
437 (data->state.authhost.picked == CURLAUTH_NTLM) ||
438 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
439 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
440 if(((expectsend - bytessent) < 2000) ||
441 (conn->ntlm.state != NTLMSTATE_NONE) ||
442 (conn->proxyntlm.state != NTLMSTATE_NONE)) {
443 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
444 data left to send, keep on sending. */
446 /* rewind data when completely done sending! */
447 if(!conn->bits.authneg) {
448 conn->bits.rewindaftersend = TRUE;
449 infof(data, "Rewind stream after send\n");
456 /* this is already marked to get closed */
459 infof(data, "NTLM send, close instead of sending %"
460 CURL_FORMAT_CURL_OFF_T " bytes\n",
461 (curl_off_t)(expectsend - bytessent));
465 /* This is not NTLM or many bytes left to send: close */
466 streamclose(conn, "Mid-auth HTTP and much data left to send");
467 data->req.size = 0; /* don't download any more than 0 bytes */
469 /* There still is data left to send, but this connection is marked for
470 closure so we can safely do the rewind right now */
474 /* we rewind now at once since if we already sent something */
475 return Curl_readrewind(conn);
481 * Curl_http_auth_act() gets called when all HTTP headers have been received
482 * and it checks what authentication methods that are available and decides
483 * which one (if any) to use. It will set 'newurl' if an auth method was
487 CURLcode Curl_http_auth_act(struct connectdata *conn)
489 struct Curl_easy *data = conn->data;
490 bool pickhost = FALSE;
491 bool pickproxy = FALSE;
492 CURLcode result = CURLE_OK;
494 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
495 /* this is a transient response code, ignore */
498 if(data->state.authproblem)
499 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
501 if(conn->bits.user_passwd &&
502 ((data->req.httpcode == 401) ||
503 (conn->bits.authneg && data->req.httpcode < 300))) {
504 pickhost = pickoneauth(&data->state.authhost);
506 data->state.authproblem = TRUE;
508 if(conn->bits.proxy_user_passwd &&
509 ((data->req.httpcode == 407) ||
510 (conn->bits.authneg && data->req.httpcode < 300))) {
511 pickproxy = pickoneauth(&data->state.authproxy);
513 data->state.authproblem = TRUE;
516 if(pickhost || pickproxy) {
517 /* In case this is GSS auth, the newurl field is already allocated so
518 we must make sure to free it before allocating a new one. As figured
519 out in bug #2284386 */
520 Curl_safefree(data->req.newurl);
521 data->req.newurl = strdup(data->change.url); /* clone URL */
522 if(!data->req.newurl)
523 return CURLE_OUT_OF_MEMORY;
525 if((data->set.httpreq != HTTPREQ_GET) &&
526 (data->set.httpreq != HTTPREQ_HEAD) &&
527 !conn->bits.rewindaftersend) {
528 result = http_perhapsrewind(conn);
533 else if((data->req.httpcode < 300) &&
534 (!data->state.authhost.done) &&
535 conn->bits.authneg) {
536 /* no (known) authentication available,
537 authentication is not "done" yet and
538 no authentication seems to be required and
539 we didn't try HEAD or GET */
540 if((data->set.httpreq != HTTPREQ_GET) &&
541 (data->set.httpreq != HTTPREQ_HEAD)) {
542 data->req.newurl = strdup(data->change.url); /* clone URL */
543 if(!data->req.newurl)
544 return CURLE_OUT_OF_MEMORY;
545 data->state.authhost.done = TRUE;
548 if(http_should_fail(conn)) {
549 failf(data, "The requested URL returned error: %d",
551 result = CURLE_HTTP_RETURNED_ERROR;
558 * Output the correct authentication header depending on the auth type
559 * and whether or not it is to a proxy.
562 output_auth_headers(struct connectdata *conn,
563 struct auth *authstatus,
568 const char *auth = NULL;
569 CURLcode result = CURLE_OK;
570 #if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
571 struct Curl_easy *data = conn->data;
574 struct negotiatedata *negdata = proxy ?
575 &data->state.proxyneg : &data->state.negotiate;
578 #ifdef CURL_DISABLE_CRYPTO_AUTH
584 negdata->state = GSS_AUTHNONE;
585 if((authstatus->picked == CURLAUTH_NEGOTIATE) &&
586 negdata->context && !GSS_ERROR(negdata->status)) {
588 result = Curl_output_negotiate(conn, proxy);
591 authstatus->done = TRUE;
592 negdata->state = GSS_AUTHSENT;
597 if(authstatus->picked == CURLAUTH_NTLM) {
599 result = Curl_output_ntlm(conn, proxy);
605 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
606 if(authstatus->picked == CURLAUTH_NTLM_WB) {
608 result = Curl_output_ntlm_wb(conn, proxy);
614 #ifndef CURL_DISABLE_CRYPTO_AUTH
615 if(authstatus->picked == CURLAUTH_DIGEST) {
617 result = Curl_output_digest(conn,
619 (const unsigned char *)request,
620 (const unsigned char *)path);
626 if(authstatus->picked == CURLAUTH_BASIC) {
628 if((proxy && conn->bits.proxy_user_passwd &&
629 !Curl_checkProxyheaders(conn, "Proxy-authorization:")) ||
630 (!proxy && conn->bits.user_passwd &&
631 !Curl_checkheaders(conn, "Authorization:"))) {
633 result = http_output_basic(conn, proxy);
638 /* NOTE: this function should set 'done' TRUE, as the other auth
639 functions work that way */
640 authstatus->done = TRUE;
644 infof(data, "%s auth using %s with user '%s'\n",
645 proxy ? "Proxy" : "Server", auth,
646 proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
647 (conn->user ? conn->user : ""));
648 authstatus->multi = (!authstatus->done) ? TRUE : FALSE;
651 authstatus->multi = FALSE;
657 * Curl_http_output_auth() setups the authentication headers for the
658 * host/proxy and the correct authentication
659 * method. conn->data->state.authdone is set to TRUE when authentication is
662 * @param conn all information about the current connection
663 * @param request pointer to the request keyword
664 * @param path pointer to the requested path
665 * @param proxytunnel boolean if this is the request setting up a "proxy
671 Curl_http_output_auth(struct connectdata *conn,
674 bool proxytunnel) /* TRUE if this is the request setting
675 up the proxy tunnel */
677 CURLcode result = CURLE_OK;
678 struct Curl_easy *data = conn->data;
679 struct auth *authhost;
680 struct auth *authproxy;
684 authhost = &data->state.authhost;
685 authproxy = &data->state.authproxy;
687 if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
688 conn->bits.user_passwd)
689 /* continue please */;
691 authhost->done = TRUE;
692 authproxy->done = TRUE;
693 return CURLE_OK; /* no authentication with no user or password */
696 if(authhost->want && !authhost->picked)
697 /* The app has selected one or more methods, but none has been picked
698 so far by a server round-trip. Then we set the picked one to the
699 want one, and if this is one single bit it'll be used instantly. */
700 authhost->picked = authhost->want;
702 if(authproxy->want && !authproxy->picked)
703 /* The app has selected one or more methods, but none has been picked so
704 far by a proxy round-trip. Then we set the picked one to the want one,
705 and if this is one single bit it'll be used instantly. */
706 authproxy->picked = authproxy->want;
708 #ifndef CURL_DISABLE_PROXY
709 /* Send proxy authentication header if needed */
710 if(conn->bits.httpproxy &&
711 (conn->bits.tunnel_proxy == proxytunnel)) {
712 result = output_auth_headers(conn, authproxy, request, path, TRUE);
719 #endif /* CURL_DISABLE_PROXY */
720 /* we have no proxy so let's pretend we're done authenticating
722 authproxy->done = TRUE;
724 /* To prevent the user+password to get sent to other than the original
725 host due to a location-follow, we do some weirdo checks here */
726 if(!data->state.this_is_a_follow ||
728 !data->state.first_host ||
729 data->set.http_disable_hostname_check_before_authentication ||
730 strcasecompare(data->state.first_host, conn->host.name)) {
731 result = output_auth_headers(conn, authhost, request, path, FALSE);
734 authhost->done = TRUE;
740 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
741 * headers. They are dealt with both in the transfer.c main loop and in the
742 * proxy CONNECT loop.
745 CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
746 const char *auth) /* the first non-space */
749 * This resource requires authentication
751 struct Curl_easy *data = conn->data;
754 struct negotiatedata *negdata = proxy?
755 &data->state.proxyneg:&data->state.negotiate;
757 unsigned long *availp;
761 availp = &data->info.proxyauthavail;
762 authp = &data->state.authproxy;
765 availp = &data->info.httpauthavail;
766 authp = &data->state.authhost;
770 * Here we check if we want the specific single authentication (using ==) and
771 * if we do, we initiate usage of it.
773 * If the provided authentication is wanted as one out of several accepted
774 * types (using &), we OR this authentication type to the authavail
779 * ->picked is first set to the 'want' value (one or more bits) before the
780 * request is sent, and then it is again set _after_ all response 401/407
781 * headers have been received but then only to a single preferred method
787 if(checkprefix("Negotiate", auth)) {
788 if((authp->avail & CURLAUTH_NEGOTIATE) ||
789 Curl_auth_is_spnego_supported()) {
790 *availp |= CURLAUTH_NEGOTIATE;
791 authp->avail |= CURLAUTH_NEGOTIATE;
793 if(authp->picked == CURLAUTH_NEGOTIATE) {
794 if(negdata->state == GSS_AUTHSENT ||
795 negdata->state == GSS_AUTHNONE) {
796 CURLcode result = Curl_input_negotiate(conn, proxy, auth);
798 DEBUGASSERT(!data->req.newurl);
799 data->req.newurl = strdup(data->change.url);
800 if(!data->req.newurl)
801 return CURLE_OUT_OF_MEMORY;
802 data->state.authproblem = FALSE;
803 /* we received a GSS auth token and we dealt with it fine */
804 negdata->state = GSS_AUTHRECV;
807 data->state.authproblem = TRUE;
815 /* NTLM support requires the SSL crypto libs */
816 if(checkprefix("NTLM", auth)) {
817 if((authp->avail & CURLAUTH_NTLM) ||
818 (authp->avail & CURLAUTH_NTLM_WB) ||
819 Curl_auth_is_ntlm_supported()) {
820 *availp |= CURLAUTH_NTLM;
821 authp->avail |= CURLAUTH_NTLM;
823 if(authp->picked == CURLAUTH_NTLM ||
824 authp->picked == CURLAUTH_NTLM_WB) {
825 /* NTLM authentication is picked and activated */
826 CURLcode result = Curl_input_ntlm(conn, proxy, auth);
828 data->state.authproblem = FALSE;
829 #ifdef NTLM_WB_ENABLED
830 if(authp->picked == CURLAUTH_NTLM_WB) {
831 *availp &= ~CURLAUTH_NTLM;
832 authp->avail &= ~CURLAUTH_NTLM;
833 *availp |= CURLAUTH_NTLM_WB;
834 authp->avail |= CURLAUTH_NTLM_WB;
836 /* Get the challenge-message which will be passed to
837 * ntlm_auth for generating the type 3 message later */
838 while(*auth && ISSPACE(*auth))
840 if(checkprefix("NTLM", auth)) {
841 auth += strlen("NTLM");
842 while(*auth && ISSPACE(*auth))
845 conn->challenge_header = strdup(auth);
846 if(!conn->challenge_header)
847 return CURLE_OUT_OF_MEMORY;
854 infof(data, "Authentication problem. Ignoring this.\n");
855 data->state.authproblem = TRUE;
862 #ifndef CURL_DISABLE_CRYPTO_AUTH
863 if(checkprefix("Digest", auth)) {
864 if((authp->avail & CURLAUTH_DIGEST) != 0)
865 infof(data, "Ignoring duplicate digest auth header.\n");
866 else if(Curl_auth_is_digest_supported()) {
869 *availp |= CURLAUTH_DIGEST;
870 authp->avail |= CURLAUTH_DIGEST;
872 /* We call this function on input Digest headers even if Digest
873 * authentication isn't activated yet, as we need to store the
874 * incoming data from this header in case we are going to use
876 result = Curl_input_digest(conn, proxy, auth);
878 infof(data, "Authentication problem. Ignoring this.\n");
879 data->state.authproblem = TRUE;
885 if(checkprefix("Basic", auth)) {
886 *availp |= CURLAUTH_BASIC;
887 authp->avail |= CURLAUTH_BASIC;
888 if(authp->picked == CURLAUTH_BASIC) {
889 /* We asked for Basic authentication but got a 40X back
890 anyway, which basically means our name+password isn't
892 authp->avail = CURLAUTH_NONE;
893 infof(data, "Authentication problem. Ignoring this.\n");
894 data->state.authproblem = TRUE;
898 /* there may be multiple methods on one line, so keep reading */
899 while(*auth && *auth != ',') /* read up to the next comma */
901 if(*auth == ',') /* if we're on a comma, skip it */
903 while(*auth && ISSPACE(*auth))
911 * http_should_fail() determines whether an HTTP response has gotten us
912 * into an error state or not.
914 * @param conn all information about the current connection
916 * @retval 0 communications should continue
918 * @retval 1 communications should not continue
920 static int http_should_fail(struct connectdata *conn)
922 struct Curl_easy *data;
929 httpcode = data->req.httpcode;
932 ** If we haven't been asked to fail on error,
935 if(!data->set.http_fail_on_error)
939 ** Any code < 400 is never terminal.
945 ** Any code >= 400 that's not 401 or 407 is always
948 if((httpcode != 401) && (httpcode != 407))
952 ** All we have left to deal with is 401 and 407
954 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
957 ** Examine the current authentication state to see if this
958 ** is an error. The idea is for this function to get
959 ** called after processing all the headers in a response
960 ** message. So, if we've been to asked to authenticate a
961 ** particular stage, and we've done it, we're OK. But, if
962 ** we're already completely authenticated, it's not OK to
963 ** get another 401 or 407.
965 ** It is possible for authentication to go stale such that
966 ** the client needs to reauthenticate. Once that info is
967 ** available, use it here.
971 ** Either we're not authenticating, or we're supposed to
972 ** be authenticating something else. This is an error.
974 if((httpcode == 401) && !conn->bits.user_passwd)
976 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
979 return data->state.authproblem;
983 * readmoredata() is a "fread() emulation" to provide POST and/or request
984 * data. It is used when a huge POST is to be made and the entire chunk wasn't
985 * sent in the first send(). This function will then be called from the
986 * transfer.c loop when more data is to be sent to the peer.
988 * Returns the amount of bytes it filled the buffer with.
990 static size_t readmoredata(char *buffer,
995 struct connectdata *conn = (struct connectdata *)userp;
996 struct HTTP *http = conn->data->req.protop;
997 size_t fullsize = size * nitems;
1000 /* nothing to return */
1003 /* make sure that a HTTP request is never sent away chunked! */
1004 conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
1006 if(http->postsize <= (curl_off_t)fullsize) {
1007 memcpy(buffer, http->postdata, (size_t)http->postsize);
1008 fullsize = (size_t)http->postsize;
1010 if(http->backup.postsize) {
1011 /* move backup data into focus and continue on that */
1012 http->postdata = http->backup.postdata;
1013 http->postsize = http->backup.postsize;
1014 conn->data->state.fread_func = http->backup.fread_func;
1015 conn->data->state.in = http->backup.fread_in;
1017 http->sending++; /* move one step up */
1019 http->backup.postsize=0;
1027 memcpy(buffer, http->postdata, fullsize);
1028 http->postdata += fullsize;
1029 http->postsize -= fullsize;
1034 /* ------------------------------------------------------------------------- */
1035 /* add_buffer functions */
1038 * Curl_add_buffer_init() sets up and returns a fine buffer struct
1040 Curl_send_buffer *Curl_add_buffer_init(void)
1042 return calloc(1, sizeof(Curl_send_buffer));
1046 * Curl_add_buffer_free() frees all associated resources.
1048 void Curl_add_buffer_free(Curl_send_buffer *buff)
1050 if(buff) /* deal with NULL input */
1056 * Curl_add_buffer_send() sends a header buffer and frees all associated
1057 * memory. Body data may be appended to the header data if desired.
1061 CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
1062 struct connectdata *conn,
1064 /* add the number of sent bytes to this
1066 long *bytes_written,
1068 /* how much of the buffer contains body data */
1069 size_t included_body_bytes,
1077 struct HTTP *http = conn->data->req.protop;
1079 curl_socket_t sockfd;
1082 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1084 sockfd = conn->sock[socketindex];
1086 /* The looping below is required since we use non-blocking sockets, but due
1087 to the circumstances we will just loop and try again and again etc */
1090 size = in->size_used;
1092 headersize = size - included_body_bytes; /* the initial part that isn't body
1095 DEBUGASSERT(size > included_body_bytes);
1097 result = Curl_convert_to_network(conn->data, ptr, headersize);
1098 /* Curl_convert_to_network calls failf if unsuccessful */
1100 /* conversion failed, free memory and return to the caller */
1101 Curl_add_buffer_free(in);
1105 if((conn->handler->flags & PROTOPT_SSL ||
1106 conn->http_proxy.proxytype == CURLPROXY_HTTPS)
1107 && conn->httpversion != 20) {
1108 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1109 when we speak HTTPS, as if only a fraction of it is sent now, this data
1110 needs to fit into the normal read-callback buffer later on and that
1111 buffer is using this size.
1114 sendsize = (size > CURL_MAX_WRITE_SIZE) ? CURL_MAX_WRITE_SIZE : size;
1116 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1117 library when we attempt to re-send this buffer. Sending the same data
1118 is not enough, we must use the exact same address. For this reason, we
1119 must copy the data to the uploadbuffer first, since that is the buffer
1120 we will be using if this send is retried later.
1122 memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1123 ptr = conn->data->state.uploadbuffer;
1128 result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1132 * Note that we may not send the entire chunk at once, and we have a set
1133 * number of data bytes at the end of the big buffer (out of which we may
1134 * only send away a part).
1136 /* how much of the header that was sent */
1137 size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
1138 size_t bodylen = amount - headlen;
1140 if(conn->data->set.verbose) {
1141 /* this data _may_ contain binary stuff */
1142 Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1144 /* there was body data sent beyond the initial header part, pass that
1145 on to the debug callback too */
1146 Curl_debug(conn->data, CURLINFO_DATA_OUT,
1147 ptr+headlen, bodylen, conn);
1151 /* 'amount' can never be a very large value here so typecasting it so a
1152 signed 31 bit value should not cause problems even if ssize_t is
1154 *bytes_written += (long)amount;
1157 /* if we sent a piece of the body here, up the byte counter for it
1159 http->writebytecount += bodylen;
1161 if((size_t)amount != size) {
1162 /* The whole request could not be sent in one system call. We must
1163 queue it up and send it later when we get the chance. We must not
1164 loop here and wait until it might work again. */
1168 ptr = in->buffer + amount;
1170 /* backup the currently set pointers */
1171 http->backup.fread_func = conn->data->state.fread_func;
1172 http->backup.fread_in = conn->data->state.in;
1173 http->backup.postdata = http->postdata;
1174 http->backup.postsize = http->postsize;
1176 /* set the new pointers for the request-sending */
1177 conn->data->state.fread_func = (curl_read_callback)readmoredata;
1178 conn->data->state.in = (void *)conn;
1179 http->postdata = ptr;
1180 http->postsize = (curl_off_t)size;
1182 http->send_buffer = in;
1183 http->sending = HTTPSEND_REQUEST;
1187 http->sending = HTTPSEND_BODY;
1188 /* the full buffer was sent, clean up and return */
1191 if((size_t)amount != size)
1192 /* We have no continue-send mechanism now, fail. This can only happen
1193 when this function is used from the CONNECT sending function. We
1194 currently (stupidly) assume that the whole request is always sent
1195 away in the first single chunk.
1199 return CURLE_SEND_ERROR;
1201 Curl_pipeline_leave_write(conn);
1204 Curl_add_buffer_free(in);
1211 * add_bufferf() add the formatted input to the buffer.
1213 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1218 s = vaprintf(fmt, ap); /* this allocs a new string to append */
1222 CURLcode result = Curl_add_buffer(in, s, strlen(s));
1226 /* If we failed, we cleanup the whole buffer and return error */
1229 return CURLE_OUT_OF_MEMORY;
1233 * add_buffer() appends a memory chunk to the existing buffer
1235 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1240 if(~size < in->size_used) {
1241 /* If resulting used size of send buffer would wrap size_t, cleanup
1242 the whole buffer and return error. Otherwise the required buffer
1243 size will fit into a single allocatable memory chunk */
1244 Curl_safefree(in->buffer);
1246 return CURLE_OUT_OF_MEMORY;
1250 ((in->size_used + size) > (in->size_max - 1))) {
1252 /* If current buffer size isn't enough to hold the result, use a
1253 buffer size that doubles the required size. If this new size
1254 would wrap size_t, then just use the largest possible one */
1256 if((size > (size_t)-1 / 2) || (in->size_used > (size_t)-1 / 2) ||
1257 (~(size * 2) < (in->size_used * 2)))
1258 new_size = (size_t)-1;
1260 new_size = (in->size_used+size) * 2;
1263 /* we have a buffer, enlarge the existing one */
1264 new_rb = Curl_saferealloc(in->buffer, new_size);
1266 /* create a new buffer */
1267 new_rb = malloc(new_size);
1270 /* If we failed, we cleanup the whole buffer and return error */
1272 return CURLE_OUT_OF_MEMORY;
1275 in->buffer = new_rb;
1276 in->size_max = new_size;
1278 memcpy(&in->buffer[in->size_used], inptr, size);
1280 in->size_used += size;
1285 /* end of the add_buffer functions */
1286 /* ------------------------------------------------------------------------- */
1291 * Curl_compareheader()
1293 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1294 * Pass headers WITH the colon.
1297 Curl_compareheader(const char *headerline, /* line to check */
1298 const char *header, /* header keyword _with_ colon */
1299 const char *content) /* content string to find */
1301 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1302 * by a colon (":") and the field value. Field names are case-insensitive.
1303 * The field value MAY be preceded by any amount of LWS, though a single SP
1306 size_t hlen = strlen(header);
1312 if(!strncasecompare(headerline, header, hlen))
1313 return FALSE; /* doesn't start with header */
1315 /* pass the header */
1316 start = &headerline[hlen];
1318 /* pass all white spaces */
1319 while(*start && ISSPACE(*start))
1322 /* find the end of the header line */
1323 end = strchr(start, '\r'); /* lines end with CRLF */
1325 /* in case there's a non-standard compliant line here */
1326 end = strchr(start, '\n');
1329 /* hm, there's no line ending here, use the zero byte! */
1330 end = strchr(start, '\0');
1333 len = end-start; /* length of the content part of the input line */
1334 clen = strlen(content); /* length of the word to find */
1336 /* find the content string in the rest of the line */
1337 for(;len>=clen;len--, start++) {
1338 if(strncasecompare(start, content, clen))
1339 return TRUE; /* match! */
1342 return FALSE; /* no match */
1346 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1347 * the generic Curl_connect().
1349 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1353 /* We default to persistent connections. We set this already in this connect
1354 function to make the re-use checks properly be able to check this bit. */
1355 connkeep(conn, "HTTP default");
1357 /* the CONNECT procedure might not have been completed */
1358 result = Curl_proxy_connect(conn, FIRSTSOCKET);
1362 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
1363 return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
1365 if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1366 /* nothing else to do except wait right now - we're not done here. */
1369 if(conn->given->flags & PROTOPT_SSL) {
1370 /* perform SSL initialization */
1371 result = https_connecting(conn, done);
1381 /* this returns the socket to wait for in the DO and DOING state for the multi
1382 interface and then we're always _sending_ a request and thus we wait for
1383 the single socket to become writable only */
1384 static int http_getsock_do(struct connectdata *conn,
1385 curl_socket_t *socks,
1389 (void)numsocks; /* unused, we trust it to be at least 1 */
1390 socks[0] = conn->sock[FIRSTSOCKET];
1391 return GETSOCK_WRITESOCK(0);
1395 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1398 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1400 /* perform SSL initialization for this socket */
1401 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1403 connclose(conn, "Failed HTTPS connection");
1408 static int https_getsock(struct connectdata *conn,
1409 curl_socket_t *socks,
1412 if(conn->handler->flags & PROTOPT_SSL)
1413 return Curl_ssl_getsock(conn, socks, numsocks);
1414 return GETSOCK_BLANK;
1416 #endif /* USE_SSL */
1419 * Curl_http_done() gets called after a single HTTP request has been
1423 CURLcode Curl_http_done(struct connectdata *conn,
1424 CURLcode status, bool premature)
1426 struct Curl_easy *data = conn->data;
1427 struct HTTP *http = data->req.protop;
1429 Curl_unencode_cleanup(conn);
1432 if(data->state.proxyneg.state == GSS_AUTHSENT ||
1433 data->state.negotiate.state == GSS_AUTHSENT) {
1434 /* add forbid re-use if http-code != 401/407 as a WA only needed for
1435 * 401/407 that signal auth failure (empty) otherwise state will be RECV
1436 * with current code.
1437 * Do not close CONNECT_ONLY connections. */
1438 if((data->req.httpcode != 401) && (data->req.httpcode != 407) &&
1439 !data->set.connect_only)
1440 streamclose(conn, "Negotiate transfer completed");
1441 Curl_cleanup_negotiate(data);
1445 /* set the proper values (possibly modified on POST) */
1446 conn->seek_func = data->set.seek_func; /* restore */
1447 conn->seek_client = data->set.seek_client; /* restore */
1452 if(http->send_buffer) {
1453 Curl_add_buffer_free(http->send_buffer);
1454 http->send_buffer = NULL; /* clear the pointer */
1457 Curl_http2_done(conn, premature);
1459 if(HTTPREQ_POST_FORM == data->set.httpreq) {
1460 data->req.bytecount = http->readbytecount + http->writebytecount;
1462 Curl_formclean(&http->sendit); /* Now free that whole lot */
1464 /* a file being uploaded was left opened, close it! */
1465 fclose(http->form.fp);
1466 http->form.fp = NULL;
1469 else if(HTTPREQ_PUT == data->set.httpreq)
1470 data->req.bytecount = http->readbytecount + http->writebytecount;
1475 if(!premature && /* this check is pointless when DONE is called before the
1476 entire operation is complete */
1477 !conn->bits.retry &&
1478 !data->set.connect_only &&
1479 (http->readbytecount +
1480 data->req.headerbytecount -
1481 data->req.deductheadercount) <= 0) {
1482 /* If this connection isn't simply closed to be retried, AND nothing was
1483 read from the HTTP server (that counts), this can't be right so we
1484 return an error here */
1485 failf(data, "Empty reply from server");
1486 return CURLE_GOT_NOTHING;
1493 * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
1494 * to avoid it include:
1496 * - if the user specifically requested HTTP 1.0
1497 * - if the server we are connected to only supports 1.0
1498 * - if any server previously contacted to handle this request only supports
1501 static bool use_http_1_1plus(const struct Curl_easy *data,
1502 const struct connectdata *conn)
1504 if((data->state.httpversion == 10) || (conn->httpversion == 10))
1506 if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
1507 (conn->httpversion <= 10))
1509 return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
1510 (data->set.httpversion >= CURL_HTTP_VERSION_1_1));
1513 static const char *get_http_string(const struct Curl_easy *data,
1514 const struct connectdata *conn)
1517 if(conn->proto.httpc.h2)
1521 if(use_http_1_1plus(data, conn))
1527 /* check and possibly add an Expect: header */
1528 static CURLcode expect100(struct Curl_easy *data,
1529 struct connectdata *conn,
1530 Curl_send_buffer *req_buffer)
1532 CURLcode result = CURLE_OK;
1534 data->state.expect100header = FALSE; /* default to false unless it is set
1536 if(use_http_1_1plus(data, conn) &&
1537 (conn->httpversion != 20)) {
1538 /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
1539 Expect: 100-continue to the headers which actually speeds up post
1540 operations (as there is one packet coming back from the web server) */
1541 ptr = Curl_checkheaders(conn, "Expect:");
1543 data->state.expect100header =
1544 Curl_compareheader(ptr, "Expect:", "100-continue");
1547 result = Curl_add_bufferf(req_buffer,
1548 "Expect: 100-continue\r\n");
1550 data->state.expect100header = TRUE;
1558 HEADER_SERVER, /* direct to server */
1559 HEADER_PROXY, /* regular request to proxy */
1560 HEADER_CONNECT /* sending CONNECT to a proxy */
1563 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1565 Curl_send_buffer *req_buffer)
1568 struct curl_slist *h[2];
1569 struct curl_slist *headers;
1570 int numlists=1; /* by default */
1571 struct Curl_easy *data = conn->data;
1574 enum proxy_use proxy;
1577 proxy = HEADER_CONNECT;
1579 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
1580 HEADER_PROXY:HEADER_SERVER;
1584 h[0] = data->set.headers;
1587 h[0] = data->set.headers;
1588 if(data->set.sep_headers) {
1589 h[1] = data->set.proxyheaders;
1593 case HEADER_CONNECT:
1594 if(data->set.sep_headers)
1595 h[0] = data->set.proxyheaders;
1597 h[0] = data->set.headers;
1601 /* loop through one or two lists */
1602 for(i=0; i < numlists; i++) {
1606 ptr = strchr(headers->data, ':');
1608 /* we require a colon for this to be a true header */
1610 ptr++; /* pass the colon */
1611 while(*ptr && ISSPACE(*ptr))
1615 /* only send this if the contents was non-blank */
1617 if(conn->allocptr.host &&
1618 /* a Host: header was sent already, don't pass on any custom Host:
1619 header as that will produce *two* in the same request! */
1620 checkprefix("Host:", headers->data))
1622 else if(data->set.httpreq == HTTPREQ_POST_FORM &&
1623 /* this header (extended by formdata.c) is sent later */
1624 checkprefix("Content-Type:", headers->data))
1626 else if(conn->bits.authneg &&
1627 /* while doing auth neg, don't allow the custom length since
1628 we will force length zero then */
1629 checkprefix("Content-Length", headers->data))
1631 else if(conn->allocptr.te &&
1632 /* when asking for Transfer-Encoding, don't pass on a custom
1634 checkprefix("Connection", headers->data))
1636 else if((conn->httpversion == 20) &&
1637 checkprefix("Transfer-Encoding:", headers->data))
1638 /* HTTP/2 doesn't support chunked requests */
1641 CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1649 ptr = strchr(headers->data, ';');
1652 ptr++; /* pass the semicolon */
1653 while(*ptr && ISSPACE(*ptr))
1657 /* this may be used for something else in the future */
1660 if(*(--ptr) == ';') {
1663 /* send no-value custom header if terminated by semicolon */
1665 result = Curl_add_bufferf(req_buffer, "%s\r\n",
1673 headers = headers->next;
1680 CURLcode Curl_add_timecondition(struct Curl_easy *data,
1681 Curl_send_buffer *req_buffer)
1683 const struct tm *tm;
1684 char *buf = data->state.buffer;
1688 if(data->set.timecondition == CURL_TIMECOND_NONE)
1689 /* no condition was asked for */
1692 result = Curl_gmtime(data->set.timevalue, &keeptime);
1694 failf(data, "Invalid TIMEVALUE");
1699 /* The If-Modified-Since header family should have their times set in
1700 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1701 * represented in Greenwich Mean Time (GMT), without exception. For the
1702 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1703 * Time)." (see page 20 of RFC2616).
1706 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1707 snprintf(buf, BUFSIZE-1,
1708 "%s, %02d %s %4d %02d:%02d:%02d GMT",
1709 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1711 Curl_month[tm->tm_mon],
1717 switch(data->set.timecondition) {
1720 case CURL_TIMECOND_IFMODSINCE:
1721 result = Curl_add_bufferf(req_buffer,
1722 "If-Modified-Since: %s\r\n", buf);
1724 case CURL_TIMECOND_IFUNMODSINCE:
1725 result = Curl_add_bufferf(req_buffer,
1726 "If-Unmodified-Since: %s\r\n", buf);
1728 case CURL_TIMECOND_LASTMOD:
1729 result = Curl_add_bufferf(req_buffer,
1730 "Last-Modified: %s\r\n", buf);
1738 * Curl_http() gets called from the generic multi_do() function when a HTTP
1739 * request is to be performed. This creates and sends a properly constructed
1742 CURLcode Curl_http(struct connectdata *conn, bool *done)
1744 struct Curl_easy *data = conn->data;
1745 CURLcode result = CURLE_OK;
1747 const char *ppath = data->state.path;
1748 bool paste_ftp_userpwd = FALSE;
1749 char ftp_typecode[sizeof("/;type=?")] = "";
1750 const char *host = conn->host.name;
1751 const char *te = ""; /* transfer-encoding */
1753 const char *request;
1754 Curl_HttpReq httpreq = data->set.httpreq;
1755 #if !defined(CURL_DISABLE_COOKIES)
1756 char *addcookies = NULL;
1758 curl_off_t included_body = 0;
1759 const char *httpstring;
1760 Curl_send_buffer *req_buffer;
1761 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1762 int seekerr = CURL_SEEKFUNC_OK;
1764 /* Always consider the DO phase done after this function call, even if there
1765 may be parts of the request that is not yet sent, since we can deal with
1766 the rest of the request in the PERFORM phase. */
1769 if(conn->httpversion < 20) { /* unless the connection is re-used and already
1771 switch(conn->negnpn) {
1772 case CURL_HTTP_VERSION_2:
1773 conn->httpversion = 20; /* we know we're on HTTP/2 now */
1775 result = Curl_http2_switched(conn, NULL, 0);
1779 case CURL_HTTP_VERSION_1_1:
1780 /* continue with HTTP/1.1 when explicitly requested */
1783 /* Check if user wants to use HTTP/2 with clear TCP*/
1785 if(conn->data->set.httpversion ==
1786 CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
1787 DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
1788 conn->httpversion = 20;
1790 result = Curl_http2_switched(conn, NULL, 0);
1799 /* prepare for a http2 request */
1800 result = Curl_http2_setup(conn);
1805 http = data->req.protop;
1807 if(!data->state.this_is_a_follow) {
1808 /* Free to avoid leaking memory on multiple requests*/
1809 free(data->state.first_host);
1811 data->state.first_host = strdup(conn->host.name);
1812 if(!data->state.first_host)
1813 return CURLE_OUT_OF_MEMORY;
1815 data->state.first_remote_port = conn->remote_port;
1817 http->writebytecount = http->readbytecount = 0;
1819 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
1821 httpreq = HTTPREQ_PUT;
1824 /* Now set the 'request' pointer to the proper request string */
1825 if(data->set.str[STRING_CUSTOMREQUEST])
1826 request = data->set.str[STRING_CUSTOMREQUEST];
1828 if(data->set.opt_no_body)
1831 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1834 case HTTPREQ_POST_FORM:
1840 default: /* this should never happen */
1851 /* The User-Agent string might have been allocated in url.c already, because
1852 it might have been used in the proxy connect, but if we have got a header
1853 with the user-agent string specified, we erase the previously made string
1855 if(Curl_checkheaders(conn, "User-Agent:")) {
1856 free(conn->allocptr.uagent);
1857 conn->allocptr.uagent=NULL;
1860 /* setup the authentication headers */
1861 result = Curl_http_output_auth(conn, request, ppath, FALSE);
1865 if((data->state.authhost.multi || data->state.authproxy.multi) &&
1866 (httpreq != HTTPREQ_GET) &&
1867 (httpreq != HTTPREQ_HEAD)) {
1868 /* Auth is required and we are not authenticated yet. Make a PUT or POST
1869 with content-length zero as a "probe". */
1870 conn->bits.authneg = TRUE;
1873 conn->bits.authneg = FALSE;
1875 Curl_safefree(conn->allocptr.ref);
1876 if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) {
1877 conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1878 if(!conn->allocptr.ref)
1879 return CURLE_OUT_OF_MEMORY;
1882 conn->allocptr.ref = NULL;
1884 #if !defined(CURL_DISABLE_COOKIES)
1885 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
1886 addcookies = data->set.str[STRING_COOKIE];
1889 if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
1890 data->set.str[STRING_ENCODING]) {
1891 Curl_safefree(conn->allocptr.accept_encoding);
1892 conn->allocptr.accept_encoding =
1893 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1894 if(!conn->allocptr.accept_encoding)
1895 return CURLE_OUT_OF_MEMORY;
1898 Curl_safefree(conn->allocptr.accept_encoding);
1899 conn->allocptr.accept_encoding = NULL;
1903 /* we only consider transfer-encoding magic if libz support is built-in */
1905 if(!Curl_checkheaders(conn, "TE:") &&
1906 data->set.http_transfer_encoding) {
1907 /* When we are to insert a TE: header in the request, we must also insert
1908 TE in a Connection: header, so we need to merge the custom provided
1909 Connection: header and prevent the original to get sent. Note that if
1910 the user has inserted his/hers own TE: header we don't do this magic
1911 but then assume that the user will handle it all! */
1912 char *cptr = Curl_checkheaders(conn, "Connection:");
1913 #define TE_HEADER "TE: gzip\r\n"
1915 Curl_safefree(conn->allocptr.te);
1917 /* Create the (updated) Connection: header */
1918 conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1919 strdup("Connection: TE\r\n" TE_HEADER);
1921 if(!conn->allocptr.te)
1922 return CURLE_OUT_OF_MEMORY;
1926 ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
1928 /* Some kind of TE is requested, check if 'chunked' is chosen */
1929 data->req.upload_chunky =
1930 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1933 if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
1935 (data->state.infilesize == -1)) {
1936 if(conn->bits.authneg)
1937 /* don't enable chunked during auth neg */
1939 else if(use_http_1_1plus(data, conn)) {
1940 /* HTTP, upload, unknown file size and not HTTP 1.0 */
1941 data->req.upload_chunky = TRUE;
1944 failf(data, "Chunky upload is not supported by HTTP 1.0");
1945 return CURLE_UPLOAD_FAILED;
1949 /* else, no chunky upload */
1950 data->req.upload_chunky = FALSE;
1953 if(data->req.upload_chunky)
1954 te = "Transfer-Encoding: chunked\r\n";
1957 Curl_safefree(conn->allocptr.host);
1959 ptr = Curl_checkheaders(conn, "Host:");
1960 if(ptr && (!data->state.this_is_a_follow ||
1961 strcasecompare(data->state.first_host, conn->host.name))) {
1962 #if !defined(CURL_DISABLE_COOKIES)
1963 /* If we have a given custom Host: header, we extract the host name in
1964 order to possibly use it for cookie reasons later on. We only allow the
1965 custom Host: header if this is NOT a redirect, as setting Host: in the
1966 redirected request is being out on thin ice. Except if the host name
1967 is the same as the first one! */
1968 char *cookiehost = Curl_copy_header_value(ptr);
1970 return CURLE_OUT_OF_MEMORY;
1972 /* ignore empty data */
1975 /* If the host begins with '[', we start searching for the port after
1976 the bracket has been closed */
1977 int startsearch = 0;
1978 if(*cookiehost == '[') {
1979 char *closingbracket;
1980 /* since the 'cookiehost' is an allocated memory area that will be
1981 freed later we cannot simply increment the pointer */
1982 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
1983 closingbracket = strchr(cookiehost, ']');
1985 *closingbracket = 0;
1988 char *colon = strchr(cookiehost + startsearch, ':');
1990 *colon = 0; /* The host must not include an embedded port number */
1992 Curl_safefree(conn->allocptr.cookiehost);
1993 conn->allocptr.cookiehost = cookiehost;
1997 if(strcmp("Host:", ptr)) {
1998 conn->allocptr.host = aprintf("%s\r\n", ptr);
1999 if(!conn->allocptr.host)
2000 return CURLE_OUT_OF_MEMORY;
2003 /* when clearing the header */
2004 conn->allocptr.host = NULL;
2007 /* When building Host: headers, we must put the host name within
2008 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
2010 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
2011 (conn->remote_port == PORT_HTTPS)) ||
2012 ((conn->given->protocol&CURLPROTO_HTTP) &&
2013 (conn->remote_port == PORT_HTTP)) )
2014 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
2015 the port number in the host string */
2016 conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
2017 conn->bits.ipv6_ip?"[":"",
2019 conn->bits.ipv6_ip?"]":"");
2021 conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
2022 conn->bits.ipv6_ip?"[":"",
2024 conn->bits.ipv6_ip?"]":"",
2027 if(!conn->allocptr.host)
2028 /* without Host: we can't make a nice request */
2029 return CURLE_OUT_OF_MEMORY;
2032 #ifndef CURL_DISABLE_PROXY
2033 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
2034 /* Using a proxy but does not tunnel through it */
2036 /* The path sent to the proxy is in fact the entire URL. But if the remote
2037 host is a IDN-name, we must make sure that the request we produce only
2038 uses the encoded host name! */
2039 if(conn->host.dispname != conn->host.name) {
2040 char *url = data->change.url;
2041 ptr = strstr(url, conn->host.dispname);
2043 /* This is where the display name starts in the URL, now replace this
2044 part with the encoded name. TODO: This method of replacing the host
2045 name is rather crude as I believe there's a slight risk that the
2046 user has entered a user name or password that contain the host name
2048 size_t currlen = strlen(conn->host.dispname);
2049 size_t newlen = strlen(conn->host.name);
2050 size_t urllen = strlen(url);
2054 newurl = malloc(urllen + newlen - currlen + 1);
2056 /* copy the part before the host name */
2057 memcpy(newurl, url, ptr - url);
2058 /* append the new host name instead of the old */
2059 memcpy(newurl + (ptr - url), conn->host.name, newlen);
2060 /* append the piece after the host name */
2061 memcpy(newurl + newlen + (ptr - url),
2062 ptr + currlen, /* copy the trailing zero byte too */
2063 urllen - (ptr-url) - currlen + 1);
2064 if(data->change.url_alloc) {
2065 Curl_safefree(data->change.url);
2066 data->change.url_alloc = FALSE;
2068 data->change.url = newurl;
2069 data->change.url_alloc = TRUE;
2072 return CURLE_OUT_OF_MEMORY;
2075 ppath = data->change.url;
2076 if(checkprefix("ftp://", ppath)) {
2077 if(data->set.proxy_transfer_mode) {
2078 /* when doing ftp, append ;type=<a|i> if not present */
2079 char *type = strstr(ppath, ";type=");
2080 if(type && type[6] && type[7] == 0) {
2081 switch(Curl_raw_toupper(type[6])) {
2091 char *p = ftp_typecode;
2092 /* avoid sending invalid URLs like ftp://example.com;type=i if the
2093 * user specified ftp://example.com without the slash */
2094 if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
2097 snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
2098 data->set.prefer_ascii ? 'a' : 'i');
2101 if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
2102 paste_ftp_userpwd = TRUE;
2105 #endif /* CURL_DISABLE_PROXY */
2107 if(HTTPREQ_POST_FORM == httpreq) {
2108 /* we must build the whole post sequence first, so that we have a size of
2109 the whole transfer before we start to send it */
2110 result = Curl_getformdata(data, &http->sendit, data->set.httppost,
2111 Curl_checkheaders(conn, "Content-Type:"),
2117 http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n";
2119 if(( (HTTPREQ_POST == httpreq) ||
2120 (HTTPREQ_POST_FORM == httpreq) ||
2121 (HTTPREQ_PUT == httpreq) ) &&
2122 data->state.resume_from) {
2123 /**********************************************************************
2124 * Resuming upload in HTTP means that we PUT or POST and that we have
2125 * got a resume_from value set. The resume value has already created
2126 * a Range: header that will be passed along. We need to "fast forward"
2127 * the file the given number of bytes and decrease the assume upload
2128 * file size before we continue this venture in the dark lands of HTTP.
2129 *********************************************************************/
2131 if(data->state.resume_from < 0) {
2133 * This is meant to get the size of the present remote-file by itself.
2134 * We don't support this now. Bail out!
2136 data->state.resume_from = 0;
2139 if(data->state.resume_from && !data->state.this_is_a_follow) {
2140 /* do we still game? */
2142 /* Now, let's read off the proper amount of bytes from the
2144 if(conn->seek_func) {
2145 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2149 if(seekerr != CURL_SEEKFUNC_OK) {
2150 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2151 failf(data, "Could not seek stream");
2152 return CURLE_READ_ERROR;
2154 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2156 curl_off_t passed=0;
2158 size_t readthisamountnow =
2159 (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
2160 BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
2162 size_t actuallyread =
2163 data->state.fread_func(data->state.buffer, 1, readthisamountnow,
2166 passed += actuallyread;
2167 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2168 /* this checks for greater-than only to make sure that the
2169 CURL_READFUNC_ABORT return code still aborts */
2170 failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2171 " bytes from the input", passed);
2172 return CURLE_READ_ERROR;
2174 } while(passed < data->state.resume_from);
2178 /* now, decrease the size of the read */
2179 if(data->state.infilesize>0) {
2180 data->state.infilesize -= data->state.resume_from;
2182 if(data->state.infilesize <= 0) {
2183 failf(data, "File already completely uploaded");
2184 return CURLE_PARTIAL_FILE;
2187 /* we've passed, proceed as normal */
2190 if(data->state.use_range) {
2192 * A range is selected. We use different headers whether we're downloading
2193 * or uploading and we always let customized headers override our internal
2194 * ones if any such are specified.
2196 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2197 !Curl_checkheaders(conn, "Range:")) {
2198 /* if a line like this was already allocated, free the previous one */
2199 free(conn->allocptr.rangeline);
2200 conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2203 else if((httpreq != HTTPREQ_GET) &&
2204 !Curl_checkheaders(conn, "Content-Range:")) {
2206 /* if a line like this was already allocated, free the previous one */
2207 free(conn->allocptr.rangeline);
2209 if(data->set.set_resume_from < 0) {
2210 /* Upload resume was asked for, but we don't know the size of the
2211 remote part so we tell the server (and act accordingly) that we
2212 upload the whole file (again) */
2213 conn->allocptr.rangeline =
2214 aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2215 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2216 data->state.infilesize - 1, data->state.infilesize);
2219 else if(data->state.resume_from) {
2220 /* This is because "resume" was selected */
2221 curl_off_t total_expected_size=
2222 data->state.resume_from + data->state.infilesize;
2223 conn->allocptr.rangeline =
2224 aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2225 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2226 data->state.range, total_expected_size-1,
2227 total_expected_size);
2230 /* Range was selected and then we just pass the incoming range and
2231 append total size */
2232 conn->allocptr.rangeline =
2233 aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2234 data->state.range, data->state.infilesize);
2236 if(!conn->allocptr.rangeline)
2237 return CURLE_OUT_OF_MEMORY;
2241 httpstring = get_http_string(data, conn);
2243 /* initialize a dynamic send-buffer */
2244 req_buffer = Curl_add_buffer_init();
2247 return CURLE_OUT_OF_MEMORY;
2249 /* add the main request stuff */
2250 /* GET/HEAD/POST/PUT */
2251 result = Curl_add_bufferf(req_buffer, "%s ", request);
2256 if(paste_ftp_userpwd)
2257 result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2258 conn->user, conn->passwd,
2259 ppath + sizeof("ftp://") - 1);
2261 result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2266 Curl_add_bufferf(req_buffer,
2267 "%s" /* ftp typecode (;type=x) */
2268 " HTTP/%s\r\n" /* HTTP version */
2270 "%s" /* proxyuserpwd */
2273 "%s" /* user agent */
2276 "%s" /* accept-encoding */
2278 "%s" /* Proxy-Connection */
2279 "%s",/* transfer-encoding */
2283 (conn->allocptr.host?conn->allocptr.host:""),
2284 conn->allocptr.proxyuserpwd?
2285 conn->allocptr.proxyuserpwd:"",
2286 conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2287 (data->state.use_range && conn->allocptr.rangeline)?
2288 conn->allocptr.rangeline:"",
2289 (data->set.str[STRING_USERAGENT] &&
2290 *data->set.str[STRING_USERAGENT] &&
2291 conn->allocptr.uagent)?
2292 conn->allocptr.uagent:"",
2293 http->p_accept?http->p_accept:"",
2294 conn->allocptr.te?conn->allocptr.te:"",
2295 (data->set.str[STRING_ENCODING] &&
2296 *data->set.str[STRING_ENCODING] &&
2297 conn->allocptr.accept_encoding)?
2298 conn->allocptr.accept_encoding:"",
2299 (data->change.referer && conn->allocptr.ref)?
2300 conn->allocptr.ref:"" /* Referer: <data> */,
2301 (conn->bits.httpproxy &&
2302 !conn->bits.tunnel_proxy &&
2303 !Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
2304 "Proxy-Connection: Keep-Alive\r\n":"",
2308 /* clear userpwd to avoid re-using credentials from re-used connections */
2309 Curl_safefree(conn->allocptr.userpwd);
2312 * Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
2313 * with the connection and shouldn't be repeated over it either.
2315 switch(data->state.authproxy.picked) {
2316 case CURLAUTH_NEGOTIATE:
2318 case CURLAUTH_NTLM_WB:
2319 Curl_safefree(conn->allocptr.proxyuserpwd);
2326 if(!(conn->handler->flags&PROTOPT_SSL) &&
2327 conn->httpversion != 20 &&
2328 (data->set.httpversion == CURL_HTTP_VERSION_2)) {
2329 /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
2331 result = Curl_http2_request_upgrade(req_buffer, conn);
2336 #if !defined(CURL_DISABLE_COOKIES)
2337 if(data->cookies || addcookies) {
2338 struct Cookie *co=NULL; /* no cookies from start */
2342 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2343 co = Curl_cookie_getlist(data->cookies,
2344 conn->allocptr.cookiehost?
2345 conn->allocptr.cookiehost:host,
2347 (conn->handler->protocol&CURLPROTO_HTTPS)?
2349 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2352 struct Cookie *store=co;
2353 /* now loop through all cookies that matched */
2357 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2361 result = Curl_add_bufferf(req_buffer,
2362 "%s%s=%s", count?"; ":"",
2363 co->name, co->value);
2368 co = co->next; /* next cookie please */
2370 Curl_cookie_freelist(store);
2372 if(addcookies && !result) {
2374 result = Curl_add_bufferf(req_buffer, "Cookie: ");
2376 result = Curl_add_bufferf(req_buffer, "%s%s", count?"; ":"",
2381 if(count && !result)
2382 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2389 result = Curl_add_timecondition(data, req_buffer);
2393 result = Curl_add_custom_headers(conn, FALSE, req_buffer);
2397 http->postdata = NULL; /* nothing to post at this point */
2398 Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
2400 /* If 'authdone' is FALSE, we must not set the write socket index to the
2401 Curl_transfer() call below, as we're not ready to actually upload any
2406 case HTTPREQ_POST_FORM:
2407 if(!http->sendit || conn->bits.authneg) {
2408 /* nothing to post! */
2409 result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2413 result = Curl_add_buffer_send(req_buffer, conn,
2414 &data->info.request_size, 0, FIRSTSOCKET);
2416 failf(data, "Failed sending POST request");
2418 /* setup variables for the upcoming transfer */
2419 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2424 if(Curl_FormInit(&http->form, http->sendit)) {
2425 failf(data, "Internal HTTP POST error!");
2426 return CURLE_HTTP_POST_ERROR;
2429 /* Get the currently set callback function pointer and store that in the
2430 form struct since we might want the actual user-provided callback later
2431 on. The data->set.fread_func pointer itself will be changed for the
2432 multipart case to the function that returns a multipart formatted
2434 http->form.fread_func = data->state.fread_func;
2436 /* Set the read function to read from the generated form data */
2437 data->state.fread_func = (curl_read_callback)Curl_FormReader;
2438 data->state.in = &http->form;
2440 http->sending = HTTPSEND_BODY;
2442 if(!data->req.upload_chunky &&
2443 !Curl_checkheaders(conn, "Content-Length:")) {
2444 /* only add Content-Length if not uploading chunked */
2445 result = Curl_add_bufferf(req_buffer,
2446 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2447 "\r\n", http->postsize);
2452 result = expect100(data, conn, req_buffer);
2458 /* Get Content-Type: line from Curl_formpostheader.
2461 size_t linelength=0;
2462 contentType = Curl_formpostheader((void *)&http->form,
2465 failf(data, "Could not get Content-Type header line!");
2466 return CURLE_HTTP_POST_ERROR;
2469 result = Curl_add_buffer(req_buffer, contentType, linelength);
2474 /* make the request end in a true CRLF */
2475 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2479 /* set upload size to the progress meter */
2480 Curl_pgrsSetUploadSize(data, http->postsize);
2482 /* fire away the whole request to the server */
2483 result = Curl_add_buffer_send(req_buffer, conn,
2484 &data->info.request_size, 0, FIRSTSOCKET);
2486 failf(data, "Failed sending POST request");
2488 /* setup variables for the upcoming transfer */
2489 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2490 &http->readbytecount, FIRSTSOCKET,
2491 &http->writebytecount);
2494 Curl_formclean(&http->sendit); /* free that whole lot */
2498 /* convert the form data */
2499 result = Curl_convert_form(data, http->sendit);
2501 Curl_formclean(&http->sendit); /* free that whole lot */
2507 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2509 if(conn->bits.authneg)
2512 postsize = data->state.infilesize;
2514 if((postsize != -1) && !data->req.upload_chunky &&
2515 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
2516 /* only add Content-Length if not uploading chunked */
2517 result = Curl_add_bufferf(req_buffer,
2518 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2525 result = expect100(data, conn, req_buffer);
2530 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2534 /* set the upload size to the progress meter */
2535 Curl_pgrsSetUploadSize(data, postsize);
2537 /* this sends the buffer and frees all the buffer resources */
2538 result = Curl_add_buffer_send(req_buffer, conn,
2539 &data->info.request_size, 0, FIRSTSOCKET);
2541 failf(data, "Failed sending PUT request");
2543 /* prepare for transfer */
2544 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2545 &http->readbytecount, postsize?FIRSTSOCKET:-1,
2546 postsize?&http->writebytecount:NULL);
2552 /* this is the simple POST, using x-www-form-urlencoded style */
2554 if(conn->bits.authneg)
2557 /* figure out the size of the postfields */
2558 postsize = (data->state.infilesize != -1)?
2559 data->state.infilesize:
2560 (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2563 /* We only set Content-Length and allow a custom Content-Length if
2564 we don't upload data chunked, as RFC2616 forbids us to set both
2565 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2566 if((postsize != -1) && !data->req.upload_chunky &&
2567 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length:"))) {
2568 /* we allow replacing this header if not during auth negotiation,
2569 although it isn't very wise to actually set your own */
2570 result = Curl_add_bufferf(req_buffer,
2571 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2577 if(!Curl_checkheaders(conn, "Content-Type:")) {
2578 result = Curl_add_bufferf(req_buffer,
2579 "Content-Type: application/"
2580 "x-www-form-urlencoded\r\n");
2585 /* For really small posts we don't use Expect: headers at all, and for
2586 the somewhat bigger ones we allow the app to disable it. Just make
2587 sure that the expect100header is always set to the preferred value
2589 ptr = Curl_checkheaders(conn, "Expect:");
2591 data->state.expect100header =
2592 Curl_compareheader(ptr, "Expect:", "100-continue");
2594 else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2595 result = expect100(data, conn, req_buffer);
2600 data->state.expect100header = FALSE;
2602 if(data->set.postfields) {
2604 /* In HTTP2, we send request body in DATA frame regardless of
2606 if(conn->httpversion != 20 &&
2607 !data->state.expect100header &&
2608 (postsize < MAX_INITIAL_POST_SIZE)) {
2609 /* if we don't use expect: 100 AND
2610 postsize is less than MAX_INITIAL_POST_SIZE
2612 then append the post data to the HTTP request header. This limit
2613 is no magic limit but only set to prevent really huge POSTs to
2614 get the data duplicated with malloc() and family. */
2616 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2620 if(!data->req.upload_chunky) {
2621 /* We're not sending it 'chunked', append it to the request
2622 already now to reduce the number if send() calls */
2623 result = Curl_add_buffer(req_buffer, data->set.postfields,
2625 included_body = postsize;
2629 /* Append the POST data chunky-style */
2630 result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2632 result = Curl_add_buffer(req_buffer, data->set.postfields,
2635 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2636 included_body = postsize + 2;
2640 result = Curl_add_buffer(req_buffer, "\x30\x0d\x0a\x0d\x0a", 5);
2646 /* Make sure the progress information is accurate */
2647 Curl_pgrsSetUploadSize(data, postsize);
2650 /* A huge POST coming up, do data separate from the request */
2651 http->postsize = postsize;
2652 http->postdata = data->set.postfields;
2654 http->sending = HTTPSEND_BODY;
2656 data->state.fread_func = (curl_read_callback)readmoredata;
2657 data->state.in = (void *)conn;
2659 /* set the upload size to the progress meter */
2660 Curl_pgrsSetUploadSize(data, http->postsize);
2662 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2668 result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2672 if(data->req.upload_chunky && conn->bits.authneg) {
2673 /* Chunky upload is selected and we're negotiating auth still, send
2675 result = Curl_add_buffer(req_buffer,
2676 "\x30\x0d\x0a\x0d\x0a", 5);
2682 else if(data->state.infilesize) {
2683 /* set the upload size to the progress meter */
2684 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2686 /* set the pointer to mark that we will send the post body using the
2687 read callback, but only if we're not in authenticate
2689 if(!conn->bits.authneg) {
2690 http->postdata = (char *)&http->postdata;
2691 http->postsize = postsize;
2695 /* issue the request */
2696 result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2697 (size_t)included_body, FIRSTSOCKET);
2700 failf(data, "Failed sending HTTP POST request");
2702 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2703 &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2704 http->postdata?&http->writebytecount:NULL);
2708 result = Curl_add_buffer(req_buffer, "\r\n", 2);
2712 /* issue the request */
2713 result = Curl_add_buffer_send(req_buffer, conn,
2714 &data->info.request_size, 0, FIRSTSOCKET);
2717 failf(data, "Failed sending HTTP request");
2719 /* HTTP GET/HEAD download: */
2720 Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2721 http->postdata?FIRSTSOCKET:-1,
2722 http->postdata?&http->writebytecount:NULL);
2727 if(http->writebytecount) {
2728 /* if a request-body has been sent off, we make sure this progress is noted
2730 Curl_pgrsSetUploadCounter(data, http->writebytecount);
2731 if(Curl_pgrsUpdate(conn))
2732 result = CURLE_ABORTED_BY_CALLBACK;
2734 if(http->writebytecount >= postsize) {
2735 /* already sent the entire request body, mark the "upload" as
2737 infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
2738 " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
2739 http->writebytecount, postsize);
2740 data->req.upload_done = TRUE;
2741 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2742 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2746 if((conn->httpversion == 20) && data->req.upload_chunky)
2747 /* upload_chunky was set above to set up the request in a chunky fashion,
2748 but is disabled here again to avoid that the chunked encoded version is
2749 actually used when sending the request body over h2 */
2750 data->req.upload_chunky = FALSE;
2757 * Returns TRUE if member of the list matches prefix of string
2760 checkhttpprefix(struct Curl_easy *data,
2763 struct curl_slist *head = data->set.http200aliases;
2765 #ifdef CURL_DOES_CONVERSIONS
2766 /* convert from the network encoding using a scratch area */
2767 char *scratch = strdup(s);
2768 if(NULL == scratch) {
2769 failf(data, "Failed to allocate memory for conversion!");
2770 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2772 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2773 /* Curl_convert_from_network calls failf if unsuccessful */
2775 return FALSE; /* can't return CURLE_foobar so return FALSE */
2778 #endif /* CURL_DOES_CONVERSIONS */
2781 if(checkprefix(head->data, s)) {
2788 if(!rc && (checkprefix("HTTP/", s)))
2791 #ifdef CURL_DOES_CONVERSIONS
2793 #endif /* CURL_DOES_CONVERSIONS */
2797 #ifndef CURL_DISABLE_RTSP
2799 checkrtspprefix(struct Curl_easy *data,
2803 #ifdef CURL_DOES_CONVERSIONS
2804 /* convert from the network encoding using a scratch area */
2805 char *scratch = strdup(s);
2806 if(NULL == scratch) {
2807 failf(data, "Failed to allocate memory for conversion!");
2808 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2810 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2811 /* Curl_convert_from_network calls failf if unsuccessful */
2813 return FALSE; /* can't return CURLE_foobar so return FALSE */
2817 (void)data; /* unused */
2818 #endif /* CURL_DOES_CONVERSIONS */
2819 if(checkprefix("RTSP/", s))
2824 #endif /* CURL_DISABLE_RTSP */
2827 checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
2830 #ifndef CURL_DISABLE_RTSP
2831 if(conn->handler->protocol & CURLPROTO_RTSP)
2832 return checkrtspprefix(data, s);
2835 #endif /* CURL_DISABLE_RTSP */
2837 return checkhttpprefix(data, s);
2841 * header_append() copies a chunk of data to the end of the already received
2842 * header. We make sure that the full string fit in the allocated header
2843 * buffer, or else we enlarge it.
2845 static CURLcode header_append(struct Curl_easy *data,
2846 struct SingleRequest *k,
2849 if(k->hbuflen + length >= data->state.headersize) {
2850 /* We enlarge the header buffer as it is too small */
2855 if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2856 /* The reason to have a max limit for this is to avoid the risk of a bad
2857 server feeding libcurl with a never-ending header that will cause
2858 reallocs infinitely */
2859 failf(data, "Avoided giant realloc for header (max is %d)!",
2860 CURL_MAX_HTTP_HEADER);
2861 return CURLE_OUT_OF_MEMORY;
2864 newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2865 hbufp_index = k->hbufp - data->state.headerbuff;
2866 newbuff = realloc(data->state.headerbuff, newsize);
2868 failf(data, "Failed to alloc memory for big header!");
2869 return CURLE_OUT_OF_MEMORY;
2871 data->state.headersize=newsize;
2872 data->state.headerbuff = newbuff;
2873 k->hbufp = data->state.headerbuff + hbufp_index;
2875 memcpy(k->hbufp, k->str_start, length);
2877 k->hbuflen += length;
2883 static void print_http_error(struct Curl_easy *data)
2885 struct SingleRequest *k = &data->req;
2888 /* make sure that data->req.p points to the HTTP status line */
2889 if(!strncmp(beg, "HTTP", 4)) {
2891 /* skip to HTTP status code */
2892 beg = strchr(beg, ' ');
2895 /* find trailing CR */
2896 char end_char = '\r';
2897 char *end = strchr(beg, end_char);
2899 /* try to find LF (workaround for non-compliant HTTP servers) */
2901 end = strchr(beg, end_char);
2905 /* temporarily replace CR or LF by NUL and print the error message */
2907 failf(data, "The requested URL returned error: %s", beg);
2909 /* restore the previously replaced CR or LF */
2916 /* fall-back to printing the HTTP status code only */
2917 failf(data, "The requested URL returned error: %d", k->httpcode);
2921 * Read any HTTP header lines from the server and pass them to the client app.
2923 CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
2924 struct connectdata *conn,
2929 struct SingleRequest *k = &data->req;
2931 /* header line within buffer loop */
2937 /* str_start is start of line within buf */
2938 k->str_start = k->str;
2940 /* data is in network encoding so use 0x0a instead of '\n' */
2941 k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2944 /* Not a complete header line within buffer, append the data to
2945 the end of the headerbuff. */
2946 result = header_append(data, k, *nread);
2950 if(!k->headerline && (k->hbuflen>5)) {
2951 /* make a first check that this looks like a protocol header */
2952 if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2953 /* this is not the beginning of a protocol first header line */
2955 k->badheader = HEADER_ALLBAD;
2960 break; /* read more and try again */
2963 /* decrease the size of the remaining (supposed) header line */
2964 rest_length = (k->end_ptr - k->str)+1;
2965 *nread -= (ssize_t)rest_length;
2967 k->str = k->end_ptr + 1; /* move past new line */
2969 full_length = k->str - k->str_start;
2971 result = header_append(data, k, full_length);
2975 k->end_ptr = k->hbufp;
2976 k->p = data->state.headerbuff;
2979 * We now have a FULL header line that p points to
2982 if(!k->headerline) {
2983 /* the first read header */
2984 if((k->hbuflen>5) &&
2985 !checkprotoprefix(data, conn, data->state.headerbuff)) {
2986 /* this is not the beginning of a protocol first header line */
2989 /* since there's more, this is a partial bad header */
2990 k->badheader = HEADER_PARTHEADER;
2992 /* this was all we read so it's all a bad header */
2993 k->badheader = HEADER_ALLBAD;
2994 *nread = (ssize_t)rest_length;
3000 /* headers are in network encoding so
3001 use 0x0a and 0x0d instead of '\n' and '\r' */
3002 if((0x0a == *k->p) || (0x0d == *k->p)) {
3004 /* Zero-length header line means end of headers! */
3006 #ifdef CURL_DOES_CONVERSIONS
3008 *k->p = '\r'; /* replace with CR in host encoding */
3009 k->p++; /* pass the CR byte */
3012 *k->p = '\n'; /* replace with LF in host encoding */
3013 k->p++; /* pass the LF byte */
3017 k->p++; /* pass the \r byte */
3019 k->p++; /* pass the \n byte */
3020 #endif /* CURL_DOES_CONVERSIONS */
3022 if(100 <= k->httpcode && 199 >= k->httpcode) {
3023 /* "A user agent MAY ignore unexpected 1xx status responses." */
3024 switch(k->httpcode) {
3027 * We have made a HTTP PUT or POST and this is 1.1-lingo
3028 * that tells us that the server is OK with this and ready
3029 * to receive the data.
3030 * However, we'll get more headers now so we must get
3031 * back into the header-parsing state!
3034 k->headerline = 0; /* restart the header line counter */
3036 /* if we did wait for this do enable write now! */
3037 if(k->exp100 > EXP100_SEND_DATA) {
3038 k->exp100 = EXP100_SEND_DATA;
3039 k->keepon |= KEEP_SEND;
3043 /* Switching Protocols */
3044 if(k->upgr101 == UPGR101_REQUESTED) {
3045 /* Switching to HTTP/2 */
3046 infof(data, "Received 101\n");
3047 k->upgr101 = UPGR101_RECEIVED;
3049 /* we'll get more headers (HTTP/2 response) */
3051 k->headerline = 0; /* restart the header line counter */
3053 /* switch to http2 now. The bytes after response headers
3054 are also processed here, otherwise they are lost. */
3055 result = Curl_http2_switched(conn, k->str, *nread);
3061 /* Switching to another protocol (e.g. WebSocket) */
3062 k->header = FALSE; /* no more header to parse! */
3066 /* the status code 1xx indicates a provisional response, so
3067 we'll get another set of headers */
3069 k->headerline = 0; /* restart the header line counter */
3074 k->header = FALSE; /* no more header to parse! */
3076 if((k->size == -1) && !k->chunk && !conn->bits.close &&
3077 (conn->httpversion == 11) &&
3078 !(conn->handler->protocol & CURLPROTO_RTSP) &&
3079 data->set.httpreq != HTTPREQ_HEAD) {
3080 /* On HTTP 1.1, when connection is not to get closed, but no
3081 Content-Length nor Content-Encoding chunked have been
3082 received, according to RFC2616 section 4.4 point 5, we
3083 assume that the server will close the connection to
3084 signal the end of the document. */
3085 infof(data, "no chunk, no close, no size. Assume close to "
3087 streamclose(conn, "HTTP: No end-of-message indicator");
3091 /* At this point we have some idea about the fate of the connection.
3092 If we are closing the connection it may result auth failure. */
3093 #if defined(USE_NTLM)
3094 if(conn->bits.close &&
3095 (((data->req.httpcode == 401) &&
3096 (conn->ntlm.state == NTLMSTATE_TYPE2)) ||
3097 ((data->req.httpcode == 407) &&
3098 (conn->proxyntlm.state == NTLMSTATE_TYPE2)))) {
3099 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
3100 data->state.authproblem = TRUE;
3105 * When all the headers have been parsed, see if we should give
3106 * up and return an error.
3108 if(http_should_fail(conn)) {
3109 failf(data, "The requested URL returned error: %d",
3111 return CURLE_HTTP_RETURNED_ERROR;
3114 /* now, only output this if the header AND body are requested:
3116 writetype = CLIENTWRITE_HEADER;
3117 if(data->set.include_header)
3118 writetype |= CLIENTWRITE_BODY;
3120 headerlen = k->p - data->state.headerbuff;
3122 result = Curl_client_write(conn, writetype,
3123 data->state.headerbuff,
3128 data->info.header_size += (long)headerlen;
3129 data->req.headerbytecount += (long)headerlen;
3131 data->req.deductheadercount =
3132 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
3134 /* Curl_http_auth_act() checks what authentication methods
3135 * that are available and decides which one (if any) to
3136 * use. It will set 'newurl' if an auth method was picked. */
3137 result = Curl_http_auth_act(conn);
3142 if(k->httpcode >= 300) {
3143 if((!conn->bits.authneg) && !conn->bits.close &&
3144 !conn->bits.rewindaftersend) {
3146 * General treatment of errors when about to send data. Including :
3147 * "417 Expectation Failed", while waiting for 100-continue.
3149 * The check for close above is done simply because of something
3150 * else has already deemed the connection to get closed then
3151 * something else should've considered the big picture and we
3154 * rewindaftersend indicates that something has told libcurl to
3155 * continue sending even if it gets discarded
3158 switch(data->set.httpreq) {
3161 case HTTPREQ_POST_FORM:
3162 /* We got an error response. If this happened before the whole
3163 * request body has been sent we stop sending and mark the
3164 * connection for closure after we've read the entire response.
3166 if(!k->upload_done) {
3167 if(data->set.http_keep_sending_on_error) {
3168 infof(data, "HTTP error before end of send, keep sending\n");
3169 if(k->exp100 > EXP100_SEND_DATA) {
3170 k->exp100 = EXP100_SEND_DATA;
3171 k->keepon |= KEEP_SEND;
3175 infof(data, "HTTP error before end of send, stop sending\n");
3176 streamclose(conn, "Stop sending data before everything sent");
3177 k->upload_done = TRUE;
3178 k->keepon &= ~KEEP_SEND; /* don't send */
3179 if(data->state.expect100header)
3180 k->exp100 = EXP100_FAILED;
3185 default: /* default label present to avoid compiler warnings */
3190 if(conn->bits.rewindaftersend) {
3191 /* We rewind after a complete send, so thus we continue
3193 infof(data, "Keep sending data to get tossed away!\n");
3194 k->keepon |= KEEP_SEND;
3200 * really end-of-headers.
3202 * If we requested a "no body", this is a good time to get
3203 * out and return home.
3205 if(data->set.opt_no_body)
3206 *stop_reading = TRUE;
3207 #ifndef CURL_DISABLE_RTSP
3208 else if((conn->handler->protocol & CURLPROTO_RTSP) &&
3209 (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
3211 /* Respect section 4.4 of rfc2326: If the Content-Length header is
3212 absent, a length 0 must be assumed. It will prevent libcurl from
3213 hanging on DESCRIBE request that got refused for whatever
3215 *stop_reading = TRUE;
3218 /* If we know the expected size of this document, we set the
3219 maximum download size to the size of the expected
3220 document or else, we won't know when to stop reading!
3222 Note that we set the download maximum even if we read a
3223 "Connection: close" header, to make sure that
3224 "Content-Length: 0" still prevents us from attempting to
3225 read the (missing) response-body.
3227 /* According to RFC2616 section 4.4, we MUST ignore
3228 Content-Length: headers if we are now receiving data
3229 using chunked Transfer-Encoding.
3232 k->maxdownload = k->size = -1;
3235 /* We do this operation even if no_body is true, since this
3236 data might be retrieved later with curl_easy_getinfo()
3237 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3239 Curl_pgrsSetDownloadSize(data, k->size);
3240 k->maxdownload = k->size;
3243 /* If max download size is *zero* (nothing) we already
3244 have nothing and can safely return ok now! */
3245 if(0 == k->maxdownload)
3246 *stop_reading = TRUE;
3249 /* we make sure that this socket isn't read more now */
3250 k->keepon &= ~KEEP_RECV;
3253 if(data->set.verbose)
3254 Curl_debug(data, CURLINFO_HEADER_IN,
3255 k->str_start, headerlen, conn);
3256 break; /* exit header line loop */
3259 /* We continue reading headers, so reset the line-based
3260 header parsing variables hbufp && hbuflen */
3261 k->hbufp = data->state.headerbuff;
3267 * Checks for special headers coming up.
3270 if(!k->headerline++) {
3271 /* This is the first header, it MUST be the error code line
3272 or else we consider this to be the body right away! */
3273 int httpversion_major;
3274 int rtspversion_major;
3276 #ifdef CURL_DOES_CONVERSIONS
3277 #define HEADER1 scratch
3278 #define SCRATCHSIZE 21
3280 char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
3281 /* We can't really convert this yet because we
3282 don't know if it's the 1st header line or the body.
3283 So we do a partial conversion into a scratch area,
3284 leaving the data at k->p as-is.
3286 strncpy(&scratch[0], k->p, SCRATCHSIZE);
3287 scratch[SCRATCHSIZE] = 0; /* null terminate */
3288 res = Curl_convert_from_network(data,
3292 /* Curl_convert_from_network calls failf if unsuccessful */
3295 #define HEADER1 k->p /* no conversion needed, just use k->p */
3296 #endif /* CURL_DOES_CONVERSIONS */
3298 if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
3300 * https://tools.ietf.org/html/rfc7230#section-3.1.2
3302 * The reponse code is always a three-digit number in HTTP as the spec
3303 * says. We try to allow any number here, but we cannot make
3304 * guarantees on future behaviors since it isn't within the protocol.
3306 nc = sscanf(HEADER1,
3312 if(nc == 1 && httpversion_major == 2 &&
3313 1 == sscanf(HEADER1, " HTTP/2 %d", &k->httpcode)) {
3314 conn->httpversion = 0;
3319 conn->httpversion += 10 * httpversion_major;
3321 if(k->upgr101 == UPGR101_RECEIVED) {
3322 /* supposedly upgraded to http2 now */
3323 if(conn->httpversion != 20)
3324 infof(data, "Lying server, not serving HTTP/2\n");
3328 /* this is the real world, not a Nirvana
3329 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3331 nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3332 conn->httpversion = 10;
3334 /* If user has set option HTTP200ALIASES,
3335 compare header line against list of aliases
3338 if(checkhttpprefix(data, k->p)) {
3341 conn->httpversion = 10;
3346 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3347 nc = sscanf(HEADER1,
3353 conn->rtspversion += 10 * rtspversion_major;
3354 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3357 /* TODO: do we care about the other cases here? */
3363 data->info.httpcode = k->httpcode;
3365 data->info.httpversion = conn->httpversion;
3366 if(!data->state.httpversion ||
3367 data->state.httpversion > conn->httpversion)
3368 /* store the lowest server version we encounter */
3369 data->state.httpversion = conn->httpversion;
3372 * This code executes as part of processing the header. As a
3373 * result, it's not totally clear how to interpret the
3374 * response code yet as that depends on what other headers may
3375 * be present. 401 and 407 may be errors, but may be OK
3376 * depending on how authentication is working. Other codes
3377 * are definitely errors, so give up here.
3379 if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3380 ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3381 ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3383 if(data->state.resume_from &&
3384 (data->set.httpreq==HTTPREQ_GET) &&
3385 (k->httpcode == 416)) {
3386 /* "Requested Range Not Satisfiable", just proceed and
3387 pretend this is no error */
3390 /* serious error, go home! */
3391 print_http_error(data);
3392 return CURLE_HTTP_RETURNED_ERROR;
3396 if(conn->httpversion == 10) {
3397 /* Default action for HTTP/1.0 must be to close, unless
3398 we get one of those fancy headers that tell us the
3399 server keeps it open for us! */
3400 infof(data, "HTTP 1.0, assume close after body\n");
3401 connclose(conn, "HTTP/1.0 close after body");
3403 else if(conn->httpversion == 20 ||
3404 (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
3405 DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
3407 /* HTTP/2 cannot blacklist multiplexing since it is a core
3408 functionality of the protocol */
3409 conn->bundle->multiuse = BUNDLE_MULTIPLEX;
3411 else if(conn->httpversion >= 11 &&
3412 !conn->bits.close) {
3413 /* If HTTP version is >= 1.1 and connection is persistent
3414 server supports pipelining. */
3416 "HTTP 1.1 or later with persistent connection, "
3417 "pipelining supported\n"));
3418 /* Activate pipelining if needed */
3420 if(!Curl_pipeline_site_blacklisted(data, conn))
3421 conn->bundle->multiuse = BUNDLE_PIPELINING;
3425 switch(k->httpcode) {
3427 /* (quote from RFC2616, section 10.2.5): The server has
3428 * fulfilled the request but does not need to return an
3429 * entity-body ... The 204 response MUST NOT include a
3430 * message-body, and thus is always terminated by the first
3431 * empty line after the header fields. */
3434 /* (quote from RFC2616, section 10.3.5): The 304 response
3435 * MUST NOT contain a message-body, and thus is always
3436 * terminated by the first empty line after the header
3438 if(data->set.timecondition)
3439 data->info.timecond = TRUE;
3442 k->ignorecl = TRUE; /* ignore Content-Length headers */
3450 k->header = FALSE; /* this is not a header line */
3455 result = Curl_convert_from_network(data, k->p, strlen(k->p));
3456 /* Curl_convert_from_network calls failf if unsuccessful */
3460 /* Check for Content-Length: header lines to get size */
3461 if(!k->ignorecl && !data->set.ignorecl &&
3462 checkprefix("Content-Length:", k->p)) {
3463 curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3464 if(data->set.max_filesize &&
3465 contentlength > data->set.max_filesize) {
3466 failf(data, "Maximum file size exceeded");
3467 return CURLE_FILESIZE_EXCEEDED;
3469 if(contentlength >= 0) {
3470 k->size = contentlength;
3471 k->maxdownload = k->size;
3472 /* we set the progress download size already at this point
3473 just to make it easier for apps/callbacks to extract this
3474 info as soon as possible */
3475 Curl_pgrsSetDownloadSize(data, k->size);
3478 /* Negative Content-Length is really odd, and we know it
3479 happens for example when older Apache servers send large
3481 streamclose(conn, "negative content-length");
3482 infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
3483 ", closing after transfer\n", contentlength);
3486 /* check for Content-Type: header lines to get the MIME-type */
3487 else if(checkprefix("Content-Type:", k->p)) {
3488 char *contenttype = Curl_copy_header_value(k->p);
3490 return CURLE_OUT_OF_MEMORY;
3492 /* ignore empty data */
3495 Curl_safefree(data->info.contenttype);
3496 data->info.contenttype = contenttype;
3499 else if(checkprefix("Server:", k->p)) {
3500 if(conn->httpversion < 20) {
3501 /* only do this for non-h2 servers */
3502 char *server_name = Curl_copy_header_value(k->p);
3504 /* Turn off pipelining if the server version is blacklisted */
3505 if(conn->bundle && (conn->bundle->multiuse == BUNDLE_PIPELINING)) {
3506 if(Curl_pipeline_server_blacklisted(data, server_name))
3507 conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
3512 else if((conn->httpversion == 10) &&
3513 conn->bits.httpproxy &&
3514 Curl_compareheader(k->p,
3515 "Proxy-Connection:", "keep-alive")) {
3517 * When a HTTP/1.0 reply comes when using a proxy, the
3518 * 'Proxy-Connection: keep-alive' line tells us the
3519 * connection will be kept alive for our pleasure.
3520 * Default action for 1.0 is to close.
3522 connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
3523 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3525 else if((conn->httpversion == 11) &&
3526 conn->bits.httpproxy &&
3527 Curl_compareheader(k->p,
3528 "Proxy-Connection:", "close")) {
3530 * We get a HTTP/1.1 response from a proxy and it says it'll
3531 * close down after this transfer.
3533 connclose(conn, "Proxy-Connection: asked to close after done");
3534 infof(data, "HTTP/1.1 proxy connection set close!\n");
3536 else if((conn->httpversion == 10) &&
3537 Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3539 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3540 * tells us the connection will be kept alive for our
3541 * pleasure. Default action for 1.0 is to close.
3543 * [RFC2068, section 19.7.1] */
3544 connkeep(conn, "Connection keep-alive");
3545 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3547 else if(Curl_compareheader(k->p, "Connection:", "close")) {
3549 * [RFC 2616, section 8.1.2.1]
3550 * "Connection: close" is HTTP/1.1 language and means that
3551 * the connection will close when this request has been
3554 streamclose(conn, "Connection: close used");
3556 else if(checkprefix("Transfer-Encoding:", k->p)) {
3557 /* One or more encodings. We check for chunked and/or a compression
3560 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3561 * means that the server will send a series of "chunks". Each
3562 * chunk starts with line with info (including size of the
3563 * coming block) (terminated with CRLF), then a block of data
3564 * with the previously mentioned size. There can be any amount
3565 * of chunks, and a chunk-data set to zero signals the
3570 /* Find the first non-space letter */
3574 /* skip whitespaces and commas */
3575 while(*start && (ISSPACE(*start) || (*start == ',')))
3578 if(checkprefix("chunked", start)) {
3579 k->chunk = TRUE; /* chunks coming our way */
3581 /* init our chunky engine */
3582 Curl_httpchunk_init(conn);
3587 if(k->auto_decoding)
3588 /* TODO: we only support the first mentioned compression for now */
3591 if(checkprefix("identity", start)) {
3592 k->auto_decoding = IDENTITY;
3595 else if(checkprefix("deflate", start)) {
3596 k->auto_decoding = DEFLATE;
3599 else if(checkprefix("gzip", start)) {
3600 k->auto_decoding = GZIP;
3603 else if(checkprefix("x-gzip", start)) {
3604 k->auto_decoding = GZIP;
3614 else if(checkprefix("Content-Encoding:", k->p) &&
3615 data->set.str[STRING_ENCODING]) {
3617 * Process Content-Encoding. Look for the values: identity,
3618 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3619 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3620 * 2616). zlib cannot handle compress. However, errors are
3621 * handled further down when the response body is processed
3625 /* Find the first non-space letter */
3627 while(*start && ISSPACE(*start))
3630 /* Record the content-encoding for later use */
3631 if(checkprefix("identity", start))
3632 k->auto_decoding = IDENTITY;
3633 else if(checkprefix("deflate", start))
3634 k->auto_decoding = DEFLATE;
3635 else if(checkprefix("gzip", start)
3636 || checkprefix("x-gzip", start))
3637 k->auto_decoding = GZIP;
3639 else if(checkprefix("Content-Range:", k->p)) {
3640 /* Content-Range: bytes [num]-
3641 Content-Range: bytes: [num]-
3642 Content-Range: [num]-
3643 Content-Range: [asterisk]/[total]
3645 The second format was added since Sun's webserver
3646 JavaWebServer/1.1.1 obviously sends the header this way!
3647 The third added since some servers use that!
3648 The forth means the requested range was unsatisfied.
3651 char *ptr = k->p + 14;
3653 /* Move forward until first digit or asterisk */
3654 while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
3657 /* if it truly stopped on a digit */
3659 k->offset = curlx_strtoofft(ptr, NULL, 10);
3661 if(data->state.resume_from == k->offset)
3662 /* we asked for a resume and we got it */
3663 k->content_range = TRUE;
3666 data->state.resume_from = 0; /* get everything */
3668 #if !defined(CURL_DISABLE_COOKIES)
3669 else if(data->cookies &&
3670 checkprefix("Set-Cookie:", k->p)) {
3671 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3672 CURL_LOCK_ACCESS_SINGLE);
3673 Curl_cookie_add(data,
3674 data->cookies, TRUE, k->p+11,
3675 /* If there is a custom-set Host: name, use it
3676 here, or else use real peer host name. */
3677 conn->allocptr.cookiehost?
3678 conn->allocptr.cookiehost:conn->host.name,
3680 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3683 else if(checkprefix("Last-Modified:", k->p) &&
3684 (data->set.timecondition || data->set.get_filetime) ) {
3685 time_t secs=time(NULL);
3686 k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3688 if(data->set.get_filetime)
3689 data->info.filetime = (long)k->timeofdoc;
3691 else if((checkprefix("WWW-Authenticate:", k->p) &&
3692 (401 == k->httpcode)) ||
3693 (checkprefix("Proxy-authenticate:", k->p) &&
3694 (407 == k->httpcode))) {
3696 bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3697 char *auth = Curl_copy_header_value(k->p);
3699 return CURLE_OUT_OF_MEMORY;
3701 result = Curl_http_input_auth(conn, proxy, auth);
3708 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3709 checkprefix("Location:", k->p) &&
3710 !data->req.location) {
3711 /* this is the URL that the server advises us to use instead */
3712 char *location = Curl_copy_header_value(k->p);
3714 return CURLE_OUT_OF_MEMORY;
3716 /* ignore empty data */
3719 data->req.location = location;
3721 if(data->set.http_follow_location) {
3722 DEBUGASSERT(!data->req.newurl);
3723 data->req.newurl = strdup(data->req.location); /* clone */
3724 if(!data->req.newurl)
3725 return CURLE_OUT_OF_MEMORY;
3727 /* some cases of POST and PUT etc needs to rewind the data
3728 stream at this point */
3729 result = http_perhapsrewind(conn);
3735 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3736 result = Curl_rtsp_parseheader(conn, k->p);
3742 * End of header-checks. Write them to the client.
3745 writetype = CLIENTWRITE_HEADER;
3746 if(data->set.include_header)
3747 writetype |= CLIENTWRITE_BODY;
3749 if(data->set.verbose)
3750 Curl_debug(data, CURLINFO_HEADER_IN,
3751 k->p, (size_t)k->hbuflen, conn);
3753 result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3757 data->info.header_size += (long)k->hbuflen;
3758 data->req.headerbytecount += (long)k->hbuflen;
3760 /* reset hbufp pointer && hbuflen */
3761 k->hbufp = data->state.headerbuff;
3764 while(*k->str); /* header line within buffer */
3766 /* We might have reached the end of the header part here, but
3767 there might be a non-header part left in the end of the read
3773 #endif /* CURL_DISABLE_HTTP */