/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at https://curl.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ***************************************************************************/

#include "curl_setup.h"

#include "http_proxy.h"

#if !defined(CURL_DISABLE_PROXY) && !defined(CURL_DISABLE_HTTP)

#include <curl/curl.h>
#ifdef USE_HYPER
#include <hyper.h>
#endif
#include "sendf.h"
#include "http.h"
#include "url.h"
#include "select.h"
#include "progress.h"
#include "non-ascii.h"
#include "connect.h"
#include "curlx.h"
#include "vtls/vtls.h"
#include "transfer.h"
#include "multiif.h"

/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#include "memdebug.h"

/*
 * Perform SSL initialization for HTTPS proxy.  Sets
 * proxy_ssl_connected connection bit when complete.  Can be
 * called multiple times.
 */
static CURLcode https_proxy_connect(struct Curl_easy *data, int sockindex)
{
#ifdef USE_SSL
  struct connectdata *conn = data->conn;
  CURLcode result = CURLE_OK;
  DEBUGASSERT(conn->http_proxy.proxytype == CURLPROXY_HTTPS);
  if(!conn->bits.proxy_ssl_connected[sockindex]) {
    /* perform SSL initialization for this socket */
    result =
      Curl_ssl_connect_nonblocking(data, conn, sockindex,
                                   &conn->bits.proxy_ssl_connected[sockindex]);
    if(result)
      /* a failed connection is marked for closure to prevent (bad) re-use or
         similar */
      connclose(conn, "TLS handshake failed");
  }
  return result;
#else
  (void) data;
  (void) sockindex;
  return CURLE_NOT_BUILT_IN;
#endif
}

CURLcode Curl_proxy_connect(struct Curl_easy *data, int sockindex)
{
  struct connectdata *conn = data->conn;
  if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
    const CURLcode result = https_proxy_connect(data, sockindex);
    if(result)
      return result;
    if(!conn->bits.proxy_ssl_connected[sockindex])
      return result; /* wait for HTTPS proxy SSL initialization to complete */
  }

  if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
#ifndef CURL_DISABLE_PROXY
    /* for [protocol] tunneled through HTTP proxy */
    const char *hostname;
    int remote_port;
    CURLcode result;

    /* We want "seamless" operations through HTTP proxy tunnel */

    /* for the secondary socket (FTP), use the "connect to host"
     * but ignore the "connect to port" (use the secondary port)
     */

    if(conn->bits.conn_to_host)
      hostname = conn->conn_to_host.name;
    else if(sockindex == SECONDARYSOCKET)
      hostname = conn->secondaryhostname;
    else
      hostname = conn->host.name;

    if(sockindex == SECONDARYSOCKET)
      remote_port = conn->secondary_port;
    else if(conn->bits.conn_to_port)
      remote_port = conn->conn_to_port;
    else
      remote_port = conn->remote_port;

    result = Curl_proxyCONNECT(data, sockindex, hostname, remote_port);
    if(CURLE_OK != result)
      return result;
    Curl_safefree(data->state.aptr.proxyuserpwd);
#else
    return CURLE_NOT_BUILT_IN;
#endif
  }
  /* no HTTP tunnel proxy, just return */
  return CURLE_OK;
}

bool Curl_connect_complete(struct connectdata *conn)
{
  return !conn->connect_state ||
    (conn->connect_state->tunnel_state == TUNNEL_COMPLETE);
}

bool Curl_connect_ongoing(struct connectdata *conn)
{
  return conn->connect_state &&
    (conn->connect_state->tunnel_state != TUNNEL_COMPLETE);
}

/* when we've sent a CONNECT to a proxy, we should rather either wait for the
   socket to become readable to be able to get the response headers or if
   we're still sending the request, wait for write. */
int Curl_connect_getsock(struct connectdata *conn)
{
  struct HTTP *http;
  DEBUGASSERT(conn);
  DEBUGASSERT(conn->connect_state);
  http = &conn->connect_state->http_proxy;

  if(http->sending)
    return GETSOCK_WRITESOCK(0);

  return GETSOCK_READSOCK(0);
}

