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