/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 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.
 *
 * SPDX-License-Identifier: curl
 *
 ***************************************************************************/

#include "curl_setup.h"

#ifndef CURL_DISABLE_HTTP

#include "urldata.h"
#include <curl/curl.h>
#include "curl_trc.h"
#include "cfilters.h"
#include "connect.h"
#include "hostip.h"
#include "multiif.h"
#include "cf-https-connect.h"
#include "http2.h"
#include "select.h"
#include "vquic/vquic.h"

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

typedef enum {
  CF_HC_INIT,
  CF_HC_CONNECT,
  CF_HC_SUCCESS,
  CF_HC_FAILURE
} cf_hc_state;

struct cf_hc_baller {
  const char *name;
  struct Curl_cfilter *cf;
  CURLcode result;
  struct curltime started;
  int reply_ms;
  unsigned char transport;
  enum alpnid alpn_id;
  BIT(shutdown);
};

static void cf_hc_baller_reset(struct cf_hc_baller *b,
                               struct Curl_easy *data)
{
  if(b->cf) {
    Curl_conn_cf_close(b->cf, data);
    Curl_conn_cf_discard_chain(&b->cf, data);
    b->cf = NULL;
  }
  b->result = CURLE_OK;
  b->reply_ms = -1;
}

static bool cf_hc_baller_is_active(struct cf_hc_baller *b)
{
  return b->cf && !b->result;
}

static bool cf_hc_baller_has_started(struct cf_hc_baller *b)
{
  return !!b->cf;
}

static int cf_hc_baller_reply_ms(struct cf_hc_baller *b,
                                 struct Curl_easy *data)
{
  if(b->cf && (b->reply_ms < 0))
    b->cf->cft->query(b->cf, data, CF_QUERY_CONNECT_REPLY_MS,
                      &b->reply_ms, NULL);
  return b->reply_ms;
}

static bool cf_hc_baller_data_pending(struct cf_hc_baller *b,
                                      const struct Curl_easy *data)
{
  return b->cf && !b->result && b->cf->cft->has_data_pending(b->cf, data);
}

static bool cf_hc_baller_needs_flush(struct cf_hc_baller *b,
                                     struct Curl_easy *data)
{
  return b->cf && !b->result && Curl_conn_cf_needs_flush(b->cf, data);
}

static CURLcode cf_hc_baller_cntrl(struct cf_hc_baller *b,
                                   struct Curl_easy *data,
                                   int event, int arg1, void *arg2)
{
  if(b->cf && !b->result)
    return Curl_conn_cf_cntrl(b->cf, data, FALSE, event, arg1, arg2);
  return CURLE_OK;
}

struct cf_hc_ctx {
  cf_hc_state state;
  struct curltime started;  /* when connect started */
  CURLcode result;          /* overall result */
  struct cf_hc_baller ballers[2];
  size_t baller_count;
  timediff_t soft_eyeballs_timeout_ms;
  timediff_t hard_eyeballs_timeout_ms;
};

static void cf_hc_baller_assign(struct cf_hc_baller *b,
                                enum alpnid alpn_id,
                                unsigned char def_transport)
{
  b->alpn_id = alpn_id;
  b->transport = def_transport;
  switch(b->alpn_id) {
  case ALPN_h3:
    b->name = "h3";
    b->transport = TRNSPRT_QUIC;
    break;
  case ALPN_h2:
    b->name = "h2";
    break;
  case ALPN_h1:
    b->name = "h1";
    break;
  default:
    b->result = CURLE_FAILED_INIT;
    break;
  }
}

static void cf_hc_baller_init(struct cf_hc_baller *b,
                              struct Curl_cfilter *cf,
                              struct Curl_easy *data,
                              int transport)
{
  struct Curl_cfilter *save = cf->next;

  cf->next = NULL;
  b->started = curlx_now();
  switch(b->alpn_id) {
  case ALPN_h3:
    transport = TRNSPRT_QUIC;
    break;
  default:
    break;
  }

  if(!b->result)
    b->result = Curl_cf_setup_insert_after(cf, data, transport,
                                           CURL_CF_SSL_ENABLE);
  b->cf = cf->next;
  cf->next = save;
}

