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