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