static CURLcode cf_hc_baller_connect(struct cf_hc_baller *b,
                                     struct Curl_cfilter *cf,
                                     struct Curl_easy *data,
                                     bool *done)
{
  struct Curl_cfilter *save = cf->next;

  cf->next = b->cf;
  b->result = Curl_conn_cf_connect(cf->next, data, done);
  b->cf = cf->next; /* it might mutate */
  cf->next = save;
  return b->result;
}

static void cf_hc_reset(struct Curl_cfilter *cf, struct Curl_easy *data)
{
  struct cf_hc_ctx *ctx = cf->ctx;
  size_t i;

  if(ctx) {
    for(i = 0; i < ctx->baller_count; ++i)
      cf_hc_baller_reset(&ctx->ballers[i], data);
    ctx->state = CF_HC_INIT;
    ctx->result = CURLE_OK;
    ctx->hard_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout;
    ctx->soft_eyeballs_timeout_ms = data->set.happy_eyeballs_timeout / 4;
  }
}

static CURLcode baller_connected(struct Curl_cfilter *cf,
                                 struct Curl_easy *data,
                                 struct cf_hc_baller *winner)
{
  struct cf_hc_ctx *ctx = cf->ctx;
  CURLcode result = CURLE_OK;
  int reply_ms;
  size_t i;

  DEBUGASSERT(winner->cf);
  for(i = 0; i < ctx->baller_count; ++i)
    if(winner != &ctx->ballers[i])
      cf_hc_baller_reset(&ctx->ballers[i], data);

  reply_ms = cf_hc_baller_reply_ms(winner, data);
  if(reply_ms >= 0)
    CURL_TRC_CF(data, cf, "connect+handshake %s: %dms, 1st data: %dms",
                winner->name, (int)curlx_timediff(curlx_now(),
                                                  winner->started), reply_ms);
  else
    CURL_TRC_CF(data, cf, "deferred handshake %s: %dms",
                winner->name, (int)curlx_timediff(curlx_now(),
                                                  winner->started));

  /* install the winning filter below this one. */
  cf->next = winner->cf;
  winner->cf = NULL;

#ifdef USE_NGHTTP2
  {
    /* Using nghttp2, we add the filter "below" us, so when the conn
     * closes, we tear it down for a fresh reconnect */
    const char *alpn = Curl_conn_cf_get_alpn_negotiated(cf->next, data);
    if(alpn && !strcmp("h2", alpn)) {
      result = Curl_http2_switch_at(cf, data);
      if(result) {
        ctx->state = CF_HC_FAILURE;
        ctx->result = result;
        return result;
      }
    }
  }
#endif

  ctx->state = CF_HC_SUCCESS;
  cf->connected = TRUE;
  return result;
}


static bool time_to_start_next(struct Curl_cfilter *cf,
                               struct Curl_easy *data,
                               size_t idx, struct curltime now)
{
  struct cf_hc_ctx *ctx = cf->ctx;
  timediff_t elapsed_ms;
  size_t i;

  if(idx >= ctx->baller_count)
    return FALSE;
  if(cf_hc_baller_has_started(&ctx->ballers[idx]))
    return FALSE;
  for(i = 0; i < idx; i++) {
    if(!ctx->ballers[i].result)
      break;
  }
  if(i == idx) {
    CURL_TRC_CF(data, cf, "all previous attempts failed, starting %s",
                ctx->ballers[idx].name);
    return TRUE;
  }
  elapsed_ms = curlx_timediff(now, ctx->started);
  if(elapsed_ms >= ctx->hard_eyeballs_timeout_ms) {
    CURL_TRC_CF(data, cf, "hard timeout of %" FMT_TIMEDIFF_T "ms reached, "
                "starting %s",
                ctx->hard_eyeballs_timeout_ms, ctx->ballers[idx].name);
    return TRUE;
  }

  if((idx > 0) && (elapsed_ms >= ctx->soft_eyeballs_timeout_ms)) {
    if(cf_hc_baller_reply_ms(&ctx->ballers[idx - 1], data) < 0) {
      CURL_TRC_CF(data, cf, "soft timeout of %" FMT_TIMEDIFF_T "ms reached, "
                  "%s has not seen any data, starting %s",
                  ctx->soft_eyeballs_timeout_ms,
                  ctx->ballers[idx - 1].name, ctx->ballers[idx].name);
      return TRUE;
    }
    /* set the effective hard timeout again */
    Curl_expire(data, ctx->hard_eyeballs_timeout_ms - elapsed_ms,
                EXPIRE_ALPN_EYEBALLS);
  }
  return FALSE;
}

