Skip to content

Commit

Permalink
coro_connection
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos committed Sep 6, 2023
1 parent 7e32423 commit 8f9ef62
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
17 changes: 15 additions & 2 deletions include/cinatra/coro_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "asio/streambuf.hpp"
#include "define.h"
#include "http_parser.hpp"
#include "ylt/coro_io/coro_io.hpp"

namespace cinatra {
Expand All @@ -19,8 +20,17 @@ class coro_connection {

async_simple::coro::Lazy<void> start() {
while (true) {
auto ec = co_await async_read_until(head_buf_, TWO_CRCF);

auto [ec, size] = co_await async_read_until(head_buf_, TWO_CRCF);
if (ec) {
// handle error
}

const char *data_ptr = asio::buffer_cast<const char *>(head_buf_.data());
parser_.parse_request(data_ptr, size, 0);
auto headers = parser_.get_headers();
for (auto [k, v] : headers) {
std::cout << k << ": " << v << "\n";
}
// ec = co_await read_body();
// route();
// prepare_response();
Expand All @@ -35,10 +45,13 @@ class coro_connection {
return coro_io::async_read_until(socket_, buffer, delim);
}

auto &get_executor() { return *executor_; }

private:
async_simple::Executor *executor_;
asio::ip::tcp::socket socket_;
asio::streambuf head_buf_;
std::string body_;
http_parser parser_;
};
} // namespace cinatra
9 changes: 9 additions & 0 deletions include/cinatra/coro_http_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "async_simple/Promise.h"
#include "async_simple/coro/Lazy.h"
#include "cinatra_log_wrapper.hpp"
#include "coro_connection.hpp"
#include "ylt/coro_io/coro_io.hpp"
#include "ylt/coro_io/io_context_pool.hpp"

Expand Down Expand Up @@ -123,9 +124,17 @@ class coro_http_server {
}

CINATRA_LOG_DEBUG << "new connection comming";
auto conn =
std::make_shared<coro_connection>(executor, std::move(socket));
start_one(conn).via(&conn->get_executor()).detach();
}
}

async_simple::coro::Lazy<void> start_one(
std::shared_ptr<coro_connection> conn) noexcept {
co_await conn->start();
}

void close_acceptor() {
asio::dispatch(acceptor_.get_executor(), [this]() {
asio::error_code ec;
Expand Down
39 changes: 39 additions & 0 deletions include/cinatra/http_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,43 @@ class http_parser {
return header_len_;
}

int parse_request(const char *data, size_t size, int last_len) {
int minor_version;

num_headers_ = CINATRA_MAX_HTTP_HEADER_FIELD_SIZE;

const char *method;
size_t method_len;
const char *url;
size_t url_len;
header_len_ = detail::phr_parse_request(
data, size, &method, &method_len, &url, &url_len, &minor_version,
headers_.data(), &num_headers_, last_len);

if (header_len_ < 0) [[unlikely]] {
CINATRA_LOG_WARNING << "parse http head failed";
if (size == CINATRA_MAX_HTTP_HEADER_FIELD_SIZE) {
CINATRA_LOG_ERROR << "the field of http head is out of max limit "
<< CINATRA_MAX_HTTP_HEADER_FIELD_SIZE
<< ", you can define macro "
"CINATRA_MAX_HTTP_HEADER_FIELD_SIZE to expand it.";
}
}

method_ = {method, method_len};
url_ = {url, url_len};

auto content_len = this->get_header_value("content-length"sv);
if (content_len.empty()) {
body_len_ = 0;
}
else {
body_len_ = atoi(content_len.data());
}

return header_len_;
}

std::string_view get_header_value(std::string_view key) const {
for (size_t i = 0; i < num_headers_; i++) {
if (iequal(headers_[i].name, key))
Expand Down Expand Up @@ -119,5 +156,7 @@ class http_parser {
int header_len_ = 0;
int body_len_ = 0;
std::array<http_header, CINATRA_MAX_HTTP_HEADER_FIELD_SIZE> headers_;
std::string_view method_;
std::string_view url_;
};
} // namespace cinatra

0 comments on commit 8f9ef62

Please sign in to comment.