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