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