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