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