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