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