static CURLcode cf_hc_connect(struct Curl_cfilter *cf,
                              struct Curl_easy *data,
                              bool *done)
{
  struct cf_hc_ctx *ctx = cf->ctx;
  struct curltime now;
  CURLcode result = CURLE_OK;
  size_t i, failed_ballers;

  if(cf->connected) {
    *done = TRUE;
    return CURLE_OK;
  }

  *done = FALSE;
  now = curlx_now();
  switch(ctx->state) {
  case CF_HC_INIT:
    DEBUGASSERT(!cf->next);
    for(i = 0; i < ctx->baller_count; i++)
      DEBUGASSERT(!ctx->ballers[i].cf);
    CURL_TRC_CF(data, cf, "connect, init");
    ctx->started = now;
    cf_hc_baller_init(&ctx->ballers[0], cf, data, ctx->ballers[0].transport);
    if(ctx->baller_count > 1) {
      Curl_expire(data, ctx->soft_eyeballs_timeout_ms, EXPIRE_ALPN_EYEBALLS);
      CURL_TRC_CF(data, cf, "set next attempt to start in %" FMT_TIMEDIFF_T
                  "ms", ctx->soft_eyeballs_timeout_ms);
    }
    ctx->state = CF_HC_CONNECT;
    FALLTHROUGH();

  case CF_HC_CONNECT:
    if(cf_hc_baller_is_active(&ctx->ballers[0])) {
      result = cf_hc_baller_connect(&ctx->ballers[0], cf, data, done);
      if(!result && *done) {
        result = baller_connected(cf, data, &ctx->ballers[0]);
        goto out;
      }
    }

    if(time_to_start_next(cf, data, 1, now)) {
      cf_hc_baller_init(&ctx->ballers[1], cf, data, ctx->ballers[1].transport);
    }

    if((ctx->baller_count > 1) && cf_hc_baller_is_active(&ctx->ballers[1])) {
      CURL_TRC_CF(data, cf, "connect, check %s", ctx->ballers[1].name);
      result = cf_hc_baller_connect(&ctx->ballers[1], cf, data, done);
      if(!result && *done) {
        result = baller_connected(cf, data, &ctx->ballers[1]);
        goto out;
      }
    }

    failed_ballers = 0;
    for(i = 0; i < ctx->baller_count; i++) {
      if(ctx->ballers[i].result)
        ++failed_ballers;
    }

    if(failed_ballers == ctx->baller_count) {
      /* all have failed. we give up */
      CURL_TRC_CF(data, cf, "connect, all attempts failed");
      for(i = 0; i < ctx->baller_count; i++) {
        if(ctx->ballers[i].result) {
          result = ctx->ballers[i].result;
          break;
        }
      }
      ctx->state = CF_HC_FAILURE;
      goto out;
    }
    result = CURLE_OK;
    *done = FALSE;
    break;

  case CF_HC_FAILURE:
    result = ctx->result;
    cf->connected = FALSE;
    *done = FALSE;
    break;

  case CF_HC_SUCCESS:
    result = CURLE_OK;
    cf->connected = TRUE;
    *done = TRUE;
    break;
  }

out:
  CURL_TRC_CF(data, cf, "connect -> %d, done=%d", result, *done);
  return result;
}

static CURLcode cf_hc_shutdown(struct Curl_cfilter *cf,
                               struct Curl_easy *data, bool *done)
{
  struct cf_hc_ctx *ctx = cf->ctx;
  size_t i;
  CURLcode result = CURLE_OK;

  DEBUGASSERT(data);
  if(cf->connected) {
    *done = TRUE;
    return CURLE_OK;
  }

