Skip to content

Commit

Permalink
support request with path
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos committed Jul 15, 2023
1 parent 4fc25af commit f2718e9
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 74 deletions.
90 changes: 61 additions & 29 deletions include/ylt/thirdparty/cinatra/coro_http_client.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
#pragma once
#include <async_simple/Future.h>
#include <async_simple/Unit.h>
#include <async_simple/coro/FutureAwaiter.h>
#include <async_simple/coro/Lazy.h>

#include <asio/dispatch.hpp>
#include <asio/streambuf.hpp>
#include <atomic>
#include <cassert>
#include <charconv>
Expand All @@ -19,14 +12,21 @@
#include <thread>
#include <unordered_map>
#include <utility>
#include <ylt/coro_io/coro_file.hpp>
#include <ylt/coro_io/coro_io.hpp>
#include <ylt/coro_io/io_context_pool.hpp>

#include "asio/dispatch.hpp"
#include "asio/error.hpp"
#include "asio/streambuf.hpp"
#include "async_simple/Future.h"
#include "async_simple/Unit.h"
#include "async_simple/coro/FutureAwaiter.h"
#include "async_simple/coro/Lazy.h"
#include "http_parser.hpp"
#include "response_cv.hpp"
#include "uri.hpp"
#include "websocket.hpp"
#include "ylt/coro_io/coro_file.hpp"
#include "ylt/coro_io/coro_io.hpp"
#include "ylt/coro_io/io_context_pool.hpp"

