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