async_simple::coro::Lazy connect()

in include/ylt/standalone/cinatra/coro_http_client.hpp [2008:2094]


  async_simple::coro::Lazy<resp_data> connect(
      const uri_t &u, std::vector<asio::ip::tcp::endpoint> *eps = nullptr) {
    std::vector<asio::ip::tcp::endpoint> eps_tmp;
    if (eps == nullptr) {
      eps = &eps_tmp;
    }
    if (socket_->has_closed_) {
      socket_->is_timeout_ = false;
      host_ = proxy_host_.empty() ? u.get_host() : proxy_host_;
      port_ = proxy_port_.empty() ? u.get_port() : proxy_port_;
      if (eps->empty()) {
        CINATRA_LOG_TRACE << "start resolve host: " << host_ << ":" << port_;
        auto [ec, iter] = co_await coro_io::async_resolve(
            &executor_wrapper_, socket_->impl_, host_, port_);
        if (ec) {
          co_return resp_data{ec, 404};
        }
        else {
          asio::ip::tcp::resolver::iterator end;
          while (iter != end) {
            eps->push_back(iter->endpoint());
            ++iter;
          }
          if (eps->empty()) [[unlikely]] {
            co_return resp_data{std::make_error_code(std::errc::not_connected),
                                404};
          }
        }
      }
      CINATRA_LOG_TRACE
          << "start connect to endpoint lists. total endpoint count:"
          << eps->size()
          << ", the first endpoint is: " << (*eps)[0].address().to_string()
          << ":" << std::to_string((*eps)[0].port());
      std::error_code ec;
      asio::ip::tcp::endpoint endpoint;
      if (std::tie(ec, endpoint) = co_await coro_io::async_connect(
              &executor_wrapper_, socket_->impl_, *eps);
          ec) {
        co_return resp_data{ec, 404};
      }
#ifdef INJECT_FOR_HTTP_CLIENT_TEST
      if (connect_timeout_forever_) {
        socket_->is_timeout_ = true;
      }
#endif
      if (socket_->is_timeout_) {
        ec = std::make_error_code(std::errc::timed_out);
        co_return resp_data{ec, 404};
      }

      if (enable_tcp_no_delay_) {
        socket_->impl_.set_option(asio::ip::tcp::no_delay(true), ec);
        if (ec) {
          co_return resp_data{ec, 404};
        }
      }

      if (u.is_ssl) {
#ifdef CINATRA_ENABLE_SSL
        if (!has_init_ssl_) {
          size_t pos = u.host.find("www.");
          std::string host;
          if (pos != std::string_view::npos) {
            host = std::string{u.host.substr(pos + 4)};
          }
          else {
            host = std::string{u.host};
          }
          bool r = init_ssl(asio::ssl::verify_none, "", host);
          if (!r) {
            co_return resp_data{
                std::make_error_code(std::errc::invalid_argument), 404};
          }
        }
#endif
        if (ec = co_await handle_shake(); ec) {
          co_return resp_data{ec, 404};
        }
      }
      socket_->has_closed_ = false;
      CINATRA_LOG_TRACE << "connect to endpoint: "
                        << endpoint.address().to_string() << ":"
                        << std::to_string(endpoint.port()) << " successfully";
    }
    co_return resp_data{};
  }