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