1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
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.se/docs/copyright.html.
13 *
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.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ***************************************************************************/
22
23#include "curl_setup.h"
24
25#ifndef CURL_DISABLE_HTTP
26
27#ifdef HAVE_NETINET_IN_H
28#include <netinet/in.h>
29#endif
30
31#ifdef HAVE_NETDB_H
32#include <netdb.h>
33#endif
34#ifdef HAVE_ARPA_INET_H
35#include <arpa/inet.h>
36#endif
37#ifdef HAVE_NET_IF_H
38#include <net/if.h>
39#endif
40#ifdef HAVE_SYS_IOCTL_H
41#include <sys/ioctl.h>
42#endif
43
44#ifdef HAVE_SYS_PARAM_H
45#include <sys/param.h>
46#endif
47
48#ifdef USE_HYPER
49#include <hyper.h>
50#endif
51
52#include "urldata.h"
53#include <curl/curl.h>
54#include "transfer.h"
55#include "sendf.h"
56#include "formdata.h"
57#include "mime.h"
58#include "progress.h"
59#include "curl_base64.h"
60#include "cookie.h"
61#include "vauth/vauth.h"
62#include "vtls/vtls.h"
63#include "http_digest.h"
64#include "http_ntlm.h"
65#include "curl_ntlm_wb.h"
66#include "http_negotiate.h"
67#include "http_aws_sigv4.h"
68#include "url.h"
69#include "share.h"
70#include "hostip.h"
71#include "http.h"
72#include "select.h"
73#include "parsedate.h" /* for the week day and month names */
74#include "strtoofft.h"
75#include "multiif.h"
76#include "strcase.h"
77#include "content_encoding.h"
78#include "http_proxy.h"
79#include "warnless.h"
80#include "non-ascii.h"
81#include "http2.h"
82#include "connect.h"
83#include "strdup.h"
84#include "altsvc.h"
85#include "hsts.h"
86#include "c-hyper.h"
87
88/* The last 3 #include files should be in this order */
89#include "curl_printf.h"
90#include "curl_memory.h"
91#include "memdebug.h"
92
93/*
94 * Forward declarations.
95 */
96
97static int http_getsock_do(struct Curl_easy *data,
98 struct connectdata *conn,
99 curl_socket_t *socks);
100static bool http_should_fail(struct Curl_easy *data);
101
102#ifndef CURL_DISABLE_PROXY
103static CURLcode add_haproxy_protocol_header(struct Curl_easy *data);
104#endif
105
106#ifdef USE_SSL
107static CURLcode https_connecting(struct Curl_easy *data, bool *done);
108static int https_getsock(struct Curl_easy *data,
109 struct connectdata *conn,
110 curl_socket_t *socks);
111#else
112#define https_connecting(x,y) CURLE_COULDNT_CONNECT
113#endif
114static CURLcode http_setup_conn(struct Curl_easy *data,
115 struct connectdata *conn);
116
117/*
118 * HTTP handler interface.
119 */
120const struct Curl_handler Curl_handler_http = {
121 "HTTP", /* scheme */
122 http_setup_conn, /* setup_connection */
123 Curl_http, /* do_it */
124 Curl_http_done, /* done */
125 ZERO_NULL, /* do_more */
126 Curl_http_connect, /* connect_it */
127 ZERO_NULL, /* connecting */
128 ZERO_NULL, /* doing */
129 ZERO_NULL, /* proto_getsock */
130 http_getsock_do, /* doing_getsock */
131 ZERO_NULL, /* domore_getsock */
132 ZERO_NULL, /* perform_getsock */
133 ZERO_NULL, /* disconnect */
134 ZERO_NULL, /* readwrite */
135 ZERO_NULL, /* connection_check */
136 ZERO_NULL, /* attach connection */
137 PORT_HTTP, /* defport */
138 CURLPROTO_HTTP, /* protocol */
139 CURLPROTO_HTTP, /* family */
140 PROTOPT_CREDSPERREQUEST | /* flags */
141 PROTOPT_USERPWDCTRL
142};
143
144#ifdef USE_SSL
145/*
146 * HTTPS handler interface.
147 */
148const struct Curl_handler Curl_handler_https = {
149 "HTTPS", /* scheme */
150 http_setup_conn, /* setup_connection */
151 Curl_http, /* do_it */
152 Curl_http_done, /* done */
153 ZERO_NULL, /* do_more */
154 Curl_http_connect, /* connect_it */
155 https_connecting, /* connecting */
156 ZERO_NULL, /* doing */
157 https_getsock, /* proto_getsock */
158 http_getsock_do, /* doing_getsock */
159 ZERO_NULL, /* domore_getsock */
160 ZERO_NULL, /* perform_getsock */
161 ZERO_NULL, /* disconnect */
162 ZERO_NULL, /* readwrite */
163 ZERO_NULL, /* connection_check */
164 ZERO_NULL, /* attach connection */
165 PORT_HTTPS, /* defport */
166 CURLPROTO_HTTPS, /* protocol */
167 CURLPROTO_HTTP, /* family */
168 PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN_NPN | /* flags */
169 PROTOPT_USERPWDCTRL
170};
171#endif
172
173static CURLcode http_setup_conn(struct Curl_easy *data,
174 struct connectdata *conn)
175{
176 /* allocate the HTTP-specific struct for the Curl_easy, only to survive
177 during this request */
178 struct HTTP *http;
179 DEBUGASSERT(data->req.p.http == NULL);
180
181 http = calloc(1, sizeof(struct HTTP));
182 if(!http)
183 return CURLE_OUT_OF_MEMORY;
184
185 Curl_mime_initpart(&http->form, data);
186 data->req.p.http = http;
187
188 if(data->state.httpwant == CURL_HTTP_VERSION_3) {
189 if(conn->handler->flags & PROTOPT_SSL)
190 /* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does
191 the QUIC dance. */
192 conn->transport = TRNSPRT_QUIC;
193 else {
194 failf(data, "HTTP/3 requested for non-HTTPS URL");
195 return CURLE_URL_MALFORMAT;
196 }
197 }
198 else {
199 if(!CONN_INUSE(conn))
200 /* if not already multi-using, setup connection details */
201 Curl_http2_setup_conn(conn);
202 Curl_http2_setup_req(data);
203 }
204 return CURLE_OK;
205}
206
207#ifndef CURL_DISABLE_PROXY
208/*
209 * checkProxyHeaders() checks the linked list of custom proxy headers
210 * if proxy headers are not available, then it will lookup into http header
211 * link list
212 *
213 * It takes a connectdata struct as input to see if this is a proxy request or
214 * not, as it then might check a different header list. Provide the header
215 * prefix without colon!
216 */
217char *Curl_checkProxyheaders(struct Curl_easy *data,
218 const struct connectdata *conn,
219 const char *thisheader)
220{
221 struct curl_slist *head;
222 size_t thislen = strlen(thisheader);
223
224 for(head = (conn->bits.proxy && data->set.sep_headers) ?
225 data->set.proxyheaders : data->set.headers;
226 head; head = head->next) {
227 if(strncasecompare(head->data, thisheader, thislen) &&
228 Curl_headersep(head->data[thislen]))
229 return head->data;
230 }
231
232 return NULL;
233}
234#else
235/* disabled */
236#define Curl_checkProxyheaders(x,y,z) NULL
237#endif
238
239/*
240 * Strip off leading and trailing whitespace from the value in the
241 * given HTTP header line and return a strdupped copy. Returns NULL in
242 * case of allocation failure. Returns an empty string if the header value
243 * consists entirely of whitespace.
244 */
245char *Curl_copy_header_value(const char *header)
246{
247 const char *start;
248 const char *end;
249 char *value;
250 size_t len;
251
252 /* Find the end of the header name */
253 while(*header && (*header != ':'))
254 ++header;
255
256 if(*header)
257 /* Skip over colon */
258 ++header;
259
260 /* Find the first non-space letter */
261 start = header;
262 while(*start && ISSPACE(*start))
263 start++;
264
265 /* data is in the host encoding so
266 use '\r' and '\n' instead of 0x0d and 0x0a */
267 end = strchr(start, '\r');
268 if(!end)
269 end = strchr(start, '\n');
270 if(!end)
271 end = strchr(start, '\0');
272 if(!end)
273 return NULL;
274
275 /* skip all trailing space letters */
276 while((end > start) && ISSPACE(*end))
277 end--;
278
279 /* get length of the type */
280 len = end - start + 1;
281
282 value = malloc(len + 1);
283 if(!value)
284 return NULL;
285
286 memcpy(value, start, len);
287 value[len] = 0; /* null-terminate */
288
289 return value;
290}
291
292#ifndef CURL_DISABLE_HTTP_AUTH
293/*
294 * http_output_basic() sets up an Authorization: header (or the proxy version)
295 * for HTTP Basic authentication.
296 *
297 * Returns CURLcode.
298 */
299static CURLcode http_output_basic(struct Curl_easy *data, bool proxy)
300{
301 size_t size = 0;
302 char *authorization = NULL;
303 char **userp;
304 const char *user;
305 const char *pwd;
306 CURLcode result;
307 char *out;
308
309 /* credentials are unique per transfer for HTTP, do not use the ones for the
310 connection */
311 if(proxy) {
312#ifndef CURL_DISABLE_PROXY
313 userp = &data->state.aptr.proxyuserpwd;
314 user = data->state.aptr.proxyuser;
315 pwd = data->state.aptr.proxypasswd;
316#else
317 return CURLE_NOT_BUILT_IN;
318#endif
319 }
320 else {
321 userp = &data->state.aptr.userpwd;
322 user = data->state.aptr.user;
323 pwd = data->state.aptr.passwd;
324 }
325
326 out = aprintf("%s:%s", user, pwd ? pwd : "");
327 if(!out)
328 return CURLE_OUT_OF_MEMORY;
329
330 result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
331 if(result)
332 goto fail;
333
334 if(!authorization) {
335 result = CURLE_REMOTE_ACCESS_DENIED;
336 goto fail;
337 }
338
339 free(*userp);
340 *userp = aprintf("%sAuthorization: Basic %s\r\n",
341 proxy ? "Proxy-" : "",
342 authorization);
343 free(authorization);
344 if(!*userp) {
345 result = CURLE_OUT_OF_MEMORY;
346 goto fail;
347 }
348
349 fail:
350 free(out);
351 return result;
352}
353
354/*
355 * http_output_bearer() sets up an Authorization: header
356 * for HTTP Bearer authentication.
357 *
358 * Returns CURLcode.
359 */
360static CURLcode http_output_bearer(struct Curl_easy *data)
361{
362 char **userp;
363 CURLcode result = CURLE_OK;
364
365 userp = &data->state.aptr.userpwd;
366 free(*userp);
367 *userp = aprintf("Authorization: Bearer %s\r\n",
368 data->set.str[STRING_BEARER]);
369
370 if(!*userp) {
371 result = CURLE_OUT_OF_MEMORY;
372 goto fail;
373 }
374
375 fail:
376 return result;
377}
378
379#endif
380
381/* pickoneauth() selects the most favourable authentication method from the
382 * ones available and the ones we want.
383 *
384 * return TRUE if one was picked
385 */
386static bool pickoneauth(struct auth *pick, unsigned long mask)
387{
388 bool picked;
389 /* only deal with authentication we want */
390 unsigned long avail = pick->avail & pick->want & mask;
391 picked = TRUE;
392
393 /* The order of these checks is highly relevant, as this will be the order
394 of preference in case of the existence of multiple accepted types. */
395 if(avail & CURLAUTH_NEGOTIATE)
396 pick->picked = CURLAUTH_NEGOTIATE;
397 else if(avail & CURLAUTH_BEARER)
398 pick->picked = CURLAUTH_BEARER;
399 else if(avail & CURLAUTH_DIGEST)
400 pick->picked = CURLAUTH_DIGEST;
401 else if(avail & CURLAUTH_NTLM)
402 pick->picked = CURLAUTH_NTLM;
403 else if(avail & CURLAUTH_NTLM_WB)
404 pick->picked = CURLAUTH_NTLM_WB;
405 else if(avail & CURLAUTH_BASIC)
406 pick->picked = CURLAUTH_BASIC;
407 else if(avail & CURLAUTH_AWS_SIGV4)
408 pick->picked = CURLAUTH_AWS_SIGV4;
409 else {
410 pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
411 picked = FALSE;
412 }
413 pick->avail = CURLAUTH_NONE; /* clear it here */
414
415 return picked;
416}
417
418/*
419 * http_perhapsrewind()
420 *
421 * If we are doing POST or PUT {
422 * If we have more data to send {
423 * If we are doing NTLM {
424 * Keep sending since we must not disconnect
425 * }
426 * else {
427 * If there is more than just a little data left to send, close
428 * the current connection by force.
429 * }
430 * }
431 * If we have sent any data {
432 * If we don't have track of all the data {
433 * call app to tell it to rewind
434 * }
435 * else {
436 * rewind internally so that the operation can restart fine
437 * }
438 * }
439 * }
440 */
441static CURLcode http_perhapsrewind(struct Curl_easy *data,
442 struct connectdata *conn)
443{
444 struct HTTP *http = data->req.p.http;
445 curl_off_t bytessent;
446 curl_off_t expectsend = -1; /* default is unknown */
447
448 if(!http)
449 /* If this is still NULL, we have not reach very far and we can safely
450 skip this rewinding stuff */
451 return CURLE_OK;
452
453 switch(data->state.httpreq) {
454 case HTTPREQ_GET:
455 case HTTPREQ_HEAD:
456 return CURLE_OK;
457 default:
458 break;
459 }
460
461 bytessent = data->req.writebytecount;
462
463 if(conn->bits.authneg) {
464 /* This is a state where we are known to be negotiating and we don't send
465 any data then. */
466 expectsend = 0;
467 }
468 else if(!conn->bits.protoconnstart) {
469 /* HTTP CONNECT in progress: there is no body */
470 expectsend = 0;
471 }
472 else {
473 /* figure out how much data we are expected to send */
474 switch(data->state.httpreq) {
475 case HTTPREQ_POST:
476 case HTTPREQ_PUT:
477 if(data->state.infilesize != -1)
478 expectsend = data->state.infilesize;
479 break;
480 case HTTPREQ_POST_FORM:
481 case HTTPREQ_POST_MIME:
482 expectsend = http->postsize;
483 break;
484 default:
485 break;
486 }
487 }
488
489 conn->bits.rewindaftersend = FALSE; /* default */
490
491 if((expectsend == -1) || (expectsend > bytessent)) {
492#if defined(USE_NTLM)
493 /* There is still data left to send */
494 if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
495 (data->state.authhost.picked == CURLAUTH_NTLM) ||
496 (data->state.authproxy.picked == CURLAUTH_NTLM_WB) ||
497 (data->state.authhost.picked == CURLAUTH_NTLM_WB)) {
498 if(((expectsend - bytessent) < 2000) ||
499 (conn->http_ntlm_state != NTLMSTATE_NONE) ||
500 (conn->proxy_ntlm_state != NTLMSTATE_NONE)) {
501 /* The NTLM-negotiation has started *OR* there is just a little (<2K)
502 data left to send, keep on sending. */
503
504 /* rewind data when completely done sending! */
505 if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
506 conn->bits.rewindaftersend = TRUE;
507 infof(data, "Rewind stream after send");
508 }
509
510 return CURLE_OK;
511 }
512
513 if(conn->bits.close)
514 /* this is already marked to get closed */
515 return CURLE_OK;
516
517 infof(data, "NTLM send, close instead of sending %"
518 CURL_FORMAT_CURL_OFF_T " bytes",
519 (curl_off_t)(expectsend - bytessent));
520 }
521#endif
522#if defined(USE_SPNEGO)
523 /* There is still data left to send */
524 if((data->state.authproxy.picked == CURLAUTH_NEGOTIATE) ||
525 (data->state.authhost.picked == CURLAUTH_NEGOTIATE)) {
526 if(((expectsend - bytessent) < 2000) ||
527 (conn->http_negotiate_state != GSS_AUTHNONE) ||
528 (conn->proxy_negotiate_state != GSS_AUTHNONE)) {
529 /* The NEGOTIATE-negotiation has started *OR*
530 there is just a little (<2K) data left to send, keep on sending. */
531
532 /* rewind data when completely done sending! */
533 if(!conn->bits.authneg && (conn->writesockfd != CURL_SOCKET_BAD)) {
534 conn->bits.rewindaftersend = TRUE;
535 infof(data, "Rewind stream after send");
536 }
537
538 return CURLE_OK;
539 }
540
541 if(conn->bits.close)
542 /* this is already marked to get closed */
543 return CURLE_OK;
544
545 infof(data, "NEGOTIATE send, close instead of sending %"
546 CURL_FORMAT_CURL_OFF_T " bytes",
547 (curl_off_t)(expectsend - bytessent));
548 }
549#endif
550
551 /* This is not NEGOTIATE/NTLM or many bytes left to send: close */
552 streamclose(conn, "Mid-auth HTTP and much data left to send");
553 data->req.size = 0; /* don't download any more than 0 bytes */
554
555 /* There still is data left to send, but this connection is marked for
556 closure so we can safely do the rewind right now */
557 }
558
559 if(bytessent)
560 /* we rewind now at once since if we already sent something */
561 return Curl_readrewind(data);
562
563 return CURLE_OK;
564}
565
566/*
567 * Curl_http_auth_act() gets called when all HTTP headers have been received
568 * and it checks what authentication methods that are available and decides
569 * which one (if any) to use. It will set 'newurl' if an auth method was
570 * picked.
571 */
572
573CURLcode Curl_http_auth_act(struct Curl_easy *data)
574{
575 struct connectdata *conn = data->conn;
576 bool pickhost = FALSE;
577 bool pickproxy = FALSE;
578 CURLcode result = CURLE_OK;
579 unsigned long authmask = ~0ul;
580
581 if(!data->set.str[STRING_BEARER])
582 authmask &= (unsigned long)~CURLAUTH_BEARER;
583
584 if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
585 /* this is a transient response code, ignore */
586 return CURLE_OK;
587
588 if(data->state.authproblem)
589 return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
590
591 if((conn->bits.user_passwd || data->set.str[STRING_BEARER]) &&
592 ((data->req.httpcode == 401) ||
593 (conn->bits.authneg && data->req.httpcode < 300))) {
594 pickhost = pickoneauth(&data->state.authhost, authmask);
595 if(!pickhost)
596 data->state.authproblem = TRUE;
597 if(data->state.authhost.picked == CURLAUTH_NTLM &&
598 conn->httpversion > 11) {
599 infof(data, "Forcing HTTP/1.1 for NTLM");
600 connclose(conn, "Force HTTP/1.1 connection");
601 data->state.httpwant = CURL_HTTP_VERSION_1_1;
602 }
603 }
604#ifndef CURL_DISABLE_PROXY
605 if(conn->bits.proxy_user_passwd &&
606 ((data->req.httpcode == 407) ||
607 (conn->bits.authneg && data->req.httpcode < 300))) {
608 pickproxy = pickoneauth(&data->state.authproxy,
609 authmask & ~CURLAUTH_BEARER);
610 if(!pickproxy)
611 data->state.authproblem = TRUE;
612 }
613#endif
614
615 if(pickhost || pickproxy) {
616 if((data->state.httpreq != HTTPREQ_GET) &&
617 (data->state.httpreq != HTTPREQ_HEAD) &&
618 !conn->bits.rewindaftersend) {
619 result = http_perhapsrewind(data, conn);
620 if(result)
621 return result;
622 }
623 /* In case this is GSS auth, the newurl field is already allocated so
624 we must make sure to free it before allocating a new one. As figured
625 out in bug #2284386 */
626 Curl_safefree(data->req.newurl);
627 data->req.newurl = strdup(data->state.url); /* clone URL */
628 if(!data->req.newurl)
629 return CURLE_OUT_OF_MEMORY;
630 }
631 else if((data->req.httpcode < 300) &&
632 (!data->state.authhost.done) &&
633 conn->bits.authneg) {
634 /* no (known) authentication available,
635 authentication is not "done" yet and
636 no authentication seems to be required and
637 we didn't try HEAD or GET */
638 if((data->state.httpreq != HTTPREQ_GET) &&
639 (data->state.httpreq != HTTPREQ_HEAD)) {
640 data->req.newurl = strdup(data->state.url); /* clone URL */
641 if(!data->req.newurl)
642 return CURLE_OUT_OF_MEMORY;
643 data->state.authhost.done = TRUE;
644 }
645 }
646 if(http_should_fail(data)) {
647 failf(data, "The requested URL returned error: %d",
648 data->req.httpcode);
649 result = CURLE_HTTP_RETURNED_ERROR;
650 }
651
652 return result;
653}
654
655#ifndef CURL_DISABLE_HTTP_AUTH
656/*
657 * Output the correct authentication header depending on the auth type
658 * and whether or not it is to a proxy.
659 */
660static CURLcode
661output_auth_headers(struct Curl_easy *data,
662 struct connectdata *conn,
663 struct auth *authstatus,
664 const char *request,
665 const char *path,
666 bool proxy)
667{
668 const char *auth = NULL;
669 CURLcode result = CURLE_OK;
670
671#ifdef CURL_DISABLE_CRYPTO_AUTH
672 (void)request;
673 (void)path;
674#endif
675#ifndef CURL_DISABLE_CRYPTO_AUTH
676 if(authstatus->picked == CURLAUTH_AWS_SIGV4) {
677 auth = "AWS_SIGV4";
678 result = Curl_output_aws_sigv4(data, proxy);
679 if(result)
680 return result;
681 }
682 else
683#endif
684#ifdef USE_SPNEGO
685 if(authstatus->picked == CURLAUTH_NEGOTIATE) {
686 auth = "Negotiate";
687 result = Curl_output_negotiate(data, conn, proxy);
688 if(result)
689 return result;
690 }
691 else
692#endif
693#ifdef USE_NTLM
694 if(authstatus->picked == CURLAUTH_NTLM) {
695 auth = "NTLM";
696 result = Curl_output_ntlm(data, proxy);
697 if(result)
698 return result;
699 }
700 else
701#endif
702#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
703 if(authstatus->picked == CURLAUTH_NTLM_WB) {
704 auth = "NTLM_WB";
705 result = Curl_output_ntlm_wb(data, conn, proxy);
706 if(result)
707 return result;
708 }
709 else
710#endif
711#ifndef CURL_DISABLE_CRYPTO_AUTH
712 if(authstatus->picked == CURLAUTH_DIGEST) {
713 auth = "Digest";
714 result = Curl_output_digest(data,
715 proxy,
716 (const unsigned char *)request,
717 (const unsigned char *)path);
718 if(result)
719 return result;
720 }
721 else
722#endif
723 if(authstatus->picked == CURLAUTH_BASIC) {
724 /* Basic */
725 if(
726#ifndef CURL_DISABLE_PROXY
727 (proxy && conn->bits.proxy_user_passwd &&
728 !Curl_checkProxyheaders(data, conn, "Proxy-authorization")) ||
729#endif
730 (!proxy && conn->bits.user_passwd &&
731 !Curl_checkheaders(data, "Authorization"))) {
732 auth = "Basic";
733 result = http_output_basic(data, proxy);
734 if(result)
735 return result;
736 }
737
738 /* NOTE: this function should set 'done' TRUE, as the other auth
739 functions work that way */
740 authstatus->done = TRUE;
741 }
742 if(authstatus->picked == CURLAUTH_BEARER) {
743 /* Bearer */
744 if((!proxy && data->set.str[STRING_BEARER] &&
745 !Curl_checkheaders(data, "Authorization"))) {
746 auth = "Bearer";
747 result = http_output_bearer(data);
748 if(result)
749 return result;
750 }
751
752 /* NOTE: this function should set 'done' TRUE, as the other auth
753 functions work that way */
754 authstatus->done = TRUE;
755 }
756
757 if(auth) {
758#ifndef CURL_DISABLE_PROXY
759 infof(data, "%s auth using %s with user '%s'",
760 proxy ? "Proxy" : "Server", auth,
761 proxy ? (data->state.aptr.proxyuser ?
762 data->state.aptr.proxyuser : "") :
763 (data->state.aptr.user ?
764 data->state.aptr.user : ""));
765#else
766 infof(data, "Server auth using %s with user '%s'",
767 auth, data->state.aptr.user ?
768 data->state.aptr.user : "");
769#endif
770 authstatus->multipass = (!authstatus->done) ? TRUE : FALSE;
771 }
772 else
773 authstatus->multipass = FALSE;
774
775 return CURLE_OK;
776}
777
778/**
779 * Curl_http_output_auth() setups the authentication headers for the
780 * host/proxy and the correct authentication
781 * method. data->state.authdone is set to TRUE when authentication is
782 * done.
783 *
784 * @param conn all information about the current connection
785 * @param request pointer to the request keyword
786 * @param path pointer to the requested path; should include query part
787 * @param proxytunnel boolean if this is the request setting up a "proxy
788 * tunnel"
789 *
790 * @returns CURLcode
791 */
792CURLcode
793Curl_http_output_auth(struct Curl_easy *data,
794 struct connectdata *conn,
795 const char *request,
796 Curl_HttpReq httpreq,
797 const char *path,
798 bool proxytunnel) /* TRUE if this is the request setting
799 up the proxy tunnel */
800{
801 CURLcode result = CURLE_OK;
802 struct auth *authhost;
803 struct auth *authproxy;
804
805 DEBUGASSERT(data);
806
807 authhost = &data->state.authhost;
808 authproxy = &data->state.authproxy;
809
810 if(
811#ifndef CURL_DISABLE_PROXY
812 (conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
813#endif
814 conn->bits.user_passwd || data->set.str[STRING_BEARER])
815 /* continue please */;
816 else {
817 authhost->done = TRUE;
818 authproxy->done = TRUE;
819 return CURLE_OK; /* no authentication with no user or password */
820 }
821
822 if(authhost->want && !authhost->picked)
823 /* The app has selected one or more methods, but none has been picked
824 so far by a server round-trip. Then we set the picked one to the
825 want one, and if this is one single bit it'll be used instantly. */
826 authhost->picked = authhost->want;
827
828 if(authproxy->want && !authproxy->picked)
829 /* The app has selected one or more methods, but none has been picked so
830 far by a proxy round-trip. Then we set the picked one to the want one,
831 and if this is one single bit it'll be used instantly. */
832 authproxy->picked = authproxy->want;
833
834#ifndef CURL_DISABLE_PROXY
835 /* Send proxy authentication header if needed */
836 if(conn->bits.httpproxy &&
837 (conn->bits.tunnel_proxy == (bit)proxytunnel)) {
838 result = output_auth_headers(data, conn, authproxy, request, path, TRUE);
839 if(result)
840 return result;
841 }
842 else
843#else
844 (void)proxytunnel;
845#endif /* CURL_DISABLE_PROXY */
846 /* we have no proxy so let's pretend we're done authenticating
847 with it */
848 authproxy->done = TRUE;
849
850 /* To prevent the user+password to get sent to other than the original
851 host due to a location-follow, we do some weirdo checks here */
852 if(!data->state.this_is_a_follow ||
853#ifndef CURL_DISABLE_NETRC
854 conn->bits.netrc ||
855#endif
856 !data->state.first_host ||
857 data->set.allow_auth_to_other_hosts ||
858 strcasecompare(data->state.first_host, conn->host.name)) {
859 result = output_auth_headers(data, conn, authhost, request, path, FALSE);
860 }
861 else
862 authhost->done = TRUE;
863
864 if(((authhost->multipass && !authhost->done) ||
865 (authproxy->multipass && !authproxy->done)) &&
866 (httpreq != HTTPREQ_GET) &&
867 (httpreq != HTTPREQ_HEAD)) {
868 /* Auth is required and we are not authenticated yet. Make a PUT or POST
869 with content-length zero as a "probe". */
870 conn->bits.authneg = TRUE;
871 }
872 else
873 conn->bits.authneg = FALSE;
874
875 return result;
876}
877
878#else
879/* when disabled */
880CURLcode
881Curl_http_output_auth(struct Curl_easy *data,
882 struct connectdata *conn,
883 const char *request,
884 Curl_HttpReq httpreq,
885 const char *path,
886 bool proxytunnel)
887{
888 (void)data;
889 (void)conn;
890 (void)request;
891 (void)httpreq;
892 (void)path;
893 (void)proxytunnel;
894 return CURLE_OK;
895}
896#endif
897
898/*
899 * Curl_http_input_auth() deals with Proxy-Authenticate: and WWW-Authenticate:
900 * headers. They are dealt with both in the transfer.c main loop and in the
901 * proxy CONNECT loop.
902 */
903
904static int is_valid_auth_separator(char ch)
905{
906 return ch == '\0' || ch == ',' || ISSPACE(ch);
907}
908
909CURLcode Curl_http_input_auth(struct Curl_easy *data, bool proxy,
910 const char *auth) /* the first non-space */
911{
912 /*
913 * This resource requires authentication
914 */
915 struct connectdata *conn = data->conn;
916#ifdef USE_SPNEGO
917 curlnegotiate *negstate = proxy ? &conn->proxy_negotiate_state :
918 &conn->http_negotiate_state;
919#endif
920 unsigned long *availp;
921 struct auth *authp;
922
923 (void) conn; /* In case conditionals make it unused. */
924
925 if(proxy) {
926 availp = &data->info.proxyauthavail;
927 authp = &data->state.authproxy;
928 }
929 else {
930 availp = &data->info.httpauthavail;
931 authp = &data->state.authhost;
932 }
933
934 /*
935 * Here we check if we want the specific single authentication (using ==) and
936 * if we do, we initiate usage of it.
937 *
938 * If the provided authentication is wanted as one out of several accepted
939 * types (using &), we OR this authentication type to the authavail
940 * variable.
941 *
942 * Note:
943 *
944 * ->picked is first set to the 'want' value (one or more bits) before the
945 * request is sent, and then it is again set _after_ all response 401/407
946 * headers have been received but then only to a single preferred method
947 * (bit).
948 */
949
950 while(*auth) {
951#ifdef USE_SPNEGO
952 if(checkprefix("Negotiate", auth) && is_valid_auth_separator(auth[9])) {
953 if((authp->avail & CURLAUTH_NEGOTIATE) ||
954 Curl_auth_is_spnego_supported()) {
955 *availp |= CURLAUTH_NEGOTIATE;
956 authp->avail |= CURLAUTH_NEGOTIATE;
957
958 if(authp->picked == CURLAUTH_NEGOTIATE) {
959 CURLcode result = Curl_input_negotiate(data, conn, proxy, auth);
960 if(!result) {
961 DEBUGASSERT(!data->req.newurl);
962 data->req.newurl = strdup(data->state.url);
963 if(!data->req.newurl)
964 return CURLE_OUT_OF_MEMORY;
965 data->state.authproblem = FALSE;
966 /* we received a GSS auth token and we dealt with it fine */
967 *negstate = GSS_AUTHRECV;
968 }
969 else
970 data->state.authproblem = TRUE;
971 }
972 }
973 }
974 else
975#endif
976#ifdef USE_NTLM
977 /* NTLM support requires the SSL crypto libs */
978 if(checkprefix("NTLM", auth) && is_valid_auth_separator(auth[4])) {
979 if((authp->avail & CURLAUTH_NTLM) ||
980 (authp->avail & CURLAUTH_NTLM_WB) ||
981 Curl_auth_is_ntlm_supported()) {
982 *availp |= CURLAUTH_NTLM;
983 authp->avail |= CURLAUTH_NTLM;
984
985 if(authp->picked == CURLAUTH_NTLM ||
986 authp->picked == CURLAUTH_NTLM_WB) {
987 /* NTLM authentication is picked and activated */
988 CURLcode result = Curl_input_ntlm(data, proxy, auth);
989 if(!result) {
990 data->state.authproblem = FALSE;
991#ifdef NTLM_WB_ENABLED
992 if(authp->picked == CURLAUTH_NTLM_WB) {
993 *availp &= ~CURLAUTH_NTLM;
994 authp->avail &= ~CURLAUTH_NTLM;
995 *availp |= CURLAUTH_NTLM_WB;
996 authp->avail |= CURLAUTH_NTLM_WB;
997
998 result = Curl_input_ntlm_wb(data, conn, proxy, auth);
999 if(result) {
1000 infof(data, "Authentication problem. Ignoring this.");
1001 data->state.authproblem = TRUE;
1002 }
1003 }
1004#endif
1005 }
1006 else {
1007 infof(data, "Authentication problem. Ignoring this.");
1008 data->state.authproblem = TRUE;
1009 }
1010 }
1011 }
1012 }
1013 else
1014#endif
1015#ifndef CURL_DISABLE_CRYPTO_AUTH
1016 if(checkprefix("Digest", auth) && is_valid_auth_separator(auth[6])) {
1017 if((authp->avail & CURLAUTH_DIGEST) != 0)
1018 infof(data, "Ignoring duplicate digest auth header.");
1019 else if(Curl_auth_is_digest_supported()) {
1020 CURLcode result;
1021
1022 *availp |= CURLAUTH_DIGEST;
1023 authp->avail |= CURLAUTH_DIGEST;
1024
1025 /* We call this function on input Digest headers even if Digest
1026 * authentication isn't activated yet, as we need to store the
1027 * incoming data from this header in case we are going to use
1028 * Digest */
1029 result = Curl_input_digest(data, proxy, auth);
1030 if(result) {
1031 infof(data, "Authentication problem. Ignoring this.");
1032 data->state.authproblem = TRUE;
1033 }
1034 }
1035 }
1036 else
1037#endif
1038 if(checkprefix("Basic", auth) &&
1039 is_valid_auth_separator(auth[5])) {
1040 *availp |= CURLAUTH_BASIC;
1041 authp->avail |= CURLAUTH_BASIC;
1042 if(authp->picked == CURLAUTH_BASIC) {
1043 /* We asked for Basic authentication but got a 40X back
1044 anyway, which basically means our name+password isn't
1045 valid. */
1046 authp->avail = CURLAUTH_NONE;
1047 infof(data, "Authentication problem. Ignoring this.");
1048 data->state.authproblem = TRUE;
1049 }
1050 }
1051 else
1052 if(checkprefix("Bearer", auth) &&
1053 is_valid_auth_separator(auth[6])) {
1054 *availp |= CURLAUTH_BEARER;
1055 authp->avail |= CURLAUTH_BEARER;
1056 if(authp->picked == CURLAUTH_BEARER) {
1057 /* We asked for Bearer authentication but got a 40X back
1058 anyway, which basically means our token isn't valid. */
1059 authp->avail = CURLAUTH_NONE;
1060 infof(data, "Authentication problem. Ignoring this.");
1061 data->state.authproblem = TRUE;
1062 }
1063 }
1064
1065 /* there may be multiple methods on one line, so keep reading */
1066 while(*auth && *auth != ',') /* read up to the next comma */
1067 auth++;
1068 if(*auth == ',') /* if we're on a comma, skip it */
1069 auth++;
1070 while(*auth && ISSPACE(*auth))
1071 auth++;
1072 }
1073
1074 return CURLE_OK;
1075}
1076
1077/**
1078 * http_should_fail() determines whether an HTTP response has gotten us
1079 * into an error state or not.
1080 *
1081 * @param conn all information about the current connection
1082 *
1083 * @retval FALSE communications should continue
1084 *
1085 * @retval TRUE communications should not continue
1086 */
1087static bool http_should_fail(struct Curl_easy *data)
1088{
1089 int httpcode;
1090 DEBUGASSERT(data);
1091 DEBUGASSERT(data->conn);
1092
1093 httpcode = data->req.httpcode;
1094
1095 /*
1096 ** If we haven't been asked to fail on error,
1097 ** don't fail.
1098 */
1099 if(!data->set.http_fail_on_error)
1100 return FALSE;
1101
1102 /*
1103 ** Any code < 400 is never terminal.
1104 */
1105 if(httpcode < 400)
1106 return FALSE;
1107
1108 /*
1109 ** A 416 response to a resume request is presumably because the file is
1110 ** already completely downloaded and thus not actually a fail.
1111 */
1112 if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET &&
1113 httpcode == 416)
1114 return FALSE;
1115
1116 /*
1117 ** Any code >= 400 that's not 401 or 407 is always
1118 ** a terminal error
1119 */
1120 if((httpcode != 401) && (httpcode != 407))
1121 return TRUE;
1122
1123 /*
1124 ** All we have left to deal with is 401 and 407
1125 */
1126 DEBUGASSERT((httpcode == 401) || (httpcode == 407));
1127
1128 /*
1129 ** Examine the current authentication state to see if this
1130 ** is an error. The idea is for this function to get
1131 ** called after processing all the headers in a response
1132 ** message. So, if we've been to asked to authenticate a
1133 ** particular stage, and we've done it, we're OK. But, if
1134 ** we're already completely authenticated, it's not OK to
1135 ** get another 401 or 407.
1136 **
1137 ** It is possible for authentication to go stale such that
1138 ** the client needs to reauthenticate. Once that info is
1139 ** available, use it here.
1140 */
1141
1142 /*
1143 ** Either we're not authenticating, or we're supposed to
1144 ** be authenticating something else. This is an error.
1145 */
1146 if((httpcode == 401) && !data->conn->bits.user_passwd)
1147 return TRUE;
1148#ifndef CURL_DISABLE_PROXY
1149 if((httpcode == 407) && !data->conn->bits.proxy_user_passwd)
1150 return TRUE;
1151#endif
1152
1153 return data->state.authproblem;
1154}
1155
1156#ifndef USE_HYPER
1157/*
1158 * readmoredata() is a "fread() emulation" to provide POST and/or request
1159 * data. It is used when a huge POST is to be made and the entire chunk wasn't
1160 * sent in the first send(). This function will then be called from the
1161 * transfer.c loop when more data is to be sent to the peer.
1162 *
1163 * Returns the amount of bytes it filled the buffer with.
1164 */
1165static size_t readmoredata(char *buffer,
1166 size_t size,
1167 size_t nitems,
1168 void *userp)
1169{
1170 struct Curl_easy *data = (struct Curl_easy *)userp;
1171 struct HTTP *http = data->req.p.http;
1172 size_t fullsize = size * nitems;
1173
1174 if(!http->postsize)
1175 /* nothing to return */
1176 return 0;
1177
1178 /* make sure that a HTTP request is never sent away chunked! */
1179 data->req.forbidchunk = (http->sending == HTTPSEND_REQUEST)?TRUE:FALSE;
1180
1181 if(data->set.max_send_speed &&
1182 (data->set.max_send_speed < (curl_off_t)fullsize) &&
1183 (data->set.max_send_speed < http->postsize))
1184 /* speed limit */
1185 fullsize = (size_t)data->set.max_send_speed;
1186
1187 else if(http->postsize <= (curl_off_t)fullsize) {
1188 memcpy(buffer, http->postdata, (size_t)http->postsize);
1189 fullsize = (size_t)http->postsize;
1190
1191 if(http->backup.postsize) {
1192 /* move backup data into focus and continue on that */
1193 http->postdata = http->backup.postdata;
1194 http->postsize = http->backup.postsize;
1195 data->state.fread_func = http->backup.fread_func;
1196 data->state.in = http->backup.fread_in;
1197
1198 http->sending++; /* move one step up */
1199
1200 http->backup.postsize = 0;
1201 }
1202 else
1203 http->postsize = 0;
1204
1205 return fullsize;
1206 }
1207
1208 memcpy(buffer, http->postdata, fullsize);
1209 http->postdata += fullsize;
1210 http->postsize -= fullsize;
1211
1212 return fullsize;
1213}
1214
1215/*
1216 * Curl_buffer_send() sends a header buffer and frees all associated
1217 * memory. Body data may be appended to the header data if desired.
1218 *
1219 * Returns CURLcode
1220 */
1221CURLcode Curl_buffer_send(struct dynbuf *in,
1222 struct Curl_easy *data,
1223 /* add the number of sent bytes to this
1224 counter */
1225 curl_off_t *bytes_written,
1226 /* how much of the buffer contains body data */
1227 curl_off_t included_body_bytes,
1228 int socketindex)
1229{
1230 ssize_t amount;
1231 CURLcode result;
1232 char *ptr;
1233 size_t size;
1234 struct connectdata *conn = data->conn;
1235 struct HTTP *http = data->req.p.http;
1236 size_t sendsize;
1237 curl_socket_t sockfd;
1238 size_t headersize;
1239
1240 DEBUGASSERT(socketindex <= SECONDARYSOCKET);
1241
1242 sockfd = conn->sock[socketindex];
1243
1244 /* The looping below is required since we use non-blocking sockets, but due
1245 to the circumstances we will just loop and try again and again etc */
1246
1247 ptr = Curl_dyn_ptr(in);
1248 size = Curl_dyn_len(in);
1249
1250 headersize = size - (size_t)included_body_bytes; /* the initial part that
1251 isn't body is header */
1252
1253 DEBUGASSERT(size > (size_t)included_body_bytes);
1254
1255 result = Curl_convert_to_network(data, ptr, headersize);
1256 /* Curl_convert_to_network calls failf if unsuccessful */
1257 if(result) {
1258 /* conversion failed, free memory and return to the caller */
1259 Curl_dyn_free(in);
1260 return result;
1261 }
1262
1263 if((conn->handler->flags & PROTOPT_SSL
1264#ifndef CURL_DISABLE_PROXY
1265 || conn->http_proxy.proxytype == CURLPROXY_HTTPS
1266#endif
1267 )
1268 && conn->httpversion != 20) {
1269 /* Make sure this doesn't send more body bytes than what the max send
1270 speed says. The request bytes do not count to the max speed.
1271 */
1272 if(data->set.max_send_speed &&
1273 (included_body_bytes > data->set.max_send_speed)) {
1274 curl_off_t overflow = included_body_bytes - data->set.max_send_speed;
1275 DEBUGASSERT((size_t)overflow < size);
1276 sendsize = size - (size_t)overflow;
1277 }
1278 else
1279 sendsize = size;
1280
1281 /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1282 library when we attempt to re-send this buffer. Sending the same data
1283 is not enough, we must use the exact same address. For this reason, we
1284 must copy the data to the uploadbuffer first, since that is the buffer
1285 we will be using if this send is retried later.
1286 */
1287 result = Curl_get_upload_buffer(data);
1288 if(result) {
1289 /* malloc failed, free memory and return to the caller */
1290 Curl_dyn_free(in);
1291 return result;
1292 }
1293 /* We never send more than upload_buffer_size bytes in one single chunk
1294 when we speak HTTPS, as if only a fraction of it is sent now, this data
1295 needs to fit into the normal read-callback buffer later on and that
1296 buffer is using this size.
1297 */
1298 if(sendsize > (size_t)data->set.upload_buffer_size)
1299 sendsize = (size_t)data->set.upload_buffer_size;
1300
1301 memcpy(data->state.ulbuf, ptr, sendsize);
1302 ptr = data->state.ulbuf;
1303 }
1304 else {
1305#ifdef CURLDEBUG
1306 /* Allow debug builds to override this logic to force short initial
1307 sends
1308 */
1309 char *p = getenv("CURL_SMALLREQSEND");
1310 if(p) {
1311 size_t altsize = (size_t)strtoul(p, NULL, 10);
1312 if(altsize)
1313 sendsize = CURLMIN(size, altsize);
1314 else
1315 sendsize = size;
1316 }
1317 else
1318#endif
1319 {
1320 /* Make sure this doesn't send more body bytes than what the max send
1321 speed says. The request bytes do not count to the max speed.
1322 */
1323 if(data->set.max_send_speed &&
1324 (included_body_bytes > data->set.max_send_speed)) {
1325 curl_off_t overflow = included_body_bytes - data->set.max_send_speed;
1326 DEBUGASSERT((size_t)overflow < size);
1327 sendsize = size - (size_t)overflow;
1328 }
1329 else
1330 sendsize = size;
1331 }
1332 }
1333
1334 result = Curl_write(data, sockfd, ptr, sendsize, &amount);
1335
1336 if(!result) {
1337 /*
1338 * Note that we may not send the entire chunk at once, and we have a set
1339 * number of data bytes at the end of the big buffer (out of which we may
1340 * only send away a part).
1341 */
1342 /* how much of the header that was sent */
1343 size_t headlen = (size_t)amount>headersize ? headersize : (size_t)amount;
1344 size_t bodylen = amount - headlen;
1345
1346 /* this data _may_ contain binary stuff */
1347 Curl_debug(data, CURLINFO_HEADER_OUT, ptr, headlen);
1348 if(bodylen)
1349 /* there was body data sent beyond the initial header part, pass that on
1350 to the debug callback too */
1351 Curl_debug(data, CURLINFO_DATA_OUT, ptr + headlen, bodylen);
1352
1353 /* 'amount' can never be a very large value here so typecasting it so a
1354 signed 31 bit value should not cause problems even if ssize_t is
1355 64bit */
1356 *bytes_written += (long)amount;
1357
1358 if(http) {
1359 /* if we sent a piece of the body here, up the byte counter for it
1360 accordingly */
1361 data->req.writebytecount += bodylen;
1362 Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
1363
1364 if((size_t)amount != size) {
1365 /* The whole request could not be sent in one system call. We must
1366 queue it up and send it later when we get the chance. We must not
1367 loop here and wait until it might work again. */
1368
1369 size -= amount;
1370
1371 ptr = Curl_dyn_ptr(in) + amount;
1372
1373 /* backup the currently set pointers */
1374 http->backup.fread_func = data->state.fread_func;
1375 http->backup.fread_in = data->state.in;
1376 http->backup.postdata = http->postdata;
1377 http->backup.postsize = http->postsize;
1378
1379 /* set the new pointers for the request-sending */
1380 data->state.fread_func = (curl_read_callback)readmoredata;
1381 data->state.in = (void *)data;
1382 http->postdata = ptr;
1383 http->postsize = (curl_off_t)size;
1384
1385 /* this much data is remaining header: */
1386 data->req.pendingheader = headersize - headlen;
1387
1388 http->send_buffer = *in; /* copy the whole struct */
1389 http->sending = HTTPSEND_REQUEST;
1390
1391 return CURLE_OK;
1392 }
1393 http->sending = HTTPSEND_BODY;
1394 /* the full buffer was sent, clean up and return */
1395 }
1396 else {
1397 if((size_t)amount != size)
1398 /* We have no continue-send mechanism now, fail. This can only happen
1399 when this function is used from the CONNECT sending function. We
1400 currently (stupidly) assume that the whole request is always sent
1401 away in the first single chunk.
1402
1403 This needs FIXing.
1404 */
1405 return CURLE_SEND_ERROR;
1406 }
1407 }
1408 Curl_dyn_free(in);
1409
1410 /* no remaining header data */
1411 data->req.pendingheader = 0;
1412 return result;
1413}
1414
1415#endif
1416
1417/* end of the add_buffer functions */
1418/* ------------------------------------------------------------------------- */
1419
1420
1421
1422/*
1423 * Curl_compareheader()
1424 *
1425 * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1426 * Pass headers WITH the colon.
1427 */
1428bool
1429Curl_compareheader(const char *headerline, /* line to check */
1430 const char *header, /* header keyword _with_ colon */
1431 const char *content) /* content string to find */
1432{
1433 /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1434 * by a colon (":") and the field value. Field names are case-insensitive.
1435 * The field value MAY be preceded by any amount of LWS, though a single SP
1436 * is preferred." */
1437
1438 size_t hlen = strlen(header);
1439 size_t clen;
1440 size_t len;
1441 const char *start;
1442 const char *end;
1443
1444 if(!strncasecompare(headerline, header, hlen))
1445 return FALSE; /* doesn't start with header */
1446
1447 /* pass the header */
1448 start = &headerline[hlen];
1449
1450 /* pass all whitespace */
1451 while(*start && ISSPACE(*start))
1452 start++;
1453
1454 /* find the end of the header line */
1455 end = strchr(start, '\r'); /* lines end with CRLF */
1456 if(!end) {
1457 /* in case there's a non-standard compliant line here */
1458 end = strchr(start, '\n');
1459
1460 if(!end)
1461 /* hm, there's no line ending here, use the zero byte! */
1462 end = strchr(start, '\0');
1463 }
1464
1465 len = end-start; /* length of the content part of the input line */
1466 clen = strlen(content); /* length of the word to find */
1467
1468 /* find the content string in the rest of the line */
1469 for(; len >= clen; len--, start++) {
1470 if(strncasecompare(start, content, clen))
1471 return TRUE; /* match! */
1472 }
1473
1474 return FALSE; /* no match */
1475}
1476
1477/*
1478 * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1479 * the generic Curl_connect().
1480 */
1481CURLcode Curl_http_connect(struct Curl_easy *data, bool *done)
1482{
1483 CURLcode result;
1484 struct connectdata *conn = data->conn;
1485
1486 /* We default to persistent connections. We set this already in this connect
1487 function to make the re-use checks properly be able to check this bit. */
1488 connkeep(conn, "HTTP default");
1489
1490#ifndef CURL_DISABLE_PROXY
1491 /* the CONNECT procedure might not have been completed */
1492 result = Curl_proxy_connect(data, FIRSTSOCKET);
1493 if(result)
1494 return result;
1495
1496 if(conn->bits.proxy_connect_closed)
1497 /* this is not an error, just part of the connection negotiation */
1498 return CURLE_OK;
1499
1500 if(CONNECT_FIRSTSOCKET_PROXY_SSL())
1501 return CURLE_OK; /* wait for HTTPS proxy SSL initialization to complete */
1502
1503 if(Curl_connect_ongoing(conn))
1504 /* nothing else to do except wait right now - we're not done here. */
1505 return CURLE_OK;
1506
1507 if(data->set.haproxyprotocol) {
1508 /* add HAProxy PROXY protocol header */
1509 result = add_haproxy_protocol_header(data);
1510 if(result)
1511 return result;
1512 }
1513#endif
1514
1515 if(conn->given->protocol & CURLPROTO_HTTPS) {
1516 /* perform SSL initialization */
1517 result = https_connecting(data, done);
1518 if(result)
1519 return result;
1520 }
1521 else
1522 *done = TRUE;
1523
1524 return CURLE_OK;
1525}
1526
1527/* this returns the socket to wait for in the DO and DOING state for the multi
1528 interface and then we're always _sending_ a request and thus we wait for
1529 the single socket to become writable only */
1530static int http_getsock_do(struct Curl_easy *data,
1531 struct connectdata *conn,
1532 curl_socket_t *socks)
1533{
1534 /* write mode */
1535 (void)data;
1536 socks[0] = conn->sock[FIRSTSOCKET];
1537 return GETSOCK_WRITESOCK(0);
1538}
1539
1540#ifndef CURL_DISABLE_PROXY
1541static CURLcode add_haproxy_protocol_header(struct Curl_easy *data)
1542{
1543 struct dynbuf req;
1544 CURLcode result;
1545 const char *tcp_version;
1546 DEBUGASSERT(data->conn);
1547 Curl_dyn_init(&req, DYN_HAXPROXY);
1548
1549#ifdef USE_UNIX_SOCKETS
1550 if(data->conn->unix_domain_socket)
1551 /* the buffer is large enough to hold this! */
1552 result = Curl_dyn_add(&req, "PROXY UNKNOWN\r\n");
1553 else {
1554#endif
1555 /* Emit the correct prefix for IPv6 */
1556 tcp_version = data->conn->bits.ipv6 ? "TCP6" : "TCP4";
1557
1558 result = Curl_dyn_addf(&req, "PROXY %s %s %s %i %i\r\n",
1559 tcp_version,
1560 data->info.conn_local_ip,
1561 data->info.conn_primary_ip,
1562 data->info.conn_local_port,
1563 data->info.conn_primary_port);
1564
1565#ifdef USE_UNIX_SOCKETS
1566 }
1567#endif
1568
1569 if(!result)
1570 result = Curl_buffer_send(&req, data, &data->info.request_size,
1571 0, FIRSTSOCKET);
1572 return result;
1573}
1574#endif
1575
1576#ifdef USE_SSL
1577static CURLcode https_connecting(struct Curl_easy *data, bool *done)
1578{
1579 CURLcode result;
1580 struct connectdata *conn = data->conn;
1581 DEBUGASSERT((data) && (data->conn->handler->flags & PROTOPT_SSL));
1582
1583#ifdef ENABLE_QUIC
1584 if(conn->transport == TRNSPRT_QUIC) {
1585 *done = TRUE;
1586 return CURLE_OK;
1587 }
1588#endif
1589
1590 /* perform SSL initialization for this socket */
1591 result = Curl_ssl_connect_nonblocking(data, conn, FALSE, FIRSTSOCKET, done);
1592 if(result)
1593 connclose(conn, "Failed HTTPS connection");
1594
1595 return result;
1596}
1597
1598static int https_getsock(struct Curl_easy *data,
1599 struct connectdata *conn,
1600 curl_socket_t *socks)
1601{
1602 (void)data;
1603 if(conn->handler->flags & PROTOPT_SSL)
1604 return Curl_ssl->getsock(conn, socks);
1605 return GETSOCK_BLANK;
1606}
1607#endif /* USE_SSL */
1608
1609/*
1610 * Curl_http_done() gets called after a single HTTP request has been
1611 * performed.
1612 */
1613
1614CURLcode Curl_http_done(struct Curl_easy *data,
1615 CURLcode status, bool premature)
1616{
1617 struct connectdata *conn = data->conn;
1618 struct HTTP *http = data->req.p.http;
1619
1620 /* Clear multipass flag. If authentication isn't done yet, then it will get
1621 * a chance to be set back to true when we output the next auth header */
1622 data->state.authhost.multipass = FALSE;
1623 data->state.authproxy.multipass = FALSE;
1624
1625 Curl_unencode_cleanup(data);
1626
1627 /* set the proper values (possibly modified on POST) */
1628 conn->seek_func = data->set.seek_func; /* restore */
1629 conn->seek_client = data->set.seek_client; /* restore */
1630
1631 if(!http)
1632 return CURLE_OK;
1633
1634 Curl_dyn_free(&http->send_buffer);
1635 Curl_http2_done(data, premature);
1636 Curl_quic_done(data, premature);
1637 Curl_mime_cleanpart(&http->form);
1638 Curl_dyn_reset(&data->state.headerb);
1639 Curl_hyper_done(data);
1640
1641 if(status)
1642 return status;
1643
1644 if(!premature && /* this check is pointless when DONE is called before the
1645 entire operation is complete */
1646 !conn->bits.retry &&
1647 !data->set.connect_only &&
1648 (data->req.bytecount +
1649 data->req.headerbytecount -
1650 data->req.deductheadercount) <= 0) {
1651 /* If this connection isn't simply closed to be retried, AND nothing was
1652 read from the HTTP server (that counts), this can't be right so we
1653 return an error here */
1654 failf(data, "Empty reply from server");
1655 /* Mark it as closed to avoid the "left intact" message */
1656 streamclose(conn, "Empty reply from server");
1657 return CURLE_GOT_NOTHING;
1658 }
1659
1660 return CURLE_OK;
1661}
1662
1663/*
1664 * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
1665 * to avoid it include:
1666 *
1667 * - if the user specifically requested HTTP 1.0
1668 * - if the server we are connected to only supports 1.0
1669 * - if any server previously contacted to handle this request only supports
1670 * 1.0.
1671 */
1672bool Curl_use_http_1_1plus(const struct Curl_easy *data,
1673 const struct connectdata *conn)
1674{
1675 if((data->state.httpversion == 10) || (conn->httpversion == 10))
1676 return FALSE;
1677 if((data->state.httpwant == CURL_HTTP_VERSION_1_0) &&
1678 (conn->httpversion <= 10))
1679 return FALSE;
1680 return ((data->state.httpwant == CURL_HTTP_VERSION_NONE) ||
1681 (data->state.httpwant >= CURL_HTTP_VERSION_1_1));
1682}
1683
1684#ifndef USE_HYPER
1685static const char *get_http_string(const struct Curl_easy *data,
1686 const struct connectdata *conn)
1687{
1688#ifdef ENABLE_QUIC
1689 if((data->state.httpwant == CURL_HTTP_VERSION_3) ||
1690 (conn->httpversion == 30))
1691 return "3";
1692#endif
1693
1694#ifdef USE_NGHTTP2
1695 if(conn->proto.httpc.h2)
1696 return "2";
1697#endif
1698
1699 if(Curl_use_http_1_1plus(data, conn))
1700 return "1.1";
1701
1702 return "1.0";
1703}
1704#endif
1705
1706/* check and possibly add an Expect: header */
1707static CURLcode expect100(struct Curl_easy *data,
1708 struct connectdata *conn,
1709 struct dynbuf *req)
1710{
1711 CURLcode result = CURLE_OK;
1712 data->state.expect100header = FALSE; /* default to false unless it is set
1713 to TRUE below */
1714 if(!data->state.disableexpect && Curl_use_http_1_1plus(data, conn) &&
1715 (conn->httpversion < 20)) {
1716 /* if not doing HTTP 1.0 or version 2, or disabled explicitly, we add an
1717 Expect: 100-continue to the headers which actually speeds up post
1718 operations (as there is one packet coming back from the web server) */
1719 const char *ptr = Curl_checkheaders(data, "Expect");
1720 if(ptr) {
1721 data->state.expect100header =
1722 Curl_compareheader(ptr, "Expect:", "100-continue");
1723 }
1724 else {
1725 result = Curl_dyn_add(req, "Expect: 100-continue\r\n");
1726 if(!result)
1727 data->state.expect100header = TRUE;
1728 }
1729 }
1730
1731 return result;
1732}
1733
1734enum proxy_use {
1735 HEADER_SERVER, /* direct to server */
1736 HEADER_PROXY, /* regular request to proxy */
1737 HEADER_CONNECT /* sending CONNECT to a proxy */
1738};
1739
1740/* used to compile the provided trailers into one buffer
1741 will return an error code if one of the headers is
1742 not formatted correctly */
1743CURLcode Curl_http_compile_trailers(struct curl_slist *trailers,
1744 struct dynbuf *b,
1745 struct Curl_easy *handle)
1746{
1747 char *ptr = NULL;
1748 CURLcode result = CURLE_OK;
1749 const char *endofline_native = NULL;
1750 const char *endofline_network = NULL;
1751
1752 if(
1753#ifdef CURL_DO_LINEEND_CONV
1754 (handle->state.prefer_ascii) ||
1755#endif
1756 (handle->set.crlf)) {
1757 /* \n will become \r\n later on */
1758 endofline_native = "\n";
1759 endofline_network = "\x0a";
1760 }
1761 else {
1762 endofline_native = "\r\n";
1763 endofline_network = "\x0d\x0a";
1764 }
1765
1766 while(trailers) {
1767 /* only add correctly formatted trailers */
1768 ptr = strchr(trailers->data, ':');
1769 if(ptr && *(ptr + 1) == ' ') {
1770 result = Curl_dyn_add(b, trailers->data);
1771 if(result)
1772 return result;
1773 result = Curl_dyn_add(b, endofline_native);
1774 if(result)
1775 return result;
1776 }
1777 else
1778 infof(handle, "Malformatted trailing header ! Skipping trailer.");
1779 trailers = trailers->next;
1780 }
1781 result = Curl_dyn_add(b, endofline_network);
1782 return result;
1783}
1784
1785CURLcode Curl_add_custom_headers(struct Curl_easy *data,
1786 bool is_connect,
1787#ifndef USE_HYPER
1788 struct dynbuf *req
1789#else
1790 void *req
1791#endif
1792 )
1793{
1794 struct connectdata *conn = data->conn;
1795 char *ptr;
1796 struct curl_slist *h[2];
1797 struct curl_slist *headers;
1798 int numlists = 1; /* by default */
1799 int i;
1800
1801#ifndef CURL_DISABLE_PROXY
1802 enum proxy_use proxy;
1803
1804 if(is_connect)
1805 proxy = HEADER_CONNECT;
1806 else
1807 proxy = conn->bits.httpproxy && !conn->bits.tunnel_proxy?
1808 HEADER_PROXY:HEADER_SERVER;
1809
1810 switch(proxy) {
1811 case HEADER_SERVER:
1812 h[0] = data->set.headers;
1813 break;
1814 case HEADER_PROXY:
1815 h[0] = data->set.headers;
1816 if(data->set.sep_headers) {
1817 h[1] = data->set.proxyheaders;
1818 numlists++;
1819 }
1820 break;
1821 case HEADER_CONNECT:
1822 if(data->set.sep_headers)
1823 h[0] = data->set.proxyheaders;
1824 else
1825 h[0] = data->set.headers;
1826 break;
1827 }
1828#else
1829 (void)is_connect;
1830 h[0] = data->set.headers;
1831#endif
1832
1833 /* loop through one or two lists */
1834 for(i = 0; i < numlists; i++) {
1835 headers = h[i];
1836
1837 while(headers) {
1838 char *semicolonp = NULL;
1839 ptr = strchr(headers->data, ':');
1840 if(!ptr) {
1841 char *optr;
1842 /* no colon, semicolon? */
1843 ptr = strchr(headers->data, ';');
1844 if(ptr) {
1845 optr = ptr;
1846 ptr++; /* pass the semicolon */
1847 while(*ptr && ISSPACE(*ptr))
1848 ptr++;
1849
1850 if(*ptr) {
1851 /* this may be used for something else in the future */
1852 optr = NULL;
1853 }
1854 else {
1855 if(*(--ptr) == ';') {
1856 /* copy the source */
1857 semicolonp = strdup(headers->data);
1858 if(!semicolonp) {
1859#ifndef USE_HYPER
1860 Curl_dyn_free(req);
1861#endif
1862 return CURLE_OUT_OF_MEMORY;
1863 }
1864 /* put a colon where the semicolon is */
1865 semicolonp[ptr - headers->data] = ':';
1866 /* point at the colon */
1867 optr = &semicolonp [ptr - headers->data];
1868 }
1869 }
1870 ptr = optr;
1871 }
1872 }
1873 if(ptr) {
1874 /* we require a colon for this to be a true header */
1875
1876 ptr++; /* pass the colon */
1877 while(*ptr && ISSPACE(*ptr))
1878 ptr++;
1879
1880 if(*ptr || semicolonp) {
1881 /* only send this if the contents was non-blank or done special */
1882 CURLcode result = CURLE_OK;
1883 char *compare = semicolonp ? semicolonp : headers->data;
1884
1885 if(data->state.aptr.host &&
1886 /* a Host: header was sent already, don't pass on any custom Host:
1887 header as that will produce *two* in the same request! */
1888 checkprefix("Host:", compare))
1889 ;
1890 else if(data->state.httpreq == HTTPREQ_POST_FORM &&
1891 /* this header (extended by formdata.c) is sent later */
1892 checkprefix("Content-Type:", compare))
1893 ;
1894 else if(data->state.httpreq == HTTPREQ_POST_MIME &&
1895 /* this header is sent later */
1896 checkprefix("Content-Type:", compare))
1897 ;
1898 else if(conn->bits.authneg &&
1899 /* while doing auth neg, don't allow the custom length since
1900 we will force length zero then */
1901 checkprefix("Content-Length:", compare))
1902 ;
1903 else if(data->state.aptr.te &&
1904 /* when asking for Transfer-Encoding, don't pass on a custom
1905 Connection: */
1906 checkprefix("Connection:", compare))
1907 ;
1908 else if((conn->httpversion >= 20) &&
1909 checkprefix("Transfer-Encoding:", compare))
1910 /* HTTP/2 doesn't support chunked requests */
1911 ;
1912 else if((checkprefix("Authorization:", compare) ||
1913 checkprefix("Cookie:", compare)) &&
1914 /* be careful of sending this potentially sensitive header to
1915 other hosts */
1916 (data->state.this_is_a_follow &&
1917 data->state.first_host &&
1918 !data->set.allow_auth_to_other_hosts &&
1919 !strcasecompare(data->state.first_host, conn->host.name)))
1920 ;
1921 else {
1922#ifdef USE_HYPER
1923 result = Curl_hyper_header(data, req, compare);
1924#else
1925 result = Curl_dyn_addf(req, "%s\r\n", compare);
1926#endif
1927 }
1928 if(semicolonp)
1929 free(semicolonp);
1930 if(result)
1931 return result;
1932 }
1933 }
1934 headers = headers->next;
1935 }
1936 }
1937
1938 return CURLE_OK;
1939}
1940
1941#ifndef CURL_DISABLE_PARSEDATE
1942CURLcode Curl_add_timecondition(struct Curl_easy *data,
1943#ifndef USE_HYPER
1944 struct dynbuf *req
1945#else
1946 void *req
1947#endif
1948 )
1949{
1950 const struct tm *tm;
1951 struct tm keeptime;
1952 CURLcode result;
1953 char datestr[80];
1954 const char *condp;
1955
1956 if(data->set.timecondition == CURL_TIMECOND_NONE)
1957 /* no condition was asked for */
1958 return CURLE_OK;
1959
1960 result = Curl_gmtime(data->set.timevalue, &keeptime);
1961 if(result) {
1962 failf(data, "Invalid TIMEVALUE");
1963 return result;
1964 }
1965 tm = &keeptime;
1966
1967 switch(data->set.timecondition) {
1968 default:
1969 return CURLE_BAD_FUNCTION_ARGUMENT;
1970
1971 case CURL_TIMECOND_IFMODSINCE:
1972 condp = "If-Modified-Since";
1973 break;
1974 case CURL_TIMECOND_IFUNMODSINCE:
1975 condp = "If-Unmodified-Since";
1976 break;
1977 case CURL_TIMECOND_LASTMOD:
1978 condp = "Last-Modified";
1979 break;
1980 }
1981
1982 if(Curl_checkheaders(data, condp)) {
1983 /* A custom header was specified; it will be sent instead. */
1984 return CURLE_OK;
1985 }
1986
1987 /* The If-Modified-Since header family should have their times set in
1988 * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1989 * represented in Greenwich Mean Time (GMT), without exception. For the
1990 * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1991 * Time)." (see page 20 of RFC2616).
1992 */
1993
1994 /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1995 msnprintf(datestr, sizeof(datestr),
1996 "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
1997 condp,
1998 Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1999 tm->tm_mday,
2000 Curl_month[tm->tm_mon],
2001 tm->tm_year + 1900,
2002 tm->tm_hour,
2003 tm->tm_min,
2004 tm->tm_sec);
2005
2006#ifndef USE_HYPER
2007 result = Curl_dyn_add(req, datestr);
2008#else
2009 result = Curl_hyper_header(data, req, datestr);
2010#endif
2011
2012 return result;
2013}
2014#else
2015/* disabled */
2016CURLcode Curl_add_timecondition(struct Curl_easy *data,
2017 struct dynbuf *req)
2018{
2019 (void)data;
2020 (void)req;
2021 return CURLE_OK;
2022}
2023#endif
2024
2025void Curl_http_method(struct Curl_easy *data, struct connectdata *conn,
2026 const char **method, Curl_HttpReq *reqp)
2027{
2028 Curl_HttpReq httpreq = data->state.httpreq;
2029 const char *request;
2030 if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
2031 data->set.upload)
2032 httpreq = HTTPREQ_PUT;
2033
2034 /* Now set the 'request' pointer to the proper request string */
2035 if(data->set.str[STRING_CUSTOMREQUEST])
2036 request = data->set.str[STRING_CUSTOMREQUEST];
2037 else {
2038 if(data->set.opt_no_body)
2039 request = "HEAD";
2040 else {
2041 DEBUGASSERT((httpreq >= HTTPREQ_GET) && (httpreq <= HTTPREQ_HEAD));
2042 switch(httpreq) {
2043 case HTTPREQ_POST:
2044 case HTTPREQ_POST_FORM:
2045 case HTTPREQ_POST_MIME:
2046 request = "POST";
2047 break;
2048 case HTTPREQ_PUT:
2049 request = "PUT";
2050 break;
2051 default: /* this should never happen */
2052 case HTTPREQ_GET:
2053 request = "GET";
2054 break;
2055 case HTTPREQ_HEAD:
2056 request = "HEAD";
2057 break;
2058 }
2059 }
2060 }
2061 *method = request;
2062 *reqp = httpreq;
2063}
2064
2065CURLcode Curl_http_useragent(struct Curl_easy *data)
2066{
2067 /* The User-Agent string might have been allocated in url.c already, because
2068 it might have been used in the proxy connect, but if we have got a header
2069 with the user-agent string specified, we erase the previously made string
2070 here. */
2071 if(Curl_checkheaders(data, "User-Agent")) {
2072 free(data->state.aptr.uagent);
2073 data->state.aptr.uagent = NULL;
2074 }
2075 return CURLE_OK;
2076}
2077
2078
2079CURLcode Curl_http_host(struct Curl_easy *data, struct connectdata *conn)
2080{
2081 const char *ptr;
2082 if(!data->state.this_is_a_follow) {
2083 /* Free to avoid leaking memory on multiple requests*/
2084 free(data->state.first_host);
2085
2086 data->state.first_host = strdup(conn->host.name);
2087 if(!data->state.first_host)
2088 return CURLE_OUT_OF_MEMORY;
2089
2090 data->state.first_remote_port = conn->remote_port;
2091 }
2092 Curl_safefree(data->state.aptr.host);
2093
2094 ptr = Curl_checkheaders(data, "Host");
2095 if(ptr && (!data->state.this_is_a_follow ||
2096 strcasecompare(data->state.first_host, conn->host.name))) {
2097#if !defined(CURL_DISABLE_COOKIES)
2098 /* If we have a given custom Host: header, we extract the host name in
2099 order to possibly use it for cookie reasons later on. We only allow the
2100 custom Host: header if this is NOT a redirect, as setting Host: in the
2101 redirected request is being out on thin ice. Except if the host name
2102 is the same as the first one! */
2103 char *cookiehost = Curl_copy_header_value(ptr);
2104 if(!cookiehost)
2105 return CURLE_OUT_OF_MEMORY;
2106 if(!*cookiehost)
2107 /* ignore empty data */
2108 free(cookiehost);
2109 else {
2110 /* If the host begins with '[', we start searching for the port after
2111 the bracket has been closed */
2112 if(*cookiehost == '[') {
2113 char *closingbracket;
2114 /* since the 'cookiehost' is an allocated memory area that will be
2115 freed later we cannot simply increment the pointer */
2116 memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
2117 closingbracket = strchr(cookiehost, ']');
2118 if(closingbracket)
2119 *closingbracket = 0;
2120 }
2121 else {
2122 int startsearch = 0;
2123 char *colon = strchr(cookiehost + startsearch, ':');
2124 if(colon)
2125 *colon = 0; /* The host must not include an embedded port number */
2126 }
2127 Curl_safefree(data->state.aptr.cookiehost);
2128 data->state.aptr.cookiehost = cookiehost;
2129 }
2130#endif
2131
2132 if(strcmp("Host:", ptr)) {
2133 data->state.aptr.host = aprintf("Host:%s\r\n", &ptr[5]);
2134 if(!data->state.aptr.host)
2135 return CURLE_OUT_OF_MEMORY;
2136 }
2137 else
2138 /* when clearing the header */
2139 data->state.aptr.host = NULL;
2140 }
2141 else {
2142 /* When building Host: headers, we must put the host name within
2143 [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
2144 const char *host = conn->host.name;
2145
2146 if(((conn->given->protocol&CURLPROTO_HTTPS) &&
2147 (conn->remote_port == PORT_HTTPS)) ||
2148 ((conn->given->protocol&CURLPROTO_HTTP) &&
2149 (conn->remote_port == PORT_HTTP)) )
2150 /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
2151 the port number in the host string */
2152 data->state.aptr.host = aprintf("Host: %s%s%s\r\n",
2153 conn->bits.ipv6_ip?"[":"",
2154 host,
2155 conn->bits.ipv6_ip?"]":"");
2156 else
2157 data->state.aptr.host = aprintf("Host: %s%s%s:%d\r\n",
2158 conn->bits.ipv6_ip?"[":"",
2159 host,
2160 conn->bits.ipv6_ip?"]":"",
2161 conn->remote_port);
2162
2163 if(!data->state.aptr.host)
2164 /* without Host: we can't make a nice request */
2165 return CURLE_OUT_OF_MEMORY;
2166 }
2167 return CURLE_OK;
2168}
2169
2170/*
2171 * Append the request-target to the HTTP request
2172 */
2173CURLcode Curl_http_target(struct Curl_easy *data,
2174 struct connectdata *conn,
2175 struct dynbuf *r)
2176{
2177 CURLcode result = CURLE_OK;
2178 const char *path = data->state.up.path;
2179 const char *query = data->state.up.query;
2180
2181 if(data->set.str[STRING_TARGET]) {
2182 path = data->set.str[STRING_TARGET];
2183 query = NULL;
2184 }
2185
2186#ifndef CURL_DISABLE_PROXY
2187 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
2188 /* Using a proxy but does not tunnel through it */
2189
2190 /* The path sent to the proxy is in fact the entire URL. But if the remote
2191 host is a IDN-name, we must make sure that the request we produce only
2192 uses the encoded host name! */
2193
2194 /* and no fragment part */
2195 CURLUcode uc;
2196 char *url;
2197 CURLU *h = curl_url_dup(data->state.uh);
2198 if(!h)
2199 return CURLE_OUT_OF_MEMORY;
2200
2201 if(conn->host.dispname != conn->host.name) {
2202 uc = curl_url_set(h, CURLUPART_HOST, conn->host.name, 0);
2203 if(uc) {
2204 curl_url_cleanup(h);
2205 return CURLE_OUT_OF_MEMORY;
2206 }
2207 }
2208 uc = curl_url_set(h, CURLUPART_FRAGMENT, NULL, 0);
2209 if(uc) {
2210 curl_url_cleanup(h);
2211 return CURLE_OUT_OF_MEMORY;
2212 }
2213
2214 if(strcasecompare("http", data->state.up.scheme)) {
2215 /* when getting HTTP, we don't want the userinfo the URL */
2216 uc = curl_url_set(h, CURLUPART_USER, NULL, 0);
2217 if(uc) {
2218 curl_url_cleanup(h);
2219 return CURLE_OUT_OF_MEMORY;
2220 }
2221 uc = curl_url_set(h, CURLUPART_PASSWORD, NULL, 0);
2222 if(uc) {
2223 curl_url_cleanup(h);
2224 return CURLE_OUT_OF_MEMORY;
2225 }
2226 }
2227 /* Extract the URL to use in the request. Store in STRING_TEMP_URL for
2228 clean-up reasons if the function returns before the free() further
2229 down. */
2230 uc = curl_url_get(h, CURLUPART_URL, &url, CURLU_NO_DEFAULT_PORT);
2231 if(uc) {
2232 curl_url_cleanup(h);
2233 return CURLE_OUT_OF_MEMORY;
2234 }
2235
2236 curl_url_cleanup(h);
2237
2238 /* target or url */
2239 result = Curl_dyn_add(r, data->set.str[STRING_TARGET]?
2240 data->set.str[STRING_TARGET]:url);
2241 free(url);
2242 if(result)
2243 return (result);
2244
2245 if(strcasecompare("ftp", data->state.up.scheme)) {
2246 if(data->set.proxy_transfer_mode) {
2247 /* when doing ftp, append ;type=<a|i> if not present */
2248 char *type = strstr(path, ";type=");
2249 if(type && type[6] && type[7] == 0) {
2250 switch(Curl_raw_toupper(type[6])) {
2251 case 'A':
2252 case 'D':
2253 case 'I':
2254 break;
2255 default:
2256 type = NULL;
2257 }
2258 }
2259 if(!type) {
2260 result = Curl_dyn_addf(r, ";type=%c",
2261 data->state.prefer_ascii ? 'a' : 'i');
2262 if(result)
2263 return result;
2264 }
2265 }
2266 }
2267 }
2268
2269 else
2270#else
2271 (void)conn; /* not used in disabled-proxy builds */
2272#endif
2273 {
2274 result = Curl_dyn_add(r, path);
2275 if(result)
2276 return result;
2277 if(query)
2278 result = Curl_dyn_addf(r, "?%s", query);
2279 }
2280
2281 return result;
2282}
2283
2284CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
2285 Curl_HttpReq httpreq, const char **tep)
2286{
2287 CURLcode result = CURLE_OK;
2288 const char *ptr;
2289 struct HTTP *http = data->req.p.http;
2290 http->postsize = 0;
2291
2292 switch(httpreq) {
2293 case HTTPREQ_POST_MIME:
2294 http->sendit = &data->set.mimepost;
2295 break;
2296 case HTTPREQ_POST_FORM:
2297 /* Convert the form structure into a mime structure. */
2298 Curl_mime_cleanpart(&http->form);
2299 result = Curl_getformdata(data, &http->form, data->set.httppost,
2300 data->state.fread_func);
2301 if(result)
2302 return result;
2303 http->sendit = &http->form;
2304 break;
2305 default:
2306 http->sendit = NULL;
2307 }
2308
2309#ifndef CURL_DISABLE_MIME
2310 if(http->sendit) {
2311 const char *cthdr = Curl_checkheaders(data, "Content-Type");
2312
2313 /* Read and seek body only. */
2314 http->sendit->flags |= MIME_BODY_ONLY;
2315
2316 /* Prepare the mime structure headers & set content type. */
2317
2318 if(cthdr)
2319 for(cthdr += 13; *cthdr == ' '; cthdr++)
2320 ;
2321 else if(http->sendit->kind == MIMEKIND_MULTIPART)
2322 cthdr = "multipart/form-data";
2323
2324 curl_mime_headers(http->sendit, data->set.headers, 0);
2325 result = Curl_mime_prepare_headers(http->sendit, cthdr,
2326 NULL, MIMESTRATEGY_FORM);
2327 curl_mime_headers(http->sendit, NULL, 0);
2328 if(!result)
2329 result = Curl_mime_rewind(http->sendit);
2330 if(result)
2331 return result;
2332 http->postsize = Curl_mime_size(http->sendit);
2333 }
2334#endif
2335
2336 ptr = Curl_checkheaders(data, "Transfer-Encoding");
2337 if(ptr) {
2338 /* Some kind of TE is requested, check if 'chunked' is chosen */
2339 data->req.upload_chunky =
2340 Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
2341 }
2342 else {
2343 if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
2344 (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
2345 http->postsize < 0) ||
2346 ((data->set.upload || httpreq == HTTPREQ_POST) &&
2347 data->state.infilesize == -1))) {
2348 if(conn->bits.authneg)
2349 /* don't enable chunked during auth neg */
2350 ;
2351 else if(Curl_use_http_1_1plus(data, conn)) {
2352 if(conn->httpversion < 20)
2353 /* HTTP, upload, unknown file size and not HTTP 1.0 */
2354 data->req.upload_chunky = TRUE;
2355 }
2356 else {
2357 failf(data, "Chunky upload is not supported by HTTP 1.0");
2358 return CURLE_UPLOAD_FAILED;
2359 }
2360 }
2361 else {
2362 /* else, no chunky upload */
2363 data->req.upload_chunky = FALSE;
2364 }
2365
2366 if(data->req.upload_chunky)
2367 *tep = "Transfer-Encoding: chunked\r\n";
2368 }
2369 return result;
2370}
2371
2372CURLcode Curl_http_bodysend(struct Curl_easy *data, struct connectdata *conn,
2373 struct dynbuf *r, Curl_HttpReq httpreq)
2374{
2375#ifndef USE_HYPER
2376 /* Hyper always handles the body separately */
2377 curl_off_t included_body = 0;
2378#endif
2379 CURLcode result = CURLE_OK;
2380 struct HTTP *http = data->req.p.http;
2381 const char *ptr;
2382
2383 /* If 'authdone' is FALSE, we must not set the write socket index to the
2384 Curl_transfer() call below, as we're not ready to actually upload any
2385 data yet. */
2386
2387 switch(httpreq) {
2388
2389 case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2390
2391 if(conn->bits.authneg)
2392 http->postsize = 0;
2393 else
2394 http->postsize = data->state.infilesize;
2395
2396 if((http->postsize != -1) && !data->req.upload_chunky &&
2397 (conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
2398 /* only add Content-Length if not uploading chunked */
2399 result = Curl_dyn_addf(r, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2400 "\r\n", http->postsize);
2401 if(result)
2402 return result;
2403 }
2404
2405 if(http->postsize) {
2406 result = expect100(data, conn, r);
2407 if(result)
2408 return result;
2409 }
2410
2411 /* end of headers */
2412 result = Curl_dyn_add(r, "\r\n");
2413 if(result)
2414 return result;
2415
2416 /* set the upload size to the progress meter */
2417 Curl_pgrsSetUploadSize(data, http->postsize);
2418
2419 /* this sends the buffer and frees all the buffer resources */
2420 result = Curl_buffer_send(r, data, &data->info.request_size, 0,
2421 FIRSTSOCKET);
2422 if(result)
2423 failf(data, "Failed sending PUT request");
2424 else
2425 /* prepare for transfer */
2426 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
2427 http->postsize?FIRSTSOCKET:-1);
2428 if(result)
2429 return result;
2430 break;
2431
2432 case HTTPREQ_POST_FORM:
2433 case HTTPREQ_POST_MIME:
2434 /* This is form posting using mime data. */
2435 if(conn->bits.authneg) {
2436 /* nothing to post! */
2437 result = Curl_dyn_add(r, "Content-Length: 0\r\n\r\n");
2438 if(result)
2439 return result;
2440
2441 result = Curl_buffer_send(r, data, &data->info.request_size, 0,
2442 FIRSTSOCKET);
2443 if(result)
2444 failf(data, "Failed sending POST request");
2445 else
2446 /* setup variables for the upcoming transfer */
2447 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
2448 break;
2449 }
2450
2451 data->state.infilesize = http->postsize;
2452
2453 /* We only set Content-Length and allow a custom Content-Length if
2454 we don't upload data chunked, as RFC2616 forbids us to set both
2455 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2456 if(http->postsize != -1 && !data->req.upload_chunky &&
2457 (conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
2458 /* we allow replacing this header if not during auth negotiation,
2459 although it isn't very wise to actually set your own */
2460 result = Curl_dyn_addf(r,
2461 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2462 "\r\n", http->postsize);
2463 if(result)
2464 return result;
2465 }
2466
2467#ifndef CURL_DISABLE_MIME
2468 /* Output mime-generated headers. */
2469 {
2470 struct curl_slist *hdr;
2471
2472 for(hdr = http->sendit->curlheaders; hdr; hdr = hdr->next) {
2473 result = Curl_dyn_addf(r, "%s\r\n", hdr->data);
2474 if(result)
2475 return result;
2476 }
2477 }
2478#endif
2479
2480 /* For really small posts we don't use Expect: headers at all, and for
2481 the somewhat bigger ones we allow the app to disable it. Just make
2482 sure that the expect100header is always set to the preferred value
2483 here. */
2484 ptr = Curl_checkheaders(data, "Expect");
2485 if(ptr) {
2486 data->state.expect100header =
2487 Curl_compareheader(ptr, "Expect:", "100-continue");
2488 }
2489 else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
2490 result = expect100(data, conn, r);
2491 if(result)
2492 return result;
2493 }
2494 else
2495 data->state.expect100header = FALSE;
2496
2497 /* make the request end in a true CRLF */
2498 result = Curl_dyn_add(r, "\r\n");
2499 if(result)
2500 return result;
2501
2502 /* set the upload size to the progress meter */
2503 Curl_pgrsSetUploadSize(data, http->postsize);
2504
2505 /* Read from mime structure. */
2506 data->state.fread_func = (curl_read_callback) Curl_mime_read;
2507 data->state.in = (void *) http->sendit;
2508 http->sending = HTTPSEND_BODY;
2509
2510 /* this sends the buffer and frees all the buffer resources */
2511 result = Curl_buffer_send(r, data, &data->info.request_size, 0,
2512 FIRSTSOCKET);
2513 if(result)
2514 failf(data, "Failed sending POST request");
2515 else
2516 /* prepare for transfer */
2517 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
2518 http->postsize?FIRSTSOCKET:-1);
2519 if(result)
2520 return result;
2521
2522 break;
2523
2524 case HTTPREQ_POST:
2525 /* this is the simple POST, using x-www-form-urlencoded style */
2526
2527 if(conn->bits.authneg)
2528 http->postsize = 0;
2529 else
2530 /* the size of the post body */
2531 http->postsize = data->state.infilesize;
2532
2533 /* We only set Content-Length and allow a custom Content-Length if
2534 we don't upload data chunked, as RFC2616 forbids us to set both
2535 kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2536 if((http->postsize != -1) && !data->req.upload_chunky &&
2537 (conn->bits.authneg || !Curl_checkheaders(data, "Content-Length"))) {
2538 /* we allow replacing this header if not during auth negotiation,
2539 although it isn't very wise to actually set your own */
2540 result = Curl_dyn_addf(r, "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2541 "\r\n", http->postsize);
2542 if(result)
2543 return result;
2544 }
2545
2546 if(!Curl_checkheaders(data, "Content-Type")) {
2547 result = Curl_dyn_add(r, "Content-Type: application/"
2548 "x-www-form-urlencoded\r\n");
2549 if(result)
2550 return result;
2551 }
2552
2553 /* For really small posts we don't use Expect: headers at all, and for
2554 the somewhat bigger ones we allow the app to disable it. Just make
2555 sure that the expect100header is always set to the preferred value
2556 here. */
2557 ptr = Curl_checkheaders(data, "Expect");
2558 if(ptr) {
2559 data->state.expect100header =
2560 Curl_compareheader(ptr, "Expect:", "100-continue");
2561 }
2562 else if(http->postsize > EXPECT_100_THRESHOLD || http->postsize < 0) {
2563 result = expect100(data, conn, r);
2564 if(result)
2565 return result;
2566 }
2567 else
2568 data->state.expect100header = FALSE;
2569
2570#ifndef USE_HYPER
2571 /* With Hyper the body is always passed on separately */
2572 if(data->set.postfields) {
2573
2574 /* In HTTP2, we send request body in DATA frame regardless of
2575 its size. */
2576 if(conn->httpversion != 20 &&
2577 !data->state.expect100header &&
2578 (http->postsize < MAX_INITIAL_POST_SIZE)) {
2579 /* if we don't use expect: 100 AND
2580 postsize is less than MAX_INITIAL_POST_SIZE
2581
2582 then append the post data to the HTTP request header. This limit
2583 is no magic limit but only set to prevent really huge POSTs to
2584 get the data duplicated with malloc() and family. */
2585
2586 /* end of headers! */
2587 result = Curl_dyn_add(r, "\r\n");
2588 if(result)
2589 return result;
2590
2591 if(!data->req.upload_chunky) {
2592 /* We're not sending it 'chunked', append it to the request
2593 already now to reduce the number if send() calls */
2594 result = Curl_dyn_addn(r, data->set.postfields,
2595 (size_t)http->postsize);
2596 included_body = http->postsize;
2597 }
2598 else {
2599 if(http->postsize) {
2600 char chunk[16];
2601 /* Append the POST data chunky-style */
2602 msnprintf(chunk, sizeof(chunk), "%x\r\n", (int)http->postsize);
2603 result = Curl_dyn_add(r, chunk);
2604 if(!result) {
2605 included_body = http->postsize + strlen(chunk);
2606 result = Curl_dyn_addn(r, data->set.postfields,
2607 (size_t)http->postsize);
2608 if(!result)
2609 result = Curl_dyn_add(r, "\r\n");
2610 included_body += 2;
2611 }
2612 }
2613 if(!result) {
2614 result = Curl_dyn_add(r, "\x30\x0d\x0a\x0d\x0a");
2615 /* 0 CR LF CR LF */
2616 included_body += 5;
2617 }
2618 }
2619 if(result)
2620 return result;
2621 /* Make sure the progress information is accurate */
2622 Curl_pgrsSetUploadSize(data, http->postsize);
2623 }
2624 else {
2625 /* A huge POST coming up, do data separate from the request */
2626 http->postdata = data->set.postfields;
2627
2628 http->sending = HTTPSEND_BODY;
2629
2630 data->state.fread_func = (curl_read_callback)readmoredata;
2631 data->state.in = (void *)data;
2632
2633 /* set the upload size to the progress meter */
2634 Curl_pgrsSetUploadSize(data, http->postsize);
2635
2636 /* end of headers! */
2637 result = Curl_dyn_add(r, "\r\n");
2638 if(result)
2639 return result;
2640 }
2641 }
2642 else
2643#endif
2644 {
2645 /* end of headers! */
2646 result = Curl_dyn_add(r, "\r\n");
2647 if(result)
2648 return result;
2649
2650 if(data->req.upload_chunky && conn->bits.authneg) {
2651 /* Chunky upload is selected and we're negotiating auth still, send
2652 end-of-data only */
2653 result = Curl_dyn_add(r, (char *)"\x30\x0d\x0a\x0d\x0a");
2654 /* 0 CR LF CR LF */
2655 if(result)
2656 return result;
2657 }
2658
2659 else if(data->state.infilesize) {
2660 /* set the upload size to the progress meter */
2661 Curl_pgrsSetUploadSize(data, http->postsize?http->postsize:-1);
2662
2663 /* set the pointer to mark that we will send the post body using the
2664 read callback, but only if we're not in authenticate negotiation */
2665 if(!conn->bits.authneg)
2666 http->postdata = (char *)&http->postdata;
2667 }
2668 }
2669 /* issue the request */
2670 result = Curl_buffer_send(r, data, &data->info.request_size, included_body,
2671 FIRSTSOCKET);
2672
2673 if(result)
2674 failf(data, "Failed sending HTTP POST request");
2675 else
2676 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE,
2677 http->postdata?FIRSTSOCKET:-1);
2678 break;
2679
2680 default:
2681 result = Curl_dyn_add(r, "\r\n");
2682 if(result)
2683 return result;
2684
2685 /* issue the request */
2686 result = Curl_buffer_send(r, data, &data->info.request_size, 0,
2687 FIRSTSOCKET);
2688
2689 if(result)
2690 failf(data, "Failed sending HTTP request");
2691 else
2692 /* HTTP GET/HEAD download: */
2693 Curl_setup_transfer(data, FIRSTSOCKET, -1, TRUE, -1);
2694 }
2695
2696 return result;
2697}
2698
2699#if !defined(CURL_DISABLE_COOKIES)
2700CURLcode Curl_http_cookies(struct Curl_easy *data,
2701 struct connectdata *conn,
2702 struct dynbuf *r)
2703{
2704 CURLcode result = CURLE_OK;
2705 char *addcookies = NULL;
2706 if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie"))
2707 addcookies = data->set.str[STRING_COOKIE];
2708
2709 if(data->cookies || addcookies) {
2710 struct Cookie *co = NULL; /* no cookies from start */
2711 int count = 0;
2712
2713 if(data->cookies && data->state.cookie_engine) {
2714 const char *host = data->state.aptr.cookiehost ?
2715 data->state.aptr.cookiehost : conn->host.name;
2716 const bool secure_context =
2717 conn->handler->protocol&CURLPROTO_HTTPS ||
2718 strcasecompare("localhost", host) ||
2719 !strcmp(host, "127.0.0.1") ||
2720 !strcmp(host, "[::1]") ? TRUE : FALSE;
2721 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2722 co = Curl_cookie_getlist(data->cookies, host, data->state.up.path,
2723 secure_context);
2724 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2725 }
2726 if(co) {
2727 struct Cookie *store = co;
2728 /* now loop through all cookies that matched */
2729 while(co) {
2730 if(co->value) {
2731 if(0 == count) {
2732 result = Curl_dyn_add(r, "Cookie: ");
2733 if(result)
2734 break;
2735 }
2736 result = Curl_dyn_addf(r, "%s%s=%s", count?"; ":"",
2737 co->name, co->value);
2738 if(result)
2739 break;
2740 count++;
2741 }
2742 co = co->next; /* next cookie please */
2743 }
2744 Curl_cookie_freelist(store);
2745 }
2746 if(addcookies && !result) {
2747 if(!count)
2748 result = Curl_dyn_add(r, "Cookie: ");
2749 if(!result) {
2750 result = Curl_dyn_addf(r, "%s%s", count?"; ":"", addcookies);
2751 count++;
2752 }
2753 }
2754 if(count && !result)
2755 result = Curl_dyn_add(r, "\r\n");
2756
2757 if(result)
2758 return result;
2759 }
2760 return result;
2761}
2762#endif
2763
2764CURLcode Curl_http_range(struct Curl_easy *data,
2765 Curl_HttpReq httpreq)
2766{
2767 if(data->state.use_range) {
2768 /*
2769 * A range is selected. We use different headers whether we're downloading
2770 * or uploading and we always let customized headers override our internal
2771 * ones if any such are specified.
2772 */
2773 if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2774 !Curl_checkheaders(data, "Range")) {
2775 /* if a line like this was already allocated, free the previous one */
2776 free(data->state.aptr.rangeline);
2777 data->state.aptr.rangeline = aprintf("Range: bytes=%s\r\n",
2778 data->state.range);
2779 }
2780 else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
2781 !Curl_checkheaders(data, "Content-Range")) {
2782
2783 /* if a line like this was already allocated, free the previous one */
2784 free(data->state.aptr.rangeline);
2785
2786 if(data->set.set_resume_from < 0) {
2787 /* Upload resume was asked for, but we don't know the size of the
2788 remote part so we tell the server (and act accordingly) that we
2789 upload the whole file (again) */
2790 data->state.aptr.rangeline =
2791 aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2792 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2793 data->state.infilesize - 1, data->state.infilesize);
2794
2795 }
2796 else if(data->state.resume_from) {
2797 /* This is because "resume" was selected */
2798 curl_off_t total_expected_size =
2799 data->state.resume_from + data->state.infilesize;
2800 data->state.aptr.rangeline =
2801 aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2802 "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2803 data->state.range, total_expected_size-1,
2804 total_expected_size);
2805 }
2806 else {
2807 /* Range was selected and then we just pass the incoming range and
2808 append total size */
2809 data->state.aptr.rangeline =
2810 aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2811 data->state.range, data->state.infilesize);
2812 }
2813 if(!data->state.aptr.rangeline)
2814 return CURLE_OUT_OF_MEMORY;
2815 }
2816 }
2817 return CURLE_OK;
2818}
2819
2820CURLcode Curl_http_resume(struct Curl_easy *data,
2821 struct connectdata *conn,
2822 Curl_HttpReq httpreq)
2823{
2824 if((HTTPREQ_POST == httpreq || HTTPREQ_PUT == httpreq) &&
2825 data->state.resume_from) {
2826 /**********************************************************************
2827 * Resuming upload in HTTP means that we PUT or POST and that we have
2828 * got a resume_from value set. The resume value has already created
2829 * a Range: header that will be passed along. We need to "fast forward"
2830 * the file the given number of bytes and decrease the assume upload
2831 * file size before we continue this venture in the dark lands of HTTP.
2832 * Resuming mime/form posting at an offset > 0 has no sense and is ignored.
2833 *********************************************************************/
2834
2835 if(data->state.resume_from < 0) {
2836 /*
2837 * This is meant to get the size of the present remote-file by itself.
2838 * We don't support this now. Bail out!
2839 */
2840 data->state.resume_from = 0;
2841 }
2842
2843 if(data->state.resume_from && !data->state.this_is_a_follow) {
2844 /* do we still game? */
2845
2846 /* Now, let's read off the proper amount of bytes from the
2847 input. */
2848 int seekerr = CURL_SEEKFUNC_CANTSEEK;
2849 if(conn->seek_func) {
2850 Curl_set_in_callback(data, true);
2851 seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2852 SEEK_SET);
2853 Curl_set_in_callback(data, false);
2854 }
2855
2856 if(seekerr != CURL_SEEKFUNC_OK) {
2857 curl_off_t passed = 0;
2858
2859 if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2860 failf(data, "Could not seek stream");
2861 return CURLE_READ_ERROR;
2862 }
2863 /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2864 do {
2865 size_t readthisamountnow =
2866 (data->state.resume_from - passed > data->set.buffer_size) ?
2867 (size_t)data->set.buffer_size :
2868 curlx_sotouz(data->state.resume_from - passed);
2869
2870 size_t actuallyread =
2871 data->state.fread_func(data->state.buffer, 1, readthisamountnow,
2872 data->state.in);
2873
2874 passed += actuallyread;
2875 if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2876 /* this checks for greater-than only to make sure that the
2877 CURL_READFUNC_ABORT return code still aborts */
2878 failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2879 " bytes from the input", passed);
2880 return CURLE_READ_ERROR;
2881 }
2882 } while(passed < data->state.resume_from);
2883 }
2884
2885 /* now, decrease the size of the read */
2886 if(data->state.infilesize>0) {
2887 data->state.infilesize -= data->state.resume_from;
2888
2889 if(data->state.infilesize <= 0) {
2890 failf(data, "File already completely uploaded");
2891 return CURLE_PARTIAL_FILE;
2892 }
2893 }
2894 /* we've passed, proceed as normal */
2895 }
2896 }
2897 return CURLE_OK;
2898}
2899
2900CURLcode Curl_http_firstwrite(struct Curl_easy *data,
2901 struct connectdata *conn,
2902 bool *done)
2903{
2904 struct SingleRequest *k = &data->req;
2905 DEBUGASSERT(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP));
2906 if(data->req.ignore_cl) {
2907 k->size = k->maxdownload = -1;
2908 }
2909 else if(k->size != -1) {
2910 /* We wait until after all headers have been received to set this so that
2911 we know for sure Content-Length is valid. */
2912 if(data->set.max_filesize &&
2913 k->size > data->set.max_filesize) {
2914 failf(data, "Maximum file size exceeded");
2915 return CURLE_FILESIZE_EXCEEDED;
2916 }
2917 Curl_pgrsSetDownloadSize(data, k->size);
2918 }
2919
2920 if(data->req.newurl) {
2921 if(conn->bits.close) {
2922 /* Abort after the headers if "follow Location" is set
2923 and we're set to close anyway. */
2924 k->keepon &= ~KEEP_RECV;
2925 *done = TRUE;
2926 return CURLE_OK;
2927 }
2928 /* We have a new url to load, but since we want to be able to re-use this
2929 connection properly, we read the full response in "ignore more" */
2930 k->ignorebody = TRUE;
2931 infof(data, "Ignoring the response-body");
2932 }
2933 if(data->state.resume_from && !k->content_range &&
2934 (data->state.httpreq == HTTPREQ_GET) &&
2935 !k->ignorebody) {
2936
2937 if(k->size == data->state.resume_from) {
2938 /* The resume point is at the end of file, consider this fine even if it
2939 doesn't allow resume from here. */
2940 infof(data, "The entire document is already downloaded");
2941 connclose(conn, "already downloaded");
2942 /* Abort download */
2943 k->keepon &= ~KEEP_RECV;
2944 *done = TRUE;
2945 return CURLE_OK;
2946 }
2947
2948 /* we wanted to resume a download, although the server doesn't seem to
2949 * support this and we did this with a GET (if it wasn't a GET we did a
2950 * POST or PUT resume) */
2951 failf(data, "HTTP server doesn't seem to support "
2952 "byte ranges. Cannot resume.");
2953 return CURLE_RANGE_ERROR;
2954 }
2955
2956 if(data->set.timecondition && !data->state.range) {
2957 /* A time condition has been set AND no ranges have been requested. This
2958 seems to be what chapter 13.3.4 of RFC 2616 defines to be the correct
2959 action for a HTTP/1.1 client */
2960
2961 if(!Curl_meets_timecondition(data, k->timeofdoc)) {
2962 *done = TRUE;
2963 /* We're simulating a http 304 from server so we return
2964 what should have been returned from the server */
2965 data->info.httpcode = 304;
2966 infof(data, "Simulate a HTTP 304 response!");
2967 /* we abort the transfer before it is completed == we ruin the
2968 re-use ability. Close the connection */
2969 connclose(conn, "Simulated 304 handling");
2970 return CURLE_OK;
2971 }
2972 } /* we have a time condition */
2973
2974 return CURLE_OK;
2975}
2976
2977#ifdef HAVE_LIBZ
2978CURLcode Curl_transferencode(struct Curl_easy *data)
2979{
2980 if(!Curl_checkheaders(data, "TE") &&
2981 data->set.http_transfer_encoding) {
2982 /* When we are to insert a TE: header in the request, we must also insert
2983 TE in a Connection: header, so we need to merge the custom provided
2984 Connection: header and prevent the original to get sent. Note that if
2985 the user has inserted his/her own TE: header we don't do this magic
2986 but then assume that the user will handle it all! */
2987 char *cptr = Curl_checkheaders(data, "Connection");
2988#define TE_HEADER "TE: gzip\r\n"
2989
2990 Curl_safefree(data->state.aptr.te);
2991
2992 if(cptr) {
2993 cptr = Curl_copy_header_value(cptr);
2994 if(!cptr)
2995 return CURLE_OUT_OF_MEMORY;
2996 }
2997
2998 /* Create the (updated) Connection: header */
2999 data->state.aptr.te = aprintf("Connection: %s%sTE\r\n" TE_HEADER,
3000 cptr ? cptr : "", (cptr && *cptr) ? ", ":"");
3001
3002 free(cptr);
3003 if(!data->state.aptr.te)
3004 return CURLE_OUT_OF_MEMORY;
3005 }
3006 return CURLE_OK;
3007}
3008#endif
3009
3010#ifndef USE_HYPER
3011/*
3012 * Curl_http() gets called from the generic multi_do() function when a HTTP
3013 * request is to be performed. This creates and sends a properly constructed
3014 * HTTP request.
3015 */
3016CURLcode Curl_http(struct Curl_easy *data, bool *done)
3017{
3018 struct connectdata *conn = data->conn;
3019 CURLcode result = CURLE_OK;
3020 struct HTTP *http;
3021 Curl_HttpReq httpreq;
3022 const char *te = ""; /* transfer-encoding */
3023 const char *request;
3024 const char *httpstring;
3025 struct dynbuf req;
3026 char *altused = NULL;
3027 const char *p_accept; /* Accept: string */
3028
3029 /* Always consider the DO phase done after this function call, even if there
3030 may be parts of the request that are not yet sent, since we can deal with
3031 the rest of the request in the PERFORM phase. */
3032 *done = TRUE;
3033
3034 if(conn->transport != TRNSPRT_QUIC) {
3035 if(conn->httpversion < 20) { /* unless the connection is re-used and
3036 already http2 */
3037 switch(conn->negnpn) {
3038 case CURL_HTTP_VERSION_2:
3039 conn->httpversion = 20; /* we know we're on HTTP/2 now */
3040
3041 result = Curl_http2_switched(data, NULL, 0);
3042 if(result)
3043 return result;
3044 break;
3045 case CURL_HTTP_VERSION_1_1:
3046 /* continue with HTTP/1.1 when explicitly requested */
3047 break;
3048 default:
3049 /* Check if user wants to use HTTP/2 with clear TCP*/
3050#ifdef USE_NGHTTP2
3051 if(data->state.httpwant == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
3052#ifndef CURL_DISABLE_PROXY
3053 if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
3054 /* We don't support HTTP/2 proxies yet. Also it's debatable
3055 whether or not this setting should apply to HTTP/2 proxies. */
3056 infof(data, "Ignoring HTTP/2 prior knowledge due to proxy");
3057 break;
3058 }
3059#endif
3060 DEBUGF(infof(data, "HTTP/2 over clean TCP"));
3061 conn->httpversion = 20;
3062
3063 result = Curl_http2_switched(data, NULL, 0);
3064 if(result)
3065 return result;
3066 }
3067#endif
3068 break;
3069 }
3070 }
3071 else {
3072 /* prepare for a http2 request */
3073 result = Curl_http2_setup(data, conn);
3074 if(result)
3075 return result;
3076 }
3077 }
3078 http = data->req.p.http;
3079 DEBUGASSERT(http);
3080
3081 result = Curl_http_host(data, conn);
3082 if(result)
3083 return result;
3084
3085 result = Curl_http_useragent(data);
3086 if(result)
3087 return result;
3088
3089 Curl_http_method(data, conn, &request, &httpreq);
3090
3091 /* setup the authentication headers */
3092 {
3093 char *pq = NULL;
3094 if(data->state.up.query) {
3095 pq = aprintf("%s?%s", data->state.up.path, data->state.up.query);
3096 if(!pq)
3097 return CURLE_OUT_OF_MEMORY;
3098 }
3099 result = Curl_http_output_auth(data, conn, request, httpreq,
3100 (pq ? pq : data->state.up.path), FALSE);
3101 free(pq);
3102 if(result)
3103 return result;
3104 }
3105
3106 Curl_safefree(data->state.aptr.ref);
3107 if(data->state.referer && !Curl_checkheaders(data, "Referer")) {
3108 data->state.aptr.ref = aprintf("Referer: %s\r\n", data->state.referer);
3109 if(!data->state.aptr.ref)
3110 return CURLE_OUT_OF_MEMORY;
3111 }
3112
3113 if(!Curl_checkheaders(data, "Accept-Encoding") &&
3114 data->set.str[STRING_ENCODING]) {
3115 Curl_safefree(data->state.aptr.accept_encoding);
3116 data->state.aptr.accept_encoding =
3117 aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
3118 if(!data->state.aptr.accept_encoding)
3119 return CURLE_OUT_OF_MEMORY;
3120 }
3121 else
3122 Curl_safefree(data->state.aptr.accept_encoding);
3123
3124#ifdef HAVE_LIBZ
3125 /* we only consider transfer-encoding magic if libz support is built-in */
3126 result = Curl_transferencode(data);
3127 if(result)
3128 return result;
3129#endif
3130
3131 result = Curl_http_body(data, conn, httpreq, &te);
3132 if(result)
3133 return result;
3134
3135 p_accept = Curl_checkheaders(data, "Accept")?NULL:"Accept: */*\r\n";
3136
3137 result = Curl_http_resume(data, conn, httpreq);
3138 if(result)
3139 return result;
3140
3141 result = Curl_http_range(data, httpreq);
3142 if(result)
3143 return result;
3144
3145 httpstring = get_http_string(data, conn);
3146
3147 /* initialize a dynamic send-buffer */
3148 Curl_dyn_init(&req, DYN_HTTP_REQUEST);
3149
3150 /* make sure the header buffer is reset - if there are leftovers from a
3151 previous transfer */
3152 Curl_dyn_reset(&data->state.headerb);
3153
3154 /* add the main request stuff */
3155 /* GET/HEAD/POST/PUT */
3156 result = Curl_dyn_addf(&req, "%s ", request);
3157 if(!result)
3158 result = Curl_http_target(data, conn, &req);
3159 if(result) {
3160 Curl_dyn_free(&req);
3161 return result;
3162 }
3163
3164#ifndef CURL_DISABLE_ALTSVC
3165 if(conn->bits.altused && !Curl_checkheaders(data, "Alt-Used")) {
3166 altused = aprintf("Alt-Used: %s:%d\r\n",
3167 conn->conn_to_host.name, conn->conn_to_port);
3168 if(!altused) {
3169 Curl_dyn_free(&req);
3170 return CURLE_OUT_OF_MEMORY;
3171 }
3172 }
3173#endif
3174 result =
3175 Curl_dyn_addf(&req,
3176 " HTTP/%s\r\n" /* HTTP version */
3177 "%s" /* host */
3178 "%s" /* proxyuserpwd */
3179 "%s" /* userpwd */
3180 "%s" /* range */
3181 "%s" /* user agent */
3182 "%s" /* accept */
3183 "%s" /* TE: */
3184 "%s" /* accept-encoding */
3185 "%s" /* referer */
3186 "%s" /* Proxy-Connection */
3187 "%s" /* transfer-encoding */
3188 "%s",/* Alt-Used */
3189
3190 httpstring,
3191 (data->state.aptr.host?data->state.aptr.host:""),
3192 data->state.aptr.proxyuserpwd?
3193 data->state.aptr.proxyuserpwd:"",
3194 data->state.aptr.userpwd?data->state.aptr.userpwd:"",
3195 (data->state.use_range && data->state.aptr.rangeline)?
3196 data->state.aptr.rangeline:"",
3197 (data->set.str[STRING_USERAGENT] &&
3198 *data->set.str[STRING_USERAGENT] &&
3199 data->state.aptr.uagent)?
3200 data->state.aptr.uagent:"",
3201 p_accept?p_accept:"",
3202 data->state.aptr.te?data->state.aptr.te:"",
3203 (data->set.str[STRING_ENCODING] &&
3204 *data->set.str[STRING_ENCODING] &&
3205 data->state.aptr.accept_encoding)?
3206 data->state.aptr.accept_encoding:"",
3207 (data->state.referer && data->state.aptr.ref)?
3208 data->state.aptr.ref:"" /* Referer: <data> */,
3209#ifndef CURL_DISABLE_PROXY
3210 (conn->bits.httpproxy &&
3211 !conn->bits.tunnel_proxy &&
3212 !Curl_checkheaders(data, "Proxy-Connection") &&
3213 !Curl_checkProxyheaders(data, conn, "Proxy-Connection"))?
3214 "Proxy-Connection: Keep-Alive\r\n":"",
3215#else
3216 "",
3217#endif
3218 te,
3219 altused ? altused : ""
3220 );
3221
3222 /* clear userpwd and proxyuserpwd to avoid re-using old credentials
3223 * from re-used connections */
3224 Curl_safefree(data->state.aptr.userpwd);
3225 Curl_safefree(data->state.aptr.proxyuserpwd);
3226 free(altused);
3227
3228 if(result) {
3229 Curl_dyn_free(&req);
3230 return result;
3231 }
3232
3233 if(!(conn->handler->flags&PROTOPT_SSL) &&
3234 conn->httpversion != 20 &&
3235 (data->state.httpwant == CURL_HTTP_VERSION_2)) {
3236 /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
3237 over SSL */
3238 result = Curl_http2_request_upgrade(&req, data);
3239 if(result) {
3240 Curl_dyn_free(&req);
3241 return result;
3242 }
3243 }
3244
3245 result = Curl_http_cookies(data, conn, &req);
3246 if(!result)
3247 result = Curl_add_timecondition(data, &req);
3248 if(!result)
3249 result = Curl_add_custom_headers(data, FALSE, &req);
3250
3251 if(!result) {
3252 http->postdata = NULL; /* nothing to post at this point */
3253 if((httpreq == HTTPREQ_GET) ||
3254 (httpreq == HTTPREQ_HEAD))
3255 Curl_pgrsSetUploadSize(data, 0); /* nothing */
3256
3257 /* bodysend takes ownership of the 'req' memory on success */
3258 result = Curl_http_bodysend(data, conn, &req, httpreq);
3259 }
3260 if(result) {
3261 Curl_dyn_free(&req);
3262 return result;
3263 }
3264
3265 if((http->postsize > -1) &&
3266 (http->postsize <= data->req.writebytecount) &&
3267 (http->sending != HTTPSEND_REQUEST))
3268 data->req.upload_done = TRUE;
3269
3270 if(data->req.writebytecount) {
3271 /* if a request-body has been sent off, we make sure this progress is noted
3272 properly */
3273 Curl_pgrsSetUploadCounter(data, data->req.writebytecount);
3274 if(Curl_pgrsUpdate(data))
3275 result = CURLE_ABORTED_BY_CALLBACK;
3276
3277 if(!http->postsize) {
3278 /* already sent the entire request body, mark the "upload" as
3279 complete */
3280 infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
3281 " out of %" CURL_FORMAT_CURL_OFF_T " bytes",
3282 data->req.writebytecount, http->postsize);
3283 data->req.upload_done = TRUE;
3284 data->req.keepon &= ~KEEP_SEND; /* we're done writing */
3285 data->req.exp100 = EXP100_SEND_DATA; /* already sent */
3286 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
3287 }
3288 }
3289
3290 if((conn->httpversion == 20) && data->req.upload_chunky)
3291 /* upload_chunky was set above to set up the request in a chunky fashion,
3292 but is disabled here again to avoid that the chunked encoded version is
3293 actually used when sending the request body over h2 */
3294 data->req.upload_chunky = FALSE;
3295 return result;
3296}
3297
3298#endif /* USE_HYPER */
3299
3300typedef enum {
3301 STATUS_UNKNOWN, /* not enough data to tell yet */
3302 STATUS_DONE, /* a status line was read */
3303 STATUS_BAD /* not a status line */
3304} statusline;
3305
3306
3307/* Check a string for a prefix. Check no more than 'len' bytes */
3308static bool checkprefixmax(const char *prefix, const char *buffer, size_t len)
3309{
3310 size_t ch = CURLMIN(strlen(prefix), len);
3311 return curl_strnequal(prefix, buffer, ch);
3312}
3313
3314/*
3315 * checkhttpprefix()
3316 *
3317 * Returns TRUE if member of the list matches prefix of string
3318 */
3319static statusline
3320checkhttpprefix(struct Curl_easy *data,
3321 const char *s, size_t len)
3322{
3323 struct curl_slist *head = data->set.http200aliases;
3324 statusline rc = STATUS_BAD;
3325 statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
3326#ifdef CURL_DOES_CONVERSIONS
3327 /* convert from the network encoding using a scratch area */
3328 char *scratch = strdup(s);
3329 if(NULL == scratch) {
3330 failf(data, "Failed to allocate memory for conversion!");
3331 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
3332 }
3333 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
3334 /* Curl_convert_from_network calls failf if unsuccessful */
3335 free(scratch);
3336 return FALSE; /* can't return CURLE_foobar so return FALSE */
3337 }
3338 s = scratch;
3339#endif /* CURL_DOES_CONVERSIONS */
3340
3341 while(head) {
3342 if(checkprefixmax(head->data, s, len)) {
3343 rc = onmatch;
3344 break;
3345 }
3346 head = head->next;
3347 }
3348
3349 if((rc != STATUS_DONE) && (checkprefixmax("HTTP/", s, len)))
3350 rc = onmatch;
3351
3352#ifdef CURL_DOES_CONVERSIONS
3353 free(scratch);
3354#endif /* CURL_DOES_CONVERSIONS */
3355 return rc;
3356}
3357
3358#ifndef CURL_DISABLE_RTSP
3359static statusline
3360checkrtspprefix(struct Curl_easy *data,
3361 const char *s, size_t len)
3362{
3363 statusline result = STATUS_BAD;
3364 statusline onmatch = len >= 5? STATUS_DONE : STATUS_UNKNOWN;
3365
3366#ifdef CURL_DOES_CONVERSIONS
3367 /* convert from the network encoding using a scratch area */
3368 char *scratch = strdup(s);
3369 if(NULL == scratch) {
3370 failf(data, "Failed to allocate memory for conversion!");
3371 return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
3372 }
3373 if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s) + 1)) {
3374 /* Curl_convert_from_network calls failf if unsuccessful */
3375 result = FALSE; /* can't return CURLE_foobar so return FALSE */
3376 }
3377 else if(checkprefixmax("RTSP/", scratch, len))
3378 result = onmatch;
3379 free(scratch);
3380#else
3381 (void)data; /* unused */
3382 if(checkprefixmax("RTSP/", s, len))
3383 result = onmatch;
3384#endif /* CURL_DOES_CONVERSIONS */
3385
3386 return result;
3387}
3388#endif /* CURL_DISABLE_RTSP */
3389
3390static statusline
3391checkprotoprefix(struct Curl_easy *data, struct connectdata *conn,
3392 const char *s, size_t len)
3393{
3394#ifndef CURL_DISABLE_RTSP
3395 if(conn->handler->protocol & CURLPROTO_RTSP)
3396 return checkrtspprefix(data, s, len);
3397#else
3398 (void)conn;
3399#endif /* CURL_DISABLE_RTSP */
3400
3401 return checkhttpprefix(data, s, len);
3402}
3403
3404/*
3405 * Curl_http_header() parses a single response header.
3406 */
3407CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn,
3408 char *headp)
3409{
3410 CURLcode result;
3411 struct SingleRequest *k = &data->req;
3412 /* Check for Content-Length: header lines to get size */
3413 if(!k->http_bodyless &&
3414 !data->set.ignorecl && checkprefix("Content-Length:", headp)) {
3415 curl_off_t contentlength;
3416 CURLofft offt = curlx_strtoofft(headp + strlen("Content-Length:"),
3417 NULL, 10, &contentlength);
3418
3419 if(offt == CURL_OFFT_OK) {
3420 k->size = contentlength;
3421 k->maxdownload = k->size;
3422 }
3423 else if(offt == CURL_OFFT_FLOW) {
3424 /* out of range */
3425 if(data->set.max_filesize) {
3426 failf(data, "Maximum file size exceeded");
3427 return CURLE_FILESIZE_EXCEEDED;
3428 }
3429 streamclose(conn, "overflow content-length");
3430 infof(data, "Overflow Content-Length: value!");
3431 }
3432 else {
3433 /* negative or just rubbish - bad HTTP */
3434 failf(data, "Invalid Content-Length: value");
3435 return CURLE_WEIRD_SERVER_REPLY;
3436 }
3437 }
3438 /* check for Content-Type: header lines to get the MIME-type */
3439 else if(checkprefix("Content-Type:", headp)) {
3440 char *contenttype = Curl_copy_header_value(headp);
3441 if(!contenttype)
3442 return CURLE_OUT_OF_MEMORY;
3443 if(!*contenttype)
3444 /* ignore empty data */
3445 free(contenttype);
3446 else {
3447 Curl_safefree(data->info.contenttype);
3448 data->info.contenttype = contenttype;
3449 }
3450 }
3451#ifndef CURL_DISABLE_PROXY
3452 else if((conn->httpversion == 10) &&
3453 conn->bits.httpproxy &&
3454 Curl_compareheader(headp, "Proxy-Connection:", "keep-alive")) {
3455 /*
3456 * When a HTTP/1.0 reply comes when using a proxy, the
3457 * 'Proxy-Connection: keep-alive' line tells us the
3458 * connection will be kept alive for our pleasure.
3459 * Default action for 1.0 is to close.
3460 */
3461 connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
3462 infof(data, "HTTP/1.0 proxy connection set to keep alive!");
3463 }
3464 else if((conn->httpversion == 11) &&
3465 conn->bits.httpproxy &&
3466 Curl_compareheader(headp, "Proxy-Connection:", "close")) {
3467 /*
3468 * We get a HTTP/1.1 response from a proxy and it says it'll
3469 * close down after this transfer.
3470 */
3471 connclose(conn, "Proxy-Connection: asked to close after done");
3472 infof(data, "HTTP/1.1 proxy connection set close!");
3473 }
3474#endif
3475 else if((conn->httpversion == 10) &&
3476 Curl_compareheader(headp, "Connection:", "keep-alive")) {
3477 /*
3478 * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3479 * tells us the connection will be kept alive for our
3480 * pleasure. Default action for 1.0 is to close.
3481 *
3482 * [RFC2068, section 19.7.1] */
3483 connkeep(conn, "Connection keep-alive");
3484 infof(data, "HTTP/1.0 connection set to keep alive!");
3485 }
3486 else if(Curl_compareheader(headp, "Connection:", "close")) {
3487 /*
3488 * [RFC 2616, section 8.1.2.1]
3489 * "Connection: close" is HTTP/1.1 language and means that
3490 * the connection will close when this request has been
3491 * served.
3492 */
3493 streamclose(conn, "Connection: close used");
3494 }
3495 else if(!k->http_bodyless && checkprefix("Transfer-Encoding:", headp)) {
3496 /* One or more encodings. We check for chunked and/or a compression
3497 algorithm. */
3498 /*
3499 * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3500 * means that the server will send a series of "chunks". Each
3501 * chunk starts with line with info (including size of the
3502 * coming block) (terminated with CRLF), then a block of data
3503 * with the previously mentioned size. There can be any amount
3504 * of chunks, and a chunk-data set to zero signals the
3505 * end-of-chunks. */
3506
3507 result = Curl_build_unencoding_stack(data,
3508 headp + strlen("Transfer-Encoding:"),
3509 TRUE);
3510 if(result)
3511 return result;
3512 if(!k->chunk) {
3513 /* if this isn't chunked, only close can signal the end of this transfer
3514 as Content-Length is said not to be trusted for transfer-encoding! */
3515 connclose(conn, "HTTP/1.1 transfer-encoding without chunks");
3516 k->ignore_cl = TRUE;
3517 }
3518 }
3519 else if(!k->http_bodyless && checkprefix("Content-Encoding:", headp) &&
3520 data->set.str[STRING_ENCODING]) {
3521 /*
3522 * Process Content-Encoding. Look for the values: identity,
3523 * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3524 * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3525 * 2616). zlib cannot handle compress. However, errors are
3526 * handled further down when the response body is processed
3527 */
3528 result = Curl_build_unencoding_stack(data,
3529 headp + strlen("Content-Encoding:"),
3530 FALSE);
3531 if(result)
3532 return result;
3533 }
3534 else if(checkprefix("Retry-After:", headp)) {
3535 /* Retry-After = HTTP-date / delay-seconds */
3536 curl_off_t retry_after = 0; /* zero for unknown or "now" */
3537 time_t date = Curl_getdate_capped(headp + strlen("Retry-After:"));
3538 if(-1 == date) {
3539 /* not a date, try it as a decimal number */
3540 (void)curlx_strtoofft(headp + strlen("Retry-After:"),
3541 NULL, 10, &retry_after);
3542 }
3543 else
3544 /* convert date to number of seconds into the future */
3545 retry_after = date - time(NULL);
3546 data->info.retry_after = retry_after; /* store it */
3547 }
3548 else if(!k->http_bodyless && checkprefix("Content-Range:", headp)) {
3549 /* Content-Range: bytes [num]-
3550 Content-Range: bytes: [num]-
3551 Content-Range: [num]-
3552 Content-Range: [asterisk]/[total]
3553
3554 The second format was added since Sun's webserver
3555 JavaWebServer/1.1.1 obviously sends the header this way!
3556 The third added since some servers use that!
3557 The forth means the requested range was unsatisfied.
3558 */
3559
3560 char *ptr = headp + strlen("Content-Range:");
3561
3562 /* Move forward until first digit or asterisk */
3563 while(*ptr && !ISDIGIT(*ptr) && *ptr != '*')
3564 ptr++;
3565
3566 /* if it truly stopped on a digit */
3567 if(ISDIGIT(*ptr)) {
3568 if(!curlx_strtoofft(ptr, NULL, 10, &k->offset)) {
3569 if(data->state.resume_from == k->offset)
3570 /* we asked for a resume and we got it */
3571 k->content_range = TRUE;
3572 }
3573 }
3574 else
3575 data->state.resume_from = 0; /* get everything */
3576 }
3577#if !defined(CURL_DISABLE_COOKIES)
3578 else if(data->cookies && data->state.cookie_engine &&
3579 checkprefix("Set-Cookie:", headp)) {
3580 /* If there is a custom-set Host: name, use it here, or else use real peer
3581 host name. */
3582 const char *host = data->state.aptr.cookiehost?
3583 data->state.aptr.cookiehost:conn->host.name;
3584 const bool secure_context =
3585 conn->handler->protocol&CURLPROTO_HTTPS ||
3586 strcasecompare("localhost", host) ||
3587 !strcmp(host, "127.0.0.1") ||
3588 !strcmp(host, "[::1]") ? TRUE : FALSE;
3589
3590 Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3591 CURL_LOCK_ACCESS_SINGLE);
3592 Curl_cookie_add(data, data->cookies, TRUE, FALSE,
3593 headp + strlen("Set-Cookie:"), host,
3594 data->state.up.path, secure_context);
3595 Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3596 }
3597#endif
3598 else if(!k->http_bodyless && checkprefix("Last-Modified:", headp) &&
3599 (data->set.timecondition || data->set.get_filetime) ) {
3600 k->timeofdoc = Curl_getdate_capped(headp + strlen("Last-Modified:"));
3601 if(data->set.get_filetime)
3602 data->info.filetime = k->timeofdoc;
3603 }
3604 else if((checkprefix("WWW-Authenticate:", headp) &&
3605 (401 == k->httpcode)) ||
3606 (checkprefix("Proxy-authenticate:", headp) &&
3607 (407 == k->httpcode))) {
3608
3609 bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3610 char *auth = Curl_copy_header_value(headp);
3611 if(!auth)
3612 return CURLE_OUT_OF_MEMORY;
3613
3614 result = Curl_http_input_auth(data, proxy, auth);
3615
3616 free(auth);
3617
3618 if(result)
3619 return result;
3620 }
3621#ifdef USE_SPNEGO
3622 else if(checkprefix("Persistent-Auth:", headp)) {
3623 struct negotiatedata *negdata = &conn->negotiate;
3624 struct auth *authp = &data->state.authhost;
3625 if(authp->picked == CURLAUTH_NEGOTIATE) {
3626 char *persistentauth = Curl_copy_header_value(headp);
3627 if(!persistentauth)
3628 return CURLE_OUT_OF_MEMORY;
3629 negdata->noauthpersist = checkprefix("false", persistentauth)?
3630 TRUE:FALSE;
3631 negdata->havenoauthpersist = TRUE;
3632 infof(data, "Negotiate: noauthpersist -> %d, header part: %s",
3633 negdata->noauthpersist, persistentauth);
3634 free(persistentauth);
3635 }
3636 }
3637#endif
3638 else if((k->httpcode >= 300 && k->httpcode < 400) &&
3639 checkprefix("Location:", headp) &&
3640 !data->req.location) {
3641 /* this is the URL that the server advises us to use instead */
3642 char *location = Curl_copy_header_value(headp);
3643 if(!location)
3644 return CURLE_OUT_OF_MEMORY;
3645 if(!*location)
3646 /* ignore empty data */
3647 free(location);
3648 else {
3649 data->req.location = location;
3650
3651 if(data->set.http_follow_location) {
3652 DEBUGASSERT(!data->req.newurl);
3653 data->req.newurl = strdup(data->req.location); /* clone */
3654 if(!data->req.newurl)
3655 return CURLE_OUT_OF_MEMORY;
3656
3657 /* some cases of POST and PUT etc needs to rewind the data
3658 stream at this point */
3659 result = http_perhapsrewind(data, conn);
3660 if(result)
3661 return result;
3662 }
3663 }
3664 }
3665
3666#ifndef CURL_DISABLE_HSTS
3667 /* If enabled, the header is incoming and this is over HTTPS */
3668 else if(data->hsts && checkprefix("Strict-Transport-Security:", headp) &&
3669 (conn->handler->flags & PROTOPT_SSL)) {
3670 CURLcode check =
3671 Curl_hsts_parse(data->hsts, data->state.up.hostname,
3672 headp + strlen("Strict-Transport-Security:"));
3673 if(check)
3674 infof(data, "Illegal STS header skipped");
3675#ifdef DEBUGBUILD
3676 else
3677 infof(data, "Parsed STS header fine (%zu entries)",
3678 data->hsts->list.size);
3679#endif
3680 }
3681#endif
3682#ifndef CURL_DISABLE_ALTSVC
3683 /* If enabled, the header is incoming and this is over HTTPS */
3684 else if(data->asi && checkprefix("Alt-Svc:", headp) &&
3685 ((conn->handler->flags & PROTOPT_SSL) ||
3686#ifdef CURLDEBUG
3687 /* allow debug builds to circumvent the HTTPS restriction */
3688 getenv("CURL_ALTSVC_HTTP")
3689#else
3690 0
3691#endif
3692 )) {
3693 /* the ALPN of the current request */
3694 enum alpnid id = (conn->httpversion == 20) ? ALPN_h2 : ALPN_h1;
3695 result = Curl_altsvc_parse(data, data->asi,
3696 headp + strlen("Alt-Svc:"),
3697 id, conn->host.name,
3698 curlx_uitous(conn->remote_port));
3699 if(result)
3700 return result;
3701 }
3702#endif
3703 else if(conn->handler->protocol & CURLPROTO_RTSP) {
3704 result = Curl_rtsp_parseheader(data, headp);
3705 if(result)
3706 return result;
3707 }
3708 return CURLE_OK;
3709}
3710
3711/*
3712 * Called after the first HTTP response line (the status line) has been
3713 * received and parsed.
3714 */
3715
3716CURLcode Curl_http_statusline(struct Curl_easy *data,
3717 struct connectdata *conn)
3718{
3719 struct SingleRequest *k = &data->req;
3720 data->info.httpcode = k->httpcode;
3721
3722 data->info.httpversion = conn->httpversion;
3723 if(!data->state.httpversion ||
3724 data->state.httpversion > conn->httpversion)
3725 /* store the lowest server version we encounter */
3726 data->state.httpversion = conn->httpversion;
3727
3728 /*
3729 * This code executes as part of processing the header. As a
3730 * result, it's not totally clear how to interpret the
3731 * response code yet as that depends on what other headers may
3732 * be present. 401 and 407 may be errors, but may be OK
3733 * depending on how authentication is working. Other codes
3734 * are definitely errors, so give up here.
3735 */
3736 if(data->state.resume_from && data->state.httpreq == HTTPREQ_GET &&
3737 k->httpcode == 416) {
3738 /* "Requested Range Not Satisfiable", just proceed and
3739 pretend this is no error */
3740 k->ignorebody = TRUE; /* Avoid appending error msg to good data. */
3741 }
3742
3743 if(conn->httpversion == 10) {
3744 /* Default action for HTTP/1.0 must be to close, unless
3745 we get one of those fancy headers that tell us the
3746 server keeps it open for us! */
3747 infof(data, "HTTP 1.0, assume close after body");
3748 connclose(conn, "HTTP/1.0 close after body");
3749 }
3750 else if(conn->httpversion == 20 ||
3751 (k->upgr101 == UPGR101_REQUESTED && k->httpcode == 101)) {
3752 DEBUGF(infof(data, "HTTP/2 found, allow multiplexing"));
3753 /* HTTP/2 cannot avoid multiplexing since it is a core functionality
3754 of the protocol */
3755 conn->bundle->multiuse = BUNDLE_MULTIPLEX;
3756 }
3757 else if(conn->httpversion >= 11 &&
3758 !conn->bits.close) {
3759 /* If HTTP version is >= 1.1 and connection is persistent */
3760 DEBUGF(infof(data,
3761 "HTTP 1.1 or later with persistent connection"));
3762 }
3763
3764 k->http_bodyless = k->httpcode >= 100 && k->httpcode < 200;
3765 switch(k->httpcode) {
3766 case 304:
3767 /* (quote from RFC2616, section 10.3.5): The 304 response
3768 * MUST NOT contain a message-body, and thus is always
3769 * terminated by the first empty line after the header
3770 * fields. */
3771 if(data->set.timecondition)
3772 data->info.timecond = TRUE;
3773 /* FALLTHROUGH */
3774 case 204:
3775 /* (quote from RFC2616, section 10.2.5): The server has
3776 * fulfilled the request but does not need to return an
3777 * entity-body ... The 204 response MUST NOT include a
3778 * message-body, and thus is always terminated by the first
3779 * empty line after the header fields. */
3780 k->size = 0;
3781 k->maxdownload = 0;
3782 k->http_bodyless = TRUE;
3783 break;
3784 default:
3785 break;
3786 }
3787 return CURLE_OK;
3788}
3789
3790/*
3791 * Read any HTTP header lines from the server and pass them to the client app.
3792 */
3793CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
3794 struct connectdata *conn,
3795 ssize_t *nread,
3796 bool *stop_reading)
3797{
3798 CURLcode result;
3799 struct SingleRequest *k = &data->req;
3800 ssize_t onread = *nread;
3801 char *ostr = k->str;
3802 char *headp;
3803 char *str_start;
3804 char *end_ptr;
3805
3806 /* header line within buffer loop */
3807 do {
3808 size_t rest_length;
3809 size_t full_length;
3810 int writetype;
3811
3812 /* str_start is start of line within buf */
3813 str_start = k->str;
3814
3815 /* data is in network encoding so use 0x0a instead of '\n' */
3816 end_ptr = memchr(str_start, 0x0a, *nread);
3817
3818 if(!end_ptr) {
3819 /* Not a complete header line within buffer, append the data to
3820 the end of the headerbuff. */
3821 result = Curl_dyn_addn(&data->state.headerb, str_start, *nread);
3822 if(result)
3823 return result;
3824
3825 if(!k->headerline) {
3826 /* check if this looks like a protocol header */
3827 statusline st =
3828 checkprotoprefix(data, conn,
3829 Curl_dyn_ptr(&data->state.headerb),
3830 Curl_dyn_len(&data->state.headerb));
3831
3832 if(st == STATUS_BAD) {
3833 /* this is not the beginning of a protocol first header line */
3834 k->header = FALSE;
3835 k->badheader = HEADER_ALLBAD;
3836 streamclose(conn, "bad HTTP: No end-of-message indicator");
3837 if(!data->set.http09_allowed) {
3838 failf(data, "Received HTTP/0.9 when not allowed");
3839 return CURLE_UNSUPPORTED_PROTOCOL;
3840 }
3841 break;
3842 }
3843 }
3844
3845 break; /* read more and try again */
3846 }
3847
3848 /* decrease the size of the remaining (supposed) header line */
3849 rest_length = (end_ptr - k->str) + 1;
3850 *nread -= (ssize_t)rest_length;
3851
3852 k->str = end_ptr + 1; /* move past new line */
3853
3854 full_length = k->str - str_start;
3855
3856 result = Curl_dyn_addn(&data->state.headerb, str_start, full_length);
3857 if(result)
3858 return result;
3859
3860 /****
3861 * We now have a FULL header line in 'headerb'.
3862 *****/
3863
3864 if(!k->headerline) {
3865 /* the first read header */
3866 statusline st = checkprotoprefix(data, conn,
3867 Curl_dyn_ptr(&data->state.headerb),
3868 Curl_dyn_len(&data->state.headerb));
3869 if(st == STATUS_BAD) {
3870 streamclose(conn, "bad HTTP: No end-of-message indicator");
3871 /* this is not the beginning of a protocol first header line */
3872 if(!data->set.http09_allowed) {
3873 failf(data, "Received HTTP/0.9 when not allowed");
3874 return CURLE_UNSUPPORTED_PROTOCOL;
3875 }
3876 k->header = FALSE;
3877 if(*nread)
3878 /* since there's more, this is a partial bad header */
3879 k->badheader = HEADER_PARTHEADER;
3880 else {
3881 /* this was all we read so it's all a bad header */
3882 k->badheader = HEADER_ALLBAD;
3883 *nread = onread;
3884 k->str = ostr;
3885 return CURLE_OK;
3886 }
3887 break;
3888 }
3889 }
3890
3891 /* headers are in network encoding so use 0x0a and 0x0d instead of '\n'
3892 and '\r' */
3893 headp = Curl_dyn_ptr(&data->state.headerb);
3894 if((0x0a == *headp) || (0x0d == *headp)) {
3895 size_t headerlen;
3896 /* Zero-length header line means end of headers! */
3897
3898#ifdef CURL_DOES_CONVERSIONS
3899 if(0x0d == *headp) {
3900 *headp = '\r'; /* replace with CR in host encoding */
3901 headp++; /* pass the CR byte */
3902 }
3903 if(0x0a == *headp) {
3904 *headp = '\n'; /* replace with LF in host encoding */
3905 headp++; /* pass the LF byte */
3906 }
3907#else
3908 if('\r' == *headp)
3909 headp++; /* pass the \r byte */
3910 if('\n' == *headp)
3911 headp++; /* pass the \n byte */
3912#endif /* CURL_DOES_CONVERSIONS */
3913
3914 if(100 <= k->httpcode && 199 >= k->httpcode) {
3915 /* "A user agent MAY ignore unexpected 1xx status responses." */
3916 switch(k->httpcode) {
3917 case 100:
3918 /*
3919 * We have made a HTTP PUT or POST and this is 1.1-lingo
3920 * that tells us that the server is OK with this and ready
3921 * to receive the data.
3922 * However, we'll get more headers now so we must get
3923 * back into the header-parsing state!
3924 */
3925 k->header = TRUE;
3926 k->headerline = 0; /* restart the header line counter */
3927
3928 /* if we did wait for this do enable write now! */
3929 if(k->exp100 > EXP100_SEND_DATA) {
3930 k->exp100 = EXP100_SEND_DATA;
3931 k->keepon |= KEEP_SEND;
3932 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
3933 }
3934 break;
3935 case 101:
3936 /* Switching Protocols */
3937 if(k->upgr101 == UPGR101_REQUESTED) {
3938 /* Switching to HTTP/2 */
3939 infof(data, "Received 101");
3940 k->upgr101 = UPGR101_RECEIVED;
3941
3942 /* we'll get more headers (HTTP/2 response) */
3943 k->header = TRUE;
3944 k->headerline = 0; /* restart the header line counter */
3945
3946 /* switch to http2 now. The bytes after response headers
3947 are also processed here, otherwise they are lost. */
3948 result = Curl_http2_switched(data, k->str, *nread);
3949 if(result)
3950 return result;
3951 *nread = 0;
3952 }
3953 else {
3954 /* Switching to another protocol (e.g. WebSocket) */
3955 k->header = FALSE; /* no more header to parse! */
3956 }
3957 break;
3958 default:
3959 /* the status code 1xx indicates a provisional response, so
3960 we'll get another set of headers */
3961 k->header = TRUE;
3962 k->headerline = 0; /* restart the header line counter */
3963 break;
3964 }
3965 }
3966 else {
3967 k->header = FALSE; /* no more header to parse! */
3968
3969 if((k->size == -1) && !k->chunk && !conn->bits.close &&
3970 (conn->httpversion == 11) &&
3971 !(conn->handler->protocol & CURLPROTO_RTSP) &&
3972 data->state.httpreq != HTTPREQ_HEAD) {
3973 /* On HTTP 1.1, when connection is not to get closed, but no
3974 Content-Length nor Transfer-Encoding chunked have been
3975 received, according to RFC2616 section 4.4 point 5, we
3976 assume that the server will close the connection to
3977 signal the end of the document. */
3978 infof(data, "no chunk, no close, no size. Assume close to "
3979 "signal end");
3980 streamclose(conn, "HTTP: No end-of-message indicator");
3981 }
3982 }
3983
3984 /* At this point we have some idea about the fate of the connection.
3985 If we are closing the connection it may result auth failure. */
3986#if defined(USE_NTLM)
3987 if(conn->bits.close &&
3988 (((data->req.httpcode == 401) &&
3989 (conn->http_ntlm_state == NTLMSTATE_TYPE2)) ||
3990 ((data->req.httpcode == 407) &&
3991 (conn->proxy_ntlm_state == NTLMSTATE_TYPE2)))) {
3992 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)");
3993 data->state.authproblem = TRUE;
3994 }
3995#endif
3996#if defined(USE_SPNEGO)
3997 if(conn->bits.close &&
3998 (((data->req.httpcode == 401) &&
3999 (conn->http_negotiate_state == GSS_AUTHRECV)) ||
4000 ((data->req.httpcode == 407) &&
4001 (conn->proxy_negotiate_state == GSS_AUTHRECV)))) {
4002 infof(data, "Connection closure while negotiating auth (HTTP 1.0?)");
4003 data->state.authproblem = TRUE;
4004 }
4005 if((conn->http_negotiate_state == GSS_AUTHDONE) &&
4006 (data->req.httpcode != 401)) {
4007 conn->http_negotiate_state = GSS_AUTHSUCC;
4008 }
4009 if((conn->proxy_negotiate_state == GSS_AUTHDONE) &&
4010 (data->req.httpcode != 407)) {
4011 conn->proxy_negotiate_state = GSS_AUTHSUCC;
4012 }
4013#endif
4014
4015 /* now, only output this if the header AND body are requested:
4016 */
4017 writetype = CLIENTWRITE_HEADER;
4018 if(data->set.include_header)
4019 writetype |= CLIENTWRITE_BODY;
4020
4021 headerlen = Curl_dyn_len(&data->state.headerb);
4022 result = Curl_client_write(data, writetype,
4023 Curl_dyn_ptr(&data->state.headerb),
4024 headerlen);
4025 if(result)
4026 return result;
4027
4028 data->info.header_size += (long)headerlen;
4029 data->req.headerbytecount += (long)headerlen;
4030
4031 /*
4032 * When all the headers have been parsed, see if we should give
4033 * up and return an error.
4034 */
4035 if(http_should_fail(data)) {
4036 failf(data, "The requested URL returned error: %d",
4037 k->httpcode);
4038 return CURLE_HTTP_RETURNED_ERROR;
4039 }
4040
4041 data->req.deductheadercount =
4042 (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
4043
4044 /* Curl_http_auth_act() checks what authentication methods
4045 * that are available and decides which one (if any) to
4046 * use. It will set 'newurl' if an auth method was picked. */
4047 result = Curl_http_auth_act(data);
4048
4049 if(result)
4050 return result;
4051
4052 if(k->httpcode >= 300) {
4053 if((!conn->bits.authneg) && !conn->bits.close &&
4054 !conn->bits.rewindaftersend) {
4055 /*
4056 * General treatment of errors when about to send data. Including :
4057 * "417 Expectation Failed", while waiting for 100-continue.
4058 *
4059 * The check for close above is done simply because of something
4060 * else has already deemed the connection to get closed then
4061 * something else should've considered the big picture and we
4062 * avoid this check.
4063 *
4064 * rewindaftersend indicates that something has told libcurl to
4065 * continue sending even if it gets discarded
4066 */
4067
4068 switch(data->state.httpreq) {
4069 case HTTPREQ_PUT:
4070 case HTTPREQ_POST:
4071 case HTTPREQ_POST_FORM:
4072 case HTTPREQ_POST_MIME:
4073 /* We got an error response. If this happened before the whole
4074 * request body has been sent we stop sending and mark the
4075 * connection for closure after we've read the entire response.
4076 */
4077 Curl_expire_done(data, EXPIRE_100_TIMEOUT);
4078 if(!k->upload_done) {
4079 if((k->httpcode == 417) && data->state.expect100header) {
4080 /* 417 Expectation Failed - try again without the Expect
4081 header */
4082 infof(data, "Got 417 while waiting for a 100");
4083 data->state.disableexpect = TRUE;
4084 DEBUGASSERT(!data->req.newurl);
4085 data->req.newurl = strdup(data->state.url);
4086 Curl_done_sending(data, k);
4087 }
4088 else if(data->set.http_keep_sending_on_error) {
4089 infof(data, "HTTP error before end of send, keep sending");
4090 if(k->exp100 > EXP100_SEND_DATA) {
4091 k->exp100 = EXP100_SEND_DATA;
4092 k->keepon |= KEEP_SEND;
4093 }
4094 }
4095 else {
4096 infof(data, "HTTP error before end of send, stop sending");
4097 streamclose(conn, "Stop sending data before everything sent");
4098 result = Curl_done_sending(data, k);
4099 if(result)
4100 return result;
4101 k->upload_done = TRUE;
4102 if(data->state.expect100header)
4103 k->exp100 = EXP100_FAILED;
4104 }
4105 }
4106 break;
4107
4108 default: /* default label present to avoid compiler warnings */
4109 break;
4110 }
4111 }
4112
4113 if(conn->bits.rewindaftersend) {
4114 /* We rewind after a complete send, so thus we continue
4115 sending now */
4116 infof(data, "Keep sending data to get tossed away!");
4117 k->keepon |= KEEP_SEND;
4118 }
4119 }
4120
4121 if(!k->header) {
4122 /*
4123 * really end-of-headers.
4124 *
4125 * If we requested a "no body", this is a good time to get
4126 * out and return home.
4127 */
4128 if(data->set.opt_no_body)
4129 *stop_reading = TRUE;
4130#ifndef CURL_DISABLE_RTSP
4131 else if((conn->handler->protocol & CURLPROTO_RTSP) &&
4132 (data->set.rtspreq == RTSPREQ_DESCRIBE) &&
4133 (k->size <= -1))
4134 /* Respect section 4.4 of rfc2326: If the Content-Length header is
4135 absent, a length 0 must be assumed. It will prevent libcurl from
4136 hanging on DESCRIBE request that got refused for whatever
4137 reason */
4138 *stop_reading = TRUE;
4139#endif
4140 else {
4141 /* If we know the expected size of this document, we set the
4142 maximum download size to the size of the expected
4143 document or else, we won't know when to stop reading!
4144
4145 Note that we set the download maximum even if we read a
4146 "Connection: close" header, to make sure that
4147 "Content-Length: 0" still prevents us from attempting to
4148 read the (missing) response-body.
4149 */
4150 /* According to RFC2616 section 4.4, we MUST ignore
4151 Content-Length: headers if we are now receiving data
4152 using chunked Transfer-Encoding.
4153 */
4154 if(k->chunk)
4155 k->maxdownload = k->size = -1;
4156 }
4157 if(-1 != k->size) {
4158 /* We do this operation even if no_body is true, since this
4159 data might be retrieved later with curl_easy_getinfo()
4160 and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
4161
4162 Curl_pgrsSetDownloadSize(data, k->size);
4163 k->maxdownload = k->size;
4164 }
4165
4166 /* If max download size is *zero* (nothing) we already have
4167 nothing and can safely return ok now! But for HTTP/2, we'd
4168 like to call http2_handle_stream_close to properly close a
4169 stream. In order to do this, we keep reading until we
4170 close the stream. */
4171 if(0 == k->maxdownload
4172#if defined(USE_NGHTTP2)
4173 && !((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
4174 conn->httpversion == 20)
4175#endif
4176 )
4177 *stop_reading = TRUE;
4178
4179 if(*stop_reading) {
4180 /* we make sure that this socket isn't read more now */
4181 k->keepon &= ~KEEP_RECV;
4182 }
4183
4184 Curl_debug(data, CURLINFO_HEADER_IN, str_start, headerlen);
4185 break; /* exit header line loop */
4186 }
4187
4188 /* We continue reading headers, reset the line-based header */
4189 Curl_dyn_reset(&data->state.headerb);
4190 continue;
4191 }
4192
4193 /*
4194 * Checks for special headers coming up.
4195 */
4196
4197 if(!k->headerline++) {
4198 /* This is the first header, it MUST be the error code line
4199 or else we consider this to be the body right away! */
4200 int httpversion_major;
4201 int rtspversion_major;
4202 int nc = 0;
4203#ifdef CURL_DOES_CONVERSIONS
4204#define HEADER1 scratch
4205#define SCRATCHSIZE 21
4206 CURLcode res;
4207 char scratch[SCRATCHSIZE + 1]; /* "HTTP/major.minor 123" */
4208 /* We can't really convert this yet because we don't know if it's the
4209 1st header line or the body. So we do a partial conversion into a
4210 scratch area, leaving the data at 'headp' as-is.
4211 */
4212 strncpy(&scratch[0], headp, SCRATCHSIZE);
4213 scratch[SCRATCHSIZE] = 0; /* null terminate */
4214 res = Curl_convert_from_network(data,
4215 &scratch[0],
4216 SCRATCHSIZE);
4217 if(res)
4218 /* Curl_convert_from_network calls failf if unsuccessful */
4219 return res;
4220#else
4221#define HEADER1 headp /* no conversion needed, just use headp */
4222#endif /* CURL_DOES_CONVERSIONS */
4223
4224 if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
4225 /*
4226 * https://tools.ietf.org/html/rfc7230#section-3.1.2
4227 *
4228 * The response code is always a three-digit number in HTTP as the spec
4229 * says. We allow any three-digit number here, but we cannot make
4230 * guarantees on future behaviors since it isn't within the protocol.
4231 */
4232 char separator;
4233 char twoorthree[2];
4234 int httpversion = 0;
4235 char digit4 = 0;
4236 nc = sscanf(HEADER1,
4237 " HTTP/%1d.%1d%c%3d%c",
4238 &httpversion_major,
4239 &httpversion,
4240 &separator,
4241 &k->httpcode,
4242 &digit4);
4243
4244 if(nc == 1 && httpversion_major >= 2 &&
4245 2 == sscanf(HEADER1, " HTTP/%1[23] %d", twoorthree, &k->httpcode)) {
4246 conn->httpversion = 0;
4247 nc = 4;
4248 separator = ' ';
4249 }
4250
4251 /* There can only be a 4th response code digit stored in 'digit4' if
4252 all the other fields were parsed and stored first, so nc is 5 when
4253 digit4 a digit */
4254 else if(ISDIGIT(digit4)) {
4255 failf(data, "Unsupported response code in HTTP response");
4256 return CURLE_UNSUPPORTED_PROTOCOL;
4257 }
4258
4259 if((nc >= 4) && (' ' == separator)) {
4260 httpversion += 10 * httpversion_major;
4261 switch(httpversion) {
4262 case 10:
4263 case 11:
4264#if defined(USE_NGHTTP2) || defined(USE_HYPER)
4265 case 20:
4266#endif
4267#if defined(ENABLE_QUIC)
4268 case 30:
4269#endif
4270 conn->httpversion = (unsigned char)httpversion;
4271 break;
4272 default:
4273 failf(data, "Unsupported HTTP version (%u.%d) in response",
4274 httpversion/10, httpversion%10);
4275 return CURLE_UNSUPPORTED_PROTOCOL;
4276 }
4277
4278 if(k->upgr101 == UPGR101_RECEIVED) {
4279 /* supposedly upgraded to http2 now */
4280 if(conn->httpversion != 20)
4281 infof(data, "Lying server, not serving HTTP/2");
4282 }
4283 if(conn->httpversion < 20) {
4284 conn->bundle->multiuse = BUNDLE_NO_MULTIUSE;
4285 infof(data, "Mark bundle as not supporting multiuse");
4286 }
4287 }
4288 else if(!nc) {
4289 /* this is the real world, not a Nirvana
4290 NCSA 1.5.x returns this crap when asked for HTTP/1.1
4291 */
4292 nc = sscanf(HEADER1, " HTTP %3d", &k->httpcode);
4293 conn->httpversion = 10;
4294
4295 /* If user has set option HTTP200ALIASES,
4296 compare header line against list of aliases
4297 */
4298 if(!nc) {
4299 statusline check =
4300 checkhttpprefix(data,
4301 Curl_dyn_ptr(&data->state.headerb),
4302 Curl_dyn_len(&data->state.headerb));
4303 if(check == STATUS_DONE) {
4304 nc = 1;
4305 k->httpcode = 200;
4306 conn->httpversion = 10;
4307 }
4308 }
4309 }
4310 else {
4311 failf(data, "Unsupported HTTP version in response");
4312 return CURLE_UNSUPPORTED_PROTOCOL;
4313 }
4314 }
4315 else if(conn->handler->protocol & CURLPROTO_RTSP) {
4316 char separator;
4317 int rtspversion;
4318 nc = sscanf(HEADER1,
4319 " RTSP/%1d.%1d%c%3d",
4320 &rtspversion_major,
4321 &rtspversion,
4322 &separator,
4323 &k->httpcode);
4324 if((nc == 4) && (' ' == separator)) {
4325 conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
4326 }
4327 else {
4328 nc = 0;
4329 }
4330 }
4331
4332 if(nc) {
4333 result = Curl_http_statusline(data, conn);
4334 if(result)
4335 return result;
4336 }
4337 else {
4338 k->header = FALSE; /* this is not a header line */
4339 break;
4340 }
4341 }
4342
4343 result = Curl_convert_from_network(data, headp, strlen(headp));
4344 /* Curl_convert_from_network calls failf if unsuccessful */
4345 if(result)
4346 return result;
4347
4348 result = Curl_http_header(data, conn, headp);
4349 if(result)
4350 return result;
4351
4352 /*
4353 * End of header-checks. Write them to the client.
4354 */
4355
4356 writetype = CLIENTWRITE_HEADER;
4357 if(data->set.include_header)
4358 writetype |= CLIENTWRITE_BODY;
4359
4360 Curl_debug(data, CURLINFO_HEADER_IN, headp,
4361 Curl_dyn_len(&data->state.headerb));
4362
4363 result = Curl_client_write(data, writetype, headp,
4364 Curl_dyn_len(&data->state.headerb));
4365 if(result)
4366 return result;
4367
4368 data->info.header_size += Curl_dyn_len(&data->state.headerb);
4369 data->req.headerbytecount += Curl_dyn_len(&data->state.headerb);
4370
4371 Curl_dyn_reset(&data->state.headerb);
4372 }
4373 while(*k->str); /* header line within buffer */
4374
4375 /* We might have reached the end of the header part here, but
4376 there might be a non-header part left in the end of the read
4377 buffer. */
4378
4379 return CURLE_OK;
4380}
4381
4382#endif /* CURL_DISABLE_HTTP */
4383