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