  /* shutdown all ballers that have not done so already. If one fails,
   * continue shutting down others until all are shutdown. */
  for(i = 0; i < ctx->baller_count; i++) {
    struct cf_hc_baller *b = &ctx->ballers[i];
    bool bdone = FALSE;
    if(!cf_hc_baller_is_active(b) || b->shutdown)
      continue;
    b->result = b->cf->cft->do_shutdown(b->cf, data, &bdone);
    if(b->result || bdone)
      b->shutdown = TRUE; /* treat a failed shutdown as done */
  }

  *done = TRUE;
  for(i = 0; i < ctx->baller_count; i++) {
    if(!ctx->ballers[i].shutdown)
      *done = FALSE;
  }
  if(*done) {
    for(i = 0; i < ctx->baller_count; i++) {
      if(ctx->ballers[i].result)
        result = ctx->ballers[i].result;
    }
  }
  CURL_TRC_CF(data, cf, "shutdown -> %d, done=%d", result, *done);
  return result;
}

static CURLcode cf_hc_adjust_pollset(struct Curl_cfilter *cf,
                                     struct Curl_easy *data,
                                     struct easy_pollset *ps)
{
  CURLcode result = CURLE_OK;
  if(!cf->connected) {
    struct cf_hc_ctx *ctx = cf->ctx;
    size_t i;

    for(i = 0; (i < ctx->baller_count) && !result; i++) {
      struct cf_hc_baller *b = &ctx->ballers[i];
      if(!cf_hc_baller_is_active(b))
        continue;
      result = Curl_conn_cf_adjust_pollset(b->cf, data, ps);
    }
    CURL_TRC_CF(data, cf, "adjust_pollset -> %d, %d socks", result, ps->n);
  }
  return result;
}

static bool cf_hc_data_pending(struct Curl_cfilter *cf,
                               const struct Curl_easy *data)
{
  struct cf_hc_ctx *ctx = cf->ctx;
  size_t i;

  if(cf->connected)
    return cf->next->cft->has_data_pending(cf->next, data);

  for(i = 0; i < ctx->baller_count; i++)
    if(cf_hc_baller_data_pending(&ctx->ballers[i], data))
      return TRUE;
  return FALSE;
}

static struct curltime cf_get_max_baller_time(struct Curl_cfilter *cf,
                                              struct Curl_easy *data,
                                              int query)
{
  struct cf_hc_ctx *ctx = cf->ctx;
  struct curltime t, tmax;
  size_t i;

  memset(&tmax, 0, sizeof(tmax));
  for(i = 0; i < ctx->baller_count; i++) {
    struct Curl_cfilter *cfb = ctx->ballers[i].cf;
    memset(&t, 0, sizeof(t));
    if(cfb && !cfb->cft->query(cfb, data, query, NULL, &t)) {
      if((t.tv_sec || t.tv_usec) && curlx_timediff_us(t, tmax) > 0)
        tmax = t;
    }
  }
  return tmax;
}

static CURLcode cf_hc_query(struct Curl_cfilter *cf,
                            struct Curl_easy *data,
                            int query, int *pres1, void *pres2)
{
  struct cf_hc_ctx *ctx = cf->ctx;
  size_t i;

  if(!cf->connected) {
    switch(query) {
    case CF_QUERY_TIMER_CONNECT: {
      struct curltime *when = pres2;
      *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_CONNECT);
      return CURLE_OK;
    }
    case CF_QUERY_TIMER_APPCONNECT: {
      struct curltime *when = pres2;
      *when = cf_get_max_baller_time(cf, data, CF_QUERY_TIMER_APPCONNECT);
      return CURLE_OK;
    }
    case CF_QUERY_NEED_FLUSH: {
      for(i = 0; i < ctx->baller_count; i++)
        if(cf_hc_baller_needs_flush(&ctx->ballers[i], data)) {
          *pres1 = TRUE;
          return CURLE_OK;
        }
      break;
    }
    default:
      break;
    }
  }
  return cf->next ?
    cf->next->cft->query(cf->next, data, query, pres1, pres2) :
    CURLE_UNKNOWN_OPTION;
}

