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