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