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