VirtualBox

source: vbox/trunk/src/libs/curl-7.64.0/lib/http.c@ 85671

Last change on this file since 85671 was 85671, checked in by vboxsync, 4 years ago

Export out internal curl copy to make it a lot simpler to build VBox (OSE) on Windows. bugref:9814

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette