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