Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit test #646

Merged
merged 13 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
883 changes: 400 additions & 483 deletions include/cinatra/coro_http_client.hpp

Large diffs are not rendered by default.

41 changes: 24 additions & 17 deletions include/cinatra/coro_http_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -721,28 +721,19 @@ class coro_http_connection
case cinatra::ws_frame_type::WS_TEXT_FRAME:
case cinatra::ws_frame_type::WS_BINARY_FRAME: {
#ifdef CINATRA_ENABLE_GZIP
if (is_client_ws_compressed_) {
inflate_str_.clear();
if (!cinatra::gzip_codec::inflate(
{payload.data(), payload.size()}, inflate_str_)) {
CINATRA_LOG_ERROR << "uncompuress data error";
result.ec = std::make_error_code(std::errc::protocol_error);
break;
}
result.eof = true;
result.data = {inflate_str_.data(), inflate_str_.size()};
if (!gzip_compress(payload, result)) {
break;
}
else {
#endif
result.eof = true;
result.data = {payload.data(), payload.size()};
break;
result.eof = true;
result.data = {payload.data(), payload.size()};
} break;
case cinatra::ws_frame_type::WS_CLOSE_FRAME: {
#ifdef CINATRA_ENABLE_GZIP
if (!gzip_compress(payload, result)) {
break;
}
#endif
} break;
case cinatra::ws_frame_type::WS_CLOSE_FRAME: {
close_frame close_frame =
ws_.parse_close_payload(payload.data(), payload.size());
result.eof = true;
Expand Down Expand Up @@ -793,6 +784,22 @@ class coro_http_connection
co_return result;
}

#ifdef CINATRA_ENABLE_GZIP
bool gzip_compress(std::span<char> &payload, websocket_result &result) {
if (is_client_ws_compressed_) {
inflate_str_.clear();
if (!cinatra::gzip_codec::inflate({payload.data(), payload.size()},
inflate_str_)) {
CINATRA_LOG_ERROR << "uncompuress data error";
result.ec = std::make_error_code(std::errc::protocol_error);
return false;
}
payload = inflate_str_;
}
return true;
}
#endif

auto &tcp_socket() { return socket_; }

void set_quit_callback(std::function<void(const uint64_t &conn_id)> callback,
Expand Down Expand Up @@ -920,7 +927,7 @@ class coro_http_connection

code_utils::base64_encode(accept_key, sha1buf, sizeof(sha1buf), 0);

response_.set_status_and_content(status_type::switching_protocols);
response_.set_status_and_content(status_type::switching_protocols, "");

response_.add_header("Upgrade", "WebSocket");
response_.add_header("Connection", "Upgrade");
Expand Down
8 changes: 0 additions & 8 deletions include/cinatra/coro_http_request.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,6 @@ class coro_http_request {

bool is_chunked() { return parser_.is_chunked(); }

bool is_resp_ranges() { return parser_.is_resp_ranges(); }

bool is_req_ranges() { return parser_.is_req_ranges(); }

std::string_view get_accept_encoding() {
return get_header_value("Accept-Encoding");
}
Expand Down Expand Up @@ -243,10 +239,6 @@ class coro_http_request {
return false;
}

void set_aspect_data(std::string data) {
aspect_data_.push_back(std::move(data));
}

void set_aspect_data(std::vector<std::string> data) {
aspect_data_ = std::move(data);
}
Expand Down
12 changes: 7 additions & 5 deletions include/cinatra/coro_http_response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class coro_http_response {
has_set_content_ = true;
}
void set_status_and_content(
status_type status, std::string content = "",
status_type status, std::string content,
content_encoding encoding = content_encoding::none,
std::string_view client_encoding_type = "") {
set_status_and_content_view(status, std::move(content), encoding, false,
Expand Down Expand Up @@ -220,8 +220,10 @@ class coro_http_response {
resp_str.append(TRANSFER_ENCODING_SV);
}
else {
if (!content_.empty()) {
auto [ptr, ec] = std::to_chars(buf_, buf_ + 32, content_.size());
if (!content_.empty() || !content_view_.empty()) {
size_t content_size =
content_.empty() ? content_view_.size() : content_.size();
auto [ptr, ec] = std::to_chars(buf_, buf_ + 32, content_size);
resp_str.append(CONTENT_LENGTH_SV);
resp_str.append(std::string_view(buf_, std::distance(buf_, ptr)));
resp_str.append(CRCF);
Expand Down Expand Up @@ -385,8 +387,8 @@ class coro_http_response {
void redirect(const std::string &url, bool is_forever = false) {
add_header("Location", url);
is_forever == false
? set_status_and_content(status_type::moved_temporarily)
: set_status_and_content(status_type::moved_permanently);
? set_status_and_content(status_type::moved_temporarily, "")
: set_status_and_content(status_type::moved_permanently, "");
}

private:
Expand Down
2 changes: 1 addition & 1 deletion include/cinatra/coro_http_server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ class coro_http_server {

private:
std::error_code listen() {
CINATRA_LOG_INFO << "begin to listen";
CINATRA_LOG_INFO << "begin to listen " << port_;
using asio::ip::tcp;
asio::error_code ec;

Expand Down
8 changes: 4 additions & 4 deletions include/cinatra/gzip.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ inline bool inflate(std::string_view str_src, std::string &str_dest) {
// generated output
if (err == Z_STREAM_END) {
// Finish up
int kerr = ::inflateEnd(&zs);
[[maybe_unused]] int kerr = ::inflateEnd(&zs);

// Got a good result, set the size to the amount unzipped in this call
// (including all recursive calls)
Expand All @@ -202,7 +202,7 @@ inline bool inflate(std::string_view str_src, std::string &str_dest) {
str_dest.append((const char *)bytes_out,
OUTPUT_BUF_SIZE - zs.avail_out);

int kerr = ::inflateEnd(&zs);
[[maybe_unused]] int kerr = ::inflateEnd(&zs);

break;
}
Expand Down Expand Up @@ -252,7 +252,7 @@ inline bool deflate(std::string_view str_src, std::string &str_dest) {
// generated output
if (err == Z_STREAM_END) {
// Finish up
int kerr = ::deflateEnd(&zs);
[[maybe_unused]] int kerr = ::deflateEnd(&zs);

// Got a good result, set the size to the amount unzipped in this call
// (including all recursive calls)
Expand All @@ -277,7 +277,7 @@ inline bool deflate(std::string_view str_src, std::string &str_dest) {
str_dest.append((const char *)bytes_out,
OUTPUT_BUF_SIZE - zs.avail_out);

int kerr = ::deflateEnd(&zs);
[[maybe_unused]] int kerr = ::deflateEnd(&zs);

break;
}
Expand Down
26 changes: 8 additions & 18 deletions include/cinatra/http_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,7 @@ class http_parser {
if (header_len_ < 0) [[unlikely]] {
CINATRA_LOG_WARNING << "parse http head failed";
if (num_headers_ == 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.";
output_error();
}
}
return header_len_;
Expand All @@ -76,10 +73,7 @@ class http_parser {
if (header_len_ < 0) [[unlikely]] {
CINATRA_LOG_WARNING << "parse http head failed";
if (num_headers_ == 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.";
output_error();
}
return header_len_;
}
Expand Down Expand Up @@ -173,11 +167,6 @@ class http_parser {
return content_type.substr(pos + 1);
}

bool is_req_ranges() const {
auto value = this->get_header_value("Range"sv);
return !value.empty();
}

bool is_resp_ranges() const {
auto value = this->get_header_value("Accept-Ranges"sv);
return !value.empty();
Expand Down Expand Up @@ -248,11 +237,12 @@ class http_parser {
}
}

std::string_view trim(std::string_view v) {
v.remove_prefix((std::min)(v.find_first_not_of(" "), v.size()));
v.remove_suffix(
(std::min)(v.size() - v.find_last_not_of(" ") - 1, v.size()));
return v;
private:
void output_error() {
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.";
}

private:
Expand Down
1 change: 0 additions & 1 deletion include/cinatra/multipart.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class multipart_reader_t {

part_head_t result{};
std::error_code ec{};
size_t last_size = chunked_buf_.size();
size_t size;

auto get_part_name = [](std::string_view data, std::string_view name,
Expand Down
38 changes: 0 additions & 38 deletions include/cinatra/picohttpparser.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,44 +233,6 @@ static const char *findchar_fast(const char *buf, const char *buf_end,
return buf;
}

static const char *findchar_nonprintable_fast(const char *buf,
const char *buf_end, int *found) {
#ifdef CINATRA_ARM_OPT
*found = 0;

const size_t block_size = sizeof(uint8x16_t) - 1;
const char *const end =
(size_t)(buf_end - buf) >= block_size ? buf_end - block_size : buf;

for (; buf < end; buf += sizeof(uint8x16_t)) {
uint8x16_t v = vld1q_u8((const uint8_t *)buf);

v = vorrq_u8(vcltq_u8(v, vmovq_n_u8('\041')),
vceqq_u8(v, vmovq_n_u8('\177')));

/* Pack the comparison result into 64 bits. */
const uint8x8_t rv = vshrn_n_u16(vreinterpretq_u16_u8(v), 4);
uint64_t offset = vget_lane_u64(vreinterpret_u64_u8(rv), 0);

if (offset) {
*found = 1;
__asm__("rbit %x0, %x0" : "+r"(offset));
static_assert(sizeof(unsigned long long) == sizeof(uint64_t),
"Need the number of leading 0-bits in uint64_t.");
/* offset uses 4 bits per byte of input. */
buf += __builtin_clzll(offset) / 4;
break;
}
}

return buf;
#else
static const char ALIGNED(16) ranges2[16] = "\000\040\177\177";

return findchar_fast(buf, buf_end, ranges2, 4, found);
#endif
}

static const char *get_token_to_eol(const char *buf, const char *buf_end,
const char **token, size_t *token_len,
int *ret) {
Expand Down
Loading
Loading