static CURLcode cf_hc_cntrl(struct Curl_cfilter *cf,
                            struct Curl_easy *data,
                            int event, int arg1, void *arg2)
{
  struct cf_hc_ctx *ctx = cf->ctx;
  CURLcode result = CURLE_OK;
  size_t i;

  if(!cf->connected) {
    for(i = 0; i < ctx->baller_count; i++) {
      result = cf_hc_baller_cntrl(&ctx->ballers[i], data, event, arg1, arg2);
      if(result && (result != CURLE_AGAIN))
        goto out;
    }
    result = CURLE_OK;
  }
out:
  return result;
}

static void cf_hc_close(struct Curl_cfilter *cf, struct Curl_easy *data)
{
  CURL_TRC_CF(data, cf, "close");
  cf_hc_reset(cf, data);
  cf->connected = FALSE;

  if(cf->next) {
    cf->next->cft->do_close(cf->next, data);
    Curl_conn_cf_discard_chain(&cf->next, data);
  }
}

static void cf_hc_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
{
  struct cf_hc_ctx *ctx = cf->ctx;

  (void)data;
  CURL_TRC_CF(data, cf, "destroy");
  cf_hc_reset(cf, data);
  Curl_safefree(ctx);
}

struct Curl_cftype Curl_cft_http_connect = {
  "HTTPS-CONNECT",
  0,
  CURL_LOG_LVL_NONE,
  cf_hc_destroy,
  cf_hc_connect,
  cf_hc_close,
  cf_hc_shutdown,
  cf_hc_adjust_pollset,
  cf_hc_data_pending,
  Curl_cf_def_send,
  Curl_cf_def_recv,
  cf_hc_cntrl,
  Curl_cf_def_conn_is_alive,
  Curl_cf_def_conn_keep_alive,
  cf_hc_query,
};

static CURLcode cf_hc_create(struct Curl_cfilter **pcf,
                             struct Curl_easy *data,
                             enum alpnid *alpnids, size_t alpn_count,
                             unsigned char def_transport)
{
  struct Curl_cfilter *cf = NULL;
  struct cf_hc_ctx *ctx;
  CURLcode result = CURLE_OK;
  size_t i;

  DEBUGASSERT(alpnids);
  DEBUGASSERT(alpn_count);
  DEBUGASSERT(alpn_count <= CURL_ARRAYSIZE(ctx->ballers));
  if(!alpn_count || (alpn_count > CURL_ARRAYSIZE(ctx->ballers))) {
    failf(data, "https-connect filter create with unsupported %zu ALPN ids",
          alpn_count);
    return CURLE_FAILED_INIT;
  }

  ctx = calloc(1, sizeof(*ctx));
  if(!ctx) {
    result = CURLE_OUT_OF_MEMORY;
    goto out;
  }
  for(i = 0; i < alpn_count; ++i)
    cf_hc_baller_assign(&ctx->ballers[i], alpnids[i], def_transport);
  for(; i < CURL_ARRAYSIZE(ctx->ballers); ++i)
    ctx->ballers[i].alpn_id = ALPN_none;
  ctx->baller_count = alpn_count;

  result = Curl_cf_create(&cf, &Curl_cft_http_connect, ctx);
  if(result)
    goto out;
  ctx = NULL;
  cf_hc_reset(cf, data);

out:
  *pcf = result ? NULL : cf;
  free(ctx);
  return result;
}

static CURLcode cf_http_connect_add(struct Curl_easy *data,
                                    struct connectdata *conn,
                                    int sockindex,
                                    enum alpnid *alpn_ids, size_t alpn_count,
                                    unsigned char def_transport)
{
  struct Curl_cfilter *cf;
  CURLcode result = CURLE_OK;

  DEBUGASSERT(data);
  result = cf_hc_create(&cf, data, alpn_ids, alpn_count, def_transport);
  if(result)
    goto out;
  Curl_conn_cf_add(data, conn, sockindex, cf);
out:
  return result;
}

static bool cf_https_alpns_contain(enum alpnid id,
                                   enum alpnid *list, size_t len)
{
  size_t i;
  for(i = 0; i < len; ++i) {
    if(id == list[i])
      return TRUE;
  }
  return FALSE;
}

