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