ee5d6116a4248ef171c6c51be1abcc4da6be5ef1
[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 =
2120     Curl_add_bufferf(req_buffer,
2121                      "%s" /* ftp typecode (;type=x) */
2122                      " HTTP/%s\r\n" /* HTTP version */
2123                      "%s" /* proxyuserpwd */
2124                      "%s" /* userpwd */
2125                      "%s" /* range */
2126                      "%s" /* user agent */
2127                      "%s" /* host */
2128                      "%s" /* accept */
2129                      "%s" /* TE: */
2130                      "%s" /* accept-encoding */
2131                      "%s" /* referer */
2132                      "%s" /* Proxy-Connection */
2133                      "%s",/* transfer-encoding */
2134
2135                      ftp_typecode,
2136                      httpstring,
2137                      conn->allocptr.proxyuserpwd?
2138                      conn->allocptr.proxyuserpwd:"",
2139                      conn->allocptr.userpwd?conn->allocptr.userpwd:"",
2140                      (data->state.use_range && conn->allocptr.rangeline)?
2141                      conn->allocptr.rangeline:"",
2142                      (data->set.str[STRING_USERAGENT] &&
2143                       *data->set.str[STRING_USERAGENT] &&
2144                       conn->allocptr.uagent)?
2145                      conn->allocptr.uagent:"",
2146                      (conn->allocptr.host?conn->allocptr.host:""),
2147                      http->p_accept?http->p_accept:"",
2148                      conn->allocptr.te?conn->allocptr.te:"",
2149                      (data->set.str[STRING_ENCODING] &&
2150                       *data->set.str[STRING_ENCODING] &&
2151                       conn->allocptr.accept_encoding)?
2152                      conn->allocptr.accept_encoding:"",
2153                      (data->change.referer && conn->allocptr.ref)?
2154                      conn->allocptr.ref:"" /* Referer: <data> */,
2155                      (conn->bits.httpproxy &&
2156                       !conn->bits.tunnel_proxy &&
2157                       !Curl_checkheaders(data, "Proxy-Connection:"))?
2158                      "Proxy-Connection: Keep-Alive\r\n":"",
2159                      te
2160       );
2161
2162   /*
2163    * Free userpwd now --- cannot reuse this for Negotiate and possibly NTLM
2164    * with basic and digest, it will be freed anyway by the next request
2165    */
2166
2167   Curl_safefree (conn->allocptr.userpwd);
2168   conn->allocptr.userpwd = NULL;
2169
2170   if(result)
2171     return result;
2172
2173 #if !defined(CURL_DISABLE_COOKIES)
2174   if(data->cookies || addcookies) {
2175     struct Cookie *co=NULL; /* no cookies from start */
2176     int count=0;
2177
2178     if(data->cookies) {
2179       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
2180       co = Curl_cookie_getlist(data->cookies,
2181                                conn->allocptr.cookiehost?
2182                                conn->allocptr.cookiehost:host,
2183                                data->state.path,
2184                                (conn->handler->protocol&CURLPROTO_HTTPS)?
2185                                TRUE:FALSE);
2186       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
2187     }
2188     if(co) {
2189       struct Cookie *store=co;
2190       /* now loop through all cookies that matched */
2191       while(co) {
2192         if(co->value) {
2193           if(0 == count) {
2194             result = Curl_add_bufferf(req_buffer, "Cookie: ");
2195             if(result)
2196               break;
2197           }
2198           result = Curl_add_bufferf(req_buffer,
2199                                     "%s%s=%s", count?"; ":"",
2200                                     co->name, co->value);
2201           if(result)
2202             break;
2203           count++;
2204         }
2205         co = co->next; /* next cookie please */
2206       }
2207       Curl_cookie_freelist(store, FALSE); /* free the cookie list */
2208     }
2209     if(addcookies && (CURLE_OK == result)) {
2210       if(!count)
2211         result = Curl_add_bufferf(req_buffer, "Cookie: ");
2212       if(CURLE_OK == result) {
2213         result = Curl_add_bufferf(req_buffer, "%s%s",
2214                                   count?"; ":"",
2215                                   addcookies);
2216         count++;
2217       }
2218     }
2219     if(count && (CURLE_OK == result))
2220       result = Curl_add_buffer(req_buffer, "\r\n", 2);
2221
2222     if(result)
2223       return result;
2224   }
2225 #endif
2226
2227   if(data->set.timecondition) {
2228     result = Curl_add_timecondition(data, req_buffer);
2229     if(result)
2230       return result;
2231   }
2232
2233   result = Curl_add_custom_headers(conn, req_buffer);
2234   if(result)
2235     return result;
2236
2237   http->postdata = NULL;  /* nothing to post at this point */
2238   Curl_pgrsSetUploadSize(data, 0); /* upload size is 0 atm */
2239
2240   /* If 'authdone' is FALSE, we must not set the write socket index to the
2241      Curl_transfer() call below, as we're not ready to actually upload any
2242      data yet. */
2243
2244   switch(httpreq) {
2245
2246   case HTTPREQ_POST_FORM:
2247     if(!http->sendit || conn->bits.authneg) {
2248       /* nothing to post! */
2249       result = Curl_add_bufferf(req_buffer, "Content-Length: 0\r\n\r\n");
2250       if(result)
2251         return result;
2252
2253       result = Curl_add_buffer_send(req_buffer, conn,
2254                                     &data->info.request_size, 0, FIRSTSOCKET);
2255       if(result)
2256         failf(data, "Failed sending POST request");
2257       else
2258         /* setup variables for the upcoming transfer */
2259         Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2260                             -1, NULL);
2261       break;
2262     }
2263
2264     if(Curl_FormInit(&http->form, http->sendit)) {
2265       failf(data, "Internal HTTP POST error!");
2266       return CURLE_HTTP_POST_ERROR;
2267     }
2268
2269     /* Get the currently set callback function pointer and store that in the
2270        form struct since we might want the actual user-provided callback later
2271        on. The conn->fread_func pointer itself will be changed for the
2272        multipart case to the function that returns a multipart formatted
2273        stream. */
2274     http->form.fread_func = conn->fread_func;
2275
2276     /* Set the read function to read from the generated form data */
2277     conn->fread_func = (curl_read_callback)Curl_FormReader;
2278     conn->fread_in = &http->form;
2279
2280     http->sending = HTTPSEND_BODY;
2281
2282     if(!data->req.upload_chunky &&
2283        !Curl_checkheaders(data, "Content-Length:")) {
2284       /* only add Content-Length if not uploading chunked */
2285       result = Curl_add_bufferf(req_buffer,
2286                                 "Content-Length: %" FORMAT_OFF_T "\r\n",
2287                                 http->postsize);
2288       if(result)
2289         return result;
2290     }
2291
2292     result = expect100(data, conn, req_buffer);
2293     if(result)
2294       return result;
2295
2296     {
2297
2298       /* Get Content-Type: line from Curl_formpostheader.
2299        */
2300       char *contentType;
2301       size_t linelength=0;
2302       contentType = Curl_formpostheader((void *)&http->form,
2303                                         &linelength);
2304       if(!contentType) {
2305         failf(data, "Could not get Content-Type header line!");
2306         return CURLE_HTTP_POST_ERROR;
2307       }
2308
2309       result = Curl_add_buffer(req_buffer, contentType, linelength);
2310       if(result)
2311         return result;
2312     }
2313
2314     /* make the request end in a true CRLF */
2315     result = Curl_add_buffer(req_buffer, "\r\n", 2);
2316     if(result)
2317       return result;
2318
2319     /* set upload size to the progress meter */
2320     Curl_pgrsSetUploadSize(data, http->postsize);
2321
2322     /* fire away the whole request to the server */
2323     result = Curl_add_buffer_send(req_buffer, conn,
2324                                   &data->info.request_size, 0, FIRSTSOCKET);
2325     if(result)
2326       failf(data, "Failed sending POST request");
2327     else
2328       /* setup variables for the upcoming transfer */
2329       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2330                           &http->readbytecount, FIRSTSOCKET,
2331                           &http->writebytecount);
2332
2333     if(result) {
2334       Curl_formclean(&http->sendit); /* free that whole lot */
2335       return result;
2336     }
2337
2338     /* convert the form data */
2339     result = Curl_convert_form(data, http->sendit);
2340     if(result) {
2341       Curl_formclean(&http->sendit); /* free that whole lot */
2342       return result;
2343     }
2344
2345     break;
2346
2347   case HTTPREQ_PUT: /* Let's PUT the data to the server! */
2348
2349     if(conn->bits.authneg)
2350       postsize = 0;
2351     else
2352       postsize = data->set.infilesize;
2353
2354     if((postsize != -1) && !data->req.upload_chunky &&
2355        !Curl_checkheaders(data, "Content-Length:")) {
2356       /* only add Content-Length if not uploading chunked */
2357       result = Curl_add_bufferf(req_buffer,
2358                                 "Content-Length: %" FORMAT_OFF_T "\r\n",
2359                                 postsize );
2360       if(result)
2361         return result;
2362     }
2363
2364     result = expect100(data, conn, req_buffer);
2365     if(result)
2366       return result;
2367
2368     result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers */
2369     if(result)
2370       return result;
2371
2372     /* set the upload size to the progress meter */
2373     Curl_pgrsSetUploadSize(data, postsize);
2374
2375     /* this sends the buffer and frees all the buffer resources */
2376     result = Curl_add_buffer_send(req_buffer, conn,
2377                                   &data->info.request_size, 0, FIRSTSOCKET);
2378     if(result)
2379       failf(data, "Failed sending PUT request");
2380     else
2381       /* prepare for transfer */
2382       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2383                           &http->readbytecount, postsize?FIRSTSOCKET:-1,
2384                           postsize?&http->writebytecount:NULL);
2385     if(result)
2386       return result;
2387     break;
2388
2389   case HTTPREQ_POST:
2390     /* this is the simple POST, using x-www-form-urlencoded style */
2391
2392     if(conn->bits.authneg)
2393       postsize = 0;
2394     else {
2395       /* figure out the size of the postfields */
2396       postsize = (data->set.postfieldsize != -1)?
2397         data->set.postfieldsize:
2398         (data->set.postfields? (curl_off_t)strlen(data->set.postfields):-1);
2399     }
2400     if(!data->req.upload_chunky) {
2401       /* We only set Content-Length and allow a custom Content-Length if
2402          we don't upload data chunked, as RFC2616 forbids us to set both
2403          kinds of headers (Transfer-Encoding: chunked and Content-Length) */
2404
2405       if(conn->bits.authneg || !Curl_checkheaders(data, "Content-Length:")) {
2406         /* we allow replacing this header if not during auth negotiation,
2407            although it isn't very wise to actually set your own */
2408         result = Curl_add_bufferf(req_buffer,
2409                                   "Content-Length: %" FORMAT_OFF_T"\r\n",
2410                                   postsize);
2411         if(result)
2412           return result;
2413       }
2414     }
2415
2416     if(!Curl_checkheaders(data, "Content-Type:")) {
2417       result = Curl_add_bufferf(req_buffer,
2418                                 "Content-Type: application/"
2419                                 "x-www-form-urlencoded\r\n");
2420       if(result)
2421         return result;
2422     }
2423
2424     /* For really small posts we don't use Expect: headers at all, and for
2425        the somewhat bigger ones we allow the app to disable it. Just make
2426        sure that the expect100header is always set to the preferred value
2427        here. */
2428     ptr = Curl_checkheaders(data, "Expect:");
2429     if(ptr) {
2430       data->state.expect100header =
2431         Curl_compareheader(ptr, "Expect:", "100-continue");
2432     }
2433     else if(postsize > TINY_INITIAL_POST_SIZE || postsize < 0) {
2434       result = expect100(data, conn, req_buffer);
2435       if(result)
2436         return result;
2437     }
2438     else
2439       data->state.expect100header = FALSE;
2440
2441     if(data->set.postfields) {
2442
2443       if(!data->state.expect100header &&
2444          (postsize < MAX_INITIAL_POST_SIZE))  {
2445         /* if we don't use expect: 100  AND
2446            postsize is less than MAX_INITIAL_POST_SIZE
2447
2448            then append the post data to the HTTP request header. This limit
2449            is no magic limit but only set to prevent really huge POSTs to
2450            get the data duplicated with malloc() and family. */
2451
2452         result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2453         if(result)
2454           return result;
2455
2456         if(!data->req.upload_chunky) {
2457           /* We're not sending it 'chunked', append it to the request
2458              already now to reduce the number if send() calls */
2459           result = Curl_add_buffer(req_buffer, data->set.postfields,
2460                                    (size_t)postsize);
2461           included_body = postsize;
2462         }
2463         else {
2464           /* Append the POST data chunky-style */
2465           result = Curl_add_bufferf(req_buffer, "%x\r\n", (int)postsize);
2466           if(CURLE_OK == result)
2467             result = Curl_add_buffer(req_buffer, data->set.postfields,
2468                                      (size_t)postsize);
2469           if(CURLE_OK == result)
2470             result = Curl_add_buffer(req_buffer,
2471                                      "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2472           /* CR  LF   0  CR  LF  CR  LF */
2473           included_body = postsize + 7;
2474         }
2475         if(result)
2476           return result;
2477         /* Make sure the progress information is accurate */
2478         Curl_pgrsSetUploadSize(data, postsize);
2479       }
2480       else {
2481         /* A huge POST coming up, do data separate from the request */
2482         http->postsize = postsize;
2483         http->postdata = data->set.postfields;
2484
2485         http->sending = HTTPSEND_BODY;
2486
2487         conn->fread_func = (curl_read_callback)readmoredata;
2488         conn->fread_in = (void *)conn;
2489
2490         /* set the upload size to the progress meter */
2491         Curl_pgrsSetUploadSize(data, http->postsize);
2492
2493         result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2494         if(result)
2495           return result;
2496       }
2497     }
2498     else {
2499       result = Curl_add_buffer(req_buffer, "\r\n", 2); /* end of headers! */
2500       if(result)
2501         return result;
2502
2503       if(data->req.upload_chunky && conn->bits.authneg) {
2504         /* Chunky upload is selected and we're negotiating auth still, send
2505            end-of-data only */
2506         result = Curl_add_buffer(req_buffer,
2507                                  "\x0d\x0a\x30\x0d\x0a\x0d\x0a", 7);
2508         /* CR  LF   0  CR  LF  CR  LF */
2509         if(result)
2510           return result;
2511       }
2512
2513       else if(data->set.postfieldsize) {
2514         /* set the upload size to the progress meter */
2515         Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
2516
2517         /* set the pointer to mark that we will send the post body using the
2518            read callback, but only if we're not in authenticate
2519            negotiation  */
2520         if(!conn->bits.authneg) {
2521           http->postdata = (char *)&http->postdata;
2522           http->postsize = postsize;
2523         }
2524       }
2525     }
2526     /* issue the request */
2527     result = Curl_add_buffer_send(req_buffer, conn, &data->info.request_size,
2528                                   (size_t)included_body, FIRSTSOCKET);
2529
2530     if(result)
2531       failf(data, "Failed sending HTTP POST request");
2532     else
2533       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE,
2534                           &http->readbytecount, http->postdata?FIRSTSOCKET:-1,
2535                           http->postdata?&http->writebytecount:NULL);
2536     break;
2537
2538   default:
2539     result = Curl_add_buffer(req_buffer, "\r\n", 2);
2540     if(result)
2541       return result;
2542
2543     /* issue the request */
2544     result = Curl_add_buffer_send(req_buffer, conn,
2545                                   &data->info.request_size, 0, FIRSTSOCKET);
2546
2547     if(result)
2548       failf(data, "Failed sending HTTP request");
2549     else
2550       /* HTTP GET/HEAD download: */
2551       Curl_setup_transfer(conn, FIRSTSOCKET, -1, TRUE, &http->readbytecount,
2552                           http->postdata?FIRSTSOCKET:-1,
2553                           http->postdata?&http->writebytecount:NULL);
2554   }
2555   if(result)
2556     return result;
2557
2558   if(http->writebytecount) {
2559     /* if a request-body has been sent off, we make sure this progress is noted
2560        properly */
2561     Curl_pgrsSetUploadCounter(data, http->writebytecount);
2562     if(Curl_pgrsUpdate(conn))
2563       result = CURLE_ABORTED_BY_CALLBACK;
2564
2565     if(http->writebytecount >= postsize) {
2566       /* already sent the entire request body, mark the "upload" as
2567          complete */
2568       infof(data, "upload completely sent off: %" FORMAT_OFF_T " out of "
2569             "%" FORMAT_OFF_T " bytes\n",
2570             http->writebytecount, postsize);
2571       data->req.upload_done = TRUE;
2572       data->req.keepon &= ~KEEP_SEND; /* we're done writing */
2573       data->req.exp100 = EXP100_SEND_DATA; /* already sent */
2574     }
2575   }
2576
2577   return result;
2578 }
2579
2580 /*
2581  * checkhttpprefix()
2582  *
2583  * Returns TRUE if member of the list matches prefix of string
2584  */
2585 static bool
2586 checkhttpprefix(struct SessionHandle *data,
2587                 const char *s)
2588 {
2589   struct curl_slist *head = data->set.http200aliases;
2590   bool rc = FALSE;
2591 #ifdef CURL_DOES_CONVERSIONS
2592   /* convert from the network encoding using a scratch area */
2593   char *scratch = strdup(s);
2594   if(NULL == scratch) {
2595     failf (data, "Failed to allocate memory for conversion!");
2596     return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2597   }
2598   if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2599     /* Curl_convert_from_network calls failf if unsuccessful */
2600     free(scratch);
2601     return FALSE; /* can't return CURLE_foobar so return FALSE */
2602   }
2603   s = scratch;
2604 #endif /* CURL_DOES_CONVERSIONS */
2605
2606   while(head) {
2607     if(checkprefix(head->data, s)) {
2608       rc = TRUE;
2609       break;
2610     }
2611     head = head->next;
2612   }
2613
2614   if(!rc && (checkprefix("HTTP/", s)))
2615     rc = TRUE;
2616
2617 #ifdef CURL_DOES_CONVERSIONS
2618   free(scratch);
2619 #endif /* CURL_DOES_CONVERSIONS */
2620   return rc;
2621 }
2622
2623 #ifndef CURL_DISABLE_RTSP
2624 static bool
2625 checkrtspprefix(struct SessionHandle *data,
2626                 const char *s)
2627 {
2628
2629 #ifdef CURL_DOES_CONVERSIONS
2630   /* convert from the network encoding using a scratch area */
2631   char *scratch = strdup(s);
2632   if(NULL == scratch) {
2633     failf (data, "Failed to allocate memory for conversion!");
2634     return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
2635   }
2636   if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
2637     /* Curl_convert_from_network calls failf if unsuccessful */
2638     free(scratch);
2639     return FALSE; /* can't return CURLE_foobar so return FALSE */
2640   }
2641   s = scratch;
2642 #else
2643   (void)data; /* unused */
2644 #endif /* CURL_DOES_CONVERSIONS */
2645   if(checkprefix("RTSP/", s))
2646     return TRUE;
2647   else
2648     return FALSE;
2649 }
2650 #endif /* CURL_DISABLE_RTSP */
2651
2652 static bool
2653 checkprotoprefix(struct SessionHandle *data, struct connectdata *conn,
2654                  const char *s)
2655 {
2656 #ifndef CURL_DISABLE_RTSP
2657   if(conn->handler->protocol & CURLPROTO_RTSP)
2658     return checkrtspprefix(data, s);
2659 #else
2660   (void)conn;
2661 #endif /* CURL_DISABLE_RTSP */
2662
2663   return checkhttpprefix(data, s);
2664 }
2665
2666 /*
2667  * header_append() copies a chunk of data to the end of the already received
2668  * header. We make sure that the full string fit in the allocated header
2669  * buffer, or else we enlarge it.
2670  */
2671 static CURLcode header_append(struct SessionHandle *data,
2672                               struct SingleRequest *k,
2673                               size_t length)
2674 {
2675   if(k->hbuflen + length >= data->state.headersize) {
2676     /* We enlarge the header buffer as it is too small */
2677     char *newbuff;
2678     size_t hbufp_index;
2679     size_t newsize;
2680
2681     if(k->hbuflen + length > CURL_MAX_HTTP_HEADER) {
2682       /* The reason to have a max limit for this is to avoid the risk of a bad
2683          server feeding libcurl with a never-ending header that will cause
2684          reallocs infinitely */
2685       failf (data, "Avoided giant realloc for header (max is %d)!",
2686              CURL_MAX_HTTP_HEADER);
2687       return CURLE_OUT_OF_MEMORY;
2688     }
2689
2690     newsize=CURLMAX((k->hbuflen+ length)*3/2, data->state.headersize*2);
2691     hbufp_index = k->hbufp - data->state.headerbuff;
2692     newbuff = realloc(data->state.headerbuff, newsize);
2693     if(!newbuff) {
2694       failf (data, "Failed to alloc memory for big header!");
2695       return CURLE_OUT_OF_MEMORY;
2696     }
2697     data->state.headersize=newsize;
2698     data->state.headerbuff = newbuff;
2699     k->hbufp = data->state.headerbuff + hbufp_index;
2700   }
2701   memcpy(k->hbufp, k->str_start, length);
2702   k->hbufp += length;
2703   k->hbuflen += length;
2704   *k->hbufp = 0;
2705
2706   return CURLE_OK;
2707 }
2708
2709
2710 /*
2711  * Read any HTTP header lines from the server and pass them to the client app.
2712  */
2713 CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
2714                                        struct connectdata *conn,
2715                                        ssize_t *nread,
2716                                        bool *stop_reading)
2717 {
2718   CURLcode result;
2719   struct SingleRequest *k = &data->req;
2720
2721   /* header line within buffer loop */
2722   do {
2723     size_t rest_length;
2724     size_t full_length;
2725     int writetype;
2726
2727     /* str_start is start of line within buf */
2728     k->str_start = k->str;
2729
2730     /* data is in network encoding so use 0x0a instead of '\n' */
2731     k->end_ptr = memchr(k->str_start, 0x0a, *nread);
2732
2733     if(!k->end_ptr) {
2734       /* Not a complete header line within buffer, append the data to
2735          the end of the headerbuff. */
2736       result = header_append(data, k, *nread);
2737       if(result)
2738         return result;
2739
2740       if(!k->headerline && (k->hbuflen>5)) {
2741         /* make a first check that this looks like a protocol header */
2742         if(!checkprotoprefix(data, conn, data->state.headerbuff)) {
2743           /* this is not the beginning of a protocol first header line */
2744           k->header = FALSE;
2745           k->badheader = HEADER_ALLBAD;
2746           break;
2747         }
2748       }
2749
2750       break; /* read more and try again */
2751     }
2752
2753     /* decrease the size of the remaining (supposed) header line */
2754     rest_length = (k->end_ptr - k->str)+1;
2755     *nread -= (ssize_t)rest_length;
2756
2757     k->str = k->end_ptr + 1; /* move past new line */
2758
2759     full_length = k->str - k->str_start;
2760
2761     result = header_append(data, k, full_length);
2762     if(result)
2763       return result;
2764
2765     k->end_ptr = k->hbufp;
2766     k->p = data->state.headerbuff;
2767
2768     /****
2769      * We now have a FULL header line that p points to
2770      *****/
2771
2772     if(!k->headerline) {
2773       /* the first read header */
2774       if((k->hbuflen>5) &&
2775          !checkprotoprefix(data, conn, data->state.headerbuff)) {
2776         /* this is not the beginning of a protocol first header line */
2777         k->header = FALSE;
2778         if(*nread)
2779           /* since there's more, this is a partial bad header */
2780           k->badheader = HEADER_PARTHEADER;
2781         else {
2782           /* this was all we read so it's all a bad header */
2783           k->badheader = HEADER_ALLBAD;
2784           *nread = (ssize_t)rest_length;
2785         }
2786         break;
2787       }
2788     }
2789
2790     /* headers are in network encoding so
2791        use 0x0a and 0x0d instead of '\n' and '\r' */
2792     if((0x0a == *k->p) || (0x0d == *k->p)) {
2793       size_t headerlen;
2794       /* Zero-length header line means end of headers! */
2795
2796 #ifdef CURL_DOES_CONVERSIONS
2797       if(0x0d == *k->p) {
2798         *k->p = '\r'; /* replace with CR in host encoding */
2799         k->p++;       /* pass the CR byte */
2800       }
2801       if(0x0a == *k->p) {
2802         *k->p = '\n'; /* replace with LF in host encoding */
2803         k->p++;       /* pass the LF byte */
2804       }
2805 #else
2806       if('\r' == *k->p)
2807         k->p++; /* pass the \r byte */
2808       if('\n' == *k->p)
2809         k->p++; /* pass the \n byte */
2810 #endif /* CURL_DOES_CONVERSIONS */
2811
2812       if(100 <= k->httpcode && 199 >= k->httpcode) {
2813         /*
2814          * We have made a HTTP PUT or POST and this is 1.1-lingo
2815          * that tells us that the server is OK with this and ready
2816          * to receive the data.
2817          * However, we'll get more headers now so we must get
2818          * back into the header-parsing state!
2819          */
2820         k->header = TRUE;
2821         k->headerline = 0; /* restart the header line counter */
2822
2823         /* if we did wait for this do enable write now! */
2824         if(k->exp100) {
2825           k->exp100 = EXP100_SEND_DATA;
2826           k->keepon |= KEEP_SEND;
2827         }
2828       }
2829       else {
2830         k->header = FALSE; /* no more header to parse! */
2831
2832         if((k->size == -1) && !k->chunk && !conn->bits.close &&
2833            (conn->httpversion >= 11) &&
2834            !(conn->handler->protocol & CURLPROTO_RTSP)) {
2835           /* On HTTP 1.1, when connection is not to get closed, but no
2836              Content-Length nor Content-Encoding chunked have been
2837              received, according to RFC2616 section 4.4 point 5, we
2838              assume that the server will close the connection to
2839              signal the end of the document. */
2840           infof(data, "no chunk, no close, no size. Assume close to "
2841                 "signal end\n");
2842           conn->bits.close = TRUE;
2843         }
2844       }
2845
2846       /*
2847        * When all the headers have been parsed, see if we should give
2848        * up and return an error.
2849        */
2850       if(http_should_fail(conn)) {
2851         failf (data, "The requested URL returned error: %d",
2852                k->httpcode);
2853         return CURLE_HTTP_RETURNED_ERROR;
2854       }
2855
2856       /* now, only output this if the header AND body are requested:
2857        */
2858       writetype = CLIENTWRITE_HEADER;
2859       if(data->set.include_header)
2860         writetype |= CLIENTWRITE_BODY;
2861
2862       headerlen = k->p - data->state.headerbuff;
2863
2864       result = Curl_client_write(conn, writetype,
2865                                  data->state.headerbuff,
2866                                  headerlen);
2867       if(result)
2868         return result;
2869
2870       data->info.header_size += (long)headerlen;
2871       data->req.headerbytecount += (long)headerlen;
2872
2873       data->req.deductheadercount =
2874         (100 <= k->httpcode && 199 >= k->httpcode)?data->req.headerbytecount:0;
2875
2876       if(!*stop_reading) {
2877         /* Curl_http_auth_act() checks what authentication methods
2878          * that are available and decides which one (if any) to
2879          * use. It will set 'newurl' if an auth method was picked. */
2880         result = Curl_http_auth_act(conn);
2881
2882         if(result)
2883           return result;
2884
2885         if(k->httpcode >= 300) {
2886           if((!conn->bits.authneg) && !conn->bits.close &&
2887              !conn->bits.rewindaftersend) {
2888             /*
2889              * General treatment of errors when about to send data. Including :
2890              * "417 Expectation Failed", while waiting for 100-continue.
2891              *
2892              * The check for close above is done simply because of something
2893              * else has already deemed the connection to get closed then
2894              * something else should've considered the big picture and we
2895              * avoid this check.
2896              *
2897              * rewindaftersend indicates that something has told libcurl to
2898              * continue sending even if it gets discarded
2899              */
2900
2901             switch(data->set.httpreq) {
2902             case HTTPREQ_PUT:
2903             case HTTPREQ_POST:
2904             case HTTPREQ_POST_FORM:
2905               /* We got an error response. If this happened before the whole
2906                * request body has been sent we stop sending and mark the
2907                * connection for closure after we've read the entire response.
2908                */
2909               if(!k->upload_done) {
2910                 infof(data, "HTTP error before end of send, stop sending\n");
2911                 conn->bits.close = TRUE; /* close after this */
2912                 k->upload_done = TRUE;
2913                 k->keepon &= ~KEEP_SEND; /* don't send */
2914                 if(data->state.expect100header)
2915                   k->exp100 = EXP100_FAILED;
2916               }
2917               break;
2918
2919             default: /* default label present to avoid compiler warnings */
2920               break;
2921             }
2922           }
2923         }
2924
2925         if(conn->bits.rewindaftersend) {
2926           /* We rewind after a complete send, so thus we continue
2927              sending now */
2928           infof(data, "Keep sending data to get tossed away!\n");
2929           k->keepon |= KEEP_SEND;
2930         }
2931       }
2932
2933       if(!k->header) {
2934         /*
2935          * really end-of-headers.
2936          *
2937          * If we requested a "no body", this is a good time to get
2938          * out and return home.
2939          */
2940         if(data->set.opt_no_body)
2941           *stop_reading = TRUE;
2942         else {
2943           /* If we know the expected size of this document, we set the
2944              maximum download size to the size of the expected
2945              document or else, we won't know when to stop reading!
2946
2947              Note that we set the download maximum even if we read a
2948              "Connection: close" header, to make sure that
2949              "Content-Length: 0" still prevents us from attempting to
2950              read the (missing) response-body.
2951           */
2952           /* According to RFC2616 section 4.4, we MUST ignore
2953              Content-Length: headers if we are now receiving data
2954              using chunked Transfer-Encoding.
2955           */
2956           if(k->chunk)
2957             k->maxdownload = k->size = -1;
2958         }
2959         if(-1 != k->size) {
2960           /* We do this operation even if no_body is true, since this
2961              data might be retrieved later with curl_easy_getinfo()
2962              and its CURLINFO_CONTENT_LENGTH_DOWNLOAD option. */
2963
2964           Curl_pgrsSetDownloadSize(data, k->size);
2965           k->maxdownload = k->size;
2966         }
2967
2968         /* If max download size is *zero* (nothing) we already
2969            have nothing and can safely return ok now! */
2970         if(0 == k->maxdownload)
2971           *stop_reading = TRUE;
2972
2973         if(*stop_reading) {
2974           /* we make sure that this socket isn't read more now */
2975           k->keepon &= ~KEEP_RECV;
2976         }
2977
2978         if(data->set.verbose)
2979           Curl_debug(data, CURLINFO_HEADER_IN,
2980                      k->str_start, headerlen, conn);
2981         break;          /* exit header line loop */
2982       }
2983
2984       /* We continue reading headers, so reset the line-based
2985          header parsing variables hbufp && hbuflen */
2986       k->hbufp = data->state.headerbuff;
2987       k->hbuflen = 0;
2988       continue;
2989     }
2990
2991     /*
2992      * Checks for special headers coming up.
2993      */
2994
2995     if(!k->headerline++) {
2996       /* This is the first header, it MUST be the error code line
2997          or else we consider this to be the body right away! */
2998       int httpversion_major;
2999       int rtspversion_major;
3000       int nc = 0;
3001 #ifdef CURL_DOES_CONVERSIONS
3002 #define HEADER1 scratch
3003 #define SCRATCHSIZE 21
3004       CURLcode res;
3005       char scratch[SCRATCHSIZE+1]; /* "HTTP/major.minor 123" */
3006       /* We can't really convert this yet because we
3007          don't know if it's the 1st header line or the body.
3008          So we do a partial conversion into a scratch area,
3009          leaving the data at k->p as-is.
3010       */
3011       strncpy(&scratch[0], k->p, SCRATCHSIZE);
3012       scratch[SCRATCHSIZE] = 0; /* null terminate */
3013       res = Curl_convert_from_network(data,
3014                                       &scratch[0],
3015                                       SCRATCHSIZE);
3016       if(res)
3017         /* Curl_convert_from_network calls failf if unsuccessful */
3018         return res;
3019 #else
3020 #define HEADER1 k->p /* no conversion needed, just use k->p */
3021 #endif /* CURL_DOES_CONVERSIONS */
3022
3023       if(conn->handler->protocol & CURLPROTO_HTTP) {
3024         nc = sscanf(HEADER1,
3025                     " HTTP/%d.%d %3d",
3026                     &httpversion_major,
3027                     &conn->httpversion,
3028                     &k->httpcode);
3029         if(nc==3) {
3030           conn->httpversion += 10 * httpversion_major;
3031         }
3032         else {
3033           /* this is the real world, not a Nirvana
3034              NCSA 1.5.x returns this crap when asked for HTTP/1.1
3035           */
3036           nc=sscanf(HEADER1, " HTTP %3d", &k->httpcode);
3037           conn->httpversion = 10;
3038
3039           /* If user has set option HTTP200ALIASES,
3040              compare header line against list of aliases
3041           */
3042           if(!nc) {
3043             if(checkhttpprefix(data, k->p)) {
3044               nc = 1;
3045               k->httpcode = 200;
3046               conn->httpversion = 10;
3047             }
3048           }
3049         }
3050       }
3051       else if(conn->handler->protocol & CURLPROTO_RTSP) {
3052         nc = sscanf(HEADER1,
3053                     " RTSP/%d.%d %3d",
3054                     &rtspversion_major,
3055                     &conn->rtspversion,
3056                     &k->httpcode);
3057         if(nc==3) {
3058           conn->rtspversion += 10 * rtspversion_major;
3059           conn->httpversion = 11; /* For us, RTSP acts like HTTP 1.1 */
3060         }
3061         else {
3062           /* TODO: do we care about the other cases here? */
3063           nc = 0;
3064         }
3065       }
3066
3067       if(nc) {
3068         data->info.httpcode = k->httpcode;
3069
3070         data->info.httpversion = conn->httpversion;
3071         if(!data->state.httpversion ||
3072            data->state.httpversion > conn->httpversion)
3073           /* store the lowest server version we encounter */
3074           data->state.httpversion = conn->httpversion;
3075
3076         /*
3077          * This code executes as part of processing the header.  As a
3078          * result, it's not totally clear how to interpret the
3079          * response code yet as that depends on what other headers may
3080          * be present.  401 and 407 may be errors, but may be OK
3081          * depending on how authentication is working.  Other codes
3082          * are definitely errors, so give up here.
3083          */
3084         if(data->set.http_fail_on_error && (k->httpcode >= 400) &&
3085            ((k->httpcode != 401) || !conn->bits.user_passwd) &&
3086            ((k->httpcode != 407) || !conn->bits.proxy_user_passwd) ) {
3087
3088           if(data->state.resume_from &&
3089              (data->set.httpreq==HTTPREQ_GET) &&
3090              (k->httpcode == 416)) {
3091             /* "Requested Range Not Satisfiable", just proceed and
3092                pretend this is no error */
3093           }
3094           else {
3095             /* serious error, go home! */
3096             failf (data, "The requested URL returned error: %d",
3097                    k->httpcode);
3098             return CURLE_HTTP_RETURNED_ERROR;
3099           }
3100         }
3101
3102         if(conn->httpversion == 10) {
3103           /* Default action for HTTP/1.0 must be to close, unless
3104              we get one of those fancy headers that tell us the
3105              server keeps it open for us! */
3106           infof(data, "HTTP 1.0, assume close after body\n");
3107           conn->bits.close = TRUE;
3108         }
3109         else if(conn->httpversion >= 11 &&
3110                 !conn->bits.close) {
3111           /* If HTTP version is >= 1.1 and connection is persistent
3112              server supports pipelining. */
3113           DEBUGF(infof(data,
3114                        "HTTP 1.1 or later with persistent connection, "
3115                        "pipelining supported\n"));
3116           conn->server_supports_pipelining = TRUE;
3117         }
3118
3119         switch(k->httpcode) {
3120         case 204:
3121           /* (quote from RFC2616, section 10.2.5): The server has
3122            * fulfilled the request but does not need to return an
3123            * entity-body ... The 204 response MUST NOT include a
3124            * message-body, and thus is always terminated by the first
3125            * empty line after the header fields. */
3126           /* FALLTHROUGH */
3127         case 304:
3128           /* (quote from RFC2616, section 10.3.5): The 304 response
3129            * MUST NOT contain a message-body, and thus is always
3130            * terminated by the first empty line after the header
3131            * fields.  */
3132           if(data->set.timecondition)
3133             data->info.timecond = TRUE;
3134           k->size=0;
3135           k->maxdownload=0;
3136           k->ignorecl = TRUE; /* ignore Content-Length headers */
3137           break;
3138         default:
3139           /* nothing */
3140           break;
3141         }
3142       }
3143       else {
3144         k->header = FALSE;   /* this is not a header line */
3145         break;
3146       }
3147     }
3148
3149     result = Curl_convert_from_network(data, k->p, strlen(k->p));
3150     /* Curl_convert_from_network calls failf if unsuccessful */
3151     if(result)
3152       return result;
3153
3154     /* Check for Content-Length: header lines to get size */
3155     if(!k->ignorecl && !data->set.ignorecl &&
3156        checkprefix("Content-Length:", k->p)) {
3157       curl_off_t contentlength = curlx_strtoofft(k->p+15, NULL, 10);
3158       if(data->set.max_filesize &&
3159          contentlength > data->set.max_filesize) {
3160         failf(data, "Maximum file size exceeded");
3161         return CURLE_FILESIZE_EXCEEDED;
3162       }
3163       if(contentlength >= 0) {
3164         k->size = contentlength;
3165         k->maxdownload = k->size;
3166         /* we set the progress download size already at this point
3167            just to make it easier for apps/callbacks to extract this
3168            info as soon as possible */
3169         Curl_pgrsSetDownloadSize(data, k->size);
3170       }
3171       else {
3172         /* Negative Content-Length is really odd, and we know it
3173            happens for example when older Apache servers send large
3174            files */
3175         conn->bits.close = TRUE;
3176         infof(data, "Negative content-length: %" FORMAT_OFF_T
3177               ", closing after transfer\n", contentlength);
3178       }
3179     }
3180     /* check for Content-Type: header lines to get the MIME-type */
3181     else if(checkprefix("Content-Type:", k->p)) {
3182       char *contenttype = copy_header_value(k->p);
3183       if(!contenttype)
3184         return CURLE_OUT_OF_MEMORY;
3185       if(!*contenttype)
3186         /* ignore empty data */
3187         free(contenttype);
3188       else {
3189         Curl_safefree(data->info.contenttype);
3190         data->info.contenttype = contenttype;
3191       }
3192     }
3193     else if((conn->httpversion == 10) &&
3194             conn->bits.httpproxy &&
3195             Curl_compareheader(k->p,
3196                                "Proxy-Connection:", "keep-alive")) {
3197       /*
3198        * When a HTTP/1.0 reply comes when using a proxy, the
3199        * 'Proxy-Connection: keep-alive' line tells us the
3200        * connection will be kept alive for our pleasure.
3201        * Default action for 1.0 is to close.
3202        */
3203       conn->bits.close = FALSE; /* don't close when done */
3204       infof(data, "HTTP/1.0 proxy connection set to keep alive!\n");
3205     }
3206     else if((conn->httpversion == 11) &&
3207             conn->bits.httpproxy &&
3208             Curl_compareheader(k->p,
3209                                "Proxy-Connection:", "close")) {
3210       /*
3211        * We get a HTTP/1.1 response from a proxy and it says it'll
3212        * close down after this transfer.
3213        */
3214       conn->bits.close = TRUE; /* close when done */
3215       infof(data, "HTTP/1.1 proxy connection set close!\n");
3216     }
3217     else if((conn->httpversion == 10) &&
3218             Curl_compareheader(k->p, "Connection:", "keep-alive")) {
3219       /*
3220        * A HTTP/1.0 reply with the 'Connection: keep-alive' line
3221        * tells us the connection will be kept alive for our
3222        * pleasure.  Default action for 1.0 is to close.
3223        *
3224        * [RFC2068, section 19.7.1] */
3225       conn->bits.close = FALSE; /* don't close when done */
3226       infof(data, "HTTP/1.0 connection set to keep alive!\n");
3227     }
3228     else if(Curl_compareheader(k->p, "Connection:", "close")) {
3229       /*
3230        * [RFC 2616, section 8.1.2.1]
3231        * "Connection: close" is HTTP/1.1 language and means that
3232        * the connection will close when this request has been
3233        * served.
3234        */
3235       conn->bits.close = TRUE; /* close when done */
3236     }
3237     else if(checkprefix("Transfer-Encoding:", k->p)) {
3238       /* One or more encodings. We check for chunked and/or a compression
3239          algorithm. */
3240       /*
3241        * [RFC 2616, section 3.6.1] A 'chunked' transfer encoding
3242        * means that the server will send a series of "chunks". Each
3243        * chunk starts with line with info (including size of the
3244        * coming block) (terminated with CRLF), then a block of data
3245        * with the previously mentioned size. There can be any amount
3246        * of chunks, and a chunk-data set to zero signals the
3247        * end-of-chunks. */
3248
3249       char *start;
3250
3251       /* Find the first non-space letter */
3252       start = k->p + 18;
3253
3254       for(;;) {
3255         /* skip whitespaces and commas */
3256         while(*start && (ISSPACE(*start) || (*start == ',')))
3257           start++;
3258
3259         if(checkprefix("chunked", start)) {
3260           k->chunk = TRUE; /* chunks coming our way */
3261
3262           /* init our chunky engine */
3263           Curl_httpchunk_init(conn);
3264
3265           start += 7;
3266         }
3267
3268         if(k->auto_decoding)
3269           /* TODO: we only support the first mentioned compression for now */
3270           break;
3271
3272         if(checkprefix("identity", start)) {
3273           k->auto_decoding = IDENTITY;
3274           start += 8;
3275         }
3276         else if(checkprefix("deflate", start)) {
3277           k->auto_decoding = DEFLATE;
3278           start += 7;
3279         }
3280         else if(checkprefix("gzip", start)) {
3281           k->auto_decoding = GZIP;
3282           start += 4;
3283         }
3284         else if(checkprefix("x-gzip", start)) {
3285           k->auto_decoding = GZIP;
3286           start += 6;
3287         }
3288         else if(checkprefix("compress", start)) {
3289           k->auto_decoding = COMPRESS;
3290           start += 8;
3291         }
3292         else if(checkprefix("x-compress", start)) {
3293           k->auto_decoding = COMPRESS;
3294           start += 10;
3295         }
3296         else
3297           /* unknown! */
3298           break;
3299
3300       }
3301
3302     }
3303     else if(checkprefix("Content-Encoding:", k->p) &&
3304             data->set.str[STRING_ENCODING]) {
3305       /*
3306        * Process Content-Encoding. Look for the values: identity,
3307        * gzip, deflate, compress, x-gzip and x-compress. x-gzip and
3308        * x-compress are the same as gzip and compress. (Sec 3.5 RFC
3309        * 2616). zlib cannot handle compress.  However, errors are
3310        * handled further down when the response body is processed
3311        */
3312       char *start;
3313
3314       /* Find the first non-space letter */
3315       start = k->p + 17;
3316       while(*start && ISSPACE(*start))
3317         start++;
3318
3319       /* Record the content-encoding for later use */
3320       if(checkprefix("identity", start))
3321         k->auto_decoding = IDENTITY;
3322       else if(checkprefix("deflate", start))
3323         k->auto_decoding = DEFLATE;
3324       else if(checkprefix("gzip", start)
3325               || checkprefix("x-gzip", start))
3326         k->auto_decoding = GZIP;
3327       else if(checkprefix("compress", start)
3328               || checkprefix("x-compress", start))
3329         k->auto_decoding = COMPRESS;
3330     }
3331     else if(checkprefix("Content-Range:", k->p)) {
3332       /* Content-Range: bytes [num]-
3333          Content-Range: bytes: [num]-
3334          Content-Range: [num]-
3335
3336          The second format was added since Sun's webserver
3337          JavaWebServer/1.1.1 obviously sends the header this way!
3338          The third added since some servers use that!
3339       */
3340
3341       char *ptr = k->p + 14;
3342
3343       /* Move forward until first digit */
3344       while(*ptr && !ISDIGIT(*ptr))
3345         ptr++;
3346
3347       k->offset = curlx_strtoofft(ptr, NULL, 10);
3348
3349       if(data->state.resume_from == k->offset)
3350         /* we asked for a resume and we got it */
3351         k->content_range = TRUE;
3352     }
3353 #if !defined(CURL_DISABLE_COOKIES)
3354     else if(data->cookies &&
3355             checkprefix("Set-Cookie:", k->p)) {
3356       Curl_share_lock(data, CURL_LOCK_DATA_COOKIE,
3357                       CURL_LOCK_ACCESS_SINGLE);
3358       Curl_cookie_add(data,
3359                       data->cookies, TRUE, k->p+11,
3360                       /* If there is a custom-set Host: name, use it
3361                          here, or else use real peer host name. */
3362                       conn->allocptr.cookiehost?
3363                       conn->allocptr.cookiehost:conn->host.name,
3364                       data->state.path);
3365       Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
3366     }
3367 #endif
3368     else if(checkprefix("Last-Modified:", k->p) &&
3369             (data->set.timecondition || data->set.get_filetime) ) {
3370       time_t secs=time(NULL);
3371       k->timeofdoc = curl_getdate(k->p+strlen("Last-Modified:"),
3372                                   &secs);
3373       if(data->set.get_filetime)
3374         data->info.filetime = (long)k->timeofdoc;
3375     }
3376     else if((checkprefix("WWW-Authenticate:", k->p) &&
3377              (401 == k->httpcode)) ||
3378             (checkprefix("Proxy-authenticate:", k->p) &&
3379              (407 == k->httpcode))) {
3380       result = Curl_http_input_auth(conn, k->httpcode, k->p);
3381       if(result)
3382         return result;
3383     }
3384     else if((k->httpcode >= 300 && k->httpcode < 400) &&
3385             checkprefix("Location:", k->p) &&
3386             !data->req.location) {
3387       /* this is the URL that the server advises us to use instead */
3388       char *location = copy_header_value(k->p);
3389       if(!location)
3390         return CURLE_OUT_OF_MEMORY;
3391       if(!*location)
3392         /* ignore empty data */
3393         free(location);
3394       else {
3395         data->req.location = location;
3396
3397         if(data->set.http_follow_location) {
3398           DEBUGASSERT(!data->req.newurl);
3399           data->req.newurl = strdup(data->req.location); /* clone */
3400           if(!data->req.newurl)
3401             return CURLE_OUT_OF_MEMORY;
3402
3403           /* some cases of POST and PUT etc needs to rewind the data
3404              stream at this point */
3405           result = http_perhapsrewind(conn);
3406           if(result)
3407             return result;
3408         }
3409       }
3410     }
3411     else if(conn->handler->protocol & CURLPROTO_RTSP) {
3412       result = Curl_rtsp_parseheader(conn, k->p);
3413       if(result)
3414         return result;
3415     }
3416
3417     /*
3418      * End of header-checks. Write them to the client.
3419      */
3420
3421     writetype = CLIENTWRITE_HEADER;
3422     if(data->set.include_header)
3423       writetype |= CLIENTWRITE_BODY;
3424
3425     if(data->set.verbose)
3426       Curl_debug(data, CURLINFO_HEADER_IN,
3427                  k->p, (size_t)k->hbuflen, conn);
3428
3429     result = Curl_client_write(conn, writetype, k->p, k->hbuflen);
3430     if(result)
3431       return result;
3432
3433     data->info.header_size += (long)k->hbuflen;
3434     data->req.headerbytecount += (long)k->hbuflen;
3435
3436     /* reset hbufp pointer && hbuflen */
3437     k->hbufp = data->state.headerbuff;
3438     k->hbuflen = 0;
3439   }
3440   while(!*stop_reading && *k->str); /* header line within buffer */
3441
3442   /* We might have reached the end of the header part here, but
3443      there might be a non-header part left in the end of the read
3444      buffer. */
3445
3446   return CURLE_OK;
3447 }
3448
3449 #endif /* CURL_DISABLE_HTTP */