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