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