Revert "Update to 7.40.1"
[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       result = Curl_http2_init(conn);
1753       if(result)
1754         return result;
1755
1756       result = Curl_http2_setup(conn);
1757       if(result)
1758         return result;
1759
1760       /* TODO: add error checking here */
1761       Curl_http2_switched(conn);
1762       break;
1763     case NPN_HTTP1_1:
1764       /* continue with HTTP/1.1 when explicitly requested */
1765       break;
1766     default:
1767       /* and as fallback */
1768       break;
1769     }
1770   }
1771   else {
1772     /* prepare for a http2 request */
1773     Curl_http2_setup(conn);
1774   }
1775
1776   http = data->req.protop;
1777
1778   if(!data->state.this_is_a_follow) {
1779     /* this is not a followed location, get the original host name */
1780     if(data->state.first_host)
1781       /* Free to avoid leaking memory on multiple requests*/
1782       free(data->state.first_host);
1783
1784     data->state.first_host = strdup(conn->host.name);
1785     if(!data->state.first_host)
1786       return CURLE_OUT_OF_MEMORY;
1787   }
1788   http->writebytecount = http->readbytecount = 0;
1789
1790   if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
1791      data->set.upload) {
1792     httpreq = HTTPREQ_PUT;
1793   }
1794
1795   /* Now set the 'request' pointer to the proper request string */
1796   if(data->set.str[STRING_CUSTOMREQUEST])
1797     request = data->set.str[STRING_CUSTOMREQUEST];
1798   else {
1799     if(data->set.opt_no_body)
1800       request = "HEAD";
1801     else {
1802       DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1803       switch(httpreq) {
1804       case HTTPREQ_POST:
1805       case HTTPREQ_POST_FORM:
1806         request = "POST";
1807         break;
1808       case HTTPREQ_PUT:
1809         request = "PUT";
1810         break;
1811       default: /* this should never happen */
1812       case HTTPREQ_GET:
1813         request = "GET";
1814         break;
1815       case HTTPREQ_HEAD:
1816         request = "HEAD";
1817         break;
1818       }
1819     }
1820   }
1821
1822   /* The User-Agent string might have been allocated in url.c already, because
1823      it might have been used in the proxy connect, but if we have got a header
1824      with the user-agent string specified, we erase the previously made string
1825      here. */
1826   if(Curl_checkheaders(conn, "User-Agent:") && conn->allocptr.uagent) {
1827     free(conn->allocptr.uagent);
1828     conn->allocptr.uagent=NULL;
1829   }
1830
1831   /* setup the authentication headers */
1832   result = Curl_http_output_auth(conn, request, ppath, FALSE);
1833   if(result)
1834     return result;
1835
1836   if((data->state.authhost.multi || data->state.authproxy.multi) &&
1837      (httpreq != HTTPREQ_GET) &&
1838      (httpreq != HTTPREQ_HEAD)) {
1839     /* Auth is required and we are not authenticated yet. Make a PUT or POST
1840        with content-length zero as a "probe". */
1841     conn->bits.authneg = TRUE;
1842   }
1843   else
1844     conn->bits.authneg = FALSE;
1845
1846   Curl_safefree(conn->allocptr.ref);
1847   if(data->change.referer && !Curl_checkheaders(conn, "Referer:")) {
1848     conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1849     if(!conn->allocptr.ref)
1850       return CURLE_OUT_OF_MEMORY;
1851   }
1852   else
1853     conn->allocptr.ref = NULL;
1854
1855   if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(conn, "Cookie:"))
1856     addcookies = data->set.str[STRING_COOKIE];
1857
1858   if(!Curl_checkheaders(conn, "Accept-Encoding:") &&
1859      data->set.str[STRING_ENCODING]) {
1860     Curl_safefree(conn->allocptr.accept_encoding);
1861     conn->allocptr.accept_encoding =
1862       aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1863     if(!conn->allocptr.accept_encoding)
1864       return CURLE_OUT_OF_MEMORY;
1865   }
1866
1867 #ifdef HAVE_LIBZ
1868   /* we only consider transfer-encoding magic if libz support is built-in */
1869
1870   if(!Curl_checkheaders(conn, "TE:") &&
1871      data->set.http_transfer_encoding) {
1872     /* When we are to insert a TE: header in the request, we must also insert
1873        TE in a Connection: header, so we need to merge the custom provided
1874        Connection: header and prevent the original to get sent. Note that if
1875        the user has inserted his/hers own TE: header we don't do this magic
1876        but then assume that the user will handle it all! */
1877     char *cptr = Curl_checkheaders(conn, "Connection:");
1878 #define TE_HEADER "TE: gzip\r\n"
1879
1880     Curl_safefree(conn->allocptr.te);
1881
1882     /* Create the (updated) Connection: header */
1883     conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1884       strdup("Connection: TE\r\n" TE_HEADER);
1885
1886     if(!conn->allocptr.te)
1887       return CURLE_OUT_OF_MEMORY;
1888   }
1889 #endif
1890
1891   if(conn->httpversion == 20)
1892     /* In HTTP2 forbids Transfer-Encoding: chunked */
1893     ptr = NULL;
1894   else {
1895     ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
1896     if(ptr) {
1897       /* Some kind of TE is requested, check if 'chunked' is chosen */
1898       data->req.upload_chunky =
1899         Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1900     }
1901     else {
1902       if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
1903          data->set.upload &&
1904          (data->state.infilesize == -1)) {
1905         if(conn->bits.authneg)
1906           /* don't enable chunked during auth neg */
1907           ;
1908         else if(use_http_1_1plus(data, conn)) {
1909           /* HTTP, upload, unknown file size and not HTTP 1.0 */
1910           data->req.upload_chunky = TRUE;
1911         }
1912         else {
1913           failf(data, "Chunky upload is not supported by HTTP 1.0");
1914           return CURLE_UPLOAD_FAILED;
1915         }
1916       }
1917       else {
1918         /* else, no chunky upload */
1919         data->req.upload_chunky = FALSE;
1920       }
1921
1922       if(data->req.upload_chunky)
1923         te = "Transfer-Encoding: chunked\r\n";
1924     }
1925   }
1926
1927   Curl_safefree(conn->allocptr.host);
1928
1929   ptr = Curl_checkheaders(conn, "Host:");
1930   if(ptr && (!data->state.this_is_a_follow ||
1931              Curl_raw_equal(data->state.first_host, conn->host.name))) {
1932 #if !defined(CURL_DISABLE_COOKIES)
1933     /* If we have a given custom Host: header, we extract the host name in
1934        order to possibly use it for cookie reasons later on. We only allow the
1935        custom Host: header if this is NOT a redirect, as setting Host: in the
1936        redirected request is being out on thin ice. Except if the host name
1937        is the same as the first one! */
1938     char *cookiehost = Curl_copy_header_value(ptr);
1939     if(!cookiehost)
1940       return CURLE_OUT_OF_MEMORY;
1941     if(!*cookiehost)
1942       /* ignore empty data */
1943       free(cookiehost);
1944     else {
1945       /* If the host begins with '[', we start searching for the port after
1946          the bracket has been closed */
1947       int startsearch = 0;
1948       if(*cookiehost == '[') {
1949         char *closingbracket;
1950         /* since the 'cookiehost' is an allocated memory area that will be
1951            freed later we cannot simply increment the pointer */
1952         memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
1953         closingbracket = strchr(cookiehost, ']');
1954         if(closingbracket)
1955           *closingbracket = 0;
1956       }
1957       else {
1958         char *colon = strchr(cookiehost + startsearch, ':');
1959         if(colon)
1960           *colon = 0; /* The host must not include an embedded port number */
1961       }
1962       Curl_safefree(conn->allocptr.cookiehost);
1963       conn->allocptr.cookiehost = cookiehost;
1964     }
1965 #endif
1966
1967     conn->allocptr.host = NULL;
1968   }
1969   else {
1970     /* When building Host: headers, we must put the host name within
1971        [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
1972
1973     if(((conn->given->protocol&CURLPROTO_HTTPS) &&
1974         (conn->remote_port == PORT_HTTPS)) ||
1975        ((conn->given->protocol&CURLPROTO_HTTP) &&
1976         (conn->remote_port == PORT_HTTP)) )
1977       /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
1978          the port number in the host string */
1979       conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
1980                                     conn->bits.ipv6_ip?"[":"",
1981                                     host,
1982                                     conn->bits.ipv6_ip?"]":"");
1983     else
1984       conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
1985                                     conn->bits.ipv6_ip?"[":"",
1986                                     host,
1987                                     conn->bits.ipv6_ip?"]":"",
1988                                     conn->remote_port);
1989
1990     if(!conn->allocptr.host)
1991       /* without Host: we can't make a nice request */
1992       return CURLE_OUT_OF_MEMORY;
1993   }
1994
1995 #ifndef CURL_DISABLE_PROXY
1996   if(conn->bits.httpproxy && !conn->bits.tunnel_proxy)  {
1997     /* Using a proxy but does not tunnel through it */
1998
1999     /* The path sent to the proxy is in fact the entire URL. But if the remote
2000        host is a IDN-name, we must make sure that the request we produce only
2001        uses the encoded host name! */
2002     if(conn->host.dispname != conn->host.name) {
2003       char *url = data->change.url;
2004       ptr = strstr(url, conn->host.dispname);
2005       if(ptr) {
2006         /* This is where the display name starts in the URL, now replace this
2007            part with the encoded name. TODO: This method of replacing the host
2008            name is rather crude as I believe there's a slight risk that the
2009            user has entered a user name or password that contain the host name
2010            string. */
2011         size_t currlen = strlen(conn->host.dispname);
2012         size_t newlen = strlen(conn->host.name);
2013         size_t urllen = strlen(url);
2014
2015         char *newurl;
2016
2017         newurl = malloc(urllen + newlen - currlen + 1);
2018         if(newurl) {
2019           /* copy the part before the host name */
2020           memcpy(newurl, url, ptr - url);
2021           /* append the new host name instead of the old */
2022           memcpy(newurl + (ptr - url), conn->host.name, newlen);
2023           /* append the piece after the host name */
2024           memcpy(newurl + newlen + (ptr - url),
2025                  ptr + currlen, /* copy the trailing zero byte too */
2026                  urllen - (ptr-url) - currlen + 1);
2027           if(data->change.url_alloc) {
2028             Curl_safefree(data->change.url);
2029             data->change.url_alloc = FALSE;
2030           }
2031           data->change.url = newurl;
2032           data->change.url_alloc = TRUE;
2033         }
2034         else
2035           return CURLE_OUT_OF_MEMORY;
2036       }
2037     }
2038     ppath = data->change.url;
2039     if(checkprefix("ftp://", ppath)) {
2040       if(data->set.proxy_transfer_mode) {
2041         /* when doing ftp, append ;type=<a|i> if not present */
2042         char *type = strstr(ppath, ";type=");
2043         if(type && type[6] && type[7] == 0) {
2044           switch (Curl_raw_toupper(type[6])) {
2045           case 'A':
2046           case 'D':
2047           case 'I':
2048             break;
2049           default:
2050             type = NULL;
2051           }
2052         }
2053         if(!type) {
2054           char *p = ftp_typecode;
2055           /* avoid sending invalid URLs like ftp://example.com;type=i if the
2056            * user specified ftp://example.com without the slash */
2057           if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
2058             *p++ = '/';
2059           }
2060           snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
2061                    data->set.prefer_ascii ? 'a' : 'i');
2062         }
2063       }
2064       if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
2065         paste_ftp_userpwd = TRUE;
2066     }
2067   }
2068 #endif /* CURL_DISABLE_PROXY */
2069
2070   if(HTTPREQ_POST_FORM == httpreq) {
2071     /* we must build the whole post sequence first, so that we have a size of
2072        the whole transfer before we start to send it */
2073     result = Curl_getformdata(data, &http->sendit, data->set.httppost,
2074                               Curl_checkheaders(conn, "Content-Type:"),
2075                               &http->postsize);
2076     if(result)
2077       return result;
2078   }
2079
2080   http->p_accept = Curl_checkheaders(conn, "Accept:")?NULL:"Accept: */*\r\n";
2081
2082   if(( (HTTPREQ_POST == httpreq) ||
2083        (HTTPREQ_POST_FORM == httpreq) ||
2084        (HTTPREQ_PUT == httpreq) ) &&
2085      data->state.resume_from) {
2086     /**********************************************************************
2087      * Resuming upload in HTTP means that we PUT or POST and that we have
2088      * got a resume_from value set. The resume value has already created
2089      * a Range: header that will be passed along. We need to "fast forward"
2090      * the file the given number of bytes and decrease the assume upload
2091      * file size before we continue this venture in the dark lands of HTTP.
2092      *********************************************************************/
2093
2094     if(data->state.resume_from < 0 ) {
2095       /*
2096        * This is meant to get the size of the present remote-file by itself.
2097        * We don't support this now. Bail out!
2098        */
2099       data->state.resume_from = 0;
2100     }
2101
2102     if(data->state.resume_from && !data->state.this_is_a_follow) {
2103       /* do we still game? */
2104
2105       /* Now, let's read off the proper amount of bytes from the
2106          input. */
2107       if(conn->seek_func) {
2108         seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
2109                                   SEEK_SET);
2110       }
2111
2112       if(seekerr != CURL_SEEKFUNC_OK) {
2113         if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2114           failf(data, "Could not seek stream");
2115           return CURLE_READ_ERROR;
2116         }
2117         /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2118         else {
2119           curl_off_t passed=0;
2120           do {
2121             size_t readthisamountnow =
2122               (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
2123               BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
2124
2125             size_t actuallyread =
2126               data->set.fread_func(data->state.buffer, 1, readthisamountnow,
2127                                    data->set.in);
2128
2129             passed += actuallyread;
2130             if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2131               /* this checks for greater-than only to make sure that the
2132                  CURL_READFUNC_ABORT return code still aborts */
2133               failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2134                     " bytes from the input", passed);
2135               return CURLE_READ_ERROR;
2136             }
2137           } while(passed < data->state.resume_from);
2138         }
2139       }
2140
2141       /* now, decrease the size of the read */
2142       if(data->state.infilesize>0) {
2143         data->state.infilesize -= data->state.resume_from;
2144
2145         if(data->state.infilesize <= 0) {
2146           failf(data, "File already completely uploaded");
2147           return CURLE_PARTIAL_FILE;
2148         }
2149       }
2150       /* we've passed, proceed as normal */
2151     }
2152   }
2153   if(data->state.use_range) {
2154     /*
2155      * A range is selected. We use different headers whether we're downloading
2156      * or uploading and we always let customized headers override our internal
2157      * ones if any such are specified.
2158      */
2159     if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2160        !Curl_checkheaders(conn, "Range:")) {
2161       /* if a line like this was already allocated, free the previous one */
2162       if(conn->allocptr.rangeline)
2163         free(conn->allocptr.rangeline);
2164       conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2165                                          data->state.range);
2166     }
2167     else if((httpreq != HTTPREQ_GET) &&
2168             !Curl_checkheaders(conn, "Content-Range:")) {
2169
2170       /* if a line like this was already allocated, free the previous one */
2171       if(conn->allocptr.rangeline)
2172         free(conn->allocptr.rangeline);
2173
2174       if(data->set.set_resume_from < 0) {
2175         /* Upload resume was asked for, but we don't know the size of the
2176            remote part so we tell the server (and act accordingly) that we
2177            upload the whole file (again) */
2178         conn->allocptr.rangeline =
2179           aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2180                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2181                   data->state.infilesize - 1, data->state.infilesize);
2182
2183       }
2184       else if(data->state.resume_from) {
2185         /* This is because "resume" was selected */
2186         curl_off_t total_expected_size=
2187           data->state.resume_from + data->state.infilesize;
2188         conn->allocptr.rangeline =
2189           aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2190                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2191                   data->state.range, total_expected_size-1,
2192                   total_expected_size);
2193       }
2194       else {
2195         /* Range was selected and then we just pass the incoming range and
2196            append total size */
2197         conn->allocptr.rangeline =
2198           aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2199                   data->state.range, data->state.infilesize);
2200       }
2201       if(!conn->allocptr.rangeline)
2202         return CURLE_OUT_OF_MEMORY;
2203     }
2204   }
2205
2206   /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2207      supports 1.0 */
2208   httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
2209
2210   /* initialize a dynamic send-buffer */
2211   req_buffer = Curl_add_buffer_init();
2212
2213   if(!req_buffer)
2214     return CURLE_OUT_OF_MEMORY;
2215
2216   /* add the main request stuff */
2217   /* GET/HEAD/POST/PUT */
2218   result = Curl_add_bufferf(req_buffer, "%s ", request);
2219   if(result)
2220     return result;
2221
2222   /* url */
2223   if(paste_ftp_userpwd)
2224     result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2225                               conn->user, conn->passwd,
2226                               ppath + sizeof("ftp://") - 1);
2227   else
2228     result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2229   if(result)
2230     return result;
2231
2232   result =
2233     Curl_add_bufferf(req_buffer,
2234                      "%s" /* ftp typecode (;type=x) */
2235                      " HTTP/%s\r\n" /* HTTP version */
2236                      "%s" /* proxyuserpwd */
2237                      "%s" /* userpwd */
2238                      "%s" /* range */
2239                      "%s" /* user agent */
2240                      "%s" /* host */
2241                      "%s" /* accept */
2242                      "%s" /* TE: */
2243                      "%s" /* accept-encoding */
2244                      "%s" /* referer */
2245                      "%s" /* Proxy-Connection */
2246                      "%s",/* transfer-encoding */
2247
2248                      ftp_typecode,
2249                      httpstring,
2250                      conn->allocptr.proxyuserpwd?
2251                      conn->allocptr.proxyuserpwd:"",
2252                      conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2253                      (data->state.use_range && conn->allocptr.rangeline)?
2254                      conn->allocptr.rangeline:"",
2255                      (data->set.str[STRING_USERAGENT] &&
2256                       *data->set.str[STRING_USERAGENT] &&
2257                       conn->allocptr.uagent)?
2258                      conn->allocptr.uagent:"",
2259                      (conn->allocptr.host?conn->allocptr.host:""),
2260                      http->p_accept?http->p_accept:"",
2261                      conn->allocptr.te?conn->allocptr.te:"",
2262                      (data->set.str[STRING_ENCODING] &&
2263                       *data->set.str[STRING_ENCODING] &&
2264                       conn->allocptr.accept_encoding)?
2265                      conn->allocptr.accept_encoding:"",
2266                      (data->change.referer && conn->allocptr.ref)?
2267                      conn->allocptr.ref:"" /* Referer: <data> */,
2268                      (conn->bits.httpproxy &&
2269                       !conn->bits.tunnel_proxy &&
2270                       !Curl_checkProxyheaders(conn, "Proxy-Connection:"))?
2271                      "Proxy-Connection: Keep-Alive\r\n":"",
2272                      te
2273       );
2274
2275   /*
2276    * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
2277    * with basic and digest, it will be freed anyway by the next request
2278    */
2279
2280   Curl_safefree (conn->allocptr.userpwd);
2281   conn->allocptr.userpwd = NULL;
2282
2283   if(result)
2284     return result;
2285
2286   if(!(conn->handler->flags&PROTOPT_SSL) &&
2287      (data->set.httpversion == CURL_HTTP_VERSION_2_0)) {
2288     /* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
2289        over SSL */
2290     result = Curl_http2_request_upgrade(req_buffer, conn);
2291     if(result)
2292       return result;
2293   }
2294
2295 #if !defined(CURL_DISABLE_COOKIES)
2296   if(data->cookies || addcookies) {
2297     struct Cookie *co=NULL; /* no cookies from start */
2298     int count=0;
2299
2300     if(data->cookies) {
2301       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2302       co = Curl_cookie_getlist(data->cookies,
2303                                conn->allocptr.cookiehost?
2304                                conn->allocptr.cookiehost:host,
2305                                data->state.path,
2306                                (conn->handler->protocol&CURLPROTO_HTTPS)?
2307                                TRUE:FALSE);
2308       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2309     }
2310     if(co) {
2311       struct Cookie *store=co;
2312       /* now loop through all cookies that matched */
2313       while(co) {
2314         if(co->value) {
2315           if(0 == count) {
2316             result = Curl_add_bufferf(req_buffer, "Cookie: ");
2317             if(result)
2318               break;
2319           }
2320           result = Curl_add_bufferf(req_buffer,
2321                                     "%s%s=%s", count?"; ":"",
2322                                     co->name, co->value);
2323           if(result)
2324             break;
2325           count++;
2326         }
2327         co = co->next; /* next cookie please */
2328       }
2329       Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2330     }
2331     if(addcookies && (CURLE_OK == result)) {
2332       if(!count)
2333         result = Curl_add_bufferf(req_buffer, "Cookie: ");
2334       if(CURLE_OK == result) {
2335         result = Curl_add_bufferf(req_buffer, "%s%s",
2336                                   count?"; ":"",
2337                                   addcookies);
2338         count++;
2339       }
2340     }
2341     if(count && (CURLE_OK == result))
2342       result = Curl_add_buffer(req_buffer, "\r\n", 2);
2343
2344     if(result)
2345       return result;
2346   }
2347 #endif
2348
2349   if(data->set.timecondition) {
2350     result = Curl_add_timecondition(data, req_buffer);
2351     if(result)
2352       return result;
2353   }
2354
2355   result = Curl_add_custom_headers(conn, FALSE, req_buffer);
2356   if(result)
2357     return result;
2358
2359   http->postdata = NULL;  /* nothing to post at this point */
2360   Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
2361
2362   /* If 'authdone' is FALSE, we must not set the write socket index to the
2363      Curl_transfer() call below, as we're not ready to actually upload any
2364      data yet. */
2365
2366   switch(httpreq) {
2367
2368   case HTTPREQ_POST_FORM:
2369     if(!http->sendit || conn->bits.authneg) {
2370       /* nothing to post! */
2371       result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2372       if(result)
2373         return result;
2374
2375       result = Curl_add_buffer_send(req_buffer, conn,
2376                                     &data->info.request_size, 0, FIRSTSOCKET);
2377       if(result)
2378         failf(data, "Failed sending POST request");
2379       else
2380         /* setup variables for the upcoming transfer */
2381         Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2382                             -1, NULL);
2383       break;
2384     }
2385
2386     if(Curl_FormInit(&http->form, http->sendit)) {
2387       failf(data, "Internal HTTP POST error!");
2388       return CURLE_HTTP_POST_ERROR;
2389     }
2390
2391     /* Get the currently set callback function pointer and store that in the
2392        form struct since we might want the actual user-provided callback later
2393        on. The conn->fread_func pointer itself will be changed for the
2394        multipart case to the function that returns a multipart formatted
2395        stream. */
2396     http->form.fread_func = conn->fread_func;
2397
2398     /* Set the read function to read from the generated form data */
2399     conn->fread_func = (curl_read_callback)Curl_FormReader;
2400     conn->fread_in = &http->form;
2401
2402     http->sending = HTTPSEND_BODY;
2403
2404     if(!data->req.upload_chunky &&
2405        !Curl_checkheaders(conn, "Content-Length:")) {
2406       /* only add Content-Length if not uploading chunked */
2407       result = Curl_add_bufferf(req_buffer,
2408                                 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2409                                 "\r\n", http->postsize);
2410       if(result)
2411         return result;
2412     }
2413
2414     result = expect100(data, conn, req_buffer);
2415     if(result)
2416       return result;
2417
2418     {
2419
2420       /* Get Content-Type: line from Curl_formpostheader.
2421        */
2422       char *contentType;
2423       size_t linelength=0;
2424       contentType = Curl_formpostheader((void *)&http->form,
2425                                         &linelength);
2426       if(!contentType) {
2427         failf(data, "Could not get Content-Type header line!");
2428         return CURLE_HTTP_POST_ERROR;
2429       }
2430
2431       result = Curl_add_buffer(req_buffer, contentType, linelength);
2432       if(result)
2433         return result;
2434     }
2435
2436     /* make the request end in a true CRLF */
2437     result = Curl_add_buffer(req_buffer, "\r\n", 2);
2438     if(result)
2439       return result;
2440
2441     /* set upload size to the progress meter */
2442     Curl_pgrsSetUploadSize(data, http->postsize);
2443
2444     /* fire away the whole request to the server */
2445     result = Curl_add_buffer_send(req_buffer, conn,
2446                                   &data->info.request_size, 0, FIRSTSOCKET);
2447     if(result)
2448       failf(data, "Failed sending POST request");
2449     else
2450       /* setup variables for the upcoming transfer */
2451       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2452                           &http->readbytecount, FIRSTSOCKET,
2453                           &http->writebytecount);
2454
2455     if(result) {
2456       Curl_formclean(&http->sendit); /* free that whole lot */
2457       return result;
2458     }
2459
2460     /* convert the form data */
2461     result = Curl_convert_form(data, http->sendit);
2462     if(result) {
2463       Curl_formclean(&http->sendit); /* free that whole lot */
2464       return result;
2465     }
2466
2467     break;
2468
2469   case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2470
2471     if(conn->bits.authneg)
2472       postsize = 0;
2473     else
2474       postsize = data->state.infilesize;
2475
2476     if((postsize != -1) && !data->req.upload_chunky &&
2477        !Curl_checkheaders(conn, "Content-Length:")) {
2478       /* only add Content-Length if not uploading chunked */
2479       result = Curl_add_bufferf(req_buffer,
2480                                 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2481                                 "\r\n", postsize);
2482       if(result)
2483         return result;
2484     }
2485
2486     if(postsize != 0) {
2487       result = expect100(data, conn, req_buffer);
2488       if(result)
2489         return result;
2490     }
2491
2492     result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2493     if(result)
2494       return result;
2495
2496     /* set the upload size to the progress meter */
2497     Curl_pgrsSetUploadSize(data, postsize);
2498
2499     /* this sends the buffer and frees all the buffer resources */
2500     result = Curl_add_buffer_send(req_buffer, conn,
2501                                   &data->info.request_size, 0, FIRSTSOCKET);
2502     if(result)
2503       failf(data, "Failed sending PUT request");
2504     else
2505       /* prepare for transfer */
2506       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2507                           &http->readbytecount, postsize?FIRSTSOCKET:-1,
2508                           postsize?&http->writebytecount:NULL);
2509     if(result)
2510       return result;
2511     break;
2512
2513   case HTTPREQ_POST:
2514     /* this is the simple POST, using x-www-form-urlencoded style */
2515
2516     if(conn->bits.authneg)
2517       postsize = 0;
2518     else {
2519       /* figure out the size of the postfields */
2520       postsize = (data->set.postfieldsize != -1)?
2521         data->set.postfieldsize:
2522         (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2523     }
2524
2525     /* We only set Content-Length and allow a custom Content-Length if
2526        we don't upload data chunked, as RFC2616 forbids us to set both
2527        kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2528     if((postsize != -1) && !data->req.upload_chunky &&
2529        !Curl_checkheaders(conn, "Content-Length:")) {
2530       /* we allow replacing this header if not during auth negotiation,
2531          although it isn't very wise to actually set your own */
2532       result = Curl_add_bufferf(req_buffer,
2533                                 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2534                                 "\r\n", postsize);
2535       if(result)
2536         return result;
2537     }
2538
2539     if(!Curl_checkheaders(conn, "Content-Type:")) {
2540       result = Curl_add_bufferf(req_buffer,
2541                                 "Content-Type: application/"
2542                                 "x-www-form-urlencoded\r\n");
2543       if(result)
2544         return result;
2545     }
2546
2547     /* For really small posts we don't use Expect: headers at all, and for
2548        the somewhat bigger ones we allow the app to disable it. Just make
2549        sure that the expect100header is always set to the preferred value
2550        here. */
2551     ptr = Curl_checkheaders(conn, "Expect:");
2552     if(ptr) {
2553       data->state.expect100header =
2554         Curl_compareheader(ptr, "Expect:", "100-continue");
2555     }
2556     else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2557       result = expect100(data, conn, req_buffer);
2558       if(result)
2559         return result;
2560     }
2561     else
2562       data->state.expect100header = FALSE;
2563
2564     if(data->set.postfields) {
2565
2566       /* In HTTP2, we send request body in DATA frame regardless of
2567          its size. */
2568       if(conn->httpversion != 20 &&
2569          !data->state.expect100header &&
2570          (postsize < MAX_INITIAL_POST_SIZE))  {
2571         /* if we don't use expect: 100  AND
2572            postsize is less than MAX_INITIAL_POST_SIZE
2573
2574            then append the post data to the HTTP request header. This limit
2575            is no magic limit but only set to prevent really huge POSTs to
2576            get the data duplicated with malloc() and family. */
2577
2578         result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2579         if(result)
2580           return result;
2581
2582         if(!data->req.upload_chunky) {
2583           /* We're not sending it 'chunked', append it to the request
2584              already now to reduce the number if send() calls */
2585           result = Curl_add_buffer(req_buffer, data->set.postfields,
2586                                    (size_t)postsize);
2587           included_body = postsize;
2588         }
2589         else {
2590           if(postsize) {
2591             /* Append the POST data chunky-style */
2592             result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2593             if(CURLE_OK == result) {
2594               result = Curl_add_buffer(req_buffer, data->set.postfields,
2595                                        (size_t)postsize);
2596               if(CURLE_OK == result)
2597                  result = Curl_add_buffer(req_buffer, "\r\n", 2);
2598               included_body = postsize + 2;
2599             }
2600           }
2601           if(CURLE_OK == result)
2602             result = Curl_add_buffer(req_buffer,
2603                                      "\x30\x0d\x0a\x0d\x0a", 5);
2604           /* 0  CR  LF  CR  LF */
2605           included_body += 5;
2606         }
2607         if(result)
2608           return result;
2609         /* Make sure the progress information is accurate */
2610         Curl_pgrsSetUploadSize(data, postsize);
2611       }
2612       else {
2613         /* A huge POST coming up, do data separate from the request */
2614         http->postsize = postsize;
2615         http->postdata = data->set.postfields;
2616
2617         http->sending = HTTPSEND_BODY;
2618
2619         conn->fread_func = (curl_read_callback)readmoredata;
2620         conn->fread_in = (void *)conn;
2621
2622         /* set the upload size to the progress meter */
2623         Curl_pgrsSetUploadSize(data, http->postsize);
2624
2625         result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2626         if(result)
2627           return result;
2628       }
2629     }
2630     else {
2631       result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2632       if(result)
2633         return result;
2634
2635       if(data->req.upload_chunky && conn->bits.authneg) {
2636         /* Chunky upload is selected and we're negotiating auth still, send
2637            end-of-data only */
2638         result = Curl_add_buffer(req_buffer,
2639                                  "\x30\x0d\x0a\x0d\x0a", 5);
2640         /* 0  CR  LF  CR  LF */
2641         if(result)
2642           return result;
2643       }
2644
2645       else if(data->set.postfieldsize) {
2646         /* set the upload size to the progress meter */
2647         Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2648
2649         /* set the pointer to mark that we will send the post body using the
2650            read callback, but only if we're not in authenticate
2651            negotiation  */
2652         if(!conn->bits.authneg) {
2653           http->postdata = (char *)&http->postdata;
2654           http->postsize = postsize;
2655         }
2656       }
2657     }
2658     /* issue the request */
2659     result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2660                                   (size_t)included_body, FIRSTSOCKET);
2661
2662     if(result)
2663       failf(data, "Failed sending HTTP POST request");
2664     else
2665       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2666                           &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2667                           http->postdata?&http->writebytecount:NULL);
2668     break;
2669
2670   default:
2671     result = Curl_add_buffer(req_buffer, "\r\n", 2);
2672     if(result)
2673       return result;
2674
2675     /* issue the request */
2676     result = Curl_add_buffer_send(req_buffer, conn,
2677                                   &data->info.request_size, 0, FIRSTSOCKET);
2678
2679     if(result)
2680       failf(data, "Failed sending HTTP request");
2681     else
2682       /* HTTP GET/HEAD download: */
2683       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2684                           http->postdata?FIRSTSOCKET:-1,
2685                           http->postdata?&http->writebytecount:NULL);
2686   }
2687   if(result)
2688     return result;
2689
2690   if(http->writebytecount) {
2691     /* if a request-body has been sent off, we make sure this progress is noted
2692        properly */
2693     Curl_pgrsSetUploadCounter(data, http->writebytecount);
2694     if(Curl_pgrsUpdate(conn))
2695       result = CURLE_ABORTED_BY_CALLBACK;
2696
2697     if(http->writebytecount >= postsize) {
2698       /* already sent the entire request body, mark the "upload" as
2699          complete */
2700       infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
2701             " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
2702             http->writebytecount, postsize);
2703       data->req.upload_done = TRUE;
2704       data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2705       data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2706     }
2707   }
2708
2709   return result;
2710 }
2711
2712 /*
2713  * checkhttpprefix()
2714  *
2715  * Returns TRUE if member of the list matches prefix of string
2716  */
2717 static bool
2718 checkhttpprefix(struct SessionHandle *data,
2719                 const char *s)
2720 {
2721   struct curl_slist *head = data->set.http200aliases;
2722   bool rc = FALSE;
2723 #ifdef CURL_DOES_CONVERSIONS
2724   /* convert from the network encoding using a scratch area */
2725   char *scratch = strdup(s);
2726   if(NULL == scratch) {
2727     failf (data, "Failed to allocate memory for conversion!");
2728     return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2729   }
2730   if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2731     /* Curl_convert_from_network calls failf if unsuccessful */
2732     free(scratch);
2733     return FALSE; /* can't return CURLE_foobar so return FALSE */
2734   }
2735   s = scratch;
2736 #endif /* CURL_DOES_CONVERSIONS */
2737
2738   while(head) {
2739     if(checkprefix(head->data, s)) {
2740       rc = TRUE;
2741       break;
2742     }
2743     head = head->next;
2744   }
2745
2746   if(!rc && (checkprefix("HTTP/", s)))
2747     rc = TRUE;
2748
2749 #ifdef CURL_DOES_CONVERSIONS
2750   free(scratch);
2751 #endif /* CURL_DOES_CONVERSIONS */
2752   return rc;
2753 }
2754
2755 #ifndef CURL_DISABLE_RTSP
2756 static bool
2757 checkrtspprefix(struct SessionHandle *data,
2758                 const char *s)
2759 {
2760
2761 #ifdef CURL_DOES_CONVERSIONS
2762   /* convert from the network encoding using a scratch area */
2763   char *scratch = strdup(s);
2764   if(NULL == scratch) {
2765     failf (data, "Failed to allocate memory for conversion!");
2766     return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2767   }
2768   if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2769     /* Curl_convert_from_network calls failf if unsuccessful */
2770     free(scratch);
2771     return FALSE; /* can't return CURLE_foobar so return FALSE */
2772   }
2773   s = scratch;
2774 #else
2775   (void)data; /* unused */
2776 #endif /* CURL_DOES_CONVERSIONS */
2777   if(checkprefix("RTSP/", s))
2778     return TRUE;
2779   else
2780     return FALSE;
2781 }
2782 #endif /* CURL_DISABLE_RTSP */
2783
2784 static bool
2785 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2786                  const char *s)
2787 {
2788 #ifndef CURL_DISABLE_RTSP
2789   if(conn->handler->protocol & CURLPROTO_RTSP)
2790     return checkrtspprefix(data, s);
2791 #else
2792   (void)conn;
2793 #endif /* CURL_DISABLE_RTSP */
2794
2795   return checkhttpprefix(data, s);
2796 }
2797
2798 /*
2799  * header_append() copies a chunk of data to the end of the already received
2800  * header. We make sure that the full string fit in the allocated header
2801  * buffer, or else we enlarge it.
2802  */
2803 static CURLcode header_append(struct SessionHandle *data,
2804                               struct SingleRequest *k,
2805                               size_t length)
2806 {
2807   if(k->hbuflen + length >= data->state.headersize) {
2808     /* We enlarge the header buffer as it is too small */
2809     char *newbuff;
2810     size_t hbufp_index;
2811     size_t newsize;
2812
2813     if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2814       /* The reason to have a max limit for this is to avoid the risk of a bad
2815          server feeding libcurl with a never-ending header that will cause
2816          reallocs infinitely */
2817       failf (data, "Avoided giant realloc for header (max is %d)!",
2818              CURL_MAX_HTTP_HEADER);
2819       return CURLE_OUT_OF_MEMORY;
2820     }
2821
2822     newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2823     hbufp_index = k->hbufp - data->state.headerbuff;
2824     newbuff = realloc(data->state.headerbuff, newsize);
2825     if(!newbuff) {
2826       failf (data, "Failed to alloc memory for big header!");
2827       return CURLE_OUT_OF_MEMORY;
2828     }
2829     data->state.headersize=newsize;
2830     data->state.headerbuff = newbuff;
2831     k->hbufp = data->state.headerbuff + hbufp_index;
2832   }
2833   memcpy(k->hbufp, k->str_start, length);
2834   k->hbufp += length;
2835   k->hbuflen += length;
2836   *k->hbufp = 0;
2837
2838   return CURLE_OK;
2839 }
2840
2841 static void print_http_error(struct SessionHandle *data)
2842 {
2843   struct SingleRequest *k = &data->req;
2844   char *beg = k->p;
2845
2846   /* make sure that data->req.p points to the HTTP status line */
2847   if(!strncmp(beg, "HTTP", 4)) {
2848
2849     /* skip to HTTP status code */
2850     beg = strchr(beg, ' ');
2851     if(beg && *++beg) {
2852
2853       /* find trailing CR */
2854       char end_char = '\r';
2855       char *end = strchr(beg, end_char);
2856       if(!end) {
2857         /* try to find LF (workaround for non-compliant HTTP servers) */
2858         end_char = '\n';
2859         end = strchr(beg, end_char);
2860       }
2861
2862       if(end) {
2863         /* temporarily replace CR or LF by NUL and print the error message */
2864         *end = '\0';
2865         failf(data, "The requested URL returned error: %s", beg);
2866
2867         /* restore the previously replaced CR or LF */
2868         *end = end_char;
2869         return;
2870       }
2871     }
2872   }
2873
2874   /* fall-back to printing the HTTP status code only */
2875   failf(data, "The requested URL returned error: %d", k->httpcode);
2876 }
2877
2878 /*
2879  * Read any HTTP header lines from the server and pass them to the client app.
2880  */
2881 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2882                                        struct connectdata *conn,
2883                                        ssize_t *nread,
2884                                        bool *stop_reading)
2885 {
2886   CURLcode result;
2887   struct SingleRequest *k = &data->req;
2888
2889   /* header line within buffer loop */
2890   do {
2891     size_t rest_length;
2892     size_t full_length;
2893     int writetype;
2894
2895     /* str_start is start of line within buf */
2896     k->str_start = k->str;
2897
2898     /* data is in network encoding so use 0x0a instead of '\n' */
2899     k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2900
2901     if(!k->end_ptr) {
2902       /* Not a complete header line within buffer, append the data to
2903          the end of the headerbuff. */
2904       result = header_append(data, k, *nread);
2905       if(result)
2906         return result;
2907
2908       if(!k->headerline && (k->hbuflen>5)) {
2909         /* make a first check that this looks like a protocol header */
2910         if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2911           /* this is not the beginning of a protocol first header line */
2912           k->header = FALSE;
2913           k->badheader = HEADER_ALLBAD;
2914           break;
2915         }
2916       }
2917
2918       break; /* read more and try again */
2919     }
2920
2921     /* decrease the size of the remaining (supposed) header line */
2922     rest_length = (k->end_ptr - k->str)+1;
2923     *nread -= (ssize_t)rest_length;
2924
2925     k->str = k->end_ptr + 1; /* move past new line */
2926
2927     full_length = k->str - k->str_start;
2928
2929     result = header_append(data, k, full_length);
2930     if(result)
2931       return result;
2932
2933     k->end_ptr = k->hbufp;
2934     k->p = data->state.headerbuff;
2935
2936     /****
2937      * We now have a FULL header line that p points to
2938      *****/
2939
2940     if(!k->headerline) {
2941       /* the first read header */
2942       if((k->hbuflen>5) &&
2943          !checkprotoprefix(data, conn, data->state.headerbuff)) {
2944         /* this is not the beginning of a protocol first header line */
2945         k->header = FALSE;
2946         if(*nread)
2947           /* since there's more, this is a partial bad header */
2948           k->badheader = HEADER_PARTHEADER;
2949         else {
2950           /* this was all we read so it's all a bad header */
2951           k->badheader = HEADER_ALLBAD;
2952           *nread = (ssize_t)rest_length;
2953         }
2954         break;
2955       }
2956     }
2957
2958     /* headers are in network encoding so
2959        use 0x0a and 0x0d instead of '\n' and '\r' */
2960     if((0x0a == *k->p) || (0x0d == *k->p)) {
2961       size_t headerlen;
2962       /* Zero-length header line means end of headers! */
2963
2964 #ifdef CURL_DOES_CONVERSIONS
2965       if(0x0d == *k->p) {
2966         *k->p = '\r'; /* replace with CR in host encoding */
2967         k->p++;       /* pass the CR byte */
2968       }
2969       if(0x0a == *k->p) {
2970         *k->p = '\n'; /* replace with LF in host encoding */
2971         k->p++;       /* pass the LF byte */
2972       }
2973 #else
2974       if('\r' == *k->p)
2975         k->p++; /* pass the \r byte */
2976       if('\n' == *k->p)
2977         k->p++; /* pass the \n byte */
2978 #endif /* CURL_DOES_CONVERSIONS */
2979
2980       if(100 <= k->httpcode && 199 >= k->httpcode) {
2981         /*
2982          * We have made a HTTP PUT or POST and this is 1.1-lingo
2983          * that tells us that the server is OK with this and ready
2984          * to receive the data.
2985          * However, we'll get more headers now so we must get
2986          * back into the header-parsing state!
2987          */
2988         k->header = TRUE;
2989         k->headerline = 0; /* restart the header line counter */
2990
2991         /* "A user agent MAY ignore unexpected 1xx status responses." */
2992         switch(k->httpcode) {
2993         case 100:
2994           /* if we did wait for this do enable write now! */
2995           if(k->exp100) {
2996             k->exp100 = EXP100_SEND_DATA;
2997             k->keepon |= KEEP_SEND;
2998           }
2999           break;
3000         case 101:
3001           /* Switching Protocols */
3002           if(k->upgr101 == UPGR101_REQUESTED) {
3003             infof(data, "Received 101\n");
3004             k->upgr101 = UPGR101_RECEIVED;
3005
3006             /* switch to http2 now */
3007             /* TODO: add error checking */
3008             Curl_http2_switched(conn);
3009           }
3010           break;
3011         default:
3012           break;
3013         }
3014       }
3015       else {
3016         k->header = FALSE; /* no more header to parse! */
3017
3018         if((k->size == -1) && !k->chunk && !conn->bits.close &&
3019            (conn->httpversion == 11) &&
3020            !(conn->handler->protocol & CURLPROTO_RTSP) &&
3021            data->set.httpreq != HTTPREQ_HEAD) {
3022           /* On HTTP 1.1, when connection is not to get closed, but no
3023              Content-Length nor Content-Encoding chunked have been
3024              received, according to RFC2616 section 4.4 point 5, we
3025              assume that the server will close the connection to
3026              signal the end of the document. */
3027           infof(data, "no chunk, no close, no size. Assume close to "
3028                 "signal end\n");
3029           connclose(conn, "HTTP: No end-of-message indicator");
3030         }
3031       }
3032
3033       /*
3034        * When all the headers have been parsed, see if we should give
3035        * up and return an error.
3036        */
3037       if(http_should_fail(conn)) {
3038         failf (data, "The requested URL returned error: %d",
3039                k->httpcode);
3040         return CURLE_HTTP_RETURNED_ERROR;
3041       }
3042
3043       /* now, only output this if the header AND body are requested:
3044        */
3045       writetype = CLIENTWRITE_HEADER;
3046       if(data->set.include_header)
3047         writetype |= CLIENTWRITE_BODY;
3048
3049       headerlen = k->p - data->state.headerbuff;
3050
3051       result = Curl_client_write(conn, writetype,
3052                                  data->state.headerbuff,
3053                                  headerlen);
3054       if(result)
3055         return result;
3056
3057       data->info.header_size += (long)headerlen;
3058       data->req.headerbytecount += (long)headerlen;
3059
3060       data->req.deductheadercount =
3061         (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
3062
3063       if(!*stop_reading) {
3064         /* Curl_http_auth_act() checks what authentication methods
3065          * that are available and decides which one (if any) to
3066          * use. It will set 'newurl' if an auth method was picked. */
3067         result = Curl_http_auth_act(conn);
3068
3069         if(result)
3070           return result;
3071
3072         if(k->httpcode >= 300) {
3073           if((!conn->bits.authneg) && !conn->bits.close &&
3074              !conn->bits.rewindaftersend) {
3075             /*
3076              * General treatment of errors when about to send data. Including :
3077              * "417 Expectation Failed", while waiting for 100-continue.
3078              *
3079              * The check for close above is done simply because of something
3080              * else has already deemed the connection to get closed then
3081              * something else should've considered the big picture and we
3082              * avoid this check.
3083              *
3084              * rewindaftersend indicates that something has told libcurl to
3085              * continue sending even if it gets discarded
3086              */
3087
3088             switch(data->set.httpreq) {
3089             case HTTPREQ_PUT:
3090             case HTTPREQ_POST:
3091             case HTTPREQ_POST_FORM:
3092               /* We got an error response. If this happened before the whole
3093                * request body has been sent we stop sending and mark the
3094                * connection for closure after we've read the entire response.
3095                */
3096               if(!k->upload_done) {
3097                 infof(data, "HTTP error before end of send, stop sending\n");
3098                 connclose(conn, "Stop sending data before everything sent");
3099                 k->upload_done = TRUE;
3100                 k->keepon &= ~KEEP_SEND; /* don't send */
3101                 if(data->state.expect100header)
3102                   k->exp100 = EXP100_FAILED;
3103               }
3104               break;
3105
3106             default: /* default label present to avoid compiler warnings */
3107               break;
3108             }
3109           }
3110         }
3111
3112         if(conn->bits.rewindaftersend) {
3113           /* We rewind after a complete send, so thus we continue
3114              sending now */
3115           infof(data, "Keep sending data to get tossed away!\n");
3116           k->keepon |= KEEP_SEND;
3117         }
3118       }
3119
3120       if(!k->header) {
3121         /*
3122          * really end-of-headers.
3123          *
3124          * If we requested a "no body", this is a good time to get
3125          * out and return home.
3126          */
3127         if(data->set.opt_no_body)
3128           *stop_reading = TRUE;
3129         else {
3130           /* If we know the expected size of this document, we set the
3131              maximum download size to the size of the expected
3132              document or else, we won't know when to stop reading!
3133
3134              Note that we set the download maximum even if we read a
3135              "Connection: close" header, to make sure that
3136              "Content-Length: 0" still prevents us from attempting to
3137              read the (missing) response-body.
3138           */
3139           /* According to RFC2616 section 4.4, we MUST ignore
3140              Content-Length: headers if we are now receiving data
3141              using chunked Transfer-Encoding.
3142           */
3143           if(k->chunk)
3144             k->maxdownload = k->size = -1;
3145         }
3146         if(-1 != k->size) {
3147           /* We do this operation even if no_body is true, since this
3148              data might be retrieved later with curl_easy_getinfo()
3149              and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3150
3151           Curl_pgrsSetDownloadSize(data, k->size);
3152           k->maxdownload = k->size;
3153         }
3154
3155         /* If max download size is *zero* (nothing) we already
3156            have nothing and can safely return ok now! */
3157         if(0 == k->maxdownload)
3158           *stop_reading = TRUE;
3159
3160         if(*stop_reading) {
3161           /* we make sure that this socket isn't read more now */
3162           k->keepon &= ~KEEP_RECV;
3163         }
3164
3165         if(data->set.verbose)
3166           Curl_debug(data, CURLINFO_HEADER_IN,
3167                      k->str_start, headerlen, conn);
3168         break;          /* exit header line loop */
3169       }
3170
3171       /* We continue reading headers, so reset the line-based
3172          header parsing variables hbufp && hbuflen */
3173       k->hbufp = data->state.headerbuff;
3174       k->hbuflen = 0;
3175       continue;
3176     }
3177
3178     /*
3179      * Checks for special headers coming up.
3180      */
3181
3182     if(!k->headerline++) {
3183       /* This is the first header, it MUST be the error code line
3184          or else we consider this to be the body right away! */
3185       int httpversion_major;
3186       int rtspversion_major;
3187       int nc = 0;
3188 #ifdef CURL_DOES_CONVERSIONS
3189 #define HEADER1 scratch
3190 #define SCRATCHSIZE 21
3191       CURLcode res;
3192       char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
3193       /* We can't really convert this yet because we
3194          don't know if it's the 1st header line or the body.
3195          So we do a partial conversion into a scratch area,
3196          leaving the data at k->p as-is.
3197       */
3198       strncpy(&scratch[0], k->p, SCRATCHSIZE);
3199       scratch[SCRATCHSIZE] = 0; /* null terminate */
3200       res = Curl_convert_from_network(data,
3201                                       &scratch[0],
3202                                       SCRATCHSIZE);
3203       if(res)
3204         /* Curl_convert_from_network calls failf if unsuccessful */
3205         return res;
3206 #else
3207 #define HEADER1 k->p /* no conversion needed, just use k->p */
3208 #endif /* CURL_DOES_CONVERSIONS */
3209
3210       if(conn->handler->protocol & PROTO_FAMILY_HTTP) {
3211         nc = sscanf(HEADER1,
3212                     " HTTP/%d.%d %3d",
3213                     &httpversion_major,
3214                     &conn->httpversion,
3215                     &k->httpcode);
3216         if(nc==3) {
3217           conn->httpversion += 10 * httpversion_major;
3218         }
3219         else {
3220           /* this is the real world, not a Nirvana
3221              NCSA 1.5.x returns this crap when asked for HTTP/1.1
3222           */
3223           nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3224           conn->httpversion = 10;
3225
3226           /* If user has set option HTTP200ALIASES,
3227              compare header line against list of aliases
3228           */
3229           if(!nc) {
3230             if(checkhttpprefix(data, k->p)) {
3231               nc = 1;
3232               k->httpcode = 200;
3233               conn->httpversion = 10;
3234             }
3235           }
3236         }
3237       }
3238       else if(conn->handler->protocol & CURLPROTO_RTSP) {
3239         nc = sscanf(HEADER1,
3240                     " RTSP/%d.%d %3d",
3241                     &rtspversion_major,
3242                     &conn->rtspversion,
3243                     &k->httpcode);
3244         if(nc==3) {
3245           conn->rtspversion += 10 * rtspversion_major;
3246           conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3247         }
3248         else {
3249           /* TODO: do we care about the other cases here? */
3250           nc = 0;
3251         }
3252       }
3253
3254       if(nc) {
3255         data->info.httpcode = k->httpcode;
3256
3257         data->info.httpversion = conn->httpversion;
3258         if(!data->state.httpversion ||
3259            data->state.httpversion > conn->httpversion)
3260           /* store the lowest server version we encounter */
3261           data->state.httpversion = conn->httpversion;
3262
3263         /*
3264          * This code executes as part of processing the header.  As a
3265          * result, it's not totally clear how to interpret the
3266          * response code yet as that depends on what other headers may
3267          * be present.  401 and 407 may be errors, but may be OK
3268          * depending on how authentication is working.  Other codes
3269          * are definitely errors, so give up here.
3270          */
3271         if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3272            ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3273            ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3274
3275           if(data->state.resume_from &&
3276              (data->set.httpreq==HTTPREQ_GET) &&
3277              (k->httpcode == 416)) {
3278             /* "Requested Range Not Satisfiable", just proceed and
3279                pretend this is no error */
3280           }
3281           else {
3282             /* serious error, go home! */
3283             print_http_error(data);
3284             return CURLE_HTTP_RETURNED_ERROR;
3285           }
3286         }
3287
3288         if(conn->httpversion == 10) {
3289           /* Default action for HTTP/1.0 must be to close, unless
3290              we get one of those fancy headers that tell us the
3291              server keeps it open for us! */
3292           infof(data, "HTTP 1.0, assume close after body\n");
3293           connclose(conn, "HTTP/1.0 close after body");
3294         }
3295         else if(conn->httpversion >= 11 &&
3296                 !conn->bits.close) {
3297           struct connectbundle *cb_ptr;
3298
3299           /* If HTTP version is >= 1.1 and connection is persistent
3300              server supports pipelining. */
3301           DEBUGF(infof(data,
3302                        "HTTP 1.1 or later with persistent connection, "
3303                        "pipelining supported\n"));
3304           /* Activate pipelining if needed */
3305           cb_ptr = conn->bundle;
3306           if(cb_ptr) {
3307             if(!Curl_pipeline_site_blacklisted(data, conn))
3308               cb_ptr->server_supports_pipelining = TRUE;
3309           }
3310         }
3311
3312         switch(k->httpcode) {
3313         case 204:
3314           /* (quote from RFC2616, section 10.2.5): The server has
3315            * fulfilled the request but does not need to return an
3316            * entity-body ... The 204 response MUST NOT include a
3317            * message-body, and thus is always terminated by the first
3318            * empty line after the header fields. */
3319           /* FALLTHROUGH */
3320         case 304:
3321           /* (quote from RFC2616, section 10.3.5): The 304 response
3322            * MUST NOT contain a message-body, and thus is always
3323            * terminated by the first empty line after the header
3324            * fields.  */
3325           if(data->set.timecondition)
3326             data->info.timecond = TRUE;
3327           k->size=0;
3328           k->maxdownload=0;
3329           k->ignorecl = TRUE; /* ignore Content-Length headers */
3330           break;
3331         default:
3332           /* nothing */
3333           break;
3334         }
3335       }
3336       else {
3337         k->header = FALSE;   /* this is not a header line */
3338         break;
3339       }
3340     }
3341
3342     result = Curl_convert_from_network(data, k->p, strlen(k->p));
3343     /* Curl_convert_from_network calls failf if unsuccessful */
3344     if(result)
3345       return result;
3346
3347     /* Check for Content-Length: header lines to get size */
3348     if(!k->ignorecl && !data->set.ignorecl &&
3349        checkprefix("Content-Length:", k->p)) {
3350       curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3351       if(data->set.max_filesize &&
3352          contentlength > data->set.max_filesize) {
3353         failf(data, "Maximum file size exceeded");
3354         return CURLE_FILESIZE_EXCEEDED;
3355       }
3356       if(contentlength >= 0) {
3357         k->size = contentlength;
3358         k->maxdownload = k->size;
3359         /* we set the progress download size already at this point
3360            just to make it easier for apps/callbacks to extract this
3361            info as soon as possible */
3362         Curl_pgrsSetDownloadSize(data, k->size);
3363       }
3364       else {
3365         /* Negative Content-Length is really odd, and we know it
3366            happens for example when older Apache servers send large
3367            files */
3368         connclose(conn, "negative content-length");
3369         infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
3370               ", closing after transfer\n", contentlength);
3371       }
3372     }
3373     /* check for Content-Type: header lines to get the MIME-type */
3374     else if(checkprefix("Content-Type:", k->p)) {
3375       char *contenttype = Curl_copy_header_value(k->p);
3376       if(!contenttype)
3377         return CURLE_OUT_OF_MEMORY;
3378       if(!*contenttype)
3379         /* ignore empty data */
3380         free(contenttype);
3381       else {
3382         Curl_safefree(data->info.contenttype);
3383         data->info.contenttype = contenttype;
3384       }
3385     }
3386     else if(checkprefix("Server:", k->p)) {
3387       char *server_name = Curl_copy_header_value(k->p);
3388
3389       /* Turn off pipelining if the server version is blacklisted */
3390       if(conn->bundle && conn->bundle->server_supports_pipelining) {
3391         if(Curl_pipeline_server_blacklisted(data, server_name))
3392           conn->bundle->server_supports_pipelining = FALSE;
3393       }
3394       Curl_safefree(server_name);
3395     }
3396     else if((conn->httpversion == 10) &&
3397             conn->bits.httpproxy &&
3398             Curl_compareheader(k->p,
3399                                "Proxy-Connection:", "keep-alive")) {
3400       /*
3401        * When a HTTP/1.0 reply comes when using a proxy, the
3402        * 'Proxy-Connection: keep-alive' line tells us the
3403        * connection will be kept alive for our pleasure.
3404        * Default action for 1.0 is to close.
3405        */
3406       connkeep(conn, "Proxy-Connection keep-alive"); /* don't close */
3407       infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3408     }
3409     else if((conn->httpversion == 11) &&
3410             conn->bits.httpproxy &&
3411             Curl_compareheader(k->p,
3412                                "Proxy-Connection:", "close")) {
3413       /*
3414        * We get a HTTP/1.1 response from a proxy and it says it'll
3415        * close down after this transfer.
3416        */
3417       connclose(conn, "Proxy-Connection: asked to close after done");
3418       infof(data, "HTTP/1.1 proxy connection set close!\n");
3419     }
3420     else if((conn->httpversion == 10) &&
3421             Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3422       /*
3423        * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3424        * tells us the connection will be kept alive for our
3425        * pleasure.  Default action for 1.0 is to close.
3426        *
3427        * [RFC2068, section 19.7.1] */
3428       connkeep(conn, "Connection keep-alive");
3429       infof(data, "HTTP/1.0 connection set to keep alive!\n");
3430     }
3431     else if(Curl_compareheader(k->p, "Connection:", "close")) {
3432       /*
3433        * [RFC 2616, section 8.1.2.1]
3434        * "Connection: close" is HTTP/1.1 language and means that
3435        * the connection will close when this request has been
3436        * served.
3437        */
3438       connclose(conn, "Connection: close used");
3439     }
3440     else if(checkprefix("Transfer-Encoding:", k->p)) {
3441       /* One or more encodings. We check for chunked and/or a compression
3442          algorithm. */
3443       /*
3444        * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3445        * means that the server will send a series of "chunks". Each
3446        * chunk starts with line with info (including size of the
3447        * coming block) (terminated with CRLF), then a block of data
3448        * with the previously mentioned size. There can be any amount
3449        * of chunks, and a chunk-data set to zero signals the
3450        * end-of-chunks. */
3451
3452       char *start;
3453
3454       /* Find the first non-space letter */
3455       start = k->p + 18;
3456
3457       for(;;) {
3458         /* skip whitespaces and commas */
3459         while(*start && (ISSPACE(*start) || (*start == ',')))
3460           start++;
3461
3462         if(checkprefix("chunked", start)) {
3463           k->chunk = TRUE; /* chunks coming our way */
3464
3465           /* init our chunky engine */
3466           Curl_httpchunk_init(conn);
3467
3468           start += 7;
3469         }
3470
3471         if(k->auto_decoding)
3472           /* TODO: we only support the first mentioned compression for now */
3473           break;
3474
3475         if(checkprefix("identity", start)) {
3476           k->auto_decoding = IDENTITY;
3477           start += 8;
3478         }
3479         else if(checkprefix("deflate", start)) {
3480           k->auto_decoding = DEFLATE;
3481           start += 7;
3482         }
3483         else if(checkprefix("gzip", start)) {
3484           k->auto_decoding = GZIP;
3485           start += 4;
3486         }
3487         else if(checkprefix("x-gzip", start)) {
3488           k->auto_decoding = GZIP;
3489           start += 6;
3490         }
3491         else if(checkprefix("compress", start)) {
3492           k->auto_decoding = COMPRESS;
3493           start += 8;
3494         }
3495         else if(checkprefix("x-compress", start)) {
3496           k->auto_decoding = COMPRESS;
3497           start += 10;
3498         }
3499         else
3500           /* unknown! */
3501           break;
3502
3503       }
3504
3505     }
3506     else if(checkprefix("Content-Encoding:", k->p) &&
3507             (data->set.str[STRING_ENCODING] ||
3508              conn->httpversion == 20)) {
3509       /*
3510        * Process Content-Encoding. Look for the values: identity,
3511        * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3512        * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3513        * 2616). zlib cannot handle compress.  However, errors are
3514        * handled further down when the response body is processed
3515        */
3516       char *start;
3517
3518       /* Find the first non-space letter */
3519       start = k->p + 17;
3520       while(*start && ISSPACE(*start))
3521         start++;
3522
3523       /* Record the content-encoding for later use */
3524       if(checkprefix("identity", start))
3525         k->auto_decoding = IDENTITY;
3526       else if(checkprefix("deflate", start))
3527         k->auto_decoding = DEFLATE;
3528       else if(checkprefix("gzip", start)
3529               || checkprefix("x-gzip", start))
3530         k->auto_decoding = GZIP;
3531       else if(checkprefix("compress", start)
3532               || checkprefix("x-compress", start))
3533         k->auto_decoding = COMPRESS;
3534     }
3535     else if(checkprefix("Content-Range:", k->p)) {
3536       /* Content-Range: bytes [num]-
3537          Content-Range: bytes: [num]-
3538          Content-Range: [num]-
3539
3540          The second format was added since Sun's webserver
3541          JavaWebServer/1.1.1 obviously sends the header this way!
3542          The third added since some servers use that!
3543       */
3544
3545       char *ptr = k->p + 14;
3546
3547       /* Move forward until first digit */
3548       while(*ptr && !ISDIGIT(*ptr))
3549         ptr++;
3550
3551       k->offset = curlx_strtoofft(ptr, NULL, 10);
3552
3553       if(data->state.resume_from == k->offset)
3554         /* we asked for a resume and we got it */
3555         k->content_range = TRUE;
3556     }
3557 #if !defined(CURL_DISABLE_COOKIES)
3558     else if(data->cookies &&
3559             checkprefix("Set-Cookie:", k->p)) {
3560       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3561                       CURL_LOCK_ACCESS_SINGLE);
3562       Curl_cookie_add(data,
3563                       data->cookies, TRUE, k->p+11,
3564                       /* If there is a custom-set Host: name, use it
3565                          here, or else use real peer host name. */
3566                       conn->allocptr.cookiehost?
3567                       conn->allocptr.cookiehost:conn->host.name,
3568                       data->state.path);
3569       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3570     }
3571 #endif
3572     else if(checkprefix("Last-Modified:", k->p) &&
3573             (data->set.timecondition || data->set.get_filetime) ) {
3574       time_t secs=time(NULL);
3575       k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3576                                   &secs);
3577       if(data->set.get_filetime)
3578         data->info.filetime = (long)k->timeofdoc;
3579     }
3580     else if((checkprefix("WWW-Authenticate:", k->p) &&
3581              (401 == k->httpcode)) ||
3582             (checkprefix("Proxy-authenticate:", k->p) &&
3583              (407 == k->httpcode))) {
3584
3585       bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3586       char *auth = Curl_copy_header_value(k->p);
3587       if(!auth)
3588         return CURLE_OUT_OF_MEMORY;
3589
3590       result = Curl_http_input_auth(conn, proxy, auth);
3591
3592       Curl_safefree(auth);
3593
3594       if(result)
3595         return result;
3596     }
3597     else if((k->httpcode >= 300 && k->httpcode < 400) &&
3598             checkprefix("Location:", k->p) &&
3599             !data->req.location) {
3600       /* this is the URL that the server advises us to use instead */
3601       char *location = Curl_copy_header_value(k->p);
3602       if(!location)
3603         return CURLE_OUT_OF_MEMORY;
3604       if(!*location)
3605         /* ignore empty data */
3606         free(location);
3607       else {
3608         data->req.location = location;
3609
3610         if(data->set.http_follow_location) {
3611           DEBUGASSERT(!data->req.newurl);
3612           data->req.newurl = strdup(data->req.location); /* clone */
3613           if(!data->req.newurl)
3614             return CURLE_OUT_OF_MEMORY;
3615
3616           /* some cases of POST and PUT etc needs to rewind the data
3617              stream at this point */
3618           result = http_perhapsrewind(conn);
3619           if(result)
3620             return result;
3621         }
3622       }
3623     }
3624     else if(conn->handler->protocol & CURLPROTO_RTSP) {
3625       result = Curl_rtsp_parseheader(conn, k->p);
3626       if(result)
3627         return result;
3628     }
3629
3630     /*
3631      * End of header-checks. Write them to the client.
3632      */
3633
3634     writetype = CLIENTWRITE_HEADER;
3635     if(data->set.include_header)
3636       writetype |= CLIENTWRITE_BODY;
3637
3638     if(data->set.verbose)
3639       Curl_debug(data, CURLINFO_HEADER_IN,
3640                  k->p, (size_t)k->hbuflen, conn);
3641
3642     result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3643     if(result)
3644       return result;
3645
3646     data->info.header_size += (long)k->hbuflen;
3647     data->req.headerbytecount += (long)k->hbuflen;
3648
3649     /* reset hbufp pointer && hbuflen */
3650     k->hbufp = data->state.headerbuff;
3651     k->hbuflen = 0;
3652   }
3653   while(!*stop_reading && *k->str); /* header line within buffer */
3654
3655   /* We might have reached the end of the header part here, but
3656      there might be a non-header part left in the end of the read
3657      buffer. */
3658
3659   return CURLE_OK;
3660 }
3661
3662 #endif /* CURL_DISABLE_HTTP */