namespace coro_io {
template <typename T, typename U>
Expand Down Expand Up @@ -236,10 +236,9 @@ class coro_http_client {
}

#ifdef CINATRA_ENABLE_SSL
[[nodiscard]] bool init_ssl(const std::string &base_path,
const std::string &cert_file,
int verify_mode = asio::ssl::verify_none,
const std::string &domain = "localhost") {
bool init_ssl(const std::string &base_path, const std::string &cert_file,
int verify_mode = asio::ssl::verify_none,
const std::string &domain = "localhost") {
try {
ssl_init_ret_ = false;
auto full_cert_file = std::filesystem::path(base_path).append(cert_file);
Expand All @@ -260,6 +259,11 @@ class coro_http_client {
ssl_stream_ =
std::make_unique<asio::ssl::stream<asio::ip::tcp::socket &>>(
socket_->impl_, ssl_ctx_);
// Set SNI Hostname (many hosts need this to handshake successfully)
if (!sni_hostname_.empty()) {
SSL_set_tlsext_host_name(ssl_stream_->native_handle(),
sni_hostname_.c_str());
}
use_ssl_ = true;
ssl_init_ret_ = true;
} catch (std::exception &e) {
Expand Down Expand Up @@ -296,7 +300,13 @@ class coro_http_client {
// only make socket connet(or handshake) to the host
async_simple::coro::Lazy<resp_data> connect(std::string uri) {
resp_data data{};
auto [ok, u] = handle_uri(data, uri);
bool no_schema = !has_schema(uri);
std::string append_uri;
if (no_schema) {
append_uri.append("http://").append(uri);
}

auto [ok, u] = handle_uri(data, no_schema ? append_uri : uri);
if (!ok) {
co_return resp_data{{}, 404};
}
Expand Down Expand Up @@ -784,7 +794,6 @@ class coro_http_client {

std::string header_str =
build_request_header(u, method, ctx, true, std::move(headers));
std::cout << header_str;

std::error_code ec{};
size_t size = 0;
Expand Down Expand Up @@ -850,17 +859,21 @@ class coro_http_client {
bool is_keep_alive = true;

do {
bool no_schema = !has_schema(uri);
uri_t u;
std::string append_uri;
if (no_schema) {
append_uri.append("http://").append(uri);
}
auto [ok, u] = handle_uri(data, no_schema ? append_uri : uri);
if (!ok) {
break;
}

if (socket_->has_closed_) {
if (socket_->has_closed_ || (!uri.empty() && uri[0] != '/')) {
bool no_schema = !has_schema(uri);

if (no_schema) {
append_uri.append("http://").append(uri);
}
bool ok = false;
std::tie(ok, u) = handle_uri(data, no_schema ? append_uri : uri);
if (!ok) {
break;
}

auto conn_future = start_timer(conn_timeout_duration_, "connect timer");
std::string host = proxy_host_.empty() ? u.get_host() : proxy_host_;
std::string port = proxy_port_.empty() ? u.get_port() : proxy_port_;
Expand All @@ -870,6 +883,8 @@ class coro_http_client {
break;
}

socket_->impl_.set_option(asio::ip::tcp::no_delay(true));

if (u.is_ssl) {
if (ec = co_await handle_shake(); ec) {
break;
Expand All @@ -880,6 +895,9 @@ class coro_http_client {
break;
}
}
else {
u.path = uri;
}

std::vector<asio::const_buffer> vec;
std::string req_head_str =
Expand Down Expand Up @@ -981,6 +999,10 @@ class coro_http_client {
req_timeout_duration_ = timeout_duration;
}

#ifdef CINATRA_ENABLE_SSL
void set_sni_hostname(const std::string &host) { sni_hostname_ = host; }
#endif

template <typename T, typename U>
friend class coro_io::client_pool;

Expand Down Expand Up @@ -1369,6 +1391,8 @@ class coro_http_client {
co_return resp_data{ec, 404};
}

socket_->impl_.set_option(asio::ip::tcp::no_delay(true));

if (u.is_ssl) {
if (auto ec = co_await handle_shake(); ec) {
co_return resp_data{ec, 404};
Expand Down Expand Up @@ -1485,6 +1509,7 @@ class coro_http_client {
if (auto [ec, _] = co_await async_read(read_buf_, header_size); ec) {
data.net_err = ec;
data.status = 404;
close_socket(*socket_);
if (on_ws_msg_)
on_ws_msg_(data);
co_return;
Expand All @@ -1508,6 +1533,7 @@ class coro_http_client {
ec) {
data.net_err = ec;
data.status = 404;
close_socket(*socket_);
if (on_ws_msg_)
on_ws_msg_(data);
co_return;
Expand All @@ -1531,6 +1557,11 @@ class coro_http_client {
on_ws_close_(data.resp_body);
co_await async_send_ws("close", false, opcode::close);
async_close();

data.net_err = asio::error::eof;
data.status = 404;
if (on_ws_msg_)
on_ws_msg_(data);
co_return;
}
if (on_ws_msg_)
Expand Down Expand Up @@ -1609,10 +1640,10 @@ class coro_http_client {

template <typename S>
bool has_schema(const S &url) {
size_t pos_http = url.find_first_of("http://");
size_t pos_https = url.find_first_of("https://");
size_t pos_ws = url.find_first_of("ws://");
size_t pos_wss = url.find_first_of("wss://");
size_t pos_http = url.find("http://");
size_t pos_https = url.find("https://");
size_t pos_ws = url.find("ws://");
size_t pos_wss = url.find("wss://");
bool has_http_scheme =
((pos_http != std::string::npos) && pos_http == 0) ||
((pos_https != std::string::npos) && pos_https == 0) ||
Expand Down Expand Up @@ -1651,6 +1682,7 @@ class coro_http_client {
std::unique_ptr<asio::ssl::stream<asio::ip::tcp::socket &>> ssl_stream_;
bool ssl_init_ret_ = true;
bool use_ssl_ = false;
std::string sni_hostname_ = "";
#endif
std::string redirect_uri_;
bool enable_follow_redirect_ = false;
Expand Down
46 changes: 1 addition & 45 deletions include/ylt/thirdparty/cinatra/picohttpparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,6 @@
#include <assert.h>
#include <stddef.h>
#include <string.h>
#ifdef __SSE4_2__
#ifdef _MSC_VER
#include <nmmintrin.h>
#else
#include <x86intrin.h>
#endif
#endif

#include <sys/types.h>

#ifdef _MSC_VER
#define ssize_t intptr_t
Expand Down Expand Up @@ -172,31 +163,10 @@ static const char *findchar_fast(const char *buf, const char *buf_end,
const char *ranges, int ranges_size,
int *found) {
*found = 0;
#if __SSE4_2__
if (likely(buf_end - buf >= 16)) {
__m128i ranges16 = _mm_loadu_si128((const __m128i *)ranges);

size_t left = (buf_end - buf) & ~15;
do {
__m128i b16 = _mm_loadu_si128((const __m128i *)buf);
int r = _mm_cmpestri(
ranges16, ranges_size, b16, 16,
_SIDD_LEAST_SIGNIFICANT | _SIDD_CMP_RANGES | _SIDD_UBYTE_OPS);
if (unlikely(r != 16)) {
buf += r;
*found = 1;
break;
}
buf += 16;
left -= 16;
} while (likely(left != 0));
}
#else
/* suppress unused parameter warning */
(void)buf_end;
(void)ranges;
(void)ranges_size;
#endif
return buf;
}

Expand All @@ -205,20 +175,6 @@ static const char *get_token_to_eol(const char *buf, const char *buf_end,
int *ret) {
const char *token_start = buf;

#ifdef __SSE4_2__
static const char ranges1[] =
"\0\010"
/* allow HT */
"\012\037"
/* allow SP and up to but not including DEL */
"\177\177"
/* allow chars w. MSB set */
;
int found;
buf = findchar_fast(buf, buf_end, ranges1, sizeof(ranges1) - 1, &found);
if (found)
goto FOUND_CTL;
#else
/* find non-printable char within the next 8 bytes, this is the hottest code;
* manually inlined */
while (likely(buf_end - buf >= 8)) {
Expand All @@ -245,7 +201,7 @@ static const char *get_token_to_eol(const char *buf, const char *buf_end,
}
++buf;
}
#endif

for (;; ++buf) {
CHECK_EOF();
if (unlikely(!IS_PRINTABLE_ASCII(*buf))) {
Expand Down

0 comments on commit f2718e9

Please sign in to comment.