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