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