CURLcode Curl_cf_https_setup(struct Curl_easy *data,
                             struct connectdata *conn,
                             int sockindex)
{
  enum alpnid alpn_ids[2];
  size_t alpn_count = 0;
  CURLcode result = CURLE_OK;
  struct Curl_cfilter cf_fake, *cf = NULL;

  (void)sockindex;
  /* we want to log for the filter before we create it, fake it. */
  memset(&cf_fake, 0, sizeof(cf_fake));
  cf_fake.cft = &Curl_cft_http_connect;
  cf = &cf_fake;

  if(conn->bits.tls_enable_alpn) {
#ifdef USE_HTTPSRR
    /* Is there an HTTPSRR use its ALPNs here.
     * We are here after having selected a connection to a host+port and
     * can no longer change that. Any HTTPSRR advice for other hosts and ports
     * we need to ignore. */
    struct Curl_dns_entry *dns = data->state.dns[sockindex];
    struct Curl_https_rrinfo *rr = dns ? dns->hinfo : NULL;
    if(rr && !rr->no_def_alpn &&  /* ALPNs are defaults */
       (!rr->target ||      /* for same host */
        !rr->target[0] ||
        (rr->target[0] == '.' &&
         !rr->target[1])) &&
       (rr->port < 0 ||    /* for same port */
        rr->port == conn->remote_port)) {
      size_t i;
      for(i = 0; i < CURL_ARRAYSIZE(rr->alpns) &&
                 alpn_count < CURL_ARRAYSIZE(alpn_ids); ++i) {
        enum alpnid alpn = rr->alpns[i];
        if(cf_https_alpns_contain(alpn, alpn_ids, alpn_count))
          continue;
        switch(alpn) {
        case ALPN_h3:
          if(Curl_conn_may_http3(data, conn, conn->transport_wanted))
            break;  /* not possible */
          if(data->state.http_neg.allowed & CURL_HTTP_V3x) {
            CURL_TRC_CF(data, cf, "adding h3 via HTTPS-RR");
            alpn_ids[alpn_count++] = alpn;
          }
          break;
        case ALPN_h2:
          if(data->state.http_neg.allowed & CURL_HTTP_V2x) {
            CURL_TRC_CF(data, cf, "adding h2 via HTTPS-RR");
            alpn_ids[alpn_count++] = alpn;
          }
          break;
        case ALPN_h1:
          if(data->state.http_neg.allowed & CURL_HTTP_V1x) {
            CURL_TRC_CF(data, cf, "adding h1 via HTTPS-RR");
            alpn_ids[alpn_count++] = alpn;
          }
          break;
        default: /* ignore */
          break;
        }
      }
    }
#endif

    if((alpn_count < CURL_ARRAYSIZE(alpn_ids)) &&
       (data->state.http_neg.wanted & CURL_HTTP_V3x) &&
       !cf_https_alpns_contain(ALPN_h3, alpn_ids, alpn_count)) {
      result = Curl_conn_may_http3(data, conn, conn->transport_wanted);
      if(!result) {
        CURL_TRC_CF(data, cf, "adding wanted h3");
        alpn_ids[alpn_count++] = ALPN_h3;
      }
      else if(data->state.http_neg.wanted == CURL_HTTP_V3x)
        goto out; /* only h3 allowed, not possible, error out */
    }
    if((alpn_count < CURL_ARRAYSIZE(alpn_ids)) &&
       (data->state.http_neg.wanted & CURL_HTTP_V2x) &&
       !cf_https_alpns_contain(ALPN_h2, alpn_ids, alpn_count)) {
      CURL_TRC_CF(data, cf, "adding wanted h2");
      alpn_ids[alpn_count++] = ALPN_h2;
    }
    else if((alpn_count < CURL_ARRAYSIZE(alpn_ids)) &&
            (data->state.http_neg.wanted & CURL_HTTP_V1x) &&
            !cf_https_alpns_contain(ALPN_h1, alpn_ids, alpn_count)) {
      CURL_TRC_CF(data, cf, "adding wanted h1");
      alpn_ids[alpn_count++] = ALPN_h1;
    }
  }

  /* If we identified ALPNs to use, install our filter. Otherwise,
   * install nothing, so our call will use a default connect setup. */
  if(alpn_count) {
    result = cf_http_connect_add(data, conn, sockindex,
                                 alpn_ids, alpn_count,
                                 conn->transport_wanted);
  }

out:
  return result;
}

#endif /* !CURL_DISABLE_HTTP */
