Skip to content

Commit

Permalink
avoid copy headers (#562)
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Apr 23, 2024
1 parent d988224 commit 933a45f
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 23 deletions.
66 changes: 46 additions & 20 deletions include/cinatra/coro_http_response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifdef CINATRA_ENABLE_GZIP
#include "gzip.hpp"
#endif
#include "picohttpparser.h"
#include "response_cv.hpp"
#include "time_util.hpp"
#include "utils.hpp"
Expand Down Expand Up @@ -52,11 +53,12 @@ class coro_http_response {
void set_status_and_content(
status_type status, std::string content = "",
content_encoding encoding = content_encoding::none) {
set_status_and_content_view(status, content, encoding, false);
set_status_and_content_view(status, std::move(content), encoding, false);
}

template <typename String>
void set_status_and_content_view(
status_type status, std::string_view content = "",
status_type status, String content = "",
content_encoding encoding = content_encoding::none, bool is_view = true) {
status_ = status;
#ifdef CINATRA_ENABLE_GZIP
Expand Down Expand Up @@ -100,6 +102,10 @@ class coro_http_response {
resp_headers_.emplace_back(resp_header{std::move(k), std::move(v)});
}

void add_header_span(std::span<http_header> resp_headers) {
resp_header_span_ = resp_headers;
}

void set_keepalive(bool r) { keepalive_ = r; }

void need_date_head(bool r) { need_date_ = r; }
Expand All @@ -125,13 +131,9 @@ class coro_http_response {
resp_str.append(to_http_status_string(status_));
bool has_len = false;
bool has_host = false;
for (auto &[k, v] : resp_headers_) {
if (k == "Server") {
has_host = true;
}
if (k == "Content-Length") {
has_len = true;
}
check_header(resp_headers_, has_len, has_host);
if (!resp_header_span_.empty()) {
check_header(resp_header_span_, has_len, has_host);
}

if (!has_host) {
Expand Down Expand Up @@ -175,21 +177,27 @@ class coro_http_response {
resp_str.append(content_type_);
}

for (auto &[k, v] : resp_headers_) {
append_header_str(resp_str, resp_headers_);

if (!resp_header_span_.empty()) {
append_header_str(resp_str, resp_header_span_);
}

resp_str.append(CRCF);
resp_str.append(content_);
}

void append_header_str(auto &resp_str, auto &resp_headers) {
for (auto &[k, v] : resp_headers) {
resp_str.append(k);
resp_str.append(COLON_SV);
resp_str.append(v);
resp_str.append(CRCF);
}

resp_str.append(CRCF);
resp_str.append(content_);
}

void build_resp_head(std::vector<asio::const_buffer> &buffers) {
bool has_len = false;
bool has_host = false;
for (auto &[k, v] : resp_headers_) {
void check_header(auto &resp_headers, bool &has_len, bool &has_host) {
for (auto &[k, v] : resp_headers) {
if (k == "Server") {
has_host = true;
}
Expand All @@ -200,6 +208,15 @@ class coro_http_response {
need_date_ = false;
}
}
}

void build_resp_head(std::vector<asio::const_buffer> &buffers) {
bool has_len = false;
bool has_host = false;
check_header(resp_headers_, has_len, has_host);
if (!resp_header_span_.empty()) {
check_header(resp_header_span_, has_len, has_host);
}

if (!has_host) {
buffers.emplace_back(asio::buffer(CINATRA_HOST_SV));
Expand Down Expand Up @@ -251,14 +268,22 @@ class coro_http_response {
buffers.emplace_back(asio::buffer(content_type_));
}

for (auto &[k, v] : resp_headers_) {
append_header(buffers, resp_headers_);

if (!resp_header_span_.empty()) {
append_header(buffers, resp_header_span_);
}

buffers.emplace_back(asio::buffer(CRCF));
}

void append_header(auto &buffers, auto &resp_headers) {
for (auto &[k, v] : resp_headers) {
buffers.emplace_back(asio::buffer(k));
buffers.emplace_back(asio::buffer(COLON_SV));
buffers.emplace_back(asio::buffer(v));
buffers.emplace_back(asio::buffer(CRCF));
}

buffers.emplace_back(asio::buffer(CRCF));
}

coro_http_connection *get_conn() { return conn_; }
Expand Down Expand Up @@ -319,6 +344,7 @@ class coro_http_response {
bool delay_;
char buf_[32];
std::vector<resp_header> resp_headers_;
std::span<http_header> resp_header_span_;
coro_http_connection *conn_;
std::string boundary_;
bool has_set_content_ = false;
Expand Down
4 changes: 1 addition & 3 deletions include/cinatra/coro_http_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -854,9 +854,7 @@ class coro_http_server {
req.full_url(), method_type(req.get_method()), std::move(ctx),
std::move(req_headers));

for (auto &[k, v] : result.resp_headers) {
response.add_header(std::string(k), std::string(v));
}
response.add_header_span(result.resp_headers);

response.set_status_and_content_view(
static_cast<status_type>(result.status), result.resp_body);
Expand Down

0 comments on commit 933a45f

Please sign in to comment.