1 /***************************************************************************
3 * Project ___| | | | _ \| |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
8 * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.haxx.se/docs/copyright.html.
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
21 ***************************************************************************/
23 #include "curl_setup.h"
25 #ifndef CURL_DISABLE_HTTP
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
34 #ifdef HAVE_ARPA_INET_H
35 #include <arpa/inet.h>
40 #ifdef HAVE_SYS_IOCTL_H
41 #include <sys/ioctl.h>
44 #ifdef HAVE_SYS_PARAM_H
45 #include <sys/param.h>
49 #include <curl/curl.h>
55 #include "curl_base64.h"
57 #include "vauth/vauth.h"
58 #include "vtls/vtls.h"
59 #include "http_digest.h"
60 #include "http_ntlm.h"
61 #include "curl_ntlm_wb.h"
62 #include "http_negotiate.h"
68 #include "parsedate.h" /* for the week day and month names */
69 #include "strtoofft.h"
72 #include "content_encoding.h"
73 #include "http_proxy.h"
75 #include "non-ascii.h"
81 /* The last 3 #include files should be in this order */
82 #include "curl_printf.h"
83 #include "curl_memory.h"
87 * Forward declarations.
90 static int http_getsock_do(struct connectdata *conn,
91 curl_socket_t *socks);
92 static int http_should_fail(struct connectdata *conn);
94 #ifndef CURL_DISABLE_PROXY
95 static CURLcode add_haproxy_protocol_header(struct connectdata *conn);
99 static CURLcode https_connecting(struct connectdata *conn, bool *done);
100 static int https_getsock(struct connectdata *conn,
101 curl_socket_t *socks);
103 #define https_connecting(x,y) CURLE_COULDNT_CONNECT
105 static CURLcode http_setup_conn(struct connectdata *conn);
108 * HTTP handler interface.
110 const struct Curl_handler Curl_handler_http = {
112 http_setup_conn, /* setup_connection */
113 Curl_http, /* do_it */
114 Curl_http_done, /* done */
115 ZERO_NULL, /* do_more */
116 Curl_http_connect, /* connect_it */
117 ZERO_NULL, /* connecting */
118 ZERO_NULL, /* doing */
119 ZERO_NULL, /* proto_getsock */
120 http_getsock_do, /* doing_getsock */
121 ZERO_NULL, /* domore_getsock */
122 ZERO_NULL, /* perform_getsock */
123 ZERO_NULL, /* disconnect */
124 ZERO_NULL, /* readwrite */
125 ZERO_NULL, /* connection_check */
126 PORT_HTTP, /* defport */
127 CURLPROTO_HTTP, /* protocol */
128 CURLPROTO_HTTP, /* family */
129 PROTOPT_CREDSPERREQUEST | /* flags */
135 * HTTPS handler interface.
137 const struct Curl_handler Curl_handler_https = {
138 "HTTPS", /* scheme */
139 http_setup_conn, /* setup_connection */
140 Curl_http, /* do_it */
141 Curl_http_done, /* done */
142 ZERO_NULL, /* do_more */
143 Curl_http_connect, /* connect_it */
144 https_connecting, /* connecting */
145 ZERO_NULL, /* doing */
146 https_getsock, /* proto_getsock */
147 http_getsock_do, /* doing_getsock */
148 ZERO_NULL, /* domore_getsock */
149 ZERO_NULL, /* perform_getsock */
150 ZERO_NULL, /* disconnect */
151 ZERO_NULL, /* readwrite */
152 ZERO_NULL, /* connection_check */
153 PORT_HTTPS, /* defport */
154 CURLPROTO_HTTPS, /* protocol */
155 CURLPROTO_HTTP, /* family */
156 PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | /* flags */
161 static CURLcode http_setup_conn(struct connectdata *conn)
163 /* allocate the HTTP-specific struct for the Curl_easy, only to survive
164 during this request */
166 struct Curl_easy *data = conn->data;
167 DEBUGASSERT(data->req.protop == NULL);
169 http = calloc(1, sizeof(struct HTTP));
171 return CURLE_OUT_OF_MEMORY;
173 Curl_mime_initpart(&http->form, conn->data);
174 data->req.protop = http;
176 if(data->set.httpversion == CURL_HTTP_VERSION_3) {
177 if(conn->handler->flags & PROTOPT_SSL)
178 /* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does
180 conn->transport = TRNSPRT_QUIC;
182 failf(data, "HTTP/3 requested for non-HTTPS URL");
183 return CURLE_URL_MALFORMAT;
187 if(!CONN_INUSE(conn))
188 /* if not already multi-using, setup connection details */
189 Curl_http2_setup_conn(conn);
190 Curl_http2_setup_req(data);
195 #ifndef CURL_DISABLE_PROXY
197 * checkProxyHeaders() checks the linked list of custom proxy headers
198 * if proxy headers are not available, then it will lookup into http header
201 * It takes a connectdata struct as input instead of the Curl_easy simply to
202 * know if this is a proxy request or not, as it then might check a different
203 * header list. Provide the header prefix without colon!.
205 char *Curl_checkProxyheaders(const struct connectdata *conn,
206 const char *thisheader)
208 struct curl_slist *head;
209 size_t thislen = strlen(thisheader);
210 struct Curl_easy *data = conn->data;
212 for(head = (conn->bits.proxy && data->set.sep_headers) ?
213 data->set.proxyheaders : data->set.headers;
214 head; head = head->next) {
215 if(strncasecompare(head->data, thisheader, thislen) &&
216 Curl_headersep(head->data[thislen]))
224 #define Curl_checkProxyheaders(x,y) NULL
228 * Strip off leading and trailing whitespace from the value in the
229 * given HTTP header line and return a strdupped copy. Returns NULL in
230 * case of allocation failure. Returns an empty string if the header value
231 * consists entirely of whitespace.
233 char *Curl_copy_header_value(const char *header)
240 /* Find the end of the header name */
241 while(*header && (*header != ':'))
245 /* Skip over colon */
248 /* Find the first non-space letter */
250 while(*start && ISSPACE(*start))
253 /* data is in the host encoding so
254 use '\r' and '\n' instead of 0x0d and 0x0a */
255 end = strchr(start, '\r');
257 end = strchr(start, '\n');
259 end = strchr(start, '\0');
263 /* skip all trailing space letters */
264 while((end > start) && ISSPACE(*end))
267 /* get length of the type */
268 len = end - start + 1;
270 value = malloc(len + 1);
274 memcpy(value, start, len);
275 value[len] = 0; /* null-terminate */
280 #ifndef CURL_DISABLE_HTTP_AUTH
282 * http_output_basic() sets up an Authorization: header (or the proxy version)
283 * for HTTP Basic authentication.
287 static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
290 char *authorization = NULL;
291 struct Curl_easy *data = conn->data;
299 #ifndef CURL_DISABLE_PROXY
300 userp = &data->state.aptr.proxyuserpwd;
301 user = conn->http_proxy.user;
302 pwd = conn->http_proxy.passwd;
304 return CURLE_NOT_BUILT_IN;
308 userp = &data->state.aptr.userpwd;
313 out = aprintf("%s:%s", user, pwd ? pwd : "");
315 return CURLE_OUT_OF_MEMORY;
317 result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
322 result = CURLE_REMOTE_ACCESS_DENIED;
327 *userp = aprintf("%sAuthorization: Basic %s\r\n",
328 proxy ? "Proxy-" : "",
332 result = CURLE_OUT_OF_MEMORY;
342 * http_output_bearer() sets up an Authorization: header
343 * for HTTP Bearer authentication.
347 static CURLcode http_output_bearer(struct connectdata *conn)
350 CURLcode result = CURLE_OK;
351 struct Curl_easy *data = conn->data;
353 userp = &data->state.aptr.userpwd;
355 *userp = aprintf("Authorization: Bearer %s\r\n",
356 conn->data->set.str[STRING_BEARER]);
359 result = CURLE_OUT_OF_MEMORY;
369 /* pickoneauth() selects the most favourable authentication method from the
370 * ones available and the ones we want.
372 * return TRUE if one was picked
374 static bool pickoneauth(struct auth *pick, unsigned long mask)
377 /* only deal with authentication we want */
378 unsigned long avail = pick->avail & pick->want & mask;
381 /* The order of these checks is highly relevant, as this will be the order
382 of preference in case of the existence of multiple accepted types. */
383 if(avail & CURLAUTH_NEGOTIATE)
384 pick->picked = CURLAUTH_NEGOTIATE;
385 else if(avail & CURLAUTH_BEARER)
386 pick->picked = CURLAUTH_BEARER;
387 else if(avail & CURLAUTH_DIGEST)
388 pick->picked = CURLAUTH_DIGEST;
389 else if(avail & CURLAUTH_NTLM)
390 pick->picked = CURLAUTH_NTLM;
391 else if(avail & CURLAUTH_NTLM_WB)
392 pick->picked = CURLAUTH_NTLM_WB;
393 else if(avail & CURLAUTH_BASIC)
394 pick->picked = CURLAUTH_BASIC;
396 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
399 pick->avail = CURLAUTH_NONE; /* clear it here */
405 * http_perhapsrewind()
407 * If we are doing POST or PUT {
408 * If we have more data to send {
409 * If we are doing NTLM {
410 * Keep sending since we must not disconnect
413 * If there is more than just a little data left to send, close
414 * the current connection by force.
417 * If we have sent any data {
418 * If we don't have track of all the data {
419 * call app to tell it to rewind
422 * rewind internally so that the operation can restart fine
427 static CURLcode http_perhapsrewind(struct connectdata *conn)
429 struct Curl_easy *data = conn->data;
430 struct HTTP *http = data->req.protop;
431 curl_off_t bytessent;
432 curl_off_t expectsend = -1; /* default is unknown */
435 /* If this is still NULL, we have not reach very far and we can safely
436 skip this rewinding stuff */
439 switch(data->state.httpreq) {
447 bytessent = data->req.writebytecount;
449 if(conn->bits.authneg) {
450 /* This is a state where we are known to be negotiating and we don't send
454 else if(!conn->bits.protoconnstart) {
455 /* HTTP CONNECT in progress: there is no body */
459 /* figure out how much data we are expected to send */
460 switch(data->state.httpreq) {
463 if(data->state.infilesize != -1)
464 expectsend = data->state.infilesize;
466 case HTTPREQ_POST_FORM:
467 case HTTPREQ_POST_MIME:
468 expectsend = http->postsize;
475 conn->bits.rewindaftersend = FALSE; /* default */
477 if((expectsend == -1) || (expectsend > bytessent)) {
478 #if defined(USE_NTLM)
479 /* There is still data left to send */
480 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
481 (data->state.authhost.picked == CURLAUTH_NTLM) ||
482 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
483 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
484 if(((expectsend - bytessent) < 2000) ||
485 (conn->http_ntlm_state != NTLMSTATE_NONE) ||
486 (conn->proxy_ntlm_state != NTLMSTATE_NONE)) {
487 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
488 data left to send, keep on sending. */
490 /* rewind data when completely done sending! */
491 if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
492 conn->bits.rewindaftersend = TRUE;
493 infof(data, "Rewind stream after send\n");
500 /* this is already marked to get closed */
503 infof(data, "NTLM send, close instead of sending %"
504 CURL_FORMAT_CURL_OFF_T " bytes\n",
505 (curl_off_t)(expectsend - bytessent));
508 #if defined(USE_SPNEGO)
509 /* There is still data left to send */
510 if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) ||
511 (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) {
512 if(((expectsend - bytessent) < 2000) ||
513 (conn->http_negotiate_state != GSS_AUTHNONE) ||
514 (conn->proxy_negotiate_state != GSS_AUTHNONE)) {
515 /* The NEGOTIATE-negotiation has started *OR*
516 there is just a little (<2K) data left to send, keep on sending. */
518 /* rewind data when completely done sending! */
519 if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
520 conn->bits.rewindaftersend = TRUE;
521 infof(data, "Rewind stream after send\n");
528 /* this is already marked to get closed */
531 infof(data, "NEGOTIATE send, close instead of sending %"
532 CURL_FORMAT_CURL_OFF_T " bytes\n",
533 (curl_off_t)(expectsend - bytessent));
537 /* This is not NEGOTIATE/NTLM or many bytes left to send: close */
538 streamclose(conn, "Mid-auth HTTP and much data left to send");
539 data->req.size = 0; /* don't download any more than 0 bytes */
541 /* There still is data left to send, but this connection is marked for
542 closure so we can safely do the rewind right now */
546 /* we rewind now at once since if we already sent something */
547 return Curl_readrewind(conn);
553 * Curl_http_auth_act() gets called when all HTTP headers have been received
554 * and it checks what authentication methods that are available and decides
555 * which one (if any) to use. It will set 'newurl' if an auth method was
559 CURLcode Curl_http_auth_act(struct connectdata *conn)
561 struct Curl_easy *data = conn->data;
562 bool pickhost = FALSE;
563 bool pickproxy = FALSE;
564 CURLcode result = CURLE_OK;
565 unsigned long authmask = ~0ul;
567 if(!data->set.str[STRING_BEARER])
568 authmask &= (unsigned long)~CURLAUTH_BEARER;
570 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
571 /* this is a transient response code, ignore */
574 if(data->state.authproblem)
575 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
577 if((conn->bits.user_passwd || data->set.str[STRING_BEARER]) &&
578 ((data->req.httpcode == 401) ||
579 (conn->bits.authneg && data->req.httpcode < 300))) {
580 pickhost = pickoneauth(&data->state.authhost, authmask);
582 data->state.authproblem = TRUE;
583 if(data->state.authhost.picked == CURLAUTH_NTLM &&
584 conn->httpversion > 11) {
585 infof(data, "Forcing HTTP/1.1 for NTLM");
586 connclose(conn, "Force HTTP/1.1 connection");
587 conn->data->set.httpversion = CURL_HTTP_VERSION_1_1;
590 #ifndef CURL_DISABLE_PROXY
591 if(conn->bits.proxy_user_passwd &&
592 ((data->req.httpcode == 407) ||
593 (conn->bits.authneg && data->req.httpcode < 300))) {
594 pickproxy = pickoneauth(&data->state.authproxy,
595 authmask & ~CURLAUTH_BEARER);
597 data->state.authproblem = TRUE;
601 if(pickhost || pickproxy) {
602 if((data->state.httpreq != HTTPREQ_GET) &&
603 (data->state.httpreq != HTTPREQ_HEAD) &&
604 !conn->bits.rewindaftersend) {
605 result = http_perhapsrewind(conn);
609 /* In case this is GSS auth, the newurl field is already allocated so
610 we must make sure to free it before allocating a new one. As figured
611 out in bug #2284386 */
612 Curl_safefree(data->req.newurl);
613 data->req.newurl = strdup(data->change.url); /* clone URL */
614 if(!data->req.newurl)
615 return CURLE_OUT_OF_MEMORY;
617 else if((data->req.httpcode < 300) &&
618 (!data->state.authhost.done) &&
619 conn->bits.authneg) {
620 /* no (known) authentication available,
621 authentication is not "done" yet and
622 no authentication seems to be required and
623 we didn't try HEAD or GET */
624 if((data->state.httpreq != HTTPREQ_GET) &&
625 (data->state.httpreq != HTTPREQ_HEAD)) {
626 data->req.newurl = strdup(data->change.url); /* clone URL */
627 if(!data->req.newurl)
628 return CURLE_OUT_OF_MEMORY;
629 data->state.authhost.done = TRUE;
632 if(http_should_fail(conn)) {
633 failf(data, "The requested URL returned error: %d",
635 result = CURLE_HTTP_RETURNED_ERROR;
641 #ifndef CURL_DISABLE_HTTP_AUTH
643 * Output the correct authentication header depending on the auth type
644 * and whether or not it is to a proxy.
647 output_auth_headers(struct connectdata *conn,
648 struct auth *authstatus,
653 const char *auth = NULL;
654 CURLcode result = CURLE_OK;
655 struct Curl_easy *data = conn->data;
657 #ifdef CURL_DISABLE_CRYPTO_AUTH
663 if(authstatus->picked == CURLAUTH_NEGOTIATE) {
665 result = Curl_output_negotiate(conn, proxy);
672 if(authstatus->picked == CURLAUTH_NTLM) {
674 result = Curl_output_ntlm(conn, proxy);
680 #if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
681 if(authstatus->picked == CURLAUTH_NTLM_WB) {
683 result = Curl_output_ntlm_wb(conn, proxy);
689 #ifndef CURL_DISABLE_CRYPTO_AUTH
690 if(authstatus->picked == CURLAUTH_DIGEST) {
692 result = Curl_output_digest(conn,
694 (const unsigned char *)request,
695 (const unsigned char *)path);
701 if(authstatus->picked == CURLAUTH_BASIC) {
704 #ifndef CURL_DISABLE_PROXY
705 (proxy && conn->bits.proxy_user_passwd &&
706 !Curl_checkProxyheaders(conn, "Proxy-authorization")) ||
708 (!proxy && conn->bits.user_passwd &&
709 !Curl_checkheaders(conn, "Authorization"))) {
711 result = http_output_basic(conn, proxy);
716 /* NOTE: this function should set 'done' TRUE, as the other auth
717 functions work that way */
718 authstatus->done = TRUE;
720 if(authstatus->picked == CURLAUTH_BEARER) {
722 if((!proxy && data->set.str[STRING_BEARER] &&
723 !Curl_checkheaders(conn, "Authorization:"))) {
725 result = http_output_bearer(conn);
730 /* NOTE: this function should set 'done' TRUE, as the other auth
731 functions work that way */
732 authstatus->done = TRUE;
736 #ifndef CURL_DISABLE_PROXY
737 infof(data, "%s auth using %s with user '%s'\n",
738 proxy ? "Proxy" : "Server", auth,
739 proxy ? (conn->http_proxy.user ? conn->http_proxy.user : "") :
740 (conn->user ? conn->user : ""));
742 infof(data, "Server auth using %s with user '%s'\n",
743 auth, conn->user ? conn->user : "");
745 authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
748 authstatus->multipass = FALSE;
754 * Curl_http_output_auth() setups the authentication headers for the
755 * host/proxy and the correct authentication
756 * method. conn->data->state.authdone is set to TRUE when authentication is
759 * @param conn all information about the current connection
760 * @param request pointer to the request keyword
761 * @param path pointer to the requested path; should include query part
762 * @param proxytunnel boolean if this is the request setting up a "proxy
768 Curl_http_output_auth(struct connectdata *conn,
771 bool proxytunnel) /* TRUE if this is the request setting
772 up the proxy tunnel */
774 CURLcode result = CURLE_OK;
775 struct Curl_easy *data = conn->data;
776 struct auth *authhost;
777 struct auth *authproxy;
781 authhost = &data->state.authhost;
782 authproxy = &data->state.authproxy;
785 #ifndef CURL_DISABLE_PROXY
786 (conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
788 conn->bits.user_passwd || data->set.str[STRING_BEARER])
789 /* continue please */;
791 authhost->done = TRUE;
792 authproxy->done = TRUE;
793 return CURLE_OK; /* no authentication with no user or password */
796 if(authhost->want && !authhost->picked)
797 /* The app has selected one or more methods, but none has been picked
798 so far by a server round-trip. Then we set the picked one to the
799 want one, and if this is one single bit it'll be used instantly. */
800 authhost->picked = authhost->want;
802 if(authproxy->want && !authproxy->picked)
803 /* The app has selected one or more methods, but none has been picked so
804 far by a proxy round-trip. Then we set the picked one to the want one,
805 and if this is one single bit it'll be used instantly. */
806 authproxy->picked = authproxy->want;
808 #ifndef CURL_DISABLE_PROXY
809 /* Send proxy authentication header if needed */
810 if(conn->bits.httpproxy &&
811 (conn->bits.tunnel_proxy == (bit)proxytunnel)) {
812 result = output_auth_headers(conn, authproxy, request, path, TRUE);
819 #endif /* CURL_DISABLE_PROXY */
820 /* we have no proxy so let's pretend we're done authenticating
822 authproxy->done = TRUE;
824 /* To prevent the user+password to get sent to other than the original
825 host due to a location-follow, we do some weirdo checks here */
826 if(!data->state.this_is_a_follow ||
828 !data->state.first_host ||
829 data->set.allow_auth_to_other_hosts ||
830 strcasecompare(data->state.first_host, conn->host.name)) {
831 result = output_auth_headers(conn, authhost, request, path, FALSE);
834 authhost->done = TRUE;
842 Curl_http_output_auth(struct connectdata *conn,
856 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
857 * headers. They are dealt with both in the transfer.c main loop and in the
858 * proxy CONNECT loop.
861 CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
862 const char *auth) /* the first non-space */
865 * This resource requires authentication
867 struct Curl_easy *data = conn->data;
870 curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state :
871 &conn->http_negotiate_state;
873 unsigned long *availp;
877 availp = &data->info.proxyauthavail;
878 authp = &data->state.authproxy;
881 availp = &data->info.httpauthavail;
882 authp = &data->state.authhost;
886 * Here we check if we want the specific single authentication (using ==) and
887 * if we do, we initiate usage of it.
889 * If the provided authentication is wanted as one out of several accepted
890 * types (using &), we OR this authentication type to the authavail
895 * ->picked is first set to the 'want' value (one or more bits) before the
896 * request is sent, and then it is again set _after_ all response 401/407
897 * headers have been received but then only to a single preferred method
903 if(checkprefix("Negotiate", auth)) {
904 if((authp->avail & CURLAUTH_NEGOTIATE) ||
905 Curl_auth_is_spnego_supported()) {
906 *availp |= CURLAUTH_NEGOTIATE;
907 authp->avail |= CURLAUTH_NEGOTIATE;
909 if(authp->picked == CURLAUTH_NEGOTIATE) {
910 CURLcode result = Curl_input_negotiate(conn, proxy, auth);
912 DEBUGASSERT(!data->req.newurl);
913 data->req.newurl = strdup(data->change.url);
914 if(!data->req.newurl)
915 return CURLE_OUT_OF_MEMORY;
916 data->state.authproblem = FALSE;
917 /* we received a GSS auth token and we dealt with it fine */
918 *negstate = GSS_AUTHRECV;
921 data->state.authproblem = TRUE;
928 /* NTLM support requires the SSL crypto libs */
929 if(checkprefix("NTLM", auth)) {
930 if((authp->avail & CURLAUTH_NTLM) ||
931 (authp->avail & CURLAUTH_NTLM_WB) ||
932 Curl_auth_is_ntlm_supported()) {
933 *availp |= CURLAUTH_NTLM;
934 authp->avail |= CURLAUTH_NTLM;
936 if(authp->picked == CURLAUTH_NTLM ||
937 authp->picked == CURLAUTH_NTLM_WB) {
938 /* NTLM authentication is picked and activated */
939 CURLcode result = Curl_input_ntlm(conn, proxy, auth);
941 data->state.authproblem = FALSE;
942 #ifdef NTLM_WB_ENABLED
943 if(authp->picked == CURLAUTH_NTLM_WB) {
944 *availp &= ~CURLAUTH_NTLM;
945 authp->avail &= ~CURLAUTH_NTLM;
946 *availp |= CURLAUTH_NTLM_WB;
947 authp->avail |= CURLAUTH_NTLM_WB;
949 result = Curl_input_ntlm_wb(conn, proxy, auth);
951 infof(data, "Authentication problem. Ignoring this.\n");
952 data->state.authproblem = TRUE;
958 infof(data, "Authentication problem. Ignoring this.\n");
959 data->state.authproblem = TRUE;
966 #ifndef CURL_DISABLE_CRYPTO_AUTH
967 if(checkprefix("Digest", auth)) {
968 if((authp->avail & CURLAUTH_DIGEST) != 0)
969 infof(data, "Ignoring duplicate digest auth header.\n");
970 else if(Curl_auth_is_digest_supported()) {
973 *availp |= CURLAUTH_DIGEST;
974 authp->avail |= CURLAUTH_DIGEST;
976 /* We call this function on input Digest headers even if Digest
977 * authentication isn't activated yet, as we need to store the
978 * incoming data from this header in case we are going to use
980 result = Curl_input_digest(conn, proxy, auth);
982 infof(data, "Authentication problem. Ignoring this.\n");
983 data->state.authproblem = TRUE;
989 if(checkprefix("Basic", auth)) {
990 *availp |= CURLAUTH_BASIC;
991 authp->avail |= CURLAUTH_BASIC;
992 if(authp->picked == CURLAUTH_BASIC) {
993 /* We asked for Basic authentication but got a 40X back
994 anyway, which basically means our name+password isn't
996 authp->avail = CURLAUTH_NONE;
997 infof(data, "Authentication problem. Ignoring this.\n");
998 data->state.authproblem = TRUE;
1002 if(checkprefix("Bearer", auth)) {
1003 *availp |= CURLAUTH_BEARER;
1004 authp->avail |= CURLAUTH_BEARER;
1005 if(authp->picked == CURLAUTH_BEARER) {
1006 /* We asked for Bearer authentication but got a 40X back
1007 anyway, which basically means our token isn't valid. */
1008 authp->avail = CURLAUTH_NONE;
1009 infof(data, "Authentication problem. Ignoring this.\n");
1010 data->state.authproblem = TRUE;
1014 /* there may be multiple methods on one line, so keep reading */
1015 while(*auth && *auth != ',') /* read up to the next comma */
1017 if(*auth == ',') /* if we're on a comma, skip it */
1019 while(*auth && ISSPACE(*auth))
1027 * http_should_fail() determines whether an HTTP response has gotten us
1028 * into an error state or not.
1030 * @param conn all information about the current connection
1032 * @retval 0 communications should continue
1034 * @retval 1 communications should not continue
1036 static int http_should_fail(struct connectdata *conn)
1038 struct Curl_easy *data;
1045 httpcode = data->req.httpcode;
1048 ** If we haven't been asked to fail on error,
1051 if(!data->set.http_fail_on_error)
1055 ** Any code < 400 is never terminal.
1061 ** Any code >= 400 that's not 401 or 407 is always
1064 if((httpcode != 401) && (httpcode != 407))
1068 ** All we have left to deal with is 401 and 407
1070 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
1073 ** Examine the current authentication state to see if this
1074 ** is an error. The idea is for this function to get
1075 ** called after processing all the headers in a response
1076 ** message. So, if we've been to asked to authenticate a
1077 ** particular stage, and we've done it, we're OK. But, if
1078 ** we're already completely authenticated, it's not OK to
1079 ** get another 401 or 407.
1081 ** It is possible for authentication to go stale such that
1082 ** the client needs to reauthenticate. Once that info is
1083 ** available, use it here.
1087 ** Either we're not authenticating, or we're supposed to
1088 ** be authenticating something else. This is an error.
1090 if((httpcode == 401) && !conn->bits.user_passwd)
1092 #ifndef CURL_DISABLE_PROXY
1093 if((httpcode == 407) && !conn->bits.proxy_user_passwd)
1097 return data->state.authproblem;
1101 * readmoredata() is a "fread() emulation" to provide POST and/or request
1102 * data. It is used when a huge POST is to be made and the entire chunk wasn't
1103 * sent in the first send(). This function will then be called from the
1104 * transfer.c loop when more data is to be sent to the peer.
1106 * Returns the amount of bytes it filled the buffer with.
1108 static size_t readmoredata(char *buffer,
1113 struct connectdata *conn = (struct connectdata *)userp;
1114 struct HTTP *http = conn->data->req.protop;
1115 size_t fullsize = size * nitems;
1118 /* nothing to return */
1121 /* make sure that a HTTP request is never sent away chunked! */
1122 conn->data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
1124 if(http->postsize <= (curl_off_t)fullsize) {
1125 memcpy(buffer, http->postdata, (size_t)http->postsize);
1126 fullsize = (size_t)http->postsize;
1128 if(http->backup.postsize) {
1129 /* move backup data into focus and continue on that */
1130 http->postdata = http->backup.postdata;
1131 http->postsize = http->backup.postsize;
1132 conn->data->state.fread_func = http->backup.fread_func;
1133 conn->data->state.in = http->backup.fread_in;
1135 http->sending++; /* move one step up */
1137 http->backup.postsize = 0;
1145 memcpy(buffer, http->postdata, fullsize);
1146 http->postdata += fullsize;
1147 http->postsize -= fullsize;
1153 * Curl_buffer_send() sends a header buffer and frees all associated
1154 * memory. Body data may be appended to the header data if desired.
1158 CURLcode Curl_buffer_send(struct dynbuf *in,
1159 struct connectdata *conn,
1160 /* add the number of sent bytes to this
1162 curl_off_t *bytes_written,
1163 /* how much of the buffer contains body data */
1164 size_t included_body_bytes,
1171 struct Curl_easy *data = conn->data;
1172 struct HTTP *http = data->req.protop;
1174 curl_socket_t sockfd;
1177 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1179 sockfd = conn->sock[socketindex];
1181 /* The looping below is required since we use non-blocking sockets, but due
1182 to the circumstances we will just loop and try again and again etc */
1184 ptr = Curl_dyn_ptr(in);
1185 size = Curl_dyn_len(in);
1187 headersize = size - included_body_bytes; /* the initial part that isn't body
1190 DEBUGASSERT(size > included_body_bytes);
1192 result = Curl_convert_to_network(data, ptr, headersize);
1193 /* Curl_convert_to_network calls failf if unsuccessful */
1195 /* conversion failed, free memory and return to the caller */
1200 if((conn->handler->flags & PROTOPT_SSL
1201 #ifndef CURL_DISABLE_PROXY
1202 || conn->http_proxy.proxytype == CURLPROXY_HTTPS
1205 && conn->httpversion != 20) {
1206 /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1207 when we speak HTTPS, as if only a fraction of it is sent now, this data
1208 needs to fit into the normal read-callback buffer later on and that
1209 buffer is using this size.
1212 sendsize = CURLMIN(size, CURL_MAX_WRITE_SIZE);
1214 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1215 library when we attempt to re-send this buffer. Sending the same data
1216 is not enough, we must use the exact same address. For this reason, we
1217 must copy the data to the uploadbuffer first, since that is the buffer
1218 we will be using if this send is retried later.
1220 result = Curl_get_upload_buffer(data);
1222 /* malloc failed, free memory and return to the caller */
1226 memcpy(data->state.ulbuf, ptr, sendsize);
1227 ptr = data->state.ulbuf;
1231 /* Allow debug builds override this logic to force short initial sends */
1232 char *p = getenv("CURL_SMALLREQSEND");
1234 size_t altsize = (size_t)strtoul(p, NULL, 10);
1236 sendsize = CURLMIN(size, altsize);
1245 result = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1249 * Note that we may not send the entire chunk at once, and we have a set
1250 * number of data bytes at the end of the big buffer (out of which we may
1251 * only send away a part).
1253 /* how much of the header that was sent */
1254 size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
1255 size_t bodylen = amount - headlen;
1257 if(data->set.verbose) {
1258 /* this data _may_ contain binary stuff */
1259 Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);
1261 /* there was body data sent beyond the initial header part, pass that
1262 on to the debug callback too */
1263 Curl_debug(data, CURLINFO_DATA_OUT,
1264 ptr + headlen, bodylen);
1268 /* 'amount' can never be a very large value here so typecasting it so a
1269 signed 31 bit value should not cause problems even if ssize_t is
1271 *bytes_written += (long)amount;
1274 /* if we sent a piece of the body here, up the byte counter for it
1276 data->req.writebytecount += bodylen;
1277 Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
1279 if((size_t)amount != size) {
1280 /* The whole request could not be sent in one system call. We must
1281 queue it up and send it later when we get the chance. We must not
1282 loop here and wait until it might work again. */
1286 ptr = Curl_dyn_ptr(in) + amount;
1288 /* backup the currently set pointers */
1289 http->backup.fread_func = data->state.fread_func;
1290 http->backup.fread_in = data->state.in;
1291 http->backup.postdata = http->postdata;
1292 http->backup.postsize = http->postsize;
1294 /* set the new pointers for the request-sending */
1295 data->state.fread_func = (curl_read_callback)readmoredata;
1296 data->state.in = (void *)conn;
1297 http->postdata = ptr;
1298 http->postsize = (curl_off_t)size;
1300 http->send_buffer = *in; /* copy the whole struct */
1301 http->sending = HTTPSEND_REQUEST;
1305 http->sending = HTTPSEND_BODY;
1306 /* the full buffer was sent, clean up and return */
1309 if((size_t)amount != size)
1310 /* We have no continue-send mechanism now, fail. This can only happen
1311 when this function is used from the CONNECT sending function. We
1312 currently (stupidly) assume that the whole request is always sent
1313 away in the first single chunk.
1317 return CURLE_SEND_ERROR;
1325 /* end of the add_buffer functions */
1326 /* ------------------------------------------------------------------------- */
1331 * Curl_compareheader()
1333 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1334 * Pass headers WITH the colon.
1337 Curl_compareheader(const char *headerline, /* line to check */
1338 const char *header, /* header keyword _with_ colon */
1339 const char *content) /* content string to find */
1341 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1342 * by a colon (":") and the field value. Field names are case-insensitive.
1343 * The field value MAY be preceded by any amount of LWS, though a single SP
1346 size_t hlen = strlen(header);
1352 if(!strncasecompare(headerline, header, hlen))
1353 return FALSE; /* doesn't start with header */
1355 /* pass the header */
1356 start = &headerline[hlen];
1358 /* pass all whitespace */
1359 while(*start && ISSPACE(*start))
1362 /* find the end of the header line */
1363 end = strchr(start, '\r'); /* lines end with CRLF */
1365 /* in case there's a non-standard compliant line here */
1366 end = strchr(start, '\n');
1369 /* hm, there's no line ending here, use the zero byte! */
1370 end = strchr(start, '\0');
1373 len = end-start; /* length of the content part of the input line */
1374 clen = strlen(content); /* length of the word to find */
1376 /* find the content string in the rest of the line */
1377 for(; len >= clen; len--, start++) {
1378 if(strncasecompare(start, content, clen))
1379 return TRUE; /* match! */
1382 return FALSE; /* no match */
1386 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1387 * the generic Curl_connect().
1389 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1393 /* We default to persistent connections. We set this already in this connect
1394 function to make the re-use checks properly be able to check this bit. */
1395 connkeep(conn, "HTTP default");
1397 #ifndef CURL_DISABLE_PROXY
1398 /* the CONNECT procedure might not have been completed */
1399 result = Curl_proxy_connect(conn, FIRSTSOCKET);
1403 if(conn->bits.proxy_connect_closed)
1404 /* this is not an error, just part of the connection negotiation */
1407 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
1408 return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
1410 if(Curl_connect_ongoing(conn))
1411 /* nothing else to do except wait right now - we're not done here. */
1414 if(conn->data->set.haproxyprotocol) {
1415 /* add HAProxy PROXY protocol header */
1416 result = add_haproxy_protocol_header(conn);
1422 if(conn->given->protocol & CURLPROTO_HTTPS) {
1423 /* perform SSL initialization */
1424 result = https_connecting(conn, done);
1434 /* this returns the socket to wait for in the DO and DOING state for the multi
1435 interface and then we're always _sending_ a request and thus we wait for
1436 the single socket to become writable only */
1437 static int http_getsock_do(struct connectdata *conn,
1438 curl_socket_t *socks)
1441 socks[0] = conn->sock[FIRSTSOCKET];
1442 return GETSOCK_WRITESOCK(0);
1445 #ifndef CURL_DISABLE_PROXY
1446 static CURLcode add_haproxy_protocol_header(struct connectdata *conn)
1448 char proxy_header[128];
1451 char tcp_version[5];
1453 /* Emit the correct prefix for IPv6 */
1454 if(conn->bits.ipv6) {
1455 strcpy(tcp_version, "TCP6");
1458 strcpy(tcp_version, "TCP4");
1461 msnprintf(proxy_header,
1462 sizeof(proxy_header),
1463 "PROXY %s %s %s %li %li\r\n",
1465 conn->data->info.conn_local_ip,
1466 conn->data->info.conn_primary_ip,
1467 conn->data->info.conn_local_port,
1468 conn->data->info.conn_primary_port);
1470 Curl_dyn_init(&req, DYN_HAXPROXY);
1472 result = Curl_dyn_add(&req, proxy_header);
1476 result = Curl_buffer_send(&req, conn, &conn->data->info.request_size,
1484 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1487 DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1490 if(conn->transport == TRNSPRT_QUIC) {
1496 /* perform SSL initialization for this socket */
1497 result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1499 connclose(conn, "Failed HTTPS connection");
1504 static int https_getsock(struct connectdata *conn,
1505 curl_socket_t *socks)
1507 if(conn->handler->flags & PROTOPT_SSL)
1508 return Curl_ssl_getsock(conn, socks);
1509 return GETSOCK_BLANK;
1511 #endif /* USE_SSL */
1514 * Curl_http_done() gets called after a single HTTP request has been
1518 CURLcode Curl_http_done(struct connectdata *conn,
1519 CURLcode status, bool premature)
1521 struct Curl_easy *data = conn->data;
1522 struct HTTP *http = data->req.protop;
1524 /* Clear multipass flag. If authentication isn't done yet, then it will get
1525 * a chance to be set back to true when we output the next auth header */
1526 data->state.authhost.multipass = FALSE;
1527 data->state.authproxy.multipass = FALSE;
1529 Curl_unencode_cleanup(conn);
1531 /* set the proper values (possibly modified on POST) */
1532 conn->seek_func = data->set.seek_func; /* restore */
1533 conn->seek_client = data->set.seek_client; /* restore */
1538 Curl_dyn_free(&http->send_buffer);
1539 Curl_http2_done(data, premature);
1540 Curl_quic_done(data, premature);
1541 Curl_mime_cleanpart(&http->form);
1542 Curl_dyn_reset(&data->state.headerb);
1547 if(!premature && /* this check is pointless when DONE is called before the
1548 entire operation is complete */
1549 !conn->bits.retry &&
1550 !data->set.connect_only &&
1551 (data->req.bytecount +
1552 data->req.headerbytecount -
1553 data->req.deductheadercount) <= 0) {
1554 /* If this connection isn't simply closed to be retried, AND nothing was
1555 read from the HTTP server (that counts), this can't be right so we
1556 return an error here */
1557 failf(data, "Empty reply from server");
1558 return CURLE_GOT_NOTHING;
1565 * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
1566 * to avoid it include:
1568 * - if the user specifically requested HTTP 1.0
1569 * - if the server we are connected to only supports 1.0
1570 * - if any server previously contacted to handle this request only supports
1573 static bool use_http_1_1plus(const struct Curl_easy *data,
1574 const struct connectdata *conn)
1576 if((data->state.httpversion == 10) || (conn->httpversion == 10))
1578 if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
1579 (conn->httpversion <= 10))
1581 return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
1582 (data->set.httpversion >= CURL_HTTP_VERSION_1_1));
1585 static const char *get_http_string(const struct Curl_easy *data,
1586 const struct connectdata *conn)
1589 if((data->set.httpversion == CURL_HTTP_VERSION_3) ||
1590 (conn->httpversion == 30))
1595 if(conn->proto.httpc.h2)
1599 if(use_http_1_1plus(data, conn))
1605 /* check and possibly add an Expect: header */
1606 static CURLcode expect100(struct Curl_easy *data,
1607 struct connectdata *conn,
1610 CURLcode result = CURLE_OK;
1611 data->state.expect100header = FALSE; /* default to false unless it is set
1613 if(!data->state.disableexpect && use_http_1_1plus(data, conn) &&
1614 (conn->httpversion < 20)) {
1615 /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
1616 Expect: 100-continue to the headers which actually speeds up post
1617 operations (as there is one packet coming back from the web server) */
1618 const char *ptr = Curl_checkheaders(conn, "Expect");
1620 data->state.expect100header =
1621 Curl_compareheader(ptr, "Expect:", "100-continue");
1624 result = Curl_dyn_add(req, "Expect: 100-continue\r\n");
1626 data->state.expect100header = TRUE;
1634 HEADER_SERVER, /* direct to server */
1635 HEADER_PROXY, /* regular request to proxy */
1636 HEADER_CONNECT /* sending CONNECT to a proxy */
1639 /* used to compile the provided trailers into one buffer
1640 will return an error code if one of the headers is
1641 not formatted correctly */
1642 CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
1644 struct Curl_easy *handle)
1647 CURLcode result = CURLE_OK;
1648 const char *endofline_native = NULL;
1649 const char *endofline_network = NULL;
1652 #ifdef CURL_DO_LINEEND_CONV
1653 (handle->set.prefer_ascii) ||
1655 (handle->set.crlf)) {
1656 /* \n will become \r\n later on */
1657 endofline_native = "\n";
1658 endofline_network = "\x0a";
1661 endofline_native = "\r\n";
1662 endofline_network = "\x0d\x0a";
1666 /* only add correctly formatted trailers */
1667 ptr = strchr(trailers->data, ':');
1668 if(ptr && *(ptr + 1) == ' ') {
1669 result = Curl_dyn_add(b, trailers->data);
1672 result = Curl_dyn_add(b, endofline_native);
1677 infof(handle, "Malformatted trailing header ! Skipping trailer.");
1678 trailers = trailers->next;
1680 result = Curl_dyn_add(b, endofline_network);
1684 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1689 struct curl_slist *h[2];
1690 struct curl_slist *headers;
1691 int numlists = 1; /* by default */
1692 struct Curl_easy *data = conn->data;
1695 #ifndef CURL_DISABLE_PROXY
1696 enum proxy_use proxy;
1699 proxy = HEADER_CONNECT;
1701 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
1702 HEADER_PROXY:HEADER_SERVER;
1706 h[0] = data->set.headers;
1709 h[0] = data->set.headers;
1710 if(data->set.sep_headers) {
1711 h[1] = data->set.proxyheaders;
1715 case HEADER_CONNECT:
1716 if(data->set.sep_headers)
1717 h[0] = data->set.proxyheaders;
1719 h[0] = data->set.headers;
1724 h[0] = data->set.headers;
1727 /* loop through one or two lists */
1728 for(i = 0; i < numlists; i++) {
1732 char *semicolonp = NULL;
1733 ptr = strchr(headers->data, ':');
1736 /* no colon, semicolon? */
1737 ptr = strchr(headers->data, ';');
1740 ptr++; /* pass the semicolon */
1741 while(*ptr && ISSPACE(*ptr))
1745 /* this may be used for something else in the future */
1749 if(*(--ptr) == ';') {
1750 /* copy the source */
1751 semicolonp = strdup(headers->data);
1754 return CURLE_OUT_OF_MEMORY;
1756 /* put a colon where the semicolon is */
1757 semicolonp[ptr - headers->data] = ':';
1758 /* point at the colon */
1759 optr = &semicolonp [ptr - headers->data];
1766 /* we require a colon for this to be a true header */
1768 ptr++; /* pass the colon */
1769 while(*ptr && ISSPACE(*ptr))
1772 if(*ptr || semicolonp) {
1773 /* only send this if the contents was non-blank or done special */
1774 CURLcode result = CURLE_OK;
1775 char *compare = semicolonp ? semicolonp : headers->data;
1777 if(data->state.aptr.host &&
1778 /* a Host: header was sent already, don't pass on any custom Host:
1779 header as that will produce *two* in the same request! */
1780 checkprefix("Host:", compare))
1782 else if(data->state.httpreq == HTTPREQ_POST_FORM &&
1783 /* this header (extended by formdata.c) is sent later */
1784 checkprefix("Content-Type:", compare))
1786 else if(data->state.httpreq == HTTPREQ_POST_MIME &&
1787 /* this header is sent later */
1788 checkprefix("Content-Type:", compare))
1790 else if(conn->bits.authneg &&
1791 /* while doing auth neg, don't allow the custom length since
1792 we will force length zero then */
1793 checkprefix("Content-Length:", compare))
1795 else if(data->state.aptr.te &&
1796 /* when asking for Transfer-Encoding, don't pass on a custom
1798 checkprefix("Connection:", compare))
1800 else if((conn->httpversion >= 20) &&
1801 checkprefix("Transfer-Encoding:", compare))
1802 /* HTTP/2 doesn't support chunked requests */
1804 else if((checkprefix("Authorization:", compare) ||
1805 checkprefix("Cookie:", compare)) &&
1806 /* be careful of sending this potentially sensitive header to
1808 (data->state.this_is_a_follow &&
1809 data->state.first_host &&
1810 !data->set.allow_auth_to_other_hosts &&
1811 !strcasecompare(data->state.first_host, conn->host.name)))
1814 result = Curl_dyn_addf(req, "%s\r\n", compare);
1822 headers = headers->next;
1829 #ifndef CURL_DISABLE_PARSEDATE
1830 CURLcode Curl_add_timecondition(const struct connectdata *conn,
1833 struct Curl_easy *data = conn->data;
1834 const struct tm *tm;
1840 if(data->set.timecondition == CURL_TIMECOND_NONE)
1841 /* no condition was asked for */
1844 result = Curl_gmtime(data->set.timevalue, &keeptime);
1846 failf(data, "Invalid TIMEVALUE");
1851 switch(data->set.timecondition) {
1853 return CURLE_BAD_FUNCTION_ARGUMENT;
1855 case CURL_TIMECOND_IFMODSINCE:
1856 condp = "If-Modified-Since";
1858 case CURL_TIMECOND_IFUNMODSINCE:
1859 condp = "If-Unmodified-Since";
1861 case CURL_TIMECOND_LASTMOD:
1862 condp = "Last-Modified";
1866 if(Curl_checkheaders(conn, condp)) {
1867 /* A custom header was specified; it will be sent instead. */
1871 /* The If-Modified-Since header family should have their times set in
1872 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1873 * represented in Greenwich Mean Time (GMT), without exception. For the
1874 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1875 * Time)." (see page 20 of RFC2616).
1878 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1879 msnprintf(datestr, sizeof(datestr),
1880 "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
1882 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1884 Curl_month[tm->tm_mon],
1890 result = Curl_dyn_add(req, datestr);
1896 CURLcode Curl_add_timecondition(const struct connectdata *conn,
1906 * Curl_http() gets called from the generic multi_do() function when a HTTP
1907 * request is to be performed. This creates and sends a properly constructed
1910 CURLcode Curl_http(struct connectdata *conn, bool *done)
1912 struct Curl_easy *data = conn->data;
1913 CURLcode result = CURLE_OK;
1915 const char *path = data->state.up.path;
1916 const char *query = data->state.up.query;
1917 bool paste_ftp_userpwd = FALSE;
1918 char ftp_typecode[sizeof("/;type=?")] = "";
1919 const char *host = conn->host.name;
1920 const char *te = ""; /* transfer-encoding */
1922 const char *request;
1923 Curl_HttpReq httpreq = data->state.httpreq;
1924 #if !defined(CURL_DISABLE_COOKIES)
1925 char *addcookies = NULL;
1927 curl_off_t included_body = 0;
1928 const char *httpstring;
1930 curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1931 char *altused = NULL;
1933 /* Always consider the DO phase done after this function call, even if there
1934 may be parts of the request that is not yet sent, since we can deal with
1935 the rest of the request in the PERFORM phase. */
1938 if(conn->transport != TRNSPRT_QUIC) {
1939 if(conn->httpversion < 20) { /* unless the connection is re-used and
1941 switch(conn->negnpn) {
1942 case CURL_HTTP_VERSION_2:
1943 conn->httpversion = 20; /* we know we're on HTTP/2 now */
1945 result = Curl_http2_switched(conn, NULL, 0);
1949 case CURL_HTTP_VERSION_1_1:
1950 /* continue with HTTP/1.1 when explicitly requested */
1953 /* Check if user wants to use HTTP/2 with clear TCP*/
1955 if(conn->data->set.httpversion ==
1956 CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
1957 #ifndef CURL_DISABLE_PROXY
1958 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
1959 /* We don't support HTTP/2 proxies yet. Also it's debatable
1960 whether or not this setting should apply to HTTP/2 proxies. */
1961 infof(data, "Ignoring HTTP/2 prior knowledge due to proxy\n");
1965 DEBUGF(infof(data, "HTTP/2 over clean TCP\n"));
1966 conn->httpversion = 20;
1968 result = Curl_http2_switched(conn, NULL, 0);
1977 /* prepare for a http2 request */
1978 result = Curl_http2_setup(conn);
1983 http = data->req.protop;
1986 if(!data->state.this_is_a_follow) {
1987 /* Free to avoid leaking memory on multiple requests*/
1988 free(data->state.first_host);
1990 data->state.first_host = strdup(conn->host.name);
1991 if(!data->state.first_host)
1992 return CURLE_OUT_OF_MEMORY;
1994 data->state.first_remote_port = conn->remote_port;
1997 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
1999 httpreq = HTTPREQ_PUT;
2002 /* Now set the 'request' pointer to the proper request string */
2003 if(data->set.str[STRING_CUSTOMREQUEST])
2004 request = data->set.str[STRING_CUSTOMREQUEST];
2006 if(data->set.opt_no_body)
2009 DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
2012 case HTTPREQ_POST_FORM:
2013 case HTTPREQ_POST_MIME:
2019 default: /* this should never happen */
2030 /* The User-Agent string might have been allocated in url.c already, because
2031 it might have been used in the proxy connect, but if we have got a header
2032 with the user-agent string specified, we erase the previously made string
2034 if(Curl_checkheaders(conn, "User-Agent")) {
2035 free(data->state.aptr.uagent);
2036 data->state.aptr.uagent = NULL;
2039 /* setup the authentication headers */
2042 if(query && *query) {
2043 pq = aprintf("%s?%s", path, query);
2045 return CURLE_OUT_OF_MEMORY;
2047 result = Curl_http_output_auth(conn, request, (pq ? pq : path), FALSE);
2053 if(((data->state.authhost.multipass && !data->state.authhost.done)
2054 || (data->state.authproxy.multipass && !data->state.authproxy.done)) &&
2055 (httpreq != HTTPREQ_GET) &&
2056 (httpreq != HTTPREQ_HEAD)) {
2057 /* Auth is required and we are not authenticated yet. Make a PUT or POST
2058 with content-length zero as a "probe". */
2059 conn->bits.authneg = TRUE;
2062 conn->bits.authneg = FALSE;
2064 Curl_safefree(data->state.aptr.ref);
2065 if(data->change.referer && !Curl_checkheaders(conn, "Referer")) {
2066 data->state.aptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
2067 if(!data->state.aptr.ref)
2068 return CURLE_OUT_OF_MEMORY;
2071 data->state.aptr.ref = NULL;
2073 #if !defined(CURL_DISABLE_COOKIES)
2074 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie"))
2075 addcookies = data->set.str[STRING_COOKIE];
2078 if(!Curl_checkheaders(conn, "Accept-Encoding") &&
2079 data->set.str[STRING_ENCODING]) {
2080 Curl_safefree(data->state.aptr.accept_encoding);
2081 data->state.aptr.accept_encoding =
2082 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
2083 if(!data->state.aptr.accept_encoding)
2084 return CURLE_OUT_OF_MEMORY;
2087 Curl_safefree(data->state.aptr.accept_encoding);
2088 data->state.aptr.accept_encoding = NULL;
2092 /* we only consider transfer-encoding magic if libz support is built-in */
2094 if(!Curl_checkheaders(conn, "TE") &&
2095 data->set.http_transfer_encoding) {
2096 /* When we are to insert a TE: header in the request, we must also insert
2097 TE in a Connection: header, so we need to merge the custom provided
2098 Connection: header and prevent the original to get sent. Note that if
2099 the user has inserted his/hers own TE: header we don't do this magic
2100 but then assume that the user will handle it all! */
2101 char *cptr = Curl_checkheaders(conn, "Connection");
2102 #define TE_HEADER "TE: gzip\r\n"
2104 Curl_safefree(data->state.aptr.te);
2107 cptr = Curl_copy_header_value(cptr);
2109 return CURLE_OUT_OF_MEMORY;
2112 /* Create the (updated) Connection: header */
2113 data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
2114 cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
2117 if(!data->state.aptr.te)
2118 return CURLE_OUT_OF_MEMORY;
2123 case HTTPREQ_POST_MIME:
2124 http->sendit = &data->set.mimepost;
2126 case HTTPREQ_POST_FORM:
2127 /* Convert the form structure into a mime structure. */
2128 Curl_mime_cleanpart(&http->form);
2129 result = Curl_getformdata(data, &http->form, data->set.httppost,
2130 data->state.fread_func);
2133 http->sendit = &http->form;
2136 http->sendit = NULL;
2139 #ifndef CURL_DISABLE_MIME
2141 const char *cthdr = Curl_checkheaders(conn, "Content-Type");
2143 /* Read and seek body only. */
2144 http->sendit->flags |= MIME_BODY_ONLY;
2146 /* Prepare the mime structure headers & set content type. */
2149 for(cthdr += 13; *cthdr == ' '; cthdr++)
2151 else if(http->sendit->kind == MIMEKIND_MULTIPART)
2152 cthdr = "multipart/form-data";
2154 curl_mime_headers(http->sendit, data->set.headers, 0);
2155 result = Curl_mime_prepare_headers(http->sendit, cthdr,
2156 NULL, MIMESTRATEGY_FORM);
2157 curl_mime_headers(http->sendit, NULL, 0);
2159 result = Curl_mime_rewind(http->sendit);
2162 http->postsize = Curl_mime_size(http->sendit);
2166 ptr = Curl_checkheaders(conn, "Transfer-Encoding");
2168 /* Some kind of TE is requested, check if 'chunked' is chosen */
2169 data->req.upload_chunky =
2170 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
2173 if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
2174 (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
2175 http->postsize < 0) ||
2176 ((data->set.upload || httpreq == HTTPREQ_POST) &&
2177 data->state.infilesize == -1))) {
2178 if(conn->bits.authneg)
2179 /* don't enable chunked during auth neg */
2181 else if(use_http_1_1plus(data, conn)) {
2182 if(conn->httpversion < 20)
2183 /* HTTP, upload, unknown file size and not HTTP 1.0 */
2184 data->req.upload_chunky = TRUE;
2187 failf(data, "Chunky upload is not supported by HTTP 1.0");
2188 return CURLE_UPLOAD_FAILED;
2192 /* else, no chunky upload */
2193 data->req.upload_chunky = FALSE;
2196 if(data->req.upload_chunky)
2197 te = "Transfer-Encoding: chunked\r\n";
2200 Curl_safefree(data->state.aptr.host);
2202 ptr = Curl_checkheaders(conn, "Host");
2203 if(ptr && (!data->state.this_is_a_follow ||
2204 strcasecompare(data->state.first_host, conn->host.name))) {
2205 #if !defined(CURL_DISABLE_COOKIES)
2206 /* If we have a given custom Host: header, we extract the host name in
2207 order to possibly use it for cookie reasons later on. We only allow the
2208 custom Host: header if this is NOT a redirect, as setting Host: in the
2209 redirected request is being out on thin ice. Except if the host name
2210 is the same as the first one! */
2211 char *cookiehost = Curl_copy_header_value(ptr);
2213 return CURLE_OUT_OF_MEMORY;
2215 /* ignore empty data */
2218 /* If the host begins with '[', we start searching for the port after
2219 the bracket has been closed */
2220 if(*cookiehost == '[') {
2221 char *closingbracket;
2222 /* since the 'cookiehost' is an allocated memory area that will be
2223 freed later we cannot simply increment the pointer */
2224 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
2225 closingbracket = strchr(cookiehost, ']');
2227 *closingbracket = 0;
2230 int startsearch = 0;
2231 char *colon = strchr(cookiehost + startsearch, ':');
2233 *colon = 0; /* The host must not include an embedded port number */
2235 Curl_safefree(data->state.aptr.cookiehost);
2236 data->state.aptr.cookiehost = cookiehost;
2240 if(strcmp("Host:", ptr)) {
2241 data->state.aptr.host = aprintf("Host:%s\r\n", &ptr[5]);
2242 if(!data->state.aptr.host)
2243 return CURLE_OUT_OF_MEMORY;
2246 /* when clearing the header */
2247 data->state.aptr.host = NULL;
2250 /* When building Host: headers, we must put the host name within
2251 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
2253 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
2254 (conn->remote_port == PORT_HTTPS)) ||
2255 ((conn->given->protocol&CURLPROTO_HTTP) &&
2256 (conn->remote_port == PORT_HTTP)) )
2257 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
2258 the port number in the host string */
2259 data->state.aptr.host = aprintf("Host: %s%s%s\r\n",
2260 conn->bits.ipv6_ip?"[":"",
2262 conn->bits.ipv6_ip?"]":"");
2264 data->state.aptr.host = aprintf("Host: %s%s%s:%d\r\n",
2265 conn->bits.ipv6_ip?"[":"",
2267 conn->bits.ipv6_ip?"]":"",
2270 if(!data->state.aptr.host)
2271 /* without Host: we can't make a nice request */
2272 return CURLE_OUT_OF_MEMORY;
2275 #ifndef CURL_DISABLE_PROXY
2276 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
2277 /* Using a proxy but does not tunnel through it */
2279 /* The path sent to the proxy is in fact the entire URL. But if the remote
2280 host is a IDN-name, we must make sure that the request we produce only
2281 uses the encoded host name! */
2283 /* and no fragment part */
2285 CURLU *h = curl_url_dup(data->state.uh);
2287 return CURLE_OUT_OF_MEMORY;
2289 if(conn->host.dispname != conn->host.name) {
2290 uc = curl_url_set(h, CURLUPART_HOST, conn->host.name, 0);
2292 curl_url_cleanup(h);
2293 return CURLE_OUT_OF_MEMORY;
2296 uc = curl_url_set(h, CURLUPART_FRAGMENT, NULL, 0);
2298 curl_url_cleanup(h);
2299 return CURLE_OUT_OF_MEMORY;
2302 if(strcasecompare("http", data->state.up.scheme)) {
2303 /* when getting HTTP, we don't want the userinfo the URL */
2304 uc = curl_url_set(h, CURLUPART_USER, NULL, 0);
2306 curl_url_cleanup(h);
2307 return CURLE_OUT_OF_MEMORY;
2309 uc = curl_url_set(h, CURLUPART_PASSWORD, NULL, 0);
2311 curl_url_cleanup(h);
2312 return CURLE_OUT_OF_MEMORY;
2315 /* Extract the URL to use in the request. Store in STRING_TEMP_URL for
2316 clean-up reasons if the function returns before the free() further
2318 uc = curl_url_get(h, CURLUPART_URL, &data->set.str[STRING_TEMP_URL], 0);
2320 curl_url_cleanup(h);
2321 return CURLE_OUT_OF_MEMORY;
2324 curl_url_cleanup(h);
2326 if(strcasecompare("ftp", data->state.up.scheme)) {
2327 if(data->set.proxy_transfer_mode) {
2328 /* when doing ftp, append ;type=<a|i> if not present */
2329 char *type = strstr(path, ";type=");
2330 if(type && type[6] && type[7] == 0) {
2331 switch(Curl_raw_toupper(type[6])) {
2341 char *p = ftp_typecode;
2342 /* avoid sending invalid URLs like ftp://example.com;type=i if the
2343 * user specified ftp://example.com without the slash */
2344 if(!*data->state.up.path && path[strlen(path) - 1] != '/') {
2347 msnprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
2348 data->set.prefer_ascii ? 'a' : 'i');
2351 if(conn->bits.user_passwd)
2352 paste_ftp_userpwd = TRUE;
2355 #endif /* CURL_DISABLE_PROXY */
2357 http->p_accept = Curl_checkheaders(conn, "Accept")?NULL:"Accept: */*\r\n";
2359 if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) &&
2360 data->state.resume_from) {
2361 /**********************************************************************
2362 * Resuming upload in HTTP means that we PUT or POST and that we have
2363 * got a resume_from value set. The resume value has already created
2364 * a Range: header that will be passed along. We need to "fast forward"
2365 * the file the given number of bytes and decrease the assume upload
2366 * file size before we continue this venture in the dark lands of HTTP.
2367 * Resuming mime/form posting at an offset > 0 has no sense and is ignored.
2368 *********************************************************************/
2370 if(data->state.resume_from < 0) {
2372 * This is meant to get the size of the present remote-file by itself.
2373 * We don't support this now. Bail out!
2375 data->state.resume_from = 0;
2378 if(data->state.resume_from && !data->state.this_is_a_follow) {
2379 /* do we still game? */
2381 /* Now, let's read off the proper amount of bytes from the
2383 int seekerr = CURL_SEEKFUNC_CANTSEEK;
2384 if(conn->seek_func) {
2385 Curl_set_in_callback(data, true);
2386 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2388 Curl_set_in_callback(data, false);
2391 if(seekerr != CURL_SEEKFUNC_OK) {
2392 curl_off_t passed = 0;
2394 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2395 failf(data, "Could not seek stream");
2396 return CURLE_READ_ERROR;
2398 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2400 size_t readthisamountnow =
2401 (data->state.resume_from - passed > data->set.buffer_size) ?
2402 (size_t)data->set.buffer_size :
2403 curlx_sotouz(data->state.resume_from - passed);
2405 size_t actuallyread =
2406 data->state.fread_func(data->state.buffer, 1, readthisamountnow,
2409 passed += actuallyread;
2410 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2411 /* this checks for greater-than only to make sure that the
2412 CURL_READFUNC_ABORT return code still aborts */
2413 failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2414 " bytes from the input", passed);
2415 return CURLE_READ_ERROR;
2417 } while(passed < data->state.resume_from);
2420 /* now, decrease the size of the read */
2421 if(data->state.infilesize>0) {
2422 data->state.infilesize -= data->state.resume_from;
2424 if(data->state.infilesize <= 0) {
2425 failf(data, "File already completely uploaded");
2426 return CURLE_PARTIAL_FILE;
2429 /* we've passed, proceed as normal */
2432 if(data->state.use_range) {
2434 * A range is selected. We use different headers whether we're downloading
2435 * or uploading and we always let customized headers override our internal
2436 * ones if any such are specified.
2438 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2439 !Curl_checkheaders(conn, "Range")) {
2440 /* if a line like this was already allocated, free the previous one */
2441 free(data->state.aptr.rangeline);
2442 data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n",
2445 else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
2446 !Curl_checkheaders(conn, "Content-Range")) {
2448 /* if a line like this was already allocated, free the previous one */
2449 free(data->state.aptr.rangeline);
2451 if(data->set.set_resume_from < 0) {
2452 /* Upload resume was asked for, but we don't know the size of the
2453 remote part so we tell the server (and act accordingly) that we
2454 upload the whole file (again) */
2455 data->state.aptr.rangeline =
2456 aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2457 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2458 data->state.infilesize - 1, data->state.infilesize);
2461 else if(data->state.resume_from) {
2462 /* This is because "resume" was selected */
2463 curl_off_t total_expected_size =
2464 data->state.resume_from + data->state.infilesize;
2465 data->state.aptr.rangeline =
2466 aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2467 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2468 data->state.range, total_expected_size-1,
2469 total_expected_size);
2472 /* Range was selected and then we just pass the incoming range and
2473 append total size */
2474 data->state.aptr.rangeline =
2475 aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2476 data->state.range, data->state.infilesize);
2478 if(!data->state.aptr.rangeline)
2479 return CURLE_OUT_OF_MEMORY;
2483 httpstring = get_http_string(data, conn);
2485 /* initialize a dynamic send-buffer */
2486 Curl_dyn_init(&req, DYN_HTTP_REQUEST);
2488 /* add the main request stuff */
2489 /* GET/HEAD/POST/PUT */
2490 result = Curl_dyn_addf(&req, "%s ", request);
2494 if(data->set.str[STRING_TARGET]) {
2495 path = data->set.str[STRING_TARGET];
2499 #ifndef CURL_DISABLE_PROXY
2501 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
2502 char *url = data->set.str[STRING_TEMP_URL];
2503 result = Curl_dyn_add(&req, url);
2504 Curl_safefree(data->set.str[STRING_TEMP_URL]);
2508 if(paste_ftp_userpwd)
2509 result = Curl_dyn_addf(&req, "ftp://%s:%s@%s", conn->user, conn->passwd,
2510 path + sizeof("ftp://") - 1);
2512 result = Curl_dyn_add(&req, path);
2516 result = Curl_dyn_addf(&req, "?%s", query);
2522 if(conn->bits.altused && !Curl_checkheaders(conn, "Alt-Used")) {
2523 altused = aprintf("Alt-Used: %s:%d\r\n",
2524 conn->conn_to_host.name, conn->conn_to_port);
2526 Curl_dyn_free(&req);
2527 return CURLE_OUT_OF_MEMORY;
2533 "%s" /* ftp typecode (;type=x) */
2534 " HTTP/%s\r\n" /* HTTP version */
2536 "%s" /* proxyuserpwd */
2539 "%s" /* user agent */
2542 "%s" /* accept-encoding */
2544 "%s" /* Proxy-Connection */
2545 "%s" /* transfer-encoding */
2550 (data->state.aptr.host?data->state.aptr.host:""),
2551 data->state.aptr.proxyuserpwd?
2552 data->state.aptr.proxyuserpwd:"",
2553 data->state.aptr.userpwd?data->state.aptr.userpwd:"",
2554 (data->state.use_range && data->state.aptr.rangeline)?
2555 data->state.aptr.rangeline:"",
2556 (data->set.str[STRING_USERAGENT] &&
2557 *data->set.str[STRING_USERAGENT] &&
2558 data->state.aptr.uagent)?
2559 data->state.aptr.uagent:"",
2560 http->p_accept?http->p_accept:"",
2561 data->state.aptr.te?data->state.aptr.te:"",
2562 (data->set.str[STRING_ENCODING] &&
2563 *data->set.str[STRING_ENCODING] &&
2564 data->state.aptr.accept_encoding)?
2565 data->state.aptr.accept_encoding:"",
2566 (data->change.referer && data->state.aptr.ref)?
2567 data->state.aptr.ref:"" /* Referer: <data> */,
2568 #ifndef CURL_DISABLE_PROXY
2569 (conn->bits.httpproxy &&
2570 !conn->bits.tunnel_proxy &&
2571 !Curl_checkProxyheaders(conn, "Proxy-Connection"))?
2572 "Proxy-Connection: Keep-Alive\r\n":"",
2577 altused ? altused : ""
2580 /* clear userpwd and proxyuserpwd to avoid re-using old credentials
2581 * from re-used connections */
2582 Curl_safefree(data->state.aptr.userpwd);
2583 Curl_safefree(data->state.aptr.proxyuserpwd);
2589 if(!(conn->handler->flags&PROTOPT_SSL) &&
2590 conn->httpversion != 20 &&
2591 (data->set.httpversion == CURL_HTTP_VERSION_2)) {
2592 /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
2594 result = Curl_http2_request_upgrade(&req, conn);
2599 #if !defined(CURL_DISABLE_COOKIES)
2600 if(data->cookies || addcookies) {
2601 struct Cookie *co = NULL; /* no cookies from start */
2604 if(data->cookies && data->state.cookie_engine) {
2605 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2606 co = Curl_cookie_getlist(data->cookies,
2607 data->state.aptr.cookiehost?
2608 data->state.aptr.cookiehost:host,
2609 data->state.up.path,
2610 (conn->handler->protocol&CURLPROTO_HTTPS)?
2612 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2615 struct Cookie *store = co;
2616 /* now loop through all cookies that matched */
2620 result = Curl_dyn_add(&req, "Cookie: ");
2624 result = Curl_dyn_addf(&req, "%s%s=%s", count?"; ":"",
2625 co->name, co->value);
2630 co = co->next; /* next cookie please */
2632 Curl_cookie_freelist(store);
2634 if(addcookies && !result) {
2636 result = Curl_dyn_add(&req, "Cookie: ");
2638 result = Curl_dyn_addf(&req, "%s%s", count?"; ":"", addcookies);
2642 if(count && !result)
2643 result = Curl_dyn_add(&req, "\r\n");
2650 result = Curl_add_timecondition(conn, &req);
2654 result = Curl_add_custom_headers(conn, FALSE, &req);
2658 http->postdata = NULL; /* nothing to post at this point */
2659 Curl_pgrsSetUploadSize(data, -1); /* upload size is unknown atm */
2661 /* If 'authdone' is FALSE, we must not set the write socket index to the
2662 Curl_transfer() call below, as we're not ready to actually upload any
2667 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2669 if(conn->bits.authneg)
2672 postsize = data->state.infilesize;
2674 if((postsize != -1) && !data->req.upload_chunky &&
2675 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
2676 /* only add Content-Length if not uploading chunked */
2677 result = Curl_dyn_addf(&req, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2684 result = expect100(data, conn, &req);
2689 /* end of headers */
2690 result = Curl_dyn_add(&req, "\r\n");
2694 /* set the upload size to the progress meter */
2695 Curl_pgrsSetUploadSize(data, postsize);
2697 /* this sends the buffer and frees all the buffer resources */
2698 result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
2701 failf(data, "Failed sending PUT request");
2703 /* prepare for transfer */
2704 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
2705 postsize?FIRSTSOCKET:-1);
2710 case HTTPREQ_POST_FORM:
2711 case HTTPREQ_POST_MIME:
2712 /* This is form posting using mime data. */
2713 if(conn->bits.authneg) {
2714 /* nothing to post! */
2715 result = Curl_dyn_add(&req, "Content-Length: 0\r\n\r\n");
2719 result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
2722 failf(data, "Failed sending POST request");
2724 /* setup variables for the upcoming transfer */
2725 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
2729 data->state.infilesize = postsize = http->postsize;
2731 /* We only set Content-Length and allow a custom Content-Length if
2732 we don't upload data chunked, as RFC2616 forbids us to set both
2733 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2734 if(postsize != -1 && !data->req.upload_chunky &&
2735 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
2736 /* we allow replacing this header if not during auth negotiation,
2737 although it isn't very wise to actually set your own */
2738 result = Curl_dyn_addf(&req,
2739 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2745 #ifndef CURL_DISABLE_MIME
2746 /* Output mime-generated headers. */
2748 struct curl_slist *hdr;
2750 for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) {
2751 result = Curl_dyn_addf(&req, "%s\r\n", hdr->data);
2758 /* For really small posts we don't use Expect: headers at all, and for
2759 the somewhat bigger ones we allow the app to disable it. Just make
2760 sure that the expect100header is always set to the preferred value
2762 ptr = Curl_checkheaders(conn, "Expect");
2764 data->state.expect100header =
2765 Curl_compareheader(ptr, "Expect:", "100-continue");
2767 else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
2768 result = expect100(data, conn, &req);
2773 data->state.expect100header = FALSE;
2775 /* make the request end in a true CRLF */
2776 result = Curl_dyn_add(&req, "\r\n");
2780 /* set the upload size to the progress meter */
2781 Curl_pgrsSetUploadSize(data, postsize);
2783 /* Read from mime structure. */
2784 data->state.fread_func = (curl_read_callback) Curl_mime_read;
2785 data->state.in = (void *) http->sendit;
2786 http->sending = HTTPSEND_BODY;
2788 /* this sends the buffer and frees all the buffer resources */
2789 result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
2792 failf(data, "Failed sending POST request");
2794 /* prepare for transfer */
2795 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
2796 postsize?FIRSTSOCKET:-1);
2803 /* this is the simple POST, using x-www-form-urlencoded style */
2805 if(conn->bits.authneg)
2808 /* the size of the post body */
2809 postsize = data->state.infilesize;
2811 /* We only set Content-Length and allow a custom Content-Length if
2812 we don't upload data chunked, as RFC2616 forbids us to set both
2813 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2814 if((postsize != -1) && !data->req.upload_chunky &&
2815 (conn->bits.authneg || !Curl_checkheaders(conn, "Content-Length"))) {
2816 /* we allow replacing this header if not during auth negotiation,
2817 although it isn't very wise to actually set your own */
2818 result = Curl_dyn_addf(&req, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2824 if(!Curl_checkheaders(conn, "Content-Type")) {
2825 result = Curl_dyn_add(&req, "Content-Type: application/"
2826 "x-www-form-urlencoded\r\n");
2831 /* For really small posts we don't use Expect: headers at all, and for
2832 the somewhat bigger ones we allow the app to disable it. Just make
2833 sure that the expect100header is always set to the preferred value
2835 ptr = Curl_checkheaders(conn, "Expect");
2837 data->state.expect100header =
2838 Curl_compareheader(ptr, "Expect:", "100-continue");
2840 else if(postsize > EXPECT_100_THRESHOLD || postsize < 0) {
2841 result = expect100(data, conn, &req);
2846 data->state.expect100header = FALSE;
2848 if(data->set.postfields) {
2850 /* In HTTP2, we send request body in DATA frame regardless of
2852 if(conn->httpversion != 20 &&
2853 !data->state.expect100header &&
2854 (postsize < MAX_INITIAL_POST_SIZE)) {
2855 /* if we don't use expect: 100 AND
2856 postsize is less than MAX_INITIAL_POST_SIZE
2858 then append the post data to the HTTP request header. This limit
2859 is no magic limit but only set to prevent really huge POSTs to
2860 get the data duplicated with malloc() and family. */
2862 /* end of headers! */
2863 result = Curl_dyn_add(&req, "\r\n");
2867 if(!data->req.upload_chunky) {
2868 /* We're not sending it 'chunked', append it to the request
2869 already now to reduce the number if send() calls */
2870 result = Curl_dyn_addn(&req, data->set.postfields,
2872 included_body = postsize;
2876 /* Append the POST data chunky-style */
2877 result = Curl_dyn_addf(&req, "%x\r\n", (int)postsize);
2879 result = Curl_dyn_addn(&req, data->set.postfields,
2882 result = Curl_dyn_add(&req, "\r\n");
2883 included_body = postsize + 2;
2887 result = Curl_dyn_add(&req, "\x30\x0d\x0a\x0d\x0a");
2893 /* Make sure the progress information is accurate */
2894 Curl_pgrsSetUploadSize(data, postsize);
2897 /* A huge POST coming up, do data separate from the request */
2898 http->postsize = postsize;
2899 http->postdata = data->set.postfields;
2901 http->sending = HTTPSEND_BODY;
2903 data->state.fread_func = (curl_read_callback)readmoredata;
2904 data->state.in = (void *)conn;
2906 /* set the upload size to the progress meter */
2907 Curl_pgrsSetUploadSize(data, http->postsize);
2909 /* end of headers! */
2910 result = Curl_dyn_add(&req, "\r\n");
2916 /* end of headers! */
2917 result = Curl_dyn_add(&req, "\r\n");
2921 if(data->req.upload_chunky && conn->bits.authneg) {
2922 /* Chunky upload is selected and we're negotiating auth still, send
2924 result = Curl_dyn_add(&req, (char *)"\x30\x0d\x0a\x0d\x0a");
2930 else if(data->state.infilesize) {
2931 /* set the upload size to the progress meter */
2932 Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2934 /* set the pointer to mark that we will send the post body using the
2935 read callback, but only if we're not in authenticate
2937 if(!conn->bits.authneg) {
2938 http->postdata = (char *)&http->postdata;
2939 http->postsize = postsize;
2943 /* issue the request */
2944 result = Curl_buffer_send(&req, conn, &data->info.request_size,
2945 (size_t)included_body, FIRSTSOCKET);
2948 failf(data, "Failed sending HTTP POST request");
2950 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
2951 http->postdata?FIRSTSOCKET:-1);
2955 result = Curl_dyn_add(&req, "\r\n");
2959 /* issue the request */
2960 result = Curl_buffer_send(&req, conn, &data->info.request_size, 0,
2964 failf(data, "Failed sending HTTP request");
2966 /* HTTP GET/HEAD download: */
2967 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
2971 if(!postsize && (http->sending != HTTPSEND_REQUEST))
2972 data->req.upload_done = TRUE;
2974 if(data->req.writebytecount) {
2975 /* if a request-body has been sent off, we make sure this progress is noted
2977 Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
2978 if(Curl_pgrsUpdate(conn))
2979 result = CURLE_ABORTED_BY_CALLBACK;
2981 if(data->req.writebytecount >= postsize) {
2982 /* already sent the entire request body, mark the "upload" as
2984 infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
2985 " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
2986 data->req.writebytecount, postsize);
2987 data->req.upload_done = TRUE;
2988 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2989 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2990 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
2994 if((conn->httpversion == 20) && data->req.upload_chunky)
2995 /* upload_chunky was set above to set up the request in a chunky fashion,
2996 but is disabled here again to avoid that the chunked encoded version is
2997 actually used when sending the request body over h2 */
2998 data->req.upload_chunky = FALSE;
3003 STATUS_UNKNOWN, /* not enough data to tell yet */
3004 STATUS_DONE, /* a status line was read */
3005 STATUS_BAD /* not a status line */
3009 /* Check a string for a prefix. Check no more than 'len' bytes */
3010 static bool checkprefixmax(const char *prefix, const char *buffer, size_t len)
3012 size_t ch = CURLMIN(strlen(prefix), len);
3013 return curl_strnequal(prefix, buffer, ch);
3019 * Returns TRUE if member of the list matches prefix of string
3022 checkhttpprefix(struct Curl_easy *data,
3023 const char *s, size_t len)
3025 struct curl_slist *head = data->set.http200aliases;
3026 statusline rc = STATUS_BAD;
3027 statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
3028 #ifdef CURL_DOES_CONVERSIONS
3029 /* convert from the network encoding using a scratch area */
3030 char *scratch = strdup(s);
3031 if(NULL == scratch) {
3032 failf(data, "Failed to allocate memory for conversion!");
3033 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
3035 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
3036 /* Curl_convert_from_network calls failf if unsuccessful */
3038 return FALSE; /* can't return CURLE_foobar so return FALSE */
3041 #endif /* CURL_DOES_CONVERSIONS */
3044 if(checkprefixmax(head->data, s, len)) {
3051 if((rc != STATUS_DONE) && (checkprefixmax("HTTP/", s, len)))
3054 #ifdef CURL_DOES_CONVERSIONS
3056 #endif /* CURL_DOES_CONVERSIONS */
3060 #ifndef CURL_DISABLE_RTSP
3062 checkrtspprefix(struct Curl_easy *data,
3063 const char *s, size_t len)
3065 statusline result = STATUS_BAD;
3066 statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
3068 #ifdef CURL_DOES_CONVERSIONS
3069 /* convert from the network encoding using a scratch area */
3070 char *scratch = strdup(s);
3071 if(NULL == scratch) {
3072 failf(data, "Failed to allocate memory for conversion!");
3073 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
3075 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
3076 /* Curl_convert_from_network calls failf if unsuccessful */
3077 result = FALSE; /* can't return CURLE_foobar so return FALSE */
3079 else if(checkprefixmax("RTSP/", scratch, len))
3083 (void)data; /* unused */
3084 if(checkprefixmax("RTSP/", s, len))
3086 #endif /* CURL_DOES_CONVERSIONS */
3090 #endif /* CURL_DISABLE_RTSP */
3093 checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
3094 const char *s, size_t len)
3096 #ifndef CURL_DISABLE_RTSP
3097 if(conn->handler->protocol & CURLPROTO_RTSP)
3098 return checkrtspprefix(data, s, len);
3101 #endif /* CURL_DISABLE_RTSP */
3103 return checkhttpprefix(data, s, len);
3106 static void print_http_error(struct Curl_easy *data)
3108 struct SingleRequest *k = &data->req;
3109 char *beg = Curl_dyn_ptr(&data->state.headerb);
3111 /* make sure that data->req.p points to the HTTP status line */
3112 if(!strncmp(beg, "HTTP", 4)) {
3114 /* skip to HTTP status code */
3115 beg = strchr(beg, ' ');
3118 /* find trailing CR */
3119 char end_char = '\r';
3120 char *end = strchr(beg, end_char);
3122 /* try to find LF (workaround for non-compliant HTTP servers) */
3124 end = strchr(beg, end_char);
3128 /* temporarily replace CR or LF by NUL and print the error message */
3130 failf(data, "The requested URL returned error: %s", beg);
3132 /* restore the previously replaced CR or LF */
3139 /* fall-back to printing the HTTP status code only */
3140 failf(data, "The requested URL returned error: %d", k->httpcode);
3144 * Read any HTTP header lines from the server and pass them to the client app.
3146 CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
3147 struct connectdata *conn,
3152 struct SingleRequest *k = &data->req;
3153 ssize_t onread = *nread;
3154 char *ostr = k->str;
3159 /* header line within buffer loop */
3165 /* str_start is start of line within buf */
3168 /* data is in network encoding so use 0x0a instead of '\n' */
3169 end_ptr = memchr(str_start, 0x0a, *nread);
3172 /* Not a complete header line within buffer, append the data to
3173 the end of the headerbuff. */
3174 result = Curl_dyn_addn(&data->state.headerb, str_start, *nread);
3178 if(!k->headerline) {
3179 /* check if this looks like a protocol header */
3181 checkprotoprefix(data, conn,
3182 Curl_dyn_ptr(&data->state.headerb),
3183 Curl_dyn_len(&data->state.headerb));
3185 if(st == STATUS_BAD) {
3186 /* this is not the beginning of a protocol first header line */
3188 k->badheader = HEADER_ALLBAD;
3189 streamclose(conn, "bad HTTP: No end-of-message indicator");
3190 if(!data->set.http09_allowed) {
3191 failf(data, "Received HTTP/0.9 when not allowed\n");
3192 return CURLE_UNSUPPORTED_PROTOCOL;
3198 break; /* read more and try again */
3201 /* decrease the size of the remaining (supposed) header line */
3202 rest_length = (end_ptr - k->str) + 1;
3203 *nread -= (ssize_t)rest_length;
3205 k->str = end_ptr + 1; /* move past new line */
3207 full_length = k->str - str_start;
3209 result = Curl_dyn_addn(&data->state.headerb, str_start, full_length);
3214 * We now have a FULL header line in 'headerb'.
3217 if(!k->headerline) {
3218 /* the first read header */
3219 statusline st = checkprotoprefix(data, conn,
3220 Curl_dyn_ptr(&data->state.headerb),
3221 Curl_dyn_len(&data->state.headerb));
3222 if(st == STATUS_BAD) {
3223 streamclose(conn, "bad HTTP: No end-of-message indicator");
3224 /* this is not the beginning of a protocol first header line */
3225 if(!data->set.http09_allowed) {
3226 failf(data, "Received HTTP/0.9 when not allowed\n");
3227 return CURLE_UNSUPPORTED_PROTOCOL;
3231 /* since there's more, this is a partial bad header */
3232 k->badheader = HEADER_PARTHEADER;
3234 /* this was all we read so it's all a bad header */
3235 k->badheader = HEADER_ALLBAD;
3244 /* headers are in network encoding so use 0x0a and 0x0d instead of '\n'
3246 headp = Curl_dyn_ptr(&data->state.headerb);
3247 if((0x0a == *headp) || (0x0d == *headp)) {
3249 /* Zero-length header line means end of headers! */
3251 #ifdef CURL_DOES_CONVERSIONS
3252 if(0x0d == *headp) {
3253 *headp = '\r'; /* replace with CR in host encoding */
3254 headp++; /* pass the CR byte */
3256 if(0x0a == *headp) {
3257 *headp = '\n'; /* replace with LF in host encoding */
3258 headp++; /* pass the LF byte */
3262 headp++; /* pass the \r byte */
3264 headp++; /* pass the \n byte */
3265 #endif /* CURL_DOES_CONVERSIONS */
3267 if(100 <= k->httpcode && 199 >= k->httpcode) {
3268 /* "A user agent MAY ignore unexpected 1xx status responses." */
3269 switch(k->httpcode) {
3272 * We have made a HTTP PUT or POST and this is 1.1-lingo
3273 * that tells us that the server is OK with this and ready
3274 * to receive the data.
3275 * However, we'll get more headers now so we must get
3276 * back into the header-parsing state!
3279 k->headerline = 0; /* restart the header line counter */
3281 /* if we did wait for this do enable write now! */
3282 if(k->exp100 > EXP100_SEND_DATA) {
3283 k->exp100 = EXP100_SEND_DATA;
3284 k->keepon |= KEEP_SEND;
3285 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
3289 /* Switching Protocols */
3290 if(k->upgr101 == UPGR101_REQUESTED) {
3291 /* Switching to HTTP/2 */
3292 infof(data, "Received 101\n");
3293 k->upgr101 = UPGR101_RECEIVED;
3295 /* we'll get more headers (HTTP/2 response) */
3297 k->headerline = 0; /* restart the header line counter */
3299 /* switch to http2 now. The bytes after response headers
3300 are also processed here, otherwise they are lost. */
3301 result = Curl_http2_switched(conn, k->str, *nread);
3307 /* Switching to another protocol (e.g. WebSocket) */
3308 k->header = FALSE; /* no more header to parse! */
3312 /* the status code 1xx indicates a provisional response, so
3313 we'll get another set of headers */
3315 k->headerline = 0; /* restart the header line counter */
3320 k->header = FALSE; /* no more header to parse! */
3322 if((k->size == -1) && !k->chunk && !conn->bits.close &&
3323 (conn->httpversion == 11) &&
3324 !(conn->handler->protocol & CURLPROTO_RTSP) &&
3325 data->state.httpreq != HTTPREQ_HEAD) {
3326 /* On HTTP 1.1, when connection is not to get closed, but no
3327 Content-Length nor Transfer-Encoding chunked have been
3328 received, according to RFC2616 section 4.4 point 5, we
3329 assume that the server will close the connection to
3330 signal the end of the document. */
3331 infof(data, "no chunk, no close, no size. Assume close to "
3333 streamclose(conn, "HTTP: No end-of-message indicator");
3337 /* At this point we have some idea about the fate of the connection.
3338 If we are closing the connection it may result auth failure. */
3339 #if defined(USE_NTLM)
3340 if(conn->bits.close &&
3341 (((data->req.httpcode == 401) &&
3342 (conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
3343 ((data->req.httpcode == 407) &&
3344 (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
3345 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
3346 data->state.authproblem = TRUE;
3349 #if defined(USE_SPNEGO)
3350 if(conn->bits.close &&
3351 (((data->req.httpcode == 401) &&
3352 (conn->http_negotiate_state == GSS_AUTHRECV)) ||
3353 ((data->req.httpcode == 407) &&
3354 (conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
3355 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)\n");
3356 data->state.authproblem = TRUE;
3358 if((conn->http_negotiate_state == GSS_AUTHDONE) &&
3359 (data->req.httpcode != 401)) {
3360 conn->http_negotiate_state = GSS_AUTHSUCC;
3362 if((conn->proxy_negotiate_state == GSS_AUTHDONE) &&
3363 (data->req.httpcode != 407)) {
3364 conn->proxy_negotiate_state = GSS_AUTHSUCC;
3368 * When all the headers have been parsed, see if we should give
3369 * up and return an error.
3371 if(http_should_fail(conn)) {
3372 failf(data, "The requested URL returned error: %d",
3374 return CURLE_HTTP_RETURNED_ERROR;
3377 /* now, only output this if the header AND body are requested:
3379 writetype = CLIENTWRITE_HEADER;
3380 if(data->set.include_header)
3381 writetype |= CLIENTWRITE_BODY;
3383 headerlen = Curl_dyn_len(&data->state.headerb);
3384 result = Curl_client_write(conn, writetype,
3385 Curl_dyn_ptr(&data->state.headerb),
3390 data->info.header_size += (long)headerlen;
3391 data->req.headerbytecount += (long)headerlen;
3393 data->req.deductheadercount =
3394 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
3396 /* Curl_http_auth_act() checks what authentication methods
3397 * that are available and decides which one (if any) to
3398 * use. It will set 'newurl' if an auth method was picked. */
3399 result = Curl_http_auth_act(conn);
3404 if(k->httpcode >= 300) {
3405 if((!conn->bits.authneg) && !conn->bits.close &&
3406 !conn->bits.rewindaftersend) {
3408 * General treatment of errors when about to send data. Including :
3409 * "417 Expectation Failed", while waiting for 100-continue.
3411 * The check for close above is done simply because of something
3412 * else has already deemed the connection to get closed then
3413 * something else should've considered the big picture and we
3416 * rewindaftersend indicates that something has told libcurl to
3417 * continue sending even if it gets discarded
3420 switch(data->state.httpreq) {
3423 case HTTPREQ_POST_FORM:
3424 case HTTPREQ_POST_MIME:
3425 /* We got an error response. If this happened before the whole
3426 * request body has been sent we stop sending and mark the
3427 * connection for closure after we've read the entire response.
3429 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
3430 if(!k->upload_done) {
3431 if((k->httpcode == 417) && data->state.expect100header) {
3432 /* 417 Expectation Failed - try again without the Expect
3434 infof(data, "Got 417 while waiting for a 100\n");
3435 data->state.disableexpect = TRUE;
3436 DEBUGASSERT(!data->req.newurl);
3437 data->req.newurl = strdup(conn->data->change.url);
3438 Curl_done_sending(conn, k);
3440 else if(data->set.http_keep_sending_on_error) {
3441 infof(data, "HTTP error before end of send, keep sending\n");
3442 if(k->exp100 > EXP100_SEND_DATA) {
3443 k->exp100 = EXP100_SEND_DATA;
3444 k->keepon |= KEEP_SEND;
3448 infof(data, "HTTP error before end of send, stop sending\n");
3449 streamclose(conn, "Stop sending data before everything sent");
3450 result = Curl_done_sending(conn, k);
3453 k->upload_done = TRUE;
3454 if(data->state.expect100header)
3455 k->exp100 = EXP100_FAILED;
3460 default: /* default label present to avoid compiler warnings */
3465 if(conn->bits.rewindaftersend) {
3466 /* We rewind after a complete send, so thus we continue
3468 infof(data, "Keep sending data to get tossed away!\n");
3469 k->keepon |= KEEP_SEND;
3475 * really end-of-headers.
3477 * If we requested a "no body", this is a good time to get
3478 * out and return home.
3480 if(data->set.opt_no_body)
3481 *stop_reading = TRUE;
3482 #ifndef CURL_DISABLE_RTSP
3483 else if((conn->handler->protocol & CURLPROTO_RTSP) &&
3484 (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
3486 /* Respect section 4.4 of rfc2326: If the Content-Length header is
3487 absent, a length 0 must be assumed. It will prevent libcurl from
3488 hanging on DESCRIBE request that got refused for whatever
3490 *stop_reading = TRUE;
3493 /* If we know the expected size of this document, we set the
3494 maximum download size to the size of the expected
3495 document or else, we won't know when to stop reading!
3497 Note that we set the download maximum even if we read a
3498 "Connection: close" header, to make sure that
3499 "Content-Length: 0" still prevents us from attempting to
3500 read the (missing) response-body.
3502 /* According to RFC2616 section 4.4, we MUST ignore
3503 Content-Length: headers if we are now receiving data
3504 using chunked Transfer-Encoding.
3507 k->maxdownload = k->size = -1;
3510 /* We do this operation even if no_body is true, since this
3511 data might be retrieved later with curl_easy_getinfo()
3512 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3514 Curl_pgrsSetDownloadSize(data, k->size);
3515 k->maxdownload = k->size;
3518 /* If max download size is *zero* (nothing) we already have
3519 nothing and can safely return ok now! But for HTTP/2, we'd
3520 like to call http2_handle_stream_close to properly close a
3521 stream. In order to do this, we keep reading until we
3522 close the stream. */
3523 if(0 == k->maxdownload
3524 #if defined(USE_NGHTTP2)
3525 && !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
3526 conn->httpversion == 20)
3529 *stop_reading = TRUE;
3532 /* we make sure that this socket isn't read more now */
3533 k->keepon &= ~KEEP_RECV;
3536 if(data->set.verbose)
3537 Curl_debug(data, CURLINFO_HEADER_IN,
3538 str_start, headerlen);
3539 break; /* exit header line loop */
3542 /* We continue reading headers, reset the line-based header */
3543 Curl_dyn_reset(&data->state.headerb);
3548 * Checks for special headers coming up.
3551 if(!k->headerline++) {
3552 /* This is the first header, it MUST be the error code line
3553 or else we consider this to be the body right away! */
3554 int httpversion_major;
3555 int rtspversion_major;
3557 #ifdef CURL_DOES_CONVERSIONS
3558 #define HEADER1 scratch
3559 #define SCRATCHSIZE 21
3561 char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */
3562 /* We can't really convert this yet because we don't know if it's the
3563 1st header line or the body. So we do a partial conversion into a
3564 scratch area, leaving the data at 'headp' as-is.
3566 strncpy(&scratch[0], headp, SCRATCHSIZE);
3567 scratch[SCRATCHSIZE] = 0; /* null terminate */
3568 res = Curl_convert_from_network(data,
3572 /* Curl_convert_from_network calls failf if unsuccessful */
3575 #define HEADER1 headp /* no conversion needed, just use headp */
3576 #endif /* CURL_DOES_CONVERSIONS */
3578 if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
3580 * https://tools.ietf.org/html/rfc7230#section-3.1.2
3582 * The response code is always a three-digit number in HTTP as the spec
3583 * says. We try to allow any number here, but we cannot make
3584 * guarantees on future behaviors since it isn't within the protocol.
3588 nc = sscanf(HEADER1,
3589 " HTTP/%1d.%1d%c%3d",
3595 if(nc == 1 && httpversion_major >= 2 &&
3596 2 == sscanf(HEADER1, " HTTP/%1[23] %d", twoorthree, &k->httpcode)) {
3597 conn->httpversion = 0;
3602 if((nc == 4) && (' ' == separator)) {
3603 conn->httpversion += 10 * httpversion_major;
3605 if(k->upgr101 == UPGR101_RECEIVED) {
3606 /* supposedly upgraded to http2 now */
3607 if(conn->httpversion != 20)
3608 infof(data, "Lying server, not serving HTTP/2\n");
3610 if(conn->httpversion < 20) {
3611 conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
3612 infof(data, "Mark bundle as not supporting multiuse\n");
3616 /* this is the real world, not a Nirvana
3617 NCSA 1.5.x returns this crap when asked for HTTP/1.1
3619 nc = sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3620 conn->httpversion = 10;
3622 /* If user has set option HTTP200ALIASES,
3623 compare header line against list of aliases
3627 checkhttpprefix(data,
3628 Curl_dyn_ptr(&data->state.headerb),
3629 Curl_dyn_len(&data->state.headerb));
3630 if(check == STATUS_DONE) {
3633 conn->httpversion = 10;
3638 failf(data, "Unsupported HTTP version in response");
3639 return CURLE_UNSUPPORTED_PROTOCOL;
3642 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3644 nc = sscanf(HEADER1,
3645 " RTSP/%1d.%1d%c%3d",
3650 if((nc == 4) && (' ' == separator)) {
3651 conn->rtspversion += 10 * rtspversion_major;
3652 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3660 data->info.httpcode = k->httpcode;
3662 data->info.httpversion = conn->httpversion;
3663 if(!data->state.httpversion ||
3664 data->state.httpversion > conn->httpversion)
3665 /* store the lowest server version we encounter */
3666 data->state.httpversion = conn->httpversion;
3669 * This code executes as part of processing the header. As a
3670 * result, it's not totally clear how to interpret the
3671 * response code yet as that depends on what other headers may
3672 * be present. 401 and 407 may be errors, but may be OK
3673 * depending on how authentication is working. Other codes
3674 * are definitely errors, so give up here.
3676 if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET &&
3677 k->httpcode == 416) {
3678 /* "Requested Range Not Satisfiable", just proceed and
3679 pretend this is no error */
3680 k->ignorebody = TRUE; /* Avoid appending error msg to good data. */
3682 else if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3683 ((k->httpcode != 401) || !conn->bits.user_passwd)
3684 #ifndef CURL_DISABLE_PROXY
3685 && ((k->httpcode != 407) || !conn->bits.proxy_user_passwd)
3688 /* serious error, go home! */
3689 print_http_error(data);
3690 return CURLE_HTTP_RETURNED_ERROR;
3693 if(conn->httpversion == 10) {
3694 /* Default action for HTTP/1.0 must be to close, unless
3695 we get one of those fancy headers that tell us the
3696 server keeps it open for us! */
3697 infof(data, "HTTP 1.0, assume close after body\n");
3698 connclose(conn, "HTTP/1.0 close after body");
3700 else if(conn->httpversion == 20 ||
3701 (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
3702 DEBUGF(infof(data, "HTTP/2 found, allow multiplexing\n"));
3703 /* HTTP/2 cannot avoid multiplexing since it is a core functionality
3705 conn->bundle->multiuse = BUNDLE_MULTIPLEX;
3707 else if(conn->httpversion >= 11 &&
3708 !conn->bits.close) {
3709 /* If HTTP version is >= 1.1 and connection is persistent */
3711 "HTTP 1.1 or later with persistent connection\n"));
3714 k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200;
3715 switch(k->httpcode) {
3717 /* (quote from RFC2616, section 10.3.5): The 304 response
3718 * MUST NOT contain a message-body, and thus is always
3719 * terminated by the first empty line after the header
3721 if(data->set.timecondition)
3722 data->info.timecond = TRUE;
3725 /* (quote from RFC2616, section 10.2.5): The server has
3726 * fulfilled the request but does not need to return an
3727 * entity-body ... The 204 response MUST NOT include a
3728 * message-body, and thus is always terminated by the first
3729 * empty line after the header fields. */
3732 k->http_bodyless = TRUE;
3739 k->header = FALSE; /* this is not a header line */
3744 result = Curl_convert_from_network(data, headp, strlen(headp));
3745 /* Curl_convert_from_network calls failf if unsuccessful */
3749 /* Check for Content-Length: header lines to get size */
3750 if(!k->http_bodyless &&
3751 !data->set.ignorecl && checkprefix("Content-Length:", headp)) {
3752 curl_off_t contentlength;
3753 CURLofft offt = curlx_strtoofft(headp + 15, NULL, 10, &contentlength);
3755 if(offt == CURL_OFFT_OK) {
3756 if(data->set.max_filesize &&
3757 contentlength > data->set.max_filesize) {
3758 failf(data, "Maximum file size exceeded");
3759 return CURLE_FILESIZE_EXCEEDED;
3761 k->size = contentlength;
3762 k->maxdownload = k->size;
3763 /* we set the progress download size already at this point
3764 just to make it easier for apps/callbacks to extract this
3765 info as soon as possible */
3766 Curl_pgrsSetDownloadSize(data, k->size);
3768 else if(offt == CURL_OFFT_FLOW) {
3770 if(data->set.max_filesize) {
3771 failf(data, "Maximum file size exceeded");
3772 return CURLE_FILESIZE_EXCEEDED;
3774 streamclose(conn, "overflow content-length");
3775 infof(data, "Overflow Content-Length: value!\n");
3778 /* negative or just rubbish - bad HTTP */
3779 failf(data, "Invalid Content-Length: value");
3780 return CURLE_WEIRD_SERVER_REPLY;
3783 /* check for Content-Type: header lines to get the MIME-type */
3784 else if(checkprefix("Content-Type:", headp)) {
3785 char *contenttype = Curl_copy_header_value(headp);
3787 return CURLE_OUT_OF_MEMORY;
3789 /* ignore empty data */
3792 Curl_safefree(data->info.contenttype);
3793 data->info.contenttype = contenttype;
3796 #ifndef CURL_DISABLE_PROXY
3797 else if((conn->httpversion == 10) &&
3798 conn->bits.httpproxy &&
3799 Curl_compareheader(headp, "Proxy-Connection:", "keep-alive")) {
3801 * When a HTTP/1.0 reply comes when using a proxy, the
3802 * 'Proxy-Connection: keep-alive' line tells us the
3803 * connection will be kept alive for our pleasure.
3804 * Default action for 1.0 is to close.
3806 connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
3807 infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3809 else if((conn->httpversion == 11) &&
3810 conn->bits.httpproxy &&
3811 Curl_compareheader(headp, "Proxy-Connection:", "close")) {
3813 * We get a HTTP/1.1 response from a proxy and it says it'll
3814 * close down after this transfer.
3816 connclose(conn, "Proxy-Connection: asked to close after done");
3817 infof(data, "HTTP/1.1 proxy connection set close!\n");
3820 else if((conn->httpversion == 10) &&
3821 Curl_compareheader(headp, "Connection:", "keep-alive")) {
3823 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3824 * tells us the connection will be kept alive for our
3825 * pleasure. Default action for 1.0 is to close.
3827 * [RFC2068, section 19.7.1] */
3828 connkeep(conn, "Connection keep-alive");
3829 infof(data, "HTTP/1.0 connection set to keep alive!\n");
3831 else if(Curl_compareheader(headp, "Connection:", "close")) {
3833 * [RFC 2616, section 8.1.2.1]
3834 * "Connection: close" is HTTP/1.1 language and means that
3835 * the connection will close when this request has been
3838 streamclose(conn, "Connection: close used");
3840 else if(!k->http_bodyless && checkprefix("Transfer-Encoding:", headp)) {
3841 /* One or more encodings. We check for chunked and/or a compression
3844 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3845 * means that the server will send a series of "chunks". Each
3846 * chunk starts with line with info (including size of the
3847 * coming block) (terminated with CRLF), then a block of data
3848 * with the previously mentioned size. There can be any amount
3849 * of chunks, and a chunk-data set to zero signals the
3852 result = Curl_build_unencoding_stack(conn, headp + 18, TRUE);
3856 else if(!k->http_bodyless && checkprefix("Content-Encoding:", headp) &&
3857 data->set.str[STRING_ENCODING]) {
3859 * Process Content-Encoding. Look for the values: identity,
3860 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3861 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3862 * 2616). zlib cannot handle compress. However, errors are
3863 * handled further down when the response body is processed
3865 result = Curl_build_unencoding_stack(conn, headp + 17, FALSE);
3869 else if(checkprefix("Retry-After:", headp)) {
3870 /* Retry-After = HTTP-date / delay-seconds */
3871 curl_off_t retry_after = 0; /* zero for unknown or "now" */
3872 time_t date = Curl_getdate_capped(&headp[12]);
3874 /* not a date, try it as a decimal number */
3875 (void)curlx_strtoofft(&headp[12], NULL, 10, &retry_after);
3878 /* convert date to number of seconds into the future */
3879 retry_after = date - time(NULL);
3880 data->info.retry_after = retry_after; /* store it */
3882 else if(!k->http_bodyless && checkprefix("Content-Range:", headp)) {
3883 /* Content-Range: bytes [num]-
3884 Content-Range: bytes: [num]-
3885 Content-Range: [num]-
3886 Content-Range: [asterisk]/[total]
3888 The second format was added since Sun's webserver
3889 JavaWebServer/1.1.1 obviously sends the header this way!
3890 The third added since some servers use that!
3891 The forth means the requested range was unsatisfied.
3894 char *ptr = headp + 14;
3896 /* Move forward until first digit or asterisk */
3897 while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
3900 /* if it truly stopped on a digit */
3902 if(!curlx_strtoofft(ptr, NULL, 10, &k->offset)) {
3903 if(data->state.resume_from == k->offset)
3904 /* we asked for a resume and we got it */
3905 k->content_range = TRUE;
3909 data->state.resume_from = 0; /* get everything */
3911 #if !defined(CURL_DISABLE_COOKIES)
3912 else if(data->cookies && data->state.cookie_engine &&
3913 checkprefix("Set-Cookie:", headp)) {
3914 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3915 CURL_LOCK_ACCESS_SINGLE);
3916 Curl_cookie_add(data,
3917 data->cookies, TRUE, FALSE, headp + 11,
3918 /* If there is a custom-set Host: name, use it
3919 here, or else use real peer host name. */
3920 data->state.aptr.cookiehost?
3921 data->state.aptr.cookiehost:conn->host.name,
3922 data->state.up.path,
3923 (conn->handler->protocol&CURLPROTO_HTTPS)?
3925 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3928 else if(!k->http_bodyless && checkprefix("Last-Modified:", headp) &&
3929 (data->set.timecondition || data->set.get_filetime) ) {
3930 k->timeofdoc = Curl_getdate_capped(headp + strlen("Last-Modified:"));
3931 if(data->set.get_filetime)
3932 data->info.filetime = k->timeofdoc;
3934 else if((checkprefix("WWW-Authenticate:", headp) &&
3935 (401 == k->httpcode)) ||
3936 (checkprefix("Proxy-authenticate:", headp) &&
3937 (407 == k->httpcode))) {
3939 bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3940 char *auth = Curl_copy_header_value(headp);
3942 return CURLE_OUT_OF_MEMORY;
3944 result = Curl_http_input_auth(conn, proxy, auth);
3952 else if(checkprefix("Persistent-Auth", headp)) {
3953 struct negotiatedata *negdata = &conn->negotiate;
3954 struct auth *authp = &data->state.authhost;
3955 if(authp->picked == CURLAUTH_NEGOTIATE) {
3956 char *persistentauth = Curl_copy_header_value(headp);
3958 return CURLE_OUT_OF_MEMORY;
3959 negdata->noauthpersist = checkprefix("false", persistentauth)?
3961 negdata->havenoauthpersist = TRUE;
3962 infof(data, "Negotiate: noauthpersist -> %d, header part: %s",
3963 negdata->noauthpersist, persistentauth);
3964 free(persistentauth);
3968 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3969 checkprefix("Location:", headp) &&
3970 !data->req.location) {
3971 /* this is the URL that the server advises us to use instead */
3972 char *location = Curl_copy_header_value(headp);
3974 return CURLE_OUT_OF_MEMORY;
3976 /* ignore empty data */
3979 data->req.location = location;
3981 if(data->set.http_follow_location) {
3982 DEBUGASSERT(!data->req.newurl);
3983 data->req.newurl = strdup(data->req.location); /* clone */
3984 if(!data->req.newurl)
3985 return CURLE_OUT_OF_MEMORY;
3987 /* some cases of POST and PUT etc needs to rewind the data
3988 stream at this point */
3989 result = http_perhapsrewind(conn);
3996 /* If enabled, the header is incoming and this is over HTTPS */
3997 else if(data->asi && checkprefix("Alt-Svc:", headp) &&
3998 ((conn->handler->flags & PROTOPT_SSL) ||
4000 /* allow debug builds to circumvent the HTTPS restriction */
4001 getenv("CURL_ALTSVC_HTTP")
4006 /* the ALPN of the current request */
4007 enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
4008 result = Curl_altsvc_parse(data, data->asi,
4009 &headp[ strlen("Alt-Svc:") ],
4010 id, conn->host.name,
4011 curlx_uitous(conn->remote_port));
4016 else if(conn->handler->protocol & CURLPROTO_RTSP) {
4017 result = Curl_rtsp_parseheader(conn, headp);
4023 * End of header-checks. Write them to the client.
4026 writetype = CLIENTWRITE_HEADER;
4027 if(data->set.include_header)
4028 writetype |= CLIENTWRITE_BODY;
4030 if(data->set.verbose)
4031 Curl_debug(data, CURLINFO_HEADER_IN, headp,
4032 Curl_dyn_len(&data->state.headerb));
4034 result = Curl_client_write(conn, writetype, headp,
4035 Curl_dyn_len(&data->state.headerb));
4039 data->info.header_size += Curl_dyn_len(&data->state.headerb);
4040 data->req.headerbytecount += Curl_dyn_len(&data->state.headerb);
4042 Curl_dyn_reset(&data->state.headerb);
4044 while(*k->str); /* header line within buffer */
4046 /* We might have reached the end of the header part here, but
4047 there might be a non-header part left in the end of the read
4053 #endif /* CURL_DISABLE_HTTP */