static CURLcode connect_init(struct Curl_easy *data, bool reinit)
{
  struct http_connect_state *s;
  struct connectdata *conn = data->conn;
  if(!reinit) {
    CURLcode result;
    DEBUGASSERT(!conn->connect_state);
    /* we might need the upload buffer for streaming a partial request */
    result = Curl_get_upload_buffer(data);
    if(result)
      return result;

    s = calloc(1, sizeof(struct http_connect_state));
    if(!s)
      return CURLE_OUT_OF_MEMORY;
    infof(data, "allocate connect buffer!\n");
    conn->connect_state = s;
    Curl_dyn_init(&s->rcvbuf, DYN_PROXY_CONNECT_HEADERS);

    /* Curl_proxyCONNECT is based on a pointer to a struct HTTP at the
     * member conn->proto.http; we want [protocol] through HTTP and we have
     * to change the member temporarily for connecting to the HTTP
     * proxy. After Curl_proxyCONNECT we have to set back the member to the
     * original pointer
     *
     * This function might be called several times in the multi interface case
     * if the proxy's CONNECT response is not instant.
     */
    s->prot_save = data->req.p.http;
    data->req.p.http = &s->http_proxy;
    connkeep(conn, "HTTP proxy CONNECT");
  }
  else {
    DEBUGASSERT(conn->connect_state);
    s = conn->connect_state;
    Curl_dyn_reset(&s->rcvbuf);
  }
  s->tunnel_state = TUNNEL_INIT;
  s->keepon = KEEPON_CONNECT;
  s->cl = 0;
  s->close_connection = FALSE;
  return CURLE_OK;
}

static void connect_done(struct Curl_easy *data)
{
  struct connectdata *conn = data->conn;
  struct http_connect_state *s = conn->connect_state;
  s->tunnel_state = TUNNEL_COMPLETE;
  Curl_dyn_free(&s->rcvbuf);
  Curl_dyn_free(&s->req);

  /* retore the protocol pointer */
  data->req.p.http = s->prot_save;
  infof(data, "CONNECT phase completed!\n");
}

static CURLcode CONNECT_host(struct Curl_easy *data,
                             struct connectdata *conn,
                             const char *hostname,
                             int remote_port,
                             char **connecthostp,
                             char **hostp)
{
  char *hostheader; /* for CONNECT */
  char *host = NULL; /* Host: */
  bool ipv6_ip = conn->bits.ipv6_ip;

  /* the hostname may be different */
  if(hostname != conn->host.name)
    ipv6_ip = (strchr(hostname, ':') != NULL);
  hostheader = /* host:port with IPv6 support */
    aprintf("%s%s%s:%d", ipv6_ip?"[":"", hostname, ipv6_ip?"]":"",
            remote_port);
  if(!hostheader)
    return CURLE_OUT_OF_MEMORY;

  if(!Curl_checkProxyheaders(data, conn, "Host")) {
    host = aprintf("Host: %s\r\n", hostheader);
    if(!host) {
      free(hostheader);
      return CURLE_OUT_OF_MEMORY;
    }
  }
  *connecthostp = hostheader;
  *hostp = host;
  return CURLE_OK;
}

static CURLcode CONNECT(struct Curl_easy *data,
                        int sockindex,
                        const char *hostname,
                        int remote_port)
#ifndef USE_HYPER
{
  int subversion = 0;
  struct SingleRequest *k = &data->req;
  CURLcode result;
  struct connectdata *conn = data->conn;
  curl_socket_t tunnelsocket = conn->sock[sockindex];
  struct http_connect_state *s = conn->connect_state;
  struct HTTP *http = data->req.p.http;
  char *linep;
  size_t perline;

#define SELECT_OK      0
#define SELECT_ERROR   1

  if(Curl_connect_complete(conn))
    return CURLE_OK; /* CONNECT is already completed */

  conn->bits.proxy_connect_closed = FALSE;

  do {
    timediff_t check;
    if(TUNNEL_INIT == s->tunnel_state) {
      /* BEGIN CONNECT PHASE */
      struct dynbuf *req = &s->req;
      char *hostheader = NULL;
      char *host = NULL;

      infof(data, "Establish HTTP proxy tunnel to %s:%d\n",
            hostname, remote_port);

        /* This only happens if we've looped here due to authentication
           reasons, and we don't really use the newly cloned URL here
           then. Just free() it. */
      free(data->req.newurl);
      data->req.newurl = NULL;

      /* initialize send-buffer */
      Curl_dyn_init(req, DYN_HTTP_REQUEST);

      result = CONNECT_host(data, conn,
                            hostname, remote_port, &hostheader, &host);
      if(result)
        return result;

      /* Setup the proxy-authorization header, if any */
      result = Curl_http_output_auth(data, conn, "CONNECT", HTTPREQ_GET,
                                     hostheader, TRUE);

      if(!result) {
        const char *proxyconn = "";
        const char *useragent = "";
        const char *httpv =
          (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ? "1.0" : "1.1";

        if(!Curl_checkProxyheaders(data, conn, "Proxy-Connection"))
          proxyconn = "Proxy-Connection: Keep-Alive\r\n";

        if(!Curl_checkProxyheaders(data, conn, "User-Agent") &&
           data->set.str[STRING_USERAGENT])
          useragent = data->state.aptr.uagent;

        result =
          Curl_dyn_addf(req,
                        "CONNECT %s HTTP/%s\r\n"
                        "%s"  /* Host: */
                        "%s"  /* Proxy-Authorization */
                        "%s"  /* User-Agent */
                        "%s", /* Proxy-Connection */
                        hostheader,
                        httpv,
                        host?host:"",
                        data->state.aptr.proxyuserpwd?
                        data->state.aptr.proxyuserpwd:"",
                        useragent,
                        proxyconn);

        if(!result)
          result = Curl_add_custom_headers(data, TRUE, req);

        if(!result)
          /* CRLF terminate the request */
          result = Curl_dyn_add(req, "\r\n");

        if(!result) {
          /* Send the connect request to the proxy */
          result = Curl_buffer_send(req, data, &data->info.request_size, 0,
                                    sockindex);
        }
        if(result)
          failf(data, "Failed sending CONNECT to proxy");
      }
      free(host);
      free(hostheader);
      if(result)
        return result;

      s->tunnel_state = TUNNEL_CONNECT;
    } /* END CONNECT PHASE */

    check = Curl_timeleft(data, NULL, TRUE);
    if(check <= 0) {
      failf(data, "Proxy CONNECT aborted due to timeout");
      return CURLE_OPERATION_TIMEDOUT;
    }

    if(!Curl_conn_data_pending(conn, sockindex) && !http->sending)
      /* return so we'll be called again polling-style */
      return CURLE_OK;

    /* at this point, the tunnel_connecting phase is over. */

    if(http->sending == HTTPSEND_REQUEST) {
      if(!s->nsend) {
        size_t fillcount;
        k->upload_fromhere = data->state.ulbuf;
        result = Curl_fillreadbuffer(data, data->set.upload_buffer_size,
                                     &fillcount);
        if(result)
          return result;
        s->nsend = fillcount;
      }
      if(s->nsend) {
        ssize_t bytes_written;
        /* write to socket (send away data) */
        result = Curl_write(data,
                            conn->writesockfd,  /* socket to send to */
                            k->upload_fromhere, /* buffer pointer */
                            s->nsend,           /* buffer size */
                            &bytes_written);    /* actually sent */

        if(!result)
          /* send to debug callback! */
          result = Curl_debug(data, CURLINFO_HEADER_OUT,
                              k->upload_fromhere, bytes_written);

        s->nsend -= bytes_written;
        k->upload_fromhere += bytes_written;
        return result;
      }
      /* if nothing left to send, continue */
    }
    { /* READING RESPONSE PHASE */
      int error = SELECT_OK;

      while(s->keepon) {
        ssize_t gotbytes;
        char byte;

        /* Read one byte at a time to avoid a race condition. Wait at most one
           second before looping to ensure continuous pgrsUpdates. */
        result = Curl_read(data, tunnelsocket, &byte, 1, &gotbytes);
        if(result == CURLE_AGAIN)
          /* socket buffer drained, return */
          return CURLE_OK;

        if(Curl_pgrsUpdate(data))
          return CURLE_ABORTED_BY_CALLBACK;

        if(result) {
          s->keepon = KEEPON_DONE;
          break;
        }
        else if(gotbytes <= 0) {
          if(data->set.proxyauth && data->state.authproxy.avail &&
             data->state.aptr.proxyuserpwd) {
            /* proxy auth was requested and there was proxy auth available,
               then deem this as "mere" proxy disconnect */
            conn->bits.proxy_connect_closed = TRUE;
            infof(data, "Proxy CONNECT connection closed\n");
          }
          else {
            error = SELECT_ERROR;
            failf(data, "Proxy CONNECT aborted");
          }
          s->keepon = KEEPON_DONE;
          break;
        }

        if(s->keepon == KEEPON_IGNORE) {
          /* This means we are currently ignoring a response-body */

          if(s->cl) {
            /* A Content-Length based body: simply count down the counter
               and make sure to break out of the loop when we're done! */
            s->cl--;
            if(s->cl <= 0) {
              s->keepon = KEEPON_DONE;
              s->tunnel_state = TUNNEL_COMPLETE;
              break;
            }
          }
          else {
            /* chunked-encoded body, so we need to do the chunked dance
               properly to know when the end of the body is reached */
            CHUNKcode r;
            CURLcode extra;
            ssize_t tookcareof = 0;

            /* now parse the chunked piece of data so that we can
               properly tell when the stream ends */
            r = Curl_httpchunk_read(data, &byte, 1, &tookcareof, &extra);
            if(r == CHUNKE_STOP) {
              /* we're done reading chunks! */
              infof(data, "chunk reading DONE\n");
              s->keepon = KEEPON_DONE;
              /* we did the full CONNECT treatment, go COMPLETE */
              s->tunnel_state = TUNNEL_COMPLETE;
            }
          }
          continue;
        }

        if(Curl_dyn_addn(&s->rcvbuf, &byte, 1)) {
          failf(data, "CONNECT response too large!");
          return CURLE_RECV_ERROR;
        }

        /* if this is not the end of a header line then continue */
        if(byte != 0x0a)
          continue;

        linep = Curl_dyn_ptr(&s->rcvbuf);
        perline = Curl_dyn_len(&s->rcvbuf); /* amount of bytes in this line */

        /* convert from the network encoding */
        result = Curl_convert_from_network(data, linep, perline);
        /* Curl_convert_from_network calls failf if unsuccessful */
        if(result)
          return result;

        /* output debug if that is requested */
        Curl_debug(data, CURLINFO_HEADER_IN, linep, perline);

        if(!data->set.suppress_connect_headers) {
          /* send the header to the callback */
          int writetype = CLIENTWRITE_HEADER;
          if(data->set.include_header)
            writetype |= CLIENTWRITE_BODY;

          result = Curl_client_write(data, writetype, linep, perline);
          if(result)
            return result;
        }

        data->info.header_size += (long)perline;

        /* Newlines are CRLF, so the CR is ignored as the line isn't
           really terminated until the LF comes. Treat a following CR
           as end-of-headers as well.*/

        if(('\r' == linep[0]) ||
           ('\n' == linep[0])) {
          /* end of response-headers from the proxy */

          if((407 == k->httpcode) && !data->state.authproblem) {
            /* If we get a 407 response code with content length
               when we have no auth problem, we must ignore the
               whole response-body */
            s->keepon = KEEPON_IGNORE;

            if(s->cl) {
              infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
                    " bytes of response-body\n", s->cl);
            }
            else if(s->chunked_encoding) {
              CHUNKcode r;
              CURLcode extra;

              infof(data, "Ignore chunked response-body\n");

              /* We set ignorebody true here since the chunked decoder
                 function will acknowledge that. Pay attention so that this is
                 cleared again when this function returns! */
              k->ignorebody = TRUE;

              if(linep[1] == '\n')
                /* this can only be a LF if the letter at index 0 was a CR */
                linep++;

              /* now parse the chunked piece of data so that we can properly
                 tell when the stream ends */
              r = Curl_httpchunk_read(data, linep + 1, 1, &gotbytes,
                                      &extra);
              if(r == CHUNKE_STOP) {
                /* we're done reading chunks! */
                infof(data, "chunk reading DONE\n");
                s->keepon = KEEPON_DONE;
                /* we did the full CONNECT treatment, go to COMPLETE */
                s->tunnel_state = TUNNEL_COMPLETE;
              }
            }
            else {
              /* without content-length or chunked encoding, we
                 can't keep the connection alive since the close is
                 the end signal so we bail out at once instead */
              s->keepon = KEEPON_DONE;
            }
          }
          else
            s->keepon = KEEPON_DONE;

          if(s->keepon == KEEPON_DONE && !s->cl)
            /* we did the full CONNECT treatment, go to COMPLETE */
            s->tunnel_state = TUNNEL_COMPLETE;

          DEBUGASSERT(s->keepon == KEEPON_IGNORE || s->keepon == KEEPON_DONE);
          continue;
        }

        if((checkprefix("WWW-Authenticate:", linep) &&
            (401 == k->httpcode)) ||
           (checkprefix("Proxy-authenticate:", linep) &&
            (407 == k->httpcode))) {

          bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
          char *auth = Curl_copy_header_value(linep);
          if(!auth)
            return CURLE_OUT_OF_MEMORY;

          result = Curl_http_input_auth(data, proxy, auth);

          free(auth);

          if(result)
            return result;
        }
        else if(checkprefix("Content-Length:", linep)) {
          if(k->httpcode/100 == 2) {
            /* A client MUST ignore any Content-Length or Transfer-Encoding
               header fields received in a successful response to CONNECT.
               "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
            infof(data, "Ignoring Content-Length in CONNECT %03d response\n",
                  k->httpcode);
          }
          else {
            (void)curlx_strtoofft(linep +
                                  strlen("Content-Length:"), NULL, 10, &s->cl);
          }
        }
        else if(Curl_compareheader(linep, "Connection:", "close"))
          s->close_connection = TRUE;
        else if(checkprefix("Transfer-Encoding:", linep)) {
          if(k->httpcode/100 == 2) {
            /* A client MUST ignore any Content-Length or Transfer-Encoding
               header fields received in a successful response to CONNECT.
               "Successful" described as: 2xx (Successful). RFC 7231 4.3.6 */
            infof(data, "Ignoring Transfer-Encoding in "
                  "CONNECT %03d response\n", k->httpcode);
          }
          else if(Curl_compareheader(linep,
                                     "Transfer-Encoding:", "chunked")) {
            infof(data, "CONNECT responded chunked\n");
            s->chunked_encoding = TRUE;
            /* init our chunky engine */
            Curl_httpchunk_init(data);
          }
        }
        else if(Curl_compareheader(linep, "Proxy-Connection:", "close"))
          s->close_connection = TRUE;
        else if(2 == sscanf(linep, "HTTP/1.%d %d",
                            &subversion,
                            &k->httpcode)) {
          /* store the HTTP code from the proxy */
          data->info.httpproxycode = k->httpcode;
        }

        Curl_dyn_reset(&s->rcvbuf);
      } /* while there's buffer left and loop is requested */

      if(Curl_pgrsUpdate(data))
        return CURLE_ABORTED_BY_CALLBACK;

      if(error)
        return CURLE_RECV_ERROR;

      if(data->info.httpproxycode/100 != 2) {
        /* Deal with the possibly already received authenticate
           headers. 'newurl' is set to a new URL if we must loop. */
        result = Curl_http_auth_act(data);
        if(result)
          return result;

        if(conn->bits.close)
          /* the connection has been marked for closure, most likely in the
             Curl_http_auth_act() function and thus we can kill it at once
             below */
          s->close_connection = TRUE;
      }

      if(s->close_connection && data->req.newurl) {
        /* Connection closed by server. Don't use it anymore */
        Curl_closesocket(data, conn, conn->sock[sockindex]);
        conn->sock[sockindex] = CURL_SOCKET_BAD;
        break;
      }
    } /* END READING RESPONSE PHASE */

    /* If we are supposed to continue and request a new URL, which basically
     * means the HTTP authentication is still going on so if the tunnel
     * is complete we start over in INIT state */
    if(data->req.newurl && (TUNNEL_COMPLETE == s->tunnel_state)) {
      connect_init(data, TRUE); /* reinit */
    }

  } while(data->req.newurl);

  if(data->info.httpproxycode/100 != 2) {
    if(s->close_connection && data->req.newurl) {
      conn->bits.proxy_connect_closed = TRUE;
      infof(data, "Connect me again please\n");
      connect_done(data);
    }
    else {
      free(data->req.newurl);
      data->req.newurl = NULL;
      /* failure, close this connection to avoid re-use */
      streamclose(conn, "proxy CONNECT failure");
      Curl_closesocket(data, conn, conn->sock[sockindex]);
      conn->sock[sockindex] = CURL_SOCKET_BAD;
    }

    /* to back to init state */
    s->tunnel_state = TUNNEL_INIT;

    if(conn->bits.proxy_connect_closed)
      /* this is not an error, just part of the connection negotiation */
      return CURLE_OK;
    Curl_dyn_free(&s->rcvbuf);
    failf(data, "Received HTTP code %d from proxy after CONNECT",
          data->req.httpcode);
    return CURLE_RECV_ERROR;
  }

  s->tunnel_state = TUNNEL_COMPLETE;

  /* If a proxy-authorization header was used for the proxy, then we should
     make sure that it isn't accidentally used for the document request
     after we've connected. So let's free and clear it here. */
  Curl_safefree(data->state.aptr.proxyuserpwd);
  data->state.aptr.proxyuserpwd = NULL;

  data->state.authproxy.done = TRUE;
  data->state.authproxy.multipass = FALSE;

  infof(data, "Proxy replied %d to CONNECT request\n",
        data->info.httpproxycode);
  data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
  conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
                                         document request  */
  Curl_dyn_free(&s->rcvbuf);
  return CURLE_OK;
}
#else
/* The Hyper version of CONNECT */
{
  struct connectdata *conn = data->conn;
  struct hyptransfer *h = &data->hyp;
  curl_socket_t tunnelsocket = conn->sock[sockindex];
  struct http_connect_state *s = conn->connect_state;
  CURLcode result = CURLE_OUT_OF_MEMORY;
  hyper_io *io = NULL;
  hyper_request *req = NULL;
  hyper_headers *headers = NULL;
  hyper_clientconn_options *options = NULL;
  hyper_task *handshake = NULL;
  hyper_task *task = NULL; /* for the handshake */
  hyper_task *sendtask = NULL; /* for the send */
  hyper_clientconn *client = NULL;
  hyper_error *hypererr = NULL;
  char *hostheader = NULL; /* for CONNECT */
  char *host = NULL; /* Host: */

  if(Curl_connect_complete(conn))
    return CURLE_OK; /* CONNECT is already completed */

  conn->bits.proxy_connect_closed = FALSE;

  do {
    switch(s->tunnel_state) {
    case TUNNEL_INIT:
      /* BEGIN CONNECT PHASE */
      io = hyper_io_new();
      if(!io) {
        failf(data, "Couldn't create hyper IO");
        goto error;
      }
      /* tell Hyper how to read/write network data */
      hyper_io_set_userdata(io, data);
      hyper_io_set_read(io, Curl_hyper_recv);
      hyper_io_set_write(io, Curl_hyper_send);
      conn->sockfd = tunnelsocket;

      /* create an executor to poll futures */
      if(!h->exec) {
        h->exec = hyper_executor_new();
        if(!h->exec) {
          failf(data, "Couldn't create hyper executor");
          goto error;
        }
      }

      options = hyper_clientconn_options_new();
      if(!options) {
        failf(data, "Couldn't create hyper client options");
        goto error;
      }

      hyper_clientconn_options_exec(options, h->exec);

      /* "Both the `io` and the `options` are consumed in this function
         call" */
      handshake = hyper_clientconn_handshake(io, options);
      if(!handshake) {
        failf(data, "Couldn't create hyper client handshake");
        goto error;
      }
      io = NULL;
      options = NULL;

      if(HYPERE_OK != hyper_executor_push(h->exec, handshake)) {
        failf(data, "Couldn't hyper_executor_push the handshake");
        goto error;
      }
      handshake = NULL; /* ownership passed on */

      task = hyper_executor_poll(h->exec);
      if(!task) {
        failf(data, "Couldn't hyper_executor_poll the handshake");
        goto error;
      }

      client = hyper_task_value(task);
      hyper_task_free(task);
      req = hyper_request_new();
      if(!req) {
        failf(data, "Couldn't hyper_request_new");
        goto error;
      }
      if(hyper_request_set_method(req, (uint8_t *)"CONNECT",
                                  strlen("CONNECT"))) {
        failf(data, "error setting method");
        goto error;
      }

      result = CONNECT_host(data, conn, hostname, remote_port,
                            &hostheader, &host);
      if(result)
        goto error;

      if(hyper_request_set_uri(req, (uint8_t *)hostheader,
                               strlen(hostheader))) {
        failf(data, "error setting path");
        result = CURLE_OUT_OF_MEMORY;
      }
      /* Setup the proxy-authorization header, if any */
      result = Curl_http_output_auth(data, conn, "CONNECT", HTTPREQ_GET,
                                     hostheader, TRUE);
      if(result)
        goto error;
      Curl_safefree(hostheader);

      /* default is 1.1 */
      if((conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) &&
         (HYPERE_OK != hyper_request_set_version(req,
                                                 HYPER_HTTP_VERSION_1_0))) {
        failf(data, "error setting HTTP version");
        goto error;
      }

      headers = hyper_request_headers(req);
      if(!headers) {
        failf(data, "hyper_request_headers");
        goto error;
      }
      if(host && Curl_hyper_header(data, headers, host))
        goto error;
      Curl_safefree(host);

      if(data->state.aptr.proxyuserpwd &&
         Curl_hyper_header(data, headers, data->state.aptr.proxyuserpwd))
        goto error;

      if(data->set.str[STRING_USERAGENT] &&
         *data->set.str[STRING_USERAGENT] &&
         data->state.aptr.uagent &&
         Curl_hyper_header(data, headers, data->state.aptr.uagent))
        goto error;

      if(!Curl_checkProxyheaders(data, conn, "Proxy-Connection") &&
         Curl_hyper_header(data, headers, "Proxy-Connection: Keep-Alive"))
        goto error;

      sendtask = hyper_clientconn_send(client, req);
      if(!sendtask) {
        failf(data, "hyper_clientconn_send");
        goto error;
      }

      if(HYPERE_OK != hyper_executor_push(h->exec, sendtask)) {
        failf(data, "Couldn't hyper_executor_push the send");
        goto error;
      }

      hyper_clientconn_free(client);

      do {
        task = hyper_executor_poll(h->exec);
        if(task) {
          bool error = hyper_task_type(task) == HYPER_TASK_ERROR;
          if(error)
            hypererr = hyper_task_value(task);
          hyper_task_free(task);
          if(error)
            goto error;
        }
      } while(task);
      s->tunnel_state = TUNNEL_CONNECT;
      /* FALLTHROUGH */
    case TUNNEL_CONNECT: {
      int didwhat;
      bool done = FALSE;
      result = Curl_hyper_stream(data, conn, &didwhat, &done,
                                 CURL_CSELECT_IN | CURL_CSELECT_OUT);
      if(result)
        goto error;
      if(!done)
        break;
      fprintf(stderr, "done\n");
      s->tunnel_state = TUNNEL_COMPLETE;
      if(h->exec) {
        hyper_executor_free(h->exec);
        h->exec = NULL;
      }
      if(h->read_waker) {
        hyper_waker_free(h->read_waker);
        h->read_waker = NULL;
      }
      if(h->write_waker) {
        hyper_waker_free(h->write_waker);
        h->write_waker = NULL;
      }
    }
      /* FALLTHROUGH */
    default:
      break;
    }
  } while(data->req.newurl);

  result = CURLE_OK;
  error:
  free(host);
  free(hostheader);
  if(io)
    hyper_io_free(io);

  if(options)
    hyper_clientconn_options_free(options);

  if(handshake)
    hyper_task_free(handshake);

  if(hypererr) {
    uint8_t errbuf[256];
    size_t errlen = hyper_error_print(hypererr, errbuf, sizeof(errbuf));
    failf(data, "Hyper: %.*s", (int)errlen, errbuf);
    hyper_error_free(hypererr);
  }
  return result;
}

#endif

void Curl_connect_free(struct Curl_easy *data)
{
  struct connectdata *conn = data->conn;
  struct http_connect_state *s = conn->connect_state;
  if(s) {
    free(s);
    conn->connect_state = NULL;
  }
}

/*
 * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This
 * function will issue the necessary commands to get a seamless tunnel through
 * this proxy. After that, the socket can be used just as a normal socket.
 */

CURLcode Curl_proxyCONNECT(struct Curl_easy *data,
                           int sockindex,
                           const char *hostname,
                           int remote_port)
{
  CURLcode result;
  struct connectdata *conn = data->conn;
  if(!conn->connect_state) {
    result = connect_init(data, FALSE);
    if(result)
      return result;
  }
  result = CONNECT(data, sockindex, hostname, remote_port);

  if(result || Curl_connect_complete(conn))
    connect_done(data);

  return result;
}

#else
void Curl_connect_free(struct Curl_easy *data)
{
  (void)data;
}

#endif /* CURL_DISABLE_PROXY */
