HTTP POST: omit Content-Length if data size is unknown
[platform/upstream/curl.git] / lib / http.c
1 /***************************************************************************
2  *                                  _   _ ____  _
3  *  Project                     ___| | | |  _ \| |
4  *                             / __| | | | |_) | |
5  *                            | (__| |_| |  _ <| |___
6  *                             \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2013, 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   if(conn->handler->flags & PROTOPT_SSL) {
1060     /* We never send more than CURL_MAX_WRITE_SIZE bytes in one single chunk
1061        when we speak HTTPS, as if only a fraction of it is sent now, this data
1062        needs to fit into the normal read-callback buffer later on and that
1063        buffer is using this size.
1064     */
1065
1066     sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size;
1067
1068     /* OpenSSL is very picky and we must send the SAME buffer pointer to the
1069        library when we attempt to re-send this buffer. Sending the same data
1070        is not enough, we must use the exact same address. For this reason, we
1071        must copy the data to the uploadbuffer first, since that is the buffer
1072        we will be using if this send is retried later.
1073     */
1074     memcpy(conn->data->state.uploadbuffer, ptr, sendsize);
1075     ptr = conn->data->state.uploadbuffer;
1076   }
1077   else
1078     sendsize = size;
1079
1080   res = Curl_write(conn, sockfd, ptr, sendsize, &amount);
1081
1082   if(CURLE_OK == res) {
1083     /*
1084      * Note that we may not send the entire chunk at once, and we have a set
1085      * number of data bytes at the end of the big buffer (out of which we may
1086      * only send away a part).
1087      */
1088     /* how much of the header that was sent */
1089     size_t headlen = (size_t)amount>headersize?headersize:(size_t)amount;
1090     size_t bodylen = amount - headlen;
1091
1092     if(conn->data->set.verbose) {
1093       /* this data _may_ contain binary stuff */
1094       Curl_debug(conn->data, CURLINFO_HEADER_OUT, ptr, headlen, conn);
1095       if(bodylen) {
1096         /* there was body data sent beyond the initial header part, pass that
1097            on to the debug callback too */
1098         Curl_debug(conn->data, CURLINFO_DATA_OUT,
1099                    ptr+headlen, bodylen, conn);
1100       }
1101     }
1102     if(bodylen)
1103       /* since we sent a piece of the body here, up the byte counter for it
1104          accordingly */
1105       http->writebytecount += bodylen;
1106
1107     /* 'amount' can never be a very large value here so typecasting it so a
1108        signed 31 bit value should not cause problems even if ssize_t is
1109        64bit */
1110     *bytes_written += (long)amount;
1111
1112     if(http) {
1113       if((size_t)amount != size) {
1114         /* The whole request could not be sent in one system call. We must
1115            queue it up and send it later when we get the chance. We must not
1116            loop here and wait until it might work again. */
1117
1118         size -= amount;
1119
1120         ptr = in->buffer + amount;
1121
1122         /* backup the currently set pointers */
1123         http->backup.fread_func = conn->fread_func;
1124         http->backup.fread_in = conn->fread_in;
1125         http->backup.postdata = http->postdata;
1126         http->backup.postsize = http->postsize;
1127
1128         /* set the new pointers for the request-sending */
1129         conn->fread_func = (curl_read_callback)readmoredata;
1130         conn->fread_in = (void *)conn;
1131         http->postdata = ptr;
1132         http->postsize = (curl_off_t)size;
1133
1134         http->send_buffer = in;
1135         http->sending = HTTPSEND_REQUEST;
1136
1137         return CURLE_OK;
1138       }
1139       http->sending = HTTPSEND_BODY;
1140       /* the full buffer was sent, clean up and return */
1141     }
1142     else {
1143       if((size_t)amount != size)
1144         /* We have no continue-send mechanism now, fail. This can only happen
1145            when this function is used from the CONNECT sending function. We
1146            currently (stupidly) assume that the whole request is always sent
1147            away in the first single chunk.
1148
1149            This needs FIXing.
1150         */
1151         return CURLE_SEND_ERROR;
1152       else
1153         conn->writechannel_inuse = FALSE;
1154     }
1155   }
1156   if(in->buffer)
1157     free(in->buffer);
1158   free(in);
1159
1160   return res;
1161 }
1162
1163
1164 /*
1165  * add_bufferf() add the formatted input to the buffer.
1166  */
1167 CURLcode Curl_add_bufferf(Curl_send_buffer *in, const char *fmt, ...)
1168 {
1169   char *s;
1170   va_list ap;
1171   va_start(ap, fmt);
1172   s = vaprintf(fmt, ap); /* this allocs a new string to append */
1173   va_end(ap);
1174
1175   if(s) {
1176     CURLcode result = Curl_add_buffer(in, s, strlen(s));
1177     free(s);
1178     return result;
1179   }
1180   /* If we failed, we cleanup the whole buffer and return error */
1181   if(in->buffer)
1182     free(in->buffer);
1183   free(in);
1184   return CURLE_OUT_OF_MEMORY;
1185 }
1186
1187 /*
1188  * add_buffer() appends a memory chunk to the existing buffer
1189  */
1190 CURLcode Curl_add_buffer(Curl_send_buffer *in, const void *inptr, size_t size)
1191 {
1192   char *new_rb;
1193   size_t new_size;
1194
1195   if(~size < in->size_used) {
1196     /* If resulting used size of send buffer would wrap size_t, cleanup
1197        the whole buffer and return error. Otherwise the required buffer
1198        size will fit into a single allocatable memory chunk */
1199     Curl_safefree(in->buffer);
1200     free(in);
1201     return CURLE_OUT_OF_MEMORY;
1202   }
1203
1204   if(!in->buffer ||
1205      ((in->size_used + size) > (in->size_max - 1))) {
1206
1207     /* If current buffer size isn't enough to hold the result, use a
1208        buffer size that doubles the required size. If this new size
1209        would wrap size_t, then just use the largest possible one */
1210
1211     if((size > (size_t)-1/2) || (in->size_used > (size_t)-1/2) ||
1212        (~(size*2) < (in->size_used*2)))
1213       new_size = (size_t)-1;
1214     else
1215       new_size = (in->size_used+size)*2;
1216
1217     if(in->buffer)
1218       /* we have a buffer, enlarge the existing one */
1219       new_rb = realloc(in->buffer, new_size);
1220     else
1221       /* create a new buffer */
1222       new_rb = malloc(new_size);
1223
1224     if(!new_rb) {
1225       /* If we failed, we cleanup the whole buffer and return error */
1226       Curl_safefree(in->buffer);
1227       free(in);
1228       return CURLE_OUT_OF_MEMORY;
1229     }
1230
1231     in->buffer = new_rb;
1232     in->size_max = new_size;
1233   }
1234   memcpy(&in->buffer[in->size_used], inptr, size);
1235
1236   in->size_used += size;
1237
1238   return CURLE_OK;
1239 }
1240
1241 /* end of the add_buffer functions */
1242 /* ------------------------------------------------------------------------- */
1243
1244
1245
1246 /*
1247  * Curl_compareheader()
1248  *
1249  * Returns TRUE if 'headerline' contains the 'header' with given 'content'.
1250  * Pass headers WITH the colon.
1251  */
1252 bool
1253 Curl_compareheader(const char *headerline, /* line to check */
1254                    const char *header,  /* header keyword _with_ colon */
1255                    const char *content) /* content string to find */
1256 {
1257   /* RFC2616, section 4.2 says: "Each header field consists of a name followed
1258    * by a colon (":") and the field value. Field names are case-insensitive.
1259    * The field value MAY be preceded by any amount of LWS, though a single SP
1260    * is preferred." */
1261
1262   size_t hlen = strlen(header);
1263   size_t clen;
1264   size_t len;
1265   const char *start;
1266   const char *end;
1267
1268   if(!Curl_raw_nequal(headerline, header, hlen))
1269     return FALSE; /* doesn't start with header */
1270
1271   /* pass the header */
1272   start = &headerline[hlen];
1273
1274   /* pass all white spaces */
1275   while(*start && ISSPACE(*start))
1276     start++;
1277
1278   /* find the end of the header line */
1279   end = strchr(start, '\r'); /* lines end with CRLF */
1280   if(!end) {
1281     /* in case there's a non-standard compliant line here */
1282     end = strchr(start, '\n');
1283
1284     if(!end)
1285       /* hm, there's no line ending here, use the zero byte! */
1286       end = strchr(start, '\0');
1287   }
1288
1289   len = end-start; /* length of the content part of the input line */
1290   clen = strlen(content); /* length of the word to find */
1291
1292   /* find the content string in the rest of the line */
1293   for(;len>=clen;len--, start++) {
1294     if(Curl_raw_nequal(start, content, clen))
1295       return TRUE; /* match! */
1296   }
1297
1298   return FALSE; /* no match */
1299 }
1300
1301 /*
1302  * Curl_http_connect() performs HTTP stuff to do at connect-time, called from
1303  * the generic Curl_connect().
1304  */
1305 CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
1306 {
1307   CURLcode result;
1308
1309   /* We default to persistent connections. We set this already in this connect
1310      function to make the re-use checks properly be able to check this bit. */
1311   conn->bits.close = FALSE;
1312
1313   /* the CONNECT procedure might not have been completed */
1314   result = Curl_proxy_connect(conn);
1315   if(result)
1316     return result;
1317
1318   if(conn->tunnel_state[FIRSTSOCKET] == TUNNEL_CONNECT)
1319     /* nothing else to do except wait right now - we're not done here. */
1320     return CURLE_OK;
1321
1322   if(conn->given->flags & PROTOPT_SSL) {
1323     /* perform SSL initialization */
1324     result = https_connecting(conn, done);
1325     if(result)
1326       return result;
1327   }
1328   else
1329     *done = TRUE;
1330
1331   return CURLE_OK;
1332 }
1333
1334 /* this returns the socket to wait for in the DO and DOING state for the multi
1335    interface and then we're always _sending_ a request and thus we wait for
1336    the single socket to become writable only */
1337 static int http_getsock_do(struct connectdata *conn,
1338                            curl_socket_t *socks,
1339                            int numsocks)
1340 {
1341   /* write mode */
1342   (void)numsocks; /* unused, we trust it to be at least 1 */
1343   socks[0] = conn->sock[FIRSTSOCKET];
1344   return GETSOCK_WRITESOCK(0);
1345 }
1346
1347 #ifdef USE_SSL
1348 static CURLcode https_connecting(struct connectdata *conn, bool *done)
1349 {
1350   CURLcode result;
1351   DEBUGASSERT((conn) && (conn->handler->flags & PROTOPT_SSL));
1352
1353   /* perform SSL initialization for this socket */
1354   result = Curl_ssl_connect_nonblocking(conn, FIRSTSOCKET, done);
1355   if(result)
1356     conn->bits.close = TRUE; /* a failed connection is marked for closure
1357                                 to prevent (bad) re-use or similar */
1358   return result;
1359 }
1360 #endif
1361
1362 #if defined(USE_SSLEAY) || defined(USE_GNUTLS) || defined(USE_SCHANNEL) || \
1363     defined(USE_DARWINSSL)
1364 /* This function is for OpenSSL, GnuTLS, darwinssl, and schannel only.
1365    It should be made to query the generic SSL layer instead. */
1366 static int https_getsock(struct connectdata *conn,
1367                          curl_socket_t *socks,
1368                          int numsocks)
1369 {
1370   if(conn->handler->flags & PROTOPT_SSL) {
1371     struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
1372
1373     if(!numsocks)
1374       return GETSOCK_BLANK;
1375
1376     if(connssl->connecting_state == ssl_connect_2_writing) {
1377       /* write mode */
1378       socks[0] = conn->sock[FIRSTSOCKET];
1379       return GETSOCK_WRITESOCK(0);
1380     }
1381     else if(connssl->connecting_state == ssl_connect_2_reading) {
1382       /* read mode */
1383       socks[0] = conn->sock[FIRSTSOCKET];
1384       return GETSOCK_READSOCK(0);
1385     }
1386   }
1387   return CURLE_OK;
1388 }
1389 #else
1390 #ifdef USE_SSL
1391 static int https_getsock(struct connectdata *conn,
1392                          curl_socket_t *socks,
1393                          int numsocks)
1394 {
1395   (void)conn;
1396   (void)socks;
1397   (void)numsocks;
1398   return GETSOCK_BLANK;
1399 }
1400 #endif /* USE_SSL */
1401 #endif /* USE_SSLEAY || USE_GNUTLS || USE_SCHANNEL */
1402
1403 /*
1404  * Curl_http_done() gets called from Curl_done() after a single HTTP request
1405  * has been performed.
1406  */
1407
1408 CURLcode Curl_http_done(struct connectdata *conn,
1409                         CURLcode status, bool premature)
1410 {
1411   struct SessionHandle *data = conn->data;
1412   struct HTTP *http =data->req.protop;
1413
1414   Curl_unencode_cleanup(conn);
1415
1416   /* set the proper values (possibly modified on POST) */
1417   conn->fread_func = data->set.fread_func; /* restore */
1418   conn->fread_in = data->set.in; /* restore */
1419   conn->seek_func = data->set.seek_func; /* restore */
1420   conn->seek_client = data->set.seek_client; /* restore */
1421
1422   if(http == NULL)
1423     return CURLE_OK;
1424
1425   if(http->send_buffer) {
1426     Curl_send_buffer *buff = http->send_buffer;
1427
1428     free(buff->buffer);
1429     free(buff);
1430     http->send_buffer = NULL; /* clear the pointer */
1431   }
1432
1433   if(HTTPREQ_POST_FORM == data->set.httpreq) {
1434     data->req.bytecount = http->readbytecount + http->writebytecount;
1435
1436     Curl_formclean(&http->sendit); /* Now free that whole lot */
1437     if(http->form.fp) {
1438       /* a file being uploaded was left opened, close it! */
1439       fclose(http->form.fp);
1440       http->form.fp = NULL;
1441     }
1442   }
1443   else if(HTTPREQ_PUT == data->set.httpreq)
1444     data->req.bytecount = http->readbytecount + http->writebytecount;
1445
1446   if(status != CURLE_OK)
1447     return (status);
1448
1449   if(!premature && /* this check is pointless when DONE is called before the
1450                       entire operation is complete */
1451      !conn->bits.retry &&
1452      !data->set.connect_only &&
1453      ((http->readbytecount +
1454        data->req.headerbytecount -
1455        data->req.deductheadercount)) <= 0) {
1456     /* If this connection isn't simply closed to be retried, AND nothing was
1457        read from the HTTP server (that counts), this can't be right so we
1458        return an error here */
1459     failf(data, "Empty reply from server");
1460     return CURLE_GOT_NOTHING;
1461   }
1462
1463   return CURLE_OK;
1464 }
1465
1466
1467 /*
1468  * Determine if we should use HTTP 1.1 (OR BETTER) for this request. Reasons
1469  * to avoid it include:
1470  *
1471  * - if the user specifically requested HTTP 1.0
1472  * - if the server we are connected to only supports 1.0
1473  * - if any server previously contacted to handle this request only supports
1474  * 1.0.
1475  */
1476 static bool use_http_1_1plus(const struct SessionHandle *data,
1477                              const struct connectdata *conn)
1478 {
1479   return ((data->set.httpversion >= CURL_HTTP_VERSION_1_1) ||
1480          ((data->set.httpversion != CURL_HTTP_VERSION_1_0) &&
1481           ((conn->httpversion == 11) ||
1482            ((conn->httpversion != 10) &&
1483             (data->state.httpversion != 10))))) ? TRUE : FALSE;
1484 }
1485
1486 /* check and possibly add an Expect: header */
1487 static CURLcode expect100(struct SessionHandle *data,
1488                           struct connectdata *conn,
1489                           Curl_send_buffer *req_buffer)
1490 {
1491   CURLcode result = CURLE_OK;
1492   const char *ptr;
1493   data->state.expect100header = FALSE; /* default to false unless it is set
1494                                           to TRUE below */
1495   if(use_http_1_1plus(data, conn)) {
1496     /* if not doing HTTP 1.0 or disabled explicitly, we add a Expect:
1497        100-continue to the headers which actually speeds up post operations
1498        (as there is one packet coming back from the web server) */
1499     ptr = Curl_checkheaders(data, "Expect:");
1500     if(ptr) {
1501       data->state.expect100header =
1502         Curl_compareheader(ptr, "Expect:", "100-continue");
1503     }
1504     else {
1505       result = Curl_add_bufferf(req_buffer,
1506                          "Expect: 100-continue\r\n");
1507       if(result == CURLE_OK)
1508         data->state.expect100header = TRUE;
1509     }
1510   }
1511   return result;
1512 }
1513
1514 CURLcode Curl_add_custom_headers(struct connectdata *conn,
1515                                    Curl_send_buffer *req_buffer)
1516 {
1517   char *ptr;
1518   struct curl_slist *headers=conn->data->set.headers;
1519
1520   while(headers) {
1521     ptr = strchr(headers->data, ':');
1522     if(ptr) {
1523       /* we require a colon for this to be a true header */
1524
1525       ptr++; /* pass the colon */
1526       while(*ptr && ISSPACE(*ptr))
1527         ptr++;
1528
1529       if(*ptr) {
1530         /* only send this if the contents was non-blank */
1531
1532         if(conn->allocptr.host &&
1533            /* a Host: header was sent already, don't pass on any custom Host:
1534               header as that will produce *two* in the same request! */
1535            checkprefix("Host:", headers->data))
1536           ;
1537         else if(conn->data->set.httpreq == HTTPREQ_POST_FORM &&
1538                 /* this header (extended by formdata.c) is sent later */
1539                 checkprefix("Content-Type:", headers->data))
1540           ;
1541         else if(conn->bits.authneg &&
1542                 /* while doing auth neg, don't allow the custom length since
1543                    we will force length zero then */
1544                 checkprefix("Content-Length", headers->data))
1545           ;
1546         else if(conn->allocptr.te &&
1547                 /* when asking for Transfer-Encoding, don't pass on a custom
1548                    Connection: */
1549                 checkprefix("Connection", headers->data))
1550           ;
1551         else {
1552           CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
1553                                              headers->data);
1554           if(result)
1555             return result;
1556         }
1557       }
1558     }
1559     else {
1560       ptr = strchr(headers->data, ';');
1561       if(ptr) {
1562
1563         ptr++; /* pass the semicolon */
1564         while(*ptr && ISSPACE(*ptr))
1565           ptr++;
1566
1567         if(*ptr) {
1568           /* this may be used for something else in the future */
1569         }
1570         else {
1571           if(*(--ptr) == ';') {
1572             CURLcode result;
1573
1574             /* send no-value custom header if terminated by semicolon */
1575             *ptr = ':';
1576             result = Curl_add_bufferf(req_buffer, "%s\r\n",
1577                                              headers->data);
1578             if(result)
1579               return result;
1580           }
1581         }
1582       }
1583     }
1584     headers = headers->next;
1585   }
1586   return CURLE_OK;
1587 }
1588
1589 CURLcode Curl_add_timecondition(struct SessionHandle *data,
1590                                 Curl_send_buffer *req_buffer)
1591 {
1592   const struct tm *tm;
1593   char *buf = data->state.buffer;
1594   CURLcode result = CURLE_OK;
1595   struct tm keeptime;
1596
1597   result = Curl_gmtime(data->set.timevalue, &keeptime);
1598   if(result) {
1599     failf(data, "Invalid TIMEVALUE");
1600     return result;
1601   }
1602   tm = &keeptime;
1603
1604   /* The If-Modified-Since header family should have their times set in
1605    * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be
1606    * represented in Greenwich Mean Time (GMT), without exception. For the
1607    * purposes of HTTP, GMT is exactly equal to UTC (Coordinated Universal
1608    * Time)." (see page 20 of RFC2616).
1609    */
1610
1611   /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
1612   snprintf(buf, BUFSIZE-1,
1613            "%s, %02d %s %4d %02d:%02d:%02d GMT",
1614            Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
1615            tm->tm_mday,
1616            Curl_month[tm->tm_mon],
1617            tm->tm_year + 1900,
1618            tm->tm_hour,
1619            tm->tm_min,
1620            tm->tm_sec);
1621
1622   switch(data->set.timecondition) {
1623   case CURL_TIMECOND_IFMODSINCE:
1624   default:
1625     result = Curl_add_bufferf(req_buffer,
1626                               "If-Modified-Since: %s\r\n", buf);
1627     break;
1628   case CURL_TIMECOND_IFUNMODSINCE:
1629     result = Curl_add_bufferf(req_buffer,
1630                               "If-Unmodified-Since: %s\r\n", buf);
1631     break;
1632   case CURL_TIMECOND_LASTMOD:
1633     result = Curl_add_bufferf(req_buffer,
1634                               "Last-Modified: %s\r\n", buf);
1635     break;
1636   }
1637
1638   return result;
1639 }
1640
1641 /*
1642  * Curl_http() gets called from the generic Curl_do() function when a HTTP
1643  * request is to be performed. This creates and sends a properly constructed
1644  * HTTP request.
1645  */
1646 CURLcode Curl_http(struct connectdata *conn, bool *done)
1647 {
1648   struct SessionHandle *data=conn->data;
1649   CURLcode result=CURLE_OK;
1650   struct HTTP *http;
1651   const char *ppath = data->state.path;
1652   bool paste_ftp_userpwd = FALSE;
1653   char ftp_typecode[sizeof("/;type=?")] = "";
1654   const char *host = conn->host.name;
1655   const char *te = ""; /* transfer-encoding */
1656   const char *ptr;
1657   const char *request;
1658   Curl_HttpReq httpreq = data->set.httpreq;
1659   char *addcookies = NULL;
1660   curl_off_t included_body = 0;
1661   const char *httpstring;
1662   Curl_send_buffer *req_buffer;
1663   curl_off_t postsize = 0; /* curl_off_t to handle large file sizes */
1664   int seekerr = CURL_SEEKFUNC_OK;
1665
1666   /* Always consider the DO phase done after this function call, even if there
1667      may be parts of the request that is not yet sent, since we can deal with
1668      the rest of the request in the PERFORM phase. */
1669   *done = TRUE;
1670
1671   http = data->req.protop;
1672
1673   if(!data->state.this_is_a_follow) {
1674     /* this is not a followed location, get the original host name */
1675     if(data->state.first_host)
1676       /* Free to avoid leaking memory on multiple requests*/
1677       free(data->state.first_host);
1678
1679     data->state.first_host = strdup(conn->host.name);
1680     if(!data->state.first_host)
1681       return CURLE_OUT_OF_MEMORY;
1682   }
1683   http->writebytecount = http->readbytecount = 0;
1684
1685   if((conn->handler->protocol&(CURLPROTO_HTTP|CURLPROTO_FTP)) &&
1686      data->set.upload) {
1687     httpreq = HTTPREQ_PUT;
1688   }
1689
1690   /* Now set the 'request' pointer to the proper request string */
1691   if(data->set.str[STRING_CUSTOMREQUEST])
1692     request = data->set.str[STRING_CUSTOMREQUEST];
1693   else {
1694     if(data->set.opt_no_body)
1695       request = "HEAD";
1696     else {
1697       DEBUGASSERT((httpreq > HTTPREQ_NONE) && (httpreq < HTTPREQ_LAST));
1698       switch(httpreq) {
1699       case HTTPREQ_POST:
1700       case HTTPREQ_POST_FORM:
1701         request = "POST";
1702         break;
1703       case HTTPREQ_PUT:
1704         request = "PUT";
1705         break;
1706       default: /* this should never happen */
1707       case HTTPREQ_GET:
1708         request = "GET";
1709         break;
1710       case HTTPREQ_HEAD:
1711         request = "HEAD";
1712         break;
1713       }
1714     }
1715   }
1716
1717   /* The User-Agent string might have been allocated in url.c already, because
1718      it might have been used in the proxy connect, but if we have got a header
1719      with the user-agent string specified, we erase the previously made string
1720      here. */
1721   if(Curl_checkheaders(data, "User-Agent:") && conn->allocptr.uagent) {
1722     free(conn->allocptr.uagent);
1723     conn->allocptr.uagent=NULL;
1724   }
1725
1726   /* setup the authentication headers */
1727   result = Curl_http_output_auth(conn, request, ppath, FALSE);
1728   if(result)
1729     return result;
1730
1731   if((data->state.authhost.multi || data->state.authproxy.multi) &&
1732      (httpreq != HTTPREQ_GET) &&
1733      (httpreq != HTTPREQ_HEAD)) {
1734     /* Auth is required and we are not authenticated yet. Make a PUT or POST
1735        with content-length zero as a "probe". */
1736     conn->bits.authneg = TRUE;
1737   }
1738   else
1739     conn->bits.authneg = FALSE;
1740
1741   Curl_safefree(conn->allocptr.ref);
1742   if(data->change.referer && !Curl_checkheaders(data, "Referer:")) {
1743     conn->allocptr.ref = aprintf("Referer: %s\r\n", data->change.referer);
1744     if(!conn->allocptr.ref)
1745       return CURLE_OUT_OF_MEMORY;
1746   }
1747   else
1748     conn->allocptr.ref = NULL;
1749
1750   if(data->set.str[STRING_COOKIE] && !Curl_checkheaders(data, "Cookie:"))
1751     addcookies = data->set.str[STRING_COOKIE];
1752
1753   if(!Curl_checkheaders(data, "Accept-Encoding:") &&
1754      data->set.str[STRING_ENCODING]) {
1755     Curl_safefree(conn->allocptr.accept_encoding);
1756     conn->allocptr.accept_encoding =
1757       aprintf("Accept-Encoding: %s\r\n", data->set.str[STRING_ENCODING]);
1758     if(!conn->allocptr.accept_encoding)
1759       return CURLE_OUT_OF_MEMORY;
1760   }
1761
1762 #ifdef HAVE_LIBZ
1763   /* we only consider transfer-encoding magic if libz support is built-in */
1764
1765   if(!Curl_checkheaders(data, "TE:") && data->set.http_transfer_encoding) {
1766     /* When we are to insert a TE: header in the request, we must also insert
1767        TE in a Connection: header, so we need to merge the custom provided
1768        Connection: header and prevent the original to get sent. Note that if
1769        the user has inserted his/hers own TE: header we don't do this magic
1770        but then assume that the user will handle it all! */
1771     char *cptr = Curl_checkheaders(data, "Connection:");
1772 #define TE_HEADER "TE: gzip\r\n"
1773
1774     Curl_safefree(conn->allocptr.te);
1775
1776     /* Create the (updated) Connection: header */
1777     conn->allocptr.te = cptr? aprintf("%s, TE\r\n" TE_HEADER, cptr):
1778       strdup("Connection: TE\r\n" TE_HEADER);
1779
1780     if(!conn->allocptr.te)
1781       return CURLE_OUT_OF_MEMORY;
1782   }
1783 #endif
1784
1785   ptr = Curl_checkheaders(data, "Transfer-Encoding:");
1786   if(ptr) {
1787     /* Some kind of TE is requested, check if 'chunked' is chosen */
1788     data->req.upload_chunky =
1789       Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
1790   }
1791   else {
1792     if((conn->handler->protocol&CURLPROTO_HTTP) &&
1793        data->set.upload &&
1794        (data->set.infilesize == -1)) {
1795       if(conn->bits.authneg)
1796         /* don't enable chunked during auth neg */
1797         ;
1798       else if(use_http_1_1plus(data, conn)) {
1799         /* HTTP, upload, unknown file size and not HTTP 1.0 */
1800         data->req.upload_chunky = TRUE;
1801       }
1802       else {
1803         failf(data, "Chunky upload is not supported by HTTP 1.0");
1804         return CURLE_UPLOAD_FAILED;
1805       }
1806     }
1807     else {
1808       /* else, no chunky upload */
1809       data->req.upload_chunky = FALSE;
1810     }
1811
1812     if(data->req.upload_chunky)
1813       te = "Transfer-Encoding: chunked\r\n";
1814   }
1815
1816   Curl_safefree(conn->allocptr.host);
1817
1818   ptr = Curl_checkheaders(data, "Host:");
1819   if(ptr && (!data->state.this_is_a_follow ||
1820              Curl_raw_equal(data->state.first_host, conn->host.name))) {
1821 #if !defined(CURL_DISABLE_COOKIES)
1822     /* If we have a given custom Host: header, we extract the host name in
1823        order to possibly use it for cookie reasons later on. We only allow the
1824        custom Host: header if this is NOT a redirect, as setting Host: in the
1825        redirected request is being out on thin ice. Except if the host name
1826        is the same as the first one! */
1827     char *cookiehost = Curl_copy_header_value(ptr);
1828     if(!cookiehost)
1829       return CURLE_OUT_OF_MEMORY;
1830     if(!*cookiehost)
1831       /* ignore empty data */
1832       free(cookiehost);
1833     else {
1834       /* If the host begins with '[', we start searching for the port after
1835          the bracket has been closed */
1836       int startsearch = 0;
1837       if(*cookiehost == '[') {
1838         char *closingbracket;
1839         /* since the 'cookiehost' is an allocated memory area that will be
1840            freed later we cannot simply increment the pointer */
1841         memmove(cookiehost, cookiehost + 1, strlen(cookiehost) - 1);
1842         closingbracket = strchr(cookiehost, ']');
1843         if(closingbracket)
1844           *closingbracket = 0;
1845       }
1846       else {
1847         char *colon = strchr(cookiehost + startsearch, ':');
1848         if(colon)
1849           *colon = 0; /* The host must not include an embedded port number */
1850       }
1851       Curl_safefree(conn->allocptr.cookiehost);
1852       conn->allocptr.cookiehost = cookiehost;
1853     }
1854 #endif
1855
1856     conn->allocptr.host = NULL;
1857   }
1858   else {
1859     /* When building Host: headers, we must put the host name within
1860        [brackets] if the host name is a plain IPv6-address. RFC2732-style. */
1861
1862     if(((conn->given->protocol&CURLPROTO_HTTPS) &&
1863         (conn->remote_port == PORT_HTTPS)) ||
1864        ((conn->given->protocol&CURLPROTO_HTTP) &&
1865         (conn->remote_port == PORT_HTTP)) )
1866       /* if(HTTPS on port 443) OR (HTTP on port 80) then don't include
1867          the port number in the host string */
1868       conn->allocptr.host = aprintf("Host: %s%s%s\r\n",
1869                                     conn->bits.ipv6_ip?"[":"",
1870                                     host,
1871                                     conn->bits.ipv6_ip?"]":"");
1872     else
1873       conn->allocptr.host = aprintf("Host: %s%s%s:%hu\r\n",
1874                                     conn->bits.ipv6_ip?"[":"",
1875                                     host,
1876                                     conn->bits.ipv6_ip?"]":"",
1877                                     conn->remote_port);
1878
1879     if(!conn->allocptr.host)
1880       /* without Host: we can't make a nice request */
1881       return CURLE_OUT_OF_MEMORY;
1882   }
1883
1884 #ifndef CURL_DISABLE_PROXY
1885   if(conn->bits.httpproxy && !conn->bits.tunnel_proxy)  {
1886     /* Using a proxy but does not tunnel through it */
1887
1888     /* The path sent to the proxy is in fact the entire URL. But if the remote
1889        host is a IDN-name, we must make sure that the request we produce only
1890        uses the encoded host name! */
1891     if(conn->host.dispname != conn->host.name) {
1892       char *url = data->change.url;
1893       ptr = strstr(url, conn->host.dispname);
1894       if(ptr) {
1895         /* This is where the display name starts in the URL, now replace this
1896            part with the encoded name. TODO: This method of replacing the host
1897            name is rather crude as I believe there's a slight risk that the
1898            user has entered a user name or password that contain the host name
1899            string. */
1900         size_t currlen = strlen(conn->host.dispname);
1901         size_t newlen = strlen(conn->host.name);
1902         size_t urllen = strlen(url);
1903
1904         char *newurl;
1905
1906         newurl = malloc(urllen + newlen - currlen + 1);
1907         if(newurl) {
1908           /* copy the part before the host name */
1909           memcpy(newurl, url, ptr - url);
1910           /* append the new host name instead of the old */
1911           memcpy(newurl + (ptr - url), conn->host.name, newlen);
1912           /* append the piece after the host name */
1913           memcpy(newurl + newlen + (ptr - url),
1914                  ptr + currlen, /* copy the trailing zero byte too */
1915                  urllen - (ptr-url) - currlen + 1);
1916           if(data->change.url_alloc) {
1917             Curl_safefree(data->change.url);
1918             data->change.url_alloc = FALSE;
1919           }
1920           data->change.url = newurl;
1921           data->change.url_alloc = TRUE;
1922         }
1923         else
1924           return CURLE_OUT_OF_MEMORY;
1925       }
1926     }
1927     ppath = data->change.url;
1928     if(checkprefix("ftp://", ppath)) {
1929       if(data->set.proxy_transfer_mode) {
1930         /* when doing ftp, append ;type=<a|i> if not present */
1931         char *type = strstr(ppath, ";type=");
1932         if(type && type[6] && type[7] == 0) {
1933           switch (Curl_raw_toupper(type[6])) {
1934           case 'A':
1935           case 'D':
1936           case 'I':
1937             break;
1938           default:
1939             type = NULL;
1940           }
1941         }
1942         if(!type) {
1943           char *p = ftp_typecode;
1944           /* avoid sending invalid URLs like ftp://example.com;type=i if the
1945            * user specified ftp://example.com without the slash */
1946           if(!*data->state.path && ppath[strlen(ppath) - 1] != '/') {
1947             *p++ = '/';
1948           }
1949           snprintf(p, sizeof(ftp_typecode) - 1, ";type=%c",
1950                    data->set.prefer_ascii ? 'a' : 'i');
1951         }
1952       }
1953       if(conn->bits.user_passwd && !conn->bits.userpwd_in_url)
1954         paste_ftp_userpwd = TRUE;
1955     }
1956   }
1957 #endif /* CURL_DISABLE_PROXY */
1958
1959   if(HTTPREQ_POST_FORM == httpreq) {
1960     /* we must build the whole post sequence first, so that we have a size of
1961        the whole transfer before we start to send it */
1962     result = Curl_getformdata(data, &http->sendit, data->set.httppost,
1963                               Curl_checkheaders(data, "Content-Type:"),
1964                               &http->postsize);
1965     if(result)
1966       return result;
1967   }
1968
1969   http->p_accept = Curl_checkheaders(data, "Accept:")?NULL:"Accept: */*\r\n";
1970
1971   if(( (HTTPREQ_POST == httpreq) ||
1972        (HTTPREQ_POST_FORM == httpreq) ||
1973        (HTTPREQ_PUT == httpreq) ) &&
1974      data->state.resume_from) {
1975     /**********************************************************************
1976      * Resuming upload in HTTP means that we PUT or POST and that we have
1977      * got a resume_from value set. The resume value has already created
1978      * a Range: header that will be passed along. We need to "fast forward"
1979      * the file the given number of bytes and decrease the assume upload
1980      * file size before we continue this venture in the dark lands of HTTP.
1981      *********************************************************************/
1982
1983     if(data->state.resume_from < 0 ) {
1984       /*
1985        * This is meant to get the size of the present remote-file by itself.
1986        * We don't support this now. Bail out!
1987        */
1988       data->state.resume_from = 0;
1989     }
1990
1991     if(data->state.resume_from && !data->state.this_is_a_follow) {
1992       /* do we still game? */
1993
1994       /* Now, let's read off the proper amount of bytes from the
1995          input. */
1996       if(conn->seek_func) {
1997         seekerr = conn->seek_func(conn->seek_client, data->state.resume_from,
1998                                   SEEK_SET);
1999       }
2000
2001       if(seekerr != CURL_SEEKFUNC_OK) {
2002         if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
2003           failf(data, "Could not seek stream");
2004           return CURLE_READ_ERROR;
2005         }
2006         /* when seekerr == CURL_SEEKFUNC_CANTSEEK (can't seek to offset) */
2007         else {
2008           curl_off_t passed=0;
2009           do {
2010             size_t readthisamountnow =
2011               (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ?
2012               BUFSIZE : curlx_sotouz(data->state.resume_from - passed);
2013
2014             size_t actuallyread =
2015               data->set.fread_func(data->state.buffer, 1, readthisamountnow,
2016                                    data->set.in);
2017
2018             passed += actuallyread;
2019             if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
2020               /* this checks for greater-than only to make sure that the
2021                  CURL_READFUNC_ABORT return code still aborts */
2022               failf(data, "Could only read %" CURL_FORMAT_CURL_OFF_T
2023                     " bytes from the input", passed);
2024               return CURLE_READ_ERROR;
2025             }
2026           } while(passed < data->state.resume_from);
2027         }
2028       }
2029
2030       /* now, decrease the size of the read */
2031       if(data->set.infilesize>0) {
2032         data->set.infilesize -= data->state.resume_from;
2033
2034         if(data->set.infilesize <= 0) {
2035           failf(data, "File already completely uploaded");
2036           return CURLE_PARTIAL_FILE;
2037         }
2038       }
2039       /* we've passed, proceed as normal */
2040     }
2041   }
2042   if(data->state.use_range) {
2043     /*
2044      * A range is selected. We use different headers whether we're downloading
2045      * or uploading and we always let customized headers override our internal
2046      * ones if any such are specified.
2047      */
2048     if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
2049        !Curl_checkheaders(data, "Range:")) {
2050       /* if a line like this was already allocated, free the previous one */
2051       if(conn->allocptr.rangeline)
2052         free(conn->allocptr.rangeline);
2053       conn->allocptr.rangeline = aprintf("Range: bytes=%s\r\n",
2054                                          data->state.range);
2055     }
2056     else if((httpreq != HTTPREQ_GET) &&
2057             !Curl_checkheaders(data, "Content-Range:")) {
2058
2059       /* if a line like this was already allocated, free the previous one */
2060       if(conn->allocptr.rangeline)
2061         free(conn->allocptr.rangeline);
2062
2063       if(data->set.set_resume_from < 0) {
2064         /* Upload resume was asked for, but we don't know the size of the
2065            remote part so we tell the server (and act accordingly) that we
2066            upload the whole file (again) */
2067         conn->allocptr.rangeline =
2068           aprintf("Content-Range: bytes 0-%" CURL_FORMAT_CURL_OFF_T
2069                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2070                   data->set.infilesize - 1, data->set.infilesize);
2071
2072       }
2073       else if(data->state.resume_from) {
2074         /* This is because "resume" was selected */
2075         curl_off_t total_expected_size=
2076           data->state.resume_from + data->set.infilesize;
2077         conn->allocptr.rangeline =
2078           aprintf("Content-Range: bytes %s%" CURL_FORMAT_CURL_OFF_T
2079                   "/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2080                   data->state.range, total_expected_size-1,
2081                   total_expected_size);
2082       }
2083       else {
2084         /* Range was selected and then we just pass the incoming range and
2085            append total size */
2086         conn->allocptr.rangeline =
2087           aprintf("Content-Range: bytes %s/%" CURL_FORMAT_CURL_OFF_T "\r\n",
2088                   data->state.range, data->set.infilesize);
2089       }
2090       if(!conn->allocptr.rangeline)
2091         return CURLE_OUT_OF_MEMORY;
2092     }
2093   }
2094
2095   /* Use 1.1 unless the user specifically asked for 1.0 or the server only
2096      supports 1.0 */
2097   httpstring= use_http_1_1plus(data, conn)?"1.1":"1.0";
2098
2099   /* initialize a dynamic send-buffer */
2100   req_buffer = Curl_add_buffer_init();
2101
2102   if(!req_buffer)
2103     return CURLE_OUT_OF_MEMORY;
2104
2105   /* add the main request stuff */
2106   /* GET/HEAD/POST/PUT */
2107   result = Curl_add_bufferf(req_buffer, "%s ", request);
2108   if(result)
2109     return result;
2110
2111   /* url */
2112   if(paste_ftp_userpwd)
2113     result = Curl_add_bufferf(req_buffer, "ftp://%s:%s@%s",
2114                               conn->user, conn->passwd,
2115                               ppath + sizeof("ftp://") - 1);
2116   else
2117     result = Curl_add_buffer(req_buffer, ppath, strlen(ppath));
2118   if(result)
2119     return result;
2120
2121   result =
2122     Curl_add_bufferf(req_buffer,
2123                      "%s" /* ftp typecode (;type=x) */
2124                      " HTTP/%s\r\n" /* HTTP version */
2125                      "%s" /* proxyuserpwd */
2126                      "%s" /* userpwd */
2127                      "%s" /* range */
2128                      "%s" /* user agent */
2129                      "%s" /* host */
2130                      "%s" /* accept */
2131                      "%s" /* TE: */
2132                      "%s" /* accept-encoding */
2133                      "%s" /* referer */
2134                      "%s" /* Proxy-Connection */
2135                      "%s",/* transfer-encoding */
2136
2137                      ftp_typecode,
2138                      httpstring,
2139                      conn->allocptr.proxyuserpwd?
2140                      conn->allocptr.proxyuserpwd:"",
2141                      conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2142                      (data->state.use_range && conn->allocptr.rangeline)?
2143                      conn->allocptr.rangeline:"",
2144                      (data->set.str[STRING_USERAGENT] &&
2145                       *data->set.str[STRING_USERAGENT] &&
2146                       conn->allocptr.uagent)?
2147                      conn->allocptr.uagent:"",
2148                      (conn->allocptr.host?conn->allocptr.host:""),
2149                      http->p_accept?http->p_accept:"",
2150                      conn->allocptr.te?conn->allocptr.te:"",
2151                      (data->set.str[STRING_ENCODING] &&
2152                       *data->set.str[STRING_ENCODING] &&
2153                       conn->allocptr.accept_encoding)?
2154                      conn->allocptr.accept_encoding:"",
2155                      (data->change.referer && conn->allocptr.ref)?
2156                      conn->allocptr.ref:"" /* Referer: <data> */,
2157                      (conn->bits.httpproxy &&
2158                       !conn->bits.tunnel_proxy &&
2159                       !Curl_checkheaders(data, "Proxy-Connection:"))?
2160                      "Proxy-Connection: Keep-Alive\r\n":"",
2161                      te
2162       );
2163
2164   /*
2165    * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
2166    * with basic and digest, it will be freed anyway by the next request
2167    */
2168
2169   Curl_safefree (conn->allocptr.userpwd);
2170   conn->allocptr.userpwd = NULL;
2171
2172   if(result)
2173     return result;
2174
2175   if(!(conn->handler->flags&PROTOPT_SSL) &&
2176      (data->set.httpversion == CURL_HTTP_VERSION_2_0)) {
2177     /* append HTTP2 updrade magic stuff to the HTTP request if it isn't done
2178        over SSL */
2179     result = Curl_http2_request(req_buffer, conn);
2180     if(result)
2181       return result;
2182   }
2183
2184 #if !defined(CURL_DISABLE_COOKIES)
2185   if(data->cookies || addcookies) {
2186     struct Cookie *co=NULL; /* no cookies from start */
2187     int count=0;
2188
2189     if(data->cookies) {
2190       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2191       co = Curl_cookie_getlist(data->cookies,
2192                                conn->allocptr.cookiehost?
2193                                conn->allocptr.cookiehost:host,
2194                                data->state.path,
2195                                (conn->handler->protocol&CURLPROTO_HTTPS)?
2196                                TRUE:FALSE);
2197       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2198     }
2199     if(co) {
2200       struct Cookie *store=co;
2201       /* now loop through all cookies that matched */
2202       while(co) {
2203         if(co->value) {
2204           if(0 == count) {
2205             result = Curl_add_bufferf(req_buffer, "Cookie: ");
2206             if(result)
2207               break;
2208           }
2209           result = Curl_add_bufferf(req_buffer,
2210                                     "%s%s=%s", count?"; ":"",
2211                                     co->name, co->value);
2212           if(result)
2213             break;
2214           count++;
2215         }
2216         co = co->next; /* next cookie please */
2217       }
2218       Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2219     }
2220     if(addcookies && (CURLE_OK == result)) {
2221       if(!count)
2222         result = Curl_add_bufferf(req_buffer, "Cookie: ");
2223       if(CURLE_OK == result) {
2224         result = Curl_add_bufferf(req_buffer, "%s%s",
2225                                   count?"; ":"",
2226                                   addcookies);
2227         count++;
2228       }
2229     }
2230     if(count && (CURLE_OK == result))
2231       result = Curl_add_buffer(req_buffer, "\r\n", 2);
2232
2233     if(result)
2234       return result;
2235   }
2236 #endif
2237
2238   if(data->set.timecondition) {
2239     result = Curl_add_timecondition(data, req_buffer);
2240     if(result)
2241       return result;
2242   }
2243
2244   result = Curl_add_custom_headers(conn, req_buffer);
2245   if(result)
2246     return result;
2247
2248   http->postdata = NULL;  /* nothing to post at this point */
2249   Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
2250
2251   /* If 'authdone' is FALSE, we must not set the write socket index to the
2252      Curl_transfer() call below, as we're not ready to actually upload any
2253      data yet. */
2254
2255   switch(httpreq) {
2256
2257   case HTTPREQ_POST_FORM:
2258     if(!http->sendit || conn->bits.authneg) {
2259       /* nothing to post! */
2260       result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2261       if(result)
2262         return result;
2263
2264       result = Curl_add_buffer_send(req_buffer, conn,
2265                                     &data->info.request_size, 0, FIRSTSOCKET);
2266       if(result)
2267         failf(data, "Failed sending POST request");
2268       else
2269         /* setup variables for the upcoming transfer */
2270         Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2271                             -1, NULL);
2272       break;
2273     }
2274
2275     if(Curl_FormInit(&http->form, http->sendit)) {
2276       failf(data, "Internal HTTP POST error!");
2277       return CURLE_HTTP_POST_ERROR;
2278     }
2279
2280     /* Get the currently set callback function pointer and store that in the
2281        form struct since we might want the actual user-provided callback later
2282        on. The conn->fread_func pointer itself will be changed for the
2283        multipart case to the function that returns a multipart formatted
2284        stream. */
2285     http->form.fread_func = conn->fread_func;
2286
2287     /* Set the read function to read from the generated form data */
2288     conn->fread_func = (curl_read_callback)Curl_FormReader;
2289     conn->fread_in = &http->form;
2290
2291     http->sending = HTTPSEND_BODY;
2292
2293     if(!data->req.upload_chunky &&
2294        !Curl_checkheaders(data, "Content-Length:")) {
2295       /* only add Content-Length if not uploading chunked */
2296       result = Curl_add_bufferf(req_buffer,
2297                                 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2298                                 "\r\n", http->postsize);
2299       if(result)
2300         return result;
2301     }
2302
2303     result = expect100(data, conn, req_buffer);
2304     if(result)
2305       return result;
2306
2307     {
2308
2309       /* Get Content-Type: line from Curl_formpostheader.
2310        */
2311       char *contentType;
2312       size_t linelength=0;
2313       contentType = Curl_formpostheader((void *)&http->form,
2314                                         &linelength);
2315       if(!contentType) {
2316         failf(data, "Could not get Content-Type header line!");
2317         return CURLE_HTTP_POST_ERROR;
2318       }
2319
2320       result = Curl_add_buffer(req_buffer, contentType, linelength);
2321       if(result)
2322         return result;
2323     }
2324
2325     /* make the request end in a true CRLF */
2326     result = Curl_add_buffer(req_buffer, "\r\n", 2);
2327     if(result)
2328       return result;
2329
2330     /* set upload size to the progress meter */
2331     Curl_pgrsSetUploadSize(data, http->postsize);
2332
2333     /* fire away the whole request to the server */
2334     result = Curl_add_buffer_send(req_buffer, conn,
2335                                   &data->info.request_size, 0, FIRSTSOCKET);
2336     if(result)
2337       failf(data, "Failed sending POST request");
2338     else
2339       /* setup variables for the upcoming transfer */
2340       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2341                           &http->readbytecount, FIRSTSOCKET,
2342                           &http->writebytecount);
2343
2344     if(result) {
2345       Curl_formclean(&http->sendit); /* free that whole lot */
2346       return result;
2347     }
2348
2349     /* convert the form data */
2350     result = Curl_convert_form(data, http->sendit);
2351     if(result) {
2352       Curl_formclean(&http->sendit); /* free that whole lot */
2353       return result;
2354     }
2355
2356     break;
2357
2358   case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2359
2360     if(conn->bits.authneg)
2361       postsize = 0;
2362     else
2363       postsize = data->set.infilesize;
2364
2365     if((postsize != -1) && !data->req.upload_chunky &&
2366        !Curl_checkheaders(data, "Content-Length:")) {
2367       /* only add Content-Length if not uploading chunked */
2368       result = Curl_add_bufferf(req_buffer,
2369                                 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2370                                 "\r\n", postsize);
2371       if(result)
2372         return result;
2373     }
2374
2375     result = expect100(data, conn, req_buffer);
2376     if(result)
2377       return result;
2378
2379     result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2380     if(result)
2381       return result;
2382
2383     /* set the upload size to the progress meter */
2384     Curl_pgrsSetUploadSize(data, postsize);
2385
2386     /* this sends the buffer and frees all the buffer resources */
2387     result = Curl_add_buffer_send(req_buffer, conn,
2388                                   &data->info.request_size, 0, FIRSTSOCKET);
2389     if(result)
2390       failf(data, "Failed sending PUT request");
2391     else
2392       /* prepare for transfer */
2393       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2394                           &http->readbytecount, postsize?FIRSTSOCKET:-1,
2395                           postsize?&http->writebytecount:NULL);
2396     if(result)
2397       return result;
2398     break;
2399
2400   case HTTPREQ_POST:
2401     /* this is the simple POST, using x-www-form-urlencoded style */
2402
2403     if(conn->bits.authneg)
2404       postsize = 0;
2405     else {
2406       /* figure out the size of the postfields */
2407       postsize = (data->set.postfieldsize != -1)?
2408         data->set.postfieldsize:
2409         (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2410     }
2411
2412     /* We only set Content-Length and allow a custom Content-Length if
2413        we don't upload data chunked, as RFC2616 forbids us to set both
2414        kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2415     if((postsize != -1) && !data->req.upload_chunky &&
2416        !Curl_checkheaders(data, "Content-Length:")) {
2417       /* we allow replacing this header if not during auth negotiation,
2418          although it isn't very wise to actually set your own */
2419       result = Curl_add_bufferf(req_buffer,
2420                                 "Content-Length: %" CURL_FORMAT_CURL_OFF_T
2421                                 "\r\n", postsize);
2422       if(result)
2423         return result;
2424     }
2425
2426     if(!Curl_checkheaders(data, "Content-Type:")) {
2427       result = Curl_add_bufferf(req_buffer,
2428                                 "Content-Type: application/"
2429                                 "x-www-form-urlencoded\r\n");
2430       if(result)
2431         return result;
2432     }
2433
2434     /* For really small posts we don't use Expect: headers at all, and for
2435        the somewhat bigger ones we allow the app to disable it. Just make
2436        sure that the expect100header is always set to the preferred value
2437        here. */
2438     ptr = Curl_checkheaders(data, "Expect:");
2439     if(ptr) {
2440       data->state.expect100header =
2441         Curl_compareheader(ptr, "Expect:", "100-continue");
2442     }
2443     else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2444       result = expect100(data, conn, req_buffer);
2445       if(result)
2446         return result;
2447     }
2448     else
2449       data->state.expect100header = FALSE;
2450
2451     if(data->set.postfields) {
2452
2453       if(!data->state.expect100header &&
2454          (postsize < MAX_INITIAL_POST_SIZE))  {
2455         /* if we don't use expect: 100  AND
2456            postsize is less than MAX_INITIAL_POST_SIZE
2457
2458            then append the post data to the HTTP request header. This limit
2459            is no magic limit but only set to prevent really huge POSTs to
2460            get the data duplicated with malloc() and family. */
2461
2462         result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2463         if(result)
2464           return result;
2465
2466         if(!data->req.upload_chunky) {
2467           /* We're not sending it 'chunked', append it to the request
2468              already now to reduce the number if send() calls */
2469           result = Curl_add_buffer(req_buffer, data->set.postfields,
2470                                    (size_t)postsize);
2471           included_body = postsize;
2472         }
2473         else {
2474           if(postsize) {
2475             /* Append the POST data chunky-style */
2476             result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2477             if(CURLE_OK == result) {
2478               result = Curl_add_buffer(req_buffer, data->set.postfields,
2479                                        (size_t)postsize);
2480               if(CURLE_OK == result)
2481                  result = Curl_add_buffer(req_buffer, "\r\n", 2);
2482               included_body = postsize + 2;
2483             }
2484           }
2485           if(CURLE_OK == result)
2486             result = Curl_add_buffer(req_buffer,
2487                                      "\x30\x0d\x0a\x0d\x0a", 5);
2488           /* 0  CR  LF  CR  LF */
2489           included_body += 5;
2490         }
2491         if(result)
2492           return result;
2493         /* Make sure the progress information is accurate */
2494         Curl_pgrsSetUploadSize(data, postsize);
2495       }
2496       else {
2497         /* A huge POST coming up, do data separate from the request */
2498         http->postsize = postsize;
2499         http->postdata = data->set.postfields;
2500
2501         http->sending = HTTPSEND_BODY;
2502
2503         conn->fread_func = (curl_read_callback)readmoredata;
2504         conn->fread_in = (void *)conn;
2505
2506         /* set the upload size to the progress meter */
2507         Curl_pgrsSetUploadSize(data, http->postsize);
2508
2509         result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2510         if(result)
2511           return result;
2512       }
2513     }
2514     else {
2515       result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2516       if(result)
2517         return result;
2518
2519       if(data->req.upload_chunky && conn->bits.authneg) {
2520         /* Chunky upload is selected and we're negotiating auth still, send
2521            end-of-data only */
2522         result = Curl_add_buffer(req_buffer,
2523                                  "\x30\x0d\x0a\x0d\x0a", 5);
2524         /* 0  CR  LF  CR  LF */
2525         if(result)
2526           return result;
2527       }
2528
2529       else if(data->set.postfieldsize) {
2530         /* set the upload size to the progress meter */
2531         Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2532
2533         /* set the pointer to mark that we will send the post body using the
2534            read callback, but only if we're not in authenticate
2535            negotiation  */
2536         if(!conn->bits.authneg) {
2537           http->postdata = (char *)&http->postdata;
2538           http->postsize = postsize;
2539         }
2540       }
2541     }
2542     /* issue the request */
2543     result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2544                                   (size_t)included_body, FIRSTSOCKET);
2545
2546     if(result)
2547       failf(data, "Failed sending HTTP POST request");
2548     else
2549       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2550                           &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2551                           http->postdata?&http->writebytecount:NULL);
2552     break;
2553
2554   default:
2555     result = Curl_add_buffer(req_buffer, "\r\n", 2);
2556     if(result)
2557       return result;
2558
2559     /* issue the request */
2560     result = Curl_add_buffer_send(req_buffer, conn,
2561                                   &data->info.request_size, 0, FIRSTSOCKET);
2562
2563     if(result)
2564       failf(data, "Failed sending HTTP request");
2565     else
2566       /* HTTP GET/HEAD download: */
2567       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2568                           http->postdata?FIRSTSOCKET:-1,
2569                           http->postdata?&http->writebytecount:NULL);
2570   }
2571   if(result)
2572     return result;
2573
2574   if(http->writebytecount) {
2575     /* if a request-body has been sent off, we make sure this progress is noted
2576        properly */
2577     Curl_pgrsSetUploadCounter(data, http->writebytecount);
2578     if(Curl_pgrsUpdate(conn))
2579       result = CURLE_ABORTED_BY_CALLBACK;
2580
2581     if(http->writebytecount >= postsize) {
2582       /* already sent the entire request body, mark the "upload" as
2583          complete */
2584       infof(data, "upload completely sent off: %" CURL_FORMAT_CURL_OFF_T
2585             " out of %" CURL_FORMAT_CURL_OFF_T " bytes\n",
2586             http->writebytecount, postsize);
2587       data->req.upload_done = TRUE;
2588       data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2589       data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2590     }
2591   }
2592
2593   return result;
2594 }
2595
2596 /*
2597  * checkhttpprefix()
2598  *
2599  * Returns TRUE if member of the list matches prefix of string
2600  */
2601 static bool
2602 checkhttpprefix(struct SessionHandle *data,
2603                 const char *s)
2604 {
2605   struct curl_slist *head = data->set.http200aliases;
2606   bool rc = FALSE;
2607 #ifdef CURL_DOES_CONVERSIONS
2608   /* convert from the network encoding using a scratch area */
2609   char *scratch = strdup(s);
2610   if(NULL == scratch) {
2611     failf (data, "Failed to allocate memory for conversion!");
2612     return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2613   }
2614   if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2615     /* Curl_convert_from_network calls failf if unsuccessful */
2616     free(scratch);
2617     return FALSE; /* can't return CURLE_foobar so return FALSE */
2618   }
2619   s = scratch;
2620 #endif /* CURL_DOES_CONVERSIONS */
2621
2622   while(head) {
2623     if(checkprefix(head->data, s)) {
2624       rc = TRUE;
2625       break;
2626     }
2627     head = head->next;
2628   }
2629
2630   if(!rc && (checkprefix("HTTP/", s)))
2631     rc = TRUE;
2632
2633 #ifdef CURL_DOES_CONVERSIONS
2634   free(scratch);
2635 #endif /* CURL_DOES_CONVERSIONS */
2636   return rc;
2637 }
2638
2639 #ifndef CURL_DISABLE_RTSP
2640 static bool
2641 checkrtspprefix(struct SessionHandle *data,
2642                 const char *s)
2643 {
2644
2645 #ifdef CURL_DOES_CONVERSIONS
2646   /* convert from the network encoding using a scratch area */
2647   char *scratch = strdup(s);
2648   if(NULL == scratch) {
2649     failf (data, "Failed to allocate memory for conversion!");
2650     return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2651   }
2652   if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2653     /* Curl_convert_from_network calls failf if unsuccessful */
2654     free(scratch);
2655     return FALSE; /* can't return CURLE_foobar so return FALSE */
2656   }
2657   s = scratch;
2658 #else
2659   (void)data; /* unused */
2660 #endif /* CURL_DOES_CONVERSIONS */
2661   if(checkprefix("RTSP/", s))
2662     return TRUE;
2663   else
2664     return FALSE;
2665 }
2666 #endif /* CURL_DISABLE_RTSP */
2667
2668 static bool
2669 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2670                  const char *s)
2671 {
2672 #ifndef CURL_DISABLE_RTSP
2673   if(conn->handler->protocol & CURLPROTO_RTSP)
2674     return checkrtspprefix(data, s);
2675 #else
2676   (void)conn;
2677 #endif /* CURL_DISABLE_RTSP */
2678
2679   return checkhttpprefix(data, s);
2680 }
2681
2682 /*
2683  * header_append() copies a chunk of data to the end of the already received
2684  * header. We make sure that the full string fit in the allocated header
2685  * buffer, or else we enlarge it.
2686  */
2687 static CURLcode header_append(struct SessionHandle *data,
2688                               struct SingleRequest *k,
2689                               size_t length)
2690 {
2691   if(k->hbuflen + length >= data->state.headersize) {
2692     /* We enlarge the header buffer as it is too small */
2693     char *newbuff;
2694     size_t hbufp_index;
2695     size_t newsize;
2696
2697     if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2698       /* The reason to have a max limit for this is to avoid the risk of a bad
2699          server feeding libcurl with a never-ending header that will cause
2700          reallocs infinitely */
2701       failf (data, "Avoided giant realloc for header (max is %d)!",
2702              CURL_MAX_HTTP_HEADER);
2703       return CURLE_OUT_OF_MEMORY;
2704     }
2705
2706     newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2707     hbufp_index = k->hbufp - data->state.headerbuff;
2708     newbuff = realloc(data->state.headerbuff, newsize);
2709     if(!newbuff) {
2710       failf (data, "Failed to alloc memory for big header!");
2711       return CURLE_OUT_OF_MEMORY;
2712     }
2713     data->state.headersize=newsize;
2714     data->state.headerbuff = newbuff;
2715     k->hbufp = data->state.headerbuff + hbufp_index;
2716   }
2717   memcpy(k->hbufp, k->str_start, length);
2718   k->hbufp += length;
2719   k->hbuflen += length;
2720   *k->hbufp = 0;
2721
2722   return CURLE_OK;
2723 }
2724
2725 static void print_http_error(struct SessionHandle *data)
2726 {
2727   struct SingleRequest *k = &data->req;
2728   char *beg = k->p;
2729
2730   /* make sure that data->req.p points to the HTTP status line */
2731   if(!strncmp(beg, "HTTP", 4)) {
2732
2733     /* skip to HTTP status code */
2734     beg = strchr(beg, ' ');
2735     if(beg && *++beg) {
2736
2737       /* find trailing CR */
2738       char end_char = '\r';
2739       char *end = strchr(beg, end_char);
2740       if(!end) {
2741         /* try to find LF (workaround for non-compliant HTTP servers) */
2742         end_char = '\n';
2743         end = strchr(beg, end_char);
2744       }
2745
2746       if(end) {
2747         /* temporarily replace CR or LF by NUL and print the error message */
2748         *end = '\0';
2749         failf(data, "The requested URL returned error: %s", beg);
2750
2751         /* restore the previously replaced CR or LF */
2752         *end = end_char;
2753         return;
2754       }
2755     }
2756   }
2757
2758   /* fall-back to printing the HTTP status code only */
2759   failf(data, "The requested URL returned error: %d", k->httpcode);
2760 }
2761
2762 /*
2763  * Read any HTTP header lines from the server and pass them to the client app.
2764  */
2765 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2766                                        struct connectdata *conn,
2767                                        ssize_t *nread,
2768                                        bool *stop_reading)
2769 {
2770   CURLcode result;
2771   struct SingleRequest *k = &data->req;
2772
2773   /* header line within buffer loop */
2774   do {
2775     size_t rest_length;
2776     size_t full_length;
2777     int writetype;
2778
2779     /* str_start is start of line within buf */
2780     k->str_start = k->str;
2781
2782     /* data is in network encoding so use 0x0a instead of '\n' */
2783     k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2784
2785     if(!k->end_ptr) {
2786       /* Not a complete header line within buffer, append the data to
2787          the end of the headerbuff. */
2788       result = header_append(data, k, *nread);
2789       if(result)
2790         return result;
2791
2792       if(!k->headerline && (k->hbuflen>5)) {
2793         /* make a first check that this looks like a protocol header */
2794         if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2795           /* this is not the beginning of a protocol first header line */
2796           k->header = FALSE;
2797           k->badheader = HEADER_ALLBAD;
2798           break;
2799         }
2800       }
2801
2802       break; /* read more and try again */
2803     }
2804
2805     /* decrease the size of the remaining (supposed) header line */
2806     rest_length = (k->end_ptr - k->str)+1;
2807     *nread -= (ssize_t)rest_length;
2808
2809     k->str = k->end_ptr + 1; /* move past new line */
2810
2811     full_length = k->str - k->str_start;
2812
2813     result = header_append(data, k, full_length);
2814     if(result)
2815       return result;
2816
2817     k->end_ptr = k->hbufp;
2818     k->p = data->state.headerbuff;
2819
2820     /****
2821      * We now have a FULL header line that p points to
2822      *****/
2823
2824     if(!k->headerline) {
2825       /* the first read header */
2826       if((k->hbuflen>5) &&
2827          !checkprotoprefix(data, conn, data->state.headerbuff)) {
2828         /* this is not the beginning of a protocol first header line */
2829         k->header = FALSE;
2830         if(*nread)
2831           /* since there's more, this is a partial bad header */
2832           k->badheader = HEADER_PARTHEADER;
2833         else {
2834           /* this was all we read so it's all a bad header */
2835           k->badheader = HEADER_ALLBAD;
2836           *nread = (ssize_t)rest_length;
2837         }
2838         break;
2839       }
2840     }
2841
2842     /* headers are in network encoding so
2843        use 0x0a and 0x0d instead of '\n' and '\r' */
2844     if((0x0a == *k->p) || (0x0d == *k->p)) {
2845       size_t headerlen;
2846       /* Zero-length header line means end of headers! */
2847
2848 #ifdef CURL_DOES_CONVERSIONS
2849       if(0x0d == *k->p) {
2850         *k->p = '\r'; /* replace with CR in host encoding */
2851         k->p++;       /* pass the CR byte */
2852       }
2853       if(0x0a == *k->p) {
2854         *k->p = '\n'; /* replace with LF in host encoding */
2855         k->p++;       /* pass the LF byte */
2856       }
2857 #else
2858       if('\r' == *k->p)
2859         k->p++; /* pass the \r byte */
2860       if('\n' == *k->p)
2861         k->p++; /* pass the \n byte */
2862 #endif /* CURL_DOES_CONVERSIONS */
2863
2864       if(100 <= k->httpcode && 199 >= k->httpcode) {
2865         /*
2866          * We have made a HTTP PUT or POST and this is 1.1-lingo
2867          * that tells us that the server is OK with this and ready
2868          * to receive the data.
2869          * However, we'll get more headers now so we must get
2870          * back into the header-parsing state!
2871          */
2872         k->header = TRUE;
2873         k->headerline = 0; /* restart the header line counter */
2874
2875         /* if we did wait for this do enable write now! */
2876         if(k->exp100) {
2877           k->exp100 = EXP100_SEND_DATA;
2878           k->keepon |= KEEP_SEND;
2879         }
2880       }
2881       else {
2882         k->header = FALSE; /* no more header to parse! */
2883
2884         if((k->size == -1) && !k->chunk && !conn->bits.close &&
2885            (conn->httpversion >= 11) &&
2886            !(conn->handler->protocol & CURLPROTO_RTSP) &&
2887            data->set.httpreq != HTTPREQ_HEAD) {
2888           /* On HTTP 1.1, when connection is not to get closed, but no
2889              Content-Length nor Content-Encoding chunked have been
2890              received, according to RFC2616 section 4.4 point 5, we
2891              assume that the server will close the connection to
2892              signal the end of the document. */
2893           infof(data, "no chunk, no close, no size. Assume close to "
2894                 "signal end\n");
2895           conn->bits.close = TRUE;
2896         }
2897       }
2898
2899       /*
2900        * When all the headers have been parsed, see if we should give
2901        * up and return an error.
2902        */
2903       if(http_should_fail(conn)) {
2904         failf (data, "The requested URL returned error: %d",
2905                k->httpcode);
2906         return CURLE_HTTP_RETURNED_ERROR;
2907       }
2908
2909       /* now, only output this if the header AND body are requested:
2910        */
2911       writetype = CLIENTWRITE_HEADER;
2912       if(data->set.include_header)
2913         writetype |= CLIENTWRITE_BODY;
2914
2915       headerlen = k->p - data->state.headerbuff;
2916
2917       result = Curl_client_write(conn, writetype,
2918                                  data->state.headerbuff,
2919                                  headerlen);
2920       if(result)
2921         return result;
2922
2923       data->info.header_size += (long)headerlen;
2924       data->req.headerbytecount += (long)headerlen;
2925
2926       data->req.deductheadercount =
2927         (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
2928
2929       if(!*stop_reading) {
2930         /* Curl_http_auth_act() checks what authentication methods
2931          * that are available and decides which one (if any) to
2932          * use. It will set 'newurl' if an auth method was picked. */
2933         result = Curl_http_auth_act(conn);
2934
2935         if(result)
2936           return result;
2937
2938         if(k->httpcode >= 300) {
2939           if((!conn->bits.authneg) && !conn->bits.close &&
2940              !conn->bits.rewindaftersend) {
2941             /*
2942              * General treatment of errors when about to send data. Including :
2943              * "417 Expectation Failed", while waiting for 100-continue.
2944              *
2945              * The check for close above is done simply because of something
2946              * else has already deemed the connection to get closed then
2947              * something else should've considered the big picture and we
2948              * avoid this check.
2949              *
2950              * rewindaftersend indicates that something has told libcurl to
2951              * continue sending even if it gets discarded
2952              */
2953
2954             switch(data->set.httpreq) {
2955             case HTTPREQ_PUT:
2956             case HTTPREQ_POST:
2957             case HTTPREQ_POST_FORM:
2958               /* We got an error response. If this happened before the whole
2959                * request body has been sent we stop sending and mark the
2960                * connection for closure after we've read the entire response.
2961                */
2962               if(!k->upload_done) {
2963                 infof(data, "HTTP error before end of send, stop sending\n");
2964                 conn->bits.close = TRUE; /* close after this */
2965                 k->upload_done = TRUE;
2966                 k->keepon &= ~KEEP_SEND; /* don't send */
2967                 if(data->state.expect100header)
2968                   k->exp100 = EXP100_FAILED;
2969               }
2970               break;
2971
2972             default: /* default label present to avoid compiler warnings */
2973               break;
2974             }
2975           }
2976         }
2977
2978         if(conn->bits.rewindaftersend) {
2979           /* We rewind after a complete send, so thus we continue
2980              sending now */
2981           infof(data, "Keep sending data to get tossed away!\n");
2982           k->keepon |= KEEP_SEND;
2983         }
2984       }
2985
2986       if(!k->header) {
2987         /*
2988          * really end-of-headers.
2989          *
2990          * If we requested a "no body", this is a good time to get
2991          * out and return home.
2992          */
2993         if(data->set.opt_no_body)
2994           *stop_reading = TRUE;
2995         else {
2996           /* If we know the expected size of this document, we set the
2997              maximum download size to the size of the expected
2998              document or else, we won't know when to stop reading!
2999
3000              Note that we set the download maximum even if we read a
3001              "Connection: close" header, to make sure that
3002              "Content-Length: 0" still prevents us from attempting to
3003              read the (missing) response-body.
3004           */
3005           /* According to RFC2616 section 4.4, we MUST ignore
3006              Content-Length: headers if we are now receiving data
3007              using chunked Transfer-Encoding.
3008           */
3009           if(k->chunk)
3010             k->maxdownload = k->size = -1;
3011         }
3012         if(-1 != k->size) {
3013           /* We do this operation even if no_body is true, since this
3014              data might be retrieved later with curl_easy_getinfo()
3015              and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
3016
3017           Curl_pgrsSetDownloadSize(data, k->size);
3018           k->maxdownload = k->size;
3019         }
3020
3021         /* If max download size is *zero* (nothing) we already
3022            have nothing and can safely return ok now! */
3023         if(0 == k->maxdownload)
3024           *stop_reading = TRUE;
3025
3026         if(*stop_reading) {
3027           /* we make sure that this socket isn't read more now */
3028           k->keepon &= ~KEEP_RECV;
3029         }
3030
3031         if(data->set.verbose)
3032           Curl_debug(data, CURLINFO_HEADER_IN,
3033                      k->str_start, headerlen, conn);
3034         break;          /* exit header line loop */
3035       }
3036
3037       /* We continue reading headers, so reset the line-based
3038          header parsing variables hbufp && hbuflen */
3039       k->hbufp = data->state.headerbuff;
3040       k->hbuflen = 0;
3041       continue;
3042     }
3043
3044     /*
3045      * Checks for special headers coming up.
3046      */
3047
3048     if(!k->headerline++) {
3049       /* This is the first header, it MUST be the error code line
3050          or else we consider this to be the body right away! */
3051       int httpversion_major;
3052       int rtspversion_major;
3053       int nc = 0;
3054 #ifdef CURL_DOES_CONVERSIONS
3055 #define HEADER1 scratch
3056 #define SCRATCHSIZE 21
3057       CURLcode res;
3058       char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
3059       /* We can't really convert this yet because we
3060          don't know if it's the 1st header line or the body.
3061          So we do a partial conversion into a scratch area,
3062          leaving the data at k->p as-is.
3063       */
3064       strncpy(&scratch[0], k->p, SCRATCHSIZE);
3065       scratch[SCRATCHSIZE] = 0; /* null terminate */
3066       res = Curl_convert_from_network(data,
3067                                       &scratch[0],
3068                                       SCRATCHSIZE);
3069       if(res)
3070         /* Curl_convert_from_network calls failf if unsuccessful */
3071         return res;
3072 #else
3073 #define HEADER1 k->p /* no conversion needed, just use k->p */
3074 #endif /* CURL_DOES_CONVERSIONS */
3075
3076       if(conn->handler->protocol & CURLPROTO_HTTP) {
3077         nc = sscanf(HEADER1,
3078                     " HTTP/%d.%d %3d",
3079                     &httpversion_major,
3080                     &conn->httpversion,
3081                     &k->httpcode);
3082         if(nc==3) {
3083           conn->httpversion += 10 * httpversion_major;
3084         }
3085         else {
3086           /* this is the real world, not a Nirvana
3087              NCSA 1.5.x returns this crap when asked for HTTP/1.1
3088           */
3089           nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3090           conn->httpversion = 10;
3091
3092           /* If user has set option HTTP200ALIASES,
3093              compare header line against list of aliases
3094           */
3095           if(!nc) {
3096             if(checkhttpprefix(data, k->p)) {
3097               nc = 1;
3098               k->httpcode = 200;
3099               conn->httpversion = 10;
3100             }
3101           }
3102         }
3103       }
3104       else if(conn->handler->protocol & CURLPROTO_RTSP) {
3105         nc = sscanf(HEADER1,
3106                     " RTSP/%d.%d %3d",
3107                     &rtspversion_major,
3108                     &conn->rtspversion,
3109                     &k->httpcode);
3110         if(nc==3) {
3111           conn->rtspversion += 10 * rtspversion_major;
3112           conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3113         }
3114         else {
3115           /* TODO: do we care about the other cases here? */
3116           nc = 0;
3117         }
3118       }
3119
3120       if(nc) {
3121         data->info.httpcode = k->httpcode;
3122
3123         data->info.httpversion = conn->httpversion;
3124         if(!data->state.httpversion ||
3125            data->state.httpversion > conn->httpversion)
3126           /* store the lowest server version we encounter */
3127           data->state.httpversion = conn->httpversion;
3128
3129         /*
3130          * This code executes as part of processing the header.  As a
3131          * result, it's not totally clear how to interpret the
3132          * response code yet as that depends on what other headers may
3133          * be present.  401 and 407 may be errors, but may be OK
3134          * depending on how authentication is working.  Other codes
3135          * are definitely errors, so give up here.
3136          */
3137         if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3138            ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3139            ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3140
3141           if(data->state.resume_from &&
3142              (data->set.httpreq==HTTPREQ_GET) &&
3143              (k->httpcode == 416)) {
3144             /* "Requested Range Not Satisfiable", just proceed and
3145                pretend this is no error */
3146           }
3147           else {
3148             /* serious error, go home! */
3149             print_http_error(data);
3150             return CURLE_HTTP_RETURNED_ERROR;
3151           }
3152         }
3153
3154         if(conn->httpversion == 10) {
3155           /* Default action for HTTP/1.0 must be to close, unless
3156              we get one of those fancy headers that tell us the
3157              server keeps it open for us! */
3158           infof(data, "HTTP 1.0, assume close after body\n");
3159           conn->bits.close = TRUE;
3160         }
3161         else if(conn->httpversion >= 11 &&
3162                 !conn->bits.close) {
3163           struct connectbundle *cb_ptr;
3164
3165           /* If HTTP version is >= 1.1 and connection is persistent
3166              server supports pipelining. */
3167           DEBUGF(infof(data,
3168                        "HTTP 1.1 or later with persistent connection, "
3169                        "pipelining supported\n"));
3170           /* Activate pipelining if needed */
3171           cb_ptr = conn->bundle;
3172           if(cb_ptr) {
3173             if(!Curl_pipeline_site_blacklisted(data, conn))
3174               cb_ptr->server_supports_pipelining = TRUE;
3175           }
3176         }
3177
3178         switch(k->httpcode) {
3179         case 204:
3180           /* (quote from RFC2616, section 10.2.5): The server has
3181            * fulfilled the request but does not need to return an
3182            * entity-body ... The 204 response MUST NOT include a
3183            * message-body, and thus is always terminated by the first
3184            * empty line after the header fields. */
3185           /* FALLTHROUGH */
3186         case 304:
3187           /* (quote from RFC2616, section 10.3.5): The 304 response
3188            * MUST NOT contain a message-body, and thus is always
3189            * terminated by the first empty line after the header
3190            * fields.  */
3191           if(data->set.timecondition)
3192             data->info.timecond = TRUE;
3193           k->size=0;
3194           k->maxdownload=0;
3195           k->ignorecl = TRUE; /* ignore Content-Length headers */
3196           break;
3197         default:
3198           /* nothing */
3199           break;
3200         }
3201       }
3202       else {
3203         k->header = FALSE;   /* this is not a header line */
3204         break;
3205       }
3206     }
3207
3208     result = Curl_convert_from_network(data, k->p, strlen(k->p));
3209     /* Curl_convert_from_network calls failf if unsuccessful */
3210     if(result)
3211       return result;
3212
3213     /* Check for Content-Length: header lines to get size */
3214     if(!k->ignorecl && !data->set.ignorecl &&
3215        checkprefix("Content-Length:", k->p)) {
3216       curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3217       if(data->set.max_filesize &&
3218          contentlength > data->set.max_filesize) {
3219         failf(data, "Maximum file size exceeded");
3220         return CURLE_FILESIZE_EXCEEDED;
3221       }
3222       if(contentlength >= 0) {
3223         k->size = contentlength;
3224         k->maxdownload = k->size;
3225         /* we set the progress download size already at this point
3226            just to make it easier for apps/callbacks to extract this
3227            info as soon as possible */
3228         Curl_pgrsSetDownloadSize(data, k->size);
3229       }
3230       else {
3231         /* Negative Content-Length is really odd, and we know it
3232            happens for example when older Apache servers send large
3233            files */
3234         conn->bits.close = TRUE;
3235         infof(data, "Negative content-length: %" CURL_FORMAT_CURL_OFF_T
3236               ", closing after transfer\n", contentlength);
3237       }
3238     }
3239     /* check for Content-Type: header lines to get the MIME-type */
3240     else if(checkprefix("Content-Type:", k->p)) {
3241       char *contenttype = Curl_copy_header_value(k->p);
3242       if(!contenttype)
3243         return CURLE_OUT_OF_MEMORY;
3244       if(!*contenttype)
3245         /* ignore empty data */
3246         free(contenttype);
3247       else {
3248         Curl_safefree(data->info.contenttype);
3249         data->info.contenttype = contenttype;
3250       }
3251     }
3252     else if(checkprefix("Server:", k->p)) {
3253       char *server_name = Curl_copy_header_value(k->p);
3254
3255       /* Turn off pipelining if the server version is blacklisted */
3256       if(conn->bundle && conn->bundle->server_supports_pipelining) {
3257         if(Curl_pipeline_server_blacklisted(data, server_name))
3258           conn->bundle->server_supports_pipelining = FALSE;
3259       }
3260       Curl_safefree(server_name);
3261     }
3262     else if((conn->httpversion == 10) &&
3263             conn->bits.httpproxy &&
3264             Curl_compareheader(k->p,
3265                                "Proxy-Connection:", "keep-alive")) {
3266       /*
3267        * When a HTTP/1.0 reply comes when using a proxy, the
3268        * 'Proxy-Connection: keep-alive' line tells us the
3269        * connection will be kept alive for our pleasure.
3270        * Default action for 1.0 is to close.
3271        */
3272       conn->bits.close = FALSE; /* don't close when done */
3273       infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3274     }
3275     else if((conn->httpversion == 11) &&
3276             conn->bits.httpproxy &&
3277             Curl_compareheader(k->p,
3278                                "Proxy-Connection:", "close")) {
3279       /*
3280        * We get a HTTP/1.1 response from a proxy and it says it'll
3281        * close down after this transfer.
3282        */
3283       conn->bits.close = TRUE; /* close when done */
3284       infof(data, "HTTP/1.1 proxy connection set close!\n");
3285     }
3286     else if((conn->httpversion == 10) &&
3287             Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3288       /*
3289        * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3290        * tells us the connection will be kept alive for our
3291        * pleasure.  Default action for 1.0 is to close.
3292        *
3293        * [RFC2068, section 19.7.1] */
3294       conn->bits.close = FALSE; /* don't close when done */
3295       infof(data, "HTTP/1.0 connection set to keep alive!\n");
3296     }
3297     else if(Curl_compareheader(k->p, "Connection:", "close")) {
3298       /*
3299        * [RFC 2616, section 8.1.2.1]
3300        * "Connection: close" is HTTP/1.1 language and means that
3301        * the connection will close when this request has been
3302        * served.
3303        */
3304       conn->bits.close = TRUE; /* close when done */
3305     }
3306     else if(checkprefix("Transfer-Encoding:", k->p)) {
3307       /* One or more encodings. We check for chunked and/or a compression
3308          algorithm. */
3309       /*
3310        * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3311        * means that the server will send a series of "chunks". Each
3312        * chunk starts with line with info (including size of the
3313        * coming block) (terminated with CRLF), then a block of data
3314        * with the previously mentioned size. There can be any amount
3315        * of chunks, and a chunk-data set to zero signals the
3316        * end-of-chunks. */
3317
3318       char *start;
3319
3320       /* Find the first non-space letter */
3321       start = k->p + 18;
3322
3323       for(;;) {
3324         /* skip whitespaces and commas */
3325         while(*start && (ISSPACE(*start) || (*start == ',')))
3326           start++;
3327
3328         if(checkprefix("chunked", start)) {
3329           k->chunk = TRUE; /* chunks coming our way */
3330
3331           /* init our chunky engine */
3332           Curl_httpchunk_init(conn);
3333
3334           start += 7;
3335         }
3336
3337         if(k->auto_decoding)
3338           /* TODO: we only support the first mentioned compression for now */
3339           break;
3340
3341         if(checkprefix("identity", start)) {
3342           k->auto_decoding = IDENTITY;
3343           start += 8;
3344         }
3345         else if(checkprefix("deflate", start)) {
3346           k->auto_decoding = DEFLATE;
3347           start += 7;
3348         }
3349         else if(checkprefix("gzip", start)) {
3350           k->auto_decoding = GZIP;
3351           start += 4;
3352         }
3353         else if(checkprefix("x-gzip", start)) {
3354           k->auto_decoding = GZIP;
3355           start += 6;
3356         }
3357         else if(checkprefix("compress", start)) {
3358           k->auto_decoding = COMPRESS;
3359           start += 8;
3360         }
3361         else if(checkprefix("x-compress", start)) {
3362           k->auto_decoding = COMPRESS;
3363           start += 10;
3364         }
3365         else
3366           /* unknown! */
3367           break;
3368
3369       }
3370
3371     }
3372     else if(checkprefix("Content-Encoding:", k->p) &&
3373             data->set.str[STRING_ENCODING]) {
3374       /*
3375        * Process Content-Encoding. Look for the values: identity,
3376        * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3377        * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3378        * 2616). zlib cannot handle compress.  However, errors are
3379        * handled further down when the response body is processed
3380        */
3381       char *start;
3382
3383       /* Find the first non-space letter */
3384       start = k->p + 17;
3385       while(*start && ISSPACE(*start))
3386         start++;
3387
3388       /* Record the content-encoding for later use */
3389       if(checkprefix("identity", start))
3390         k->auto_decoding = IDENTITY;
3391       else if(checkprefix("deflate", start))
3392         k->auto_decoding = DEFLATE;
3393       else if(checkprefix("gzip", start)
3394               || checkprefix("x-gzip", start))
3395         k->auto_decoding = GZIP;
3396       else if(checkprefix("compress", start)
3397               || checkprefix("x-compress", start))
3398         k->auto_decoding = COMPRESS;
3399     }
3400     else if(checkprefix("Content-Range:", k->p)) {
3401       /* Content-Range: bytes [num]-
3402          Content-Range: bytes: [num]-
3403          Content-Range: [num]-
3404
3405          The second format was added since Sun's webserver
3406          JavaWebServer/1.1.1 obviously sends the header this way!
3407          The third added since some servers use that!
3408       */
3409
3410       char *ptr = k->p + 14;
3411
3412       /* Move forward until first digit */
3413       while(*ptr && !ISDIGIT(*ptr))
3414         ptr++;
3415
3416       k->offset = curlx_strtoofft(ptr, NULL, 10);
3417
3418       if(data->state.resume_from == k->offset)
3419         /* we asked for a resume and we got it */
3420         k->content_range = TRUE;
3421     }
3422 #if !defined(CURL_DISABLE_COOKIES)
3423     else if(data->cookies &&
3424             checkprefix("Set-Cookie:", k->p)) {
3425       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3426                       CURL_LOCK_ACCESS_SINGLE);
3427       Curl_cookie_add(data,
3428                       data->cookies, TRUE, k->p+11,
3429                       /* If there is a custom-set Host: name, use it
3430                          here, or else use real peer host name. */
3431                       conn->allocptr.cookiehost?
3432                       conn->allocptr.cookiehost:conn->host.name,
3433                       data->state.path);
3434       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3435     }
3436 #endif
3437     else if(checkprefix("Last-Modified:", k->p) &&
3438             (data->set.timecondition || data->set.get_filetime) ) {
3439       time_t secs=time(NULL);
3440       k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3441                                   &secs);
3442       if(data->set.get_filetime)
3443         data->info.filetime = (long)k->timeofdoc;
3444     }
3445     else if((checkprefix("WWW-Authenticate:", k->p) &&
3446              (401 == k->httpcode)) ||
3447             (checkprefix("Proxy-authenticate:", k->p) &&
3448              (407 == k->httpcode))) {
3449
3450       bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
3451       char *auth = Curl_copy_header_value(k->p);
3452       if(!auth)
3453         return CURLE_OUT_OF_MEMORY;
3454
3455       result = Curl_http_input_auth(conn, proxy, auth);
3456
3457       Curl_safefree(auth);
3458
3459       if(result)
3460         return result;
3461     }
3462     else if((k->httpcode >= 300 && k->httpcode < 400) &&
3463             checkprefix("Location:", k->p) &&
3464             !data->req.location) {
3465       /* this is the URL that the server advises us to use instead */
3466       char *location = Curl_copy_header_value(k->p);
3467       if(!location)
3468         return CURLE_OUT_OF_MEMORY;
3469       if(!*location)
3470         /* ignore empty data */
3471         free(location);
3472       else {
3473         data->req.location = location;
3474
3475         if(data->set.http_follow_location) {
3476           DEBUGASSERT(!data->req.newurl);
3477           data->req.newurl = strdup(data->req.location); /* clone */
3478           if(!data->req.newurl)
3479             return CURLE_OUT_OF_MEMORY;
3480
3481           /* some cases of POST and PUT etc needs to rewind the data
3482              stream at this point */
3483           result = http_perhapsrewind(conn);
3484           if(result)
3485             return result;
3486         }
3487       }
3488     }
3489     else if(conn->handler->protocol & CURLPROTO_RTSP) {
3490       result = Curl_rtsp_parseheader(conn, k->p);
3491       if(result)
3492         return result;
3493     }
3494
3495     /*
3496      * End of header-checks. Write them to the client.
3497      */
3498
3499     writetype = CLIENTWRITE_HEADER;
3500     if(data->set.include_header)
3501       writetype |= CLIENTWRITE_BODY;
3502
3503     if(data->set.verbose)
3504       Curl_debug(data, CURLINFO_HEADER_IN,
3505                  k->p, (size_t)k->hbuflen, conn);
3506
3507     result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3508     if(result)
3509       return result;
3510
3511     data->info.header_size += (long)k->hbuflen;
3512     data->req.headerbytecount += (long)k->hbuflen;
3513
3514     /* reset hbufp pointer && hbuflen */
3515     k->hbufp = data->state.headerbuff;
3516     k->hbuflen = 0;
3517   }
3518   while(!*stop_reading && *k->str); /* header line within buffer */
3519
3520   /* We might have reached the end of the header part here, but
3521      there might be a non-header part left in the end of the read
3522      buffer. */
3523
3524   return CURLE_OK;
3525 }
3526
3527 #endif /* CURL_DISABLE_HTTP */