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