Skip to content

Commit d5234a7

Browse files
authored
[coro_http][feat]replace resp body int with int64 (#981)
1 parent 48e7cfc commit d5234a7

File tree

3 files changed

+41
-18
lines changed

3 files changed

+41
-18
lines changed

include/ylt/standalone/cinatra/coro_http_client.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1706,12 +1706,17 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {
17061706
parse_ret = -1;
17071707
}
17081708
#endif
1709-
if (parse_ret < 0) {
1709+
if (parse_ret < 0) [[unlikely]] {
17101710
#ifdef INJECT_FOR_HTTP_CLIENT_TEST
17111711
inject_response_valid = ClientInjectAction::none;
17121712
#endif
17131713
return std::make_error_code(std::errc::protocol_error);
17141714
}
1715+
if (parser_.body_len() < 0) [[unlikely]] {
1716+
CINATRA_LOG_ERROR << "invalid http content length: "
1717+
<< parser_.body_len();
1718+
return std::make_error_code(std::errc::invalid_argument);
1719+
}
17151720
head_buf_.consume(header_size); // header size
17161721
data.resp_headers = parser.get_headers();
17171722
data.status = parser.status();

include/ylt/standalone/cinatra/http_parser.hpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ inline bool iequal0(std::string_view a, std::string_view b) {
2828

2929
class http_parser {
3030
public:
31+
void parse_body_len() {
32+
auto header_value = this->get_header_value("content-length"sv);
33+
if (header_value.empty()) {
34+
body_len_ = 0;
35+
}
36+
else {
37+
auto [ptr, ec] = std::from_chars(
38+
header_value.data(), header_value.data() + header_value.size(),
39+
body_len_, 10);
40+
if (ec != std::errc{}) {
41+
body_len_ = -1;
42+
}
43+
}
44+
}
45+
3146
int parse_response(const char *data, size_t size, int last_len) {
3247
int minor_version;
3348

@@ -38,13 +53,7 @@ class http_parser {
3853
data, size, &minor_version, &status_, &msg, &msg_len, headers_.data(),
3954
&num_headers_, last_len);
4055
msg_ = {msg, msg_len};
41-
auto header_value = this->get_header_value("content-length"sv);
42-
if (header_value.empty()) {
43-
body_len_ = 0;
44-
}
45-
else {
46-
body_len_ = atoi(header_value.data());
47-
}
56+
parse_body_len();
4857
if (header_len_ < 0) [[unlikely]] {
4958
CINATRA_LOG_WARNING << "parse http head failed";
5059
if (size == CINATRA_MAX_HTTP_HEADER_FIELD_SIZE) {
@@ -92,13 +101,7 @@ class http_parser {
92101
body_len_ = 0;
93102
}
94103
else {
95-
auto content_len = this->get_header_value("content-length"sv);
96-
if (content_len.empty()) {
97-
body_len_ = 0;
98-
}
99-
else {
100-
body_len_ = atoi(content_len.data());
101-
}
104+
parse_body_len();
102105
}
103106

104107
full_url_ = url_;
@@ -204,9 +207,9 @@ class http_parser {
204207

205208
int header_len() const { return header_len_; }
206209

207-
int body_len() const { return body_len_; }
210+
int64_t body_len() const { return body_len_; }
208211

209-
int total_len() const { return header_len_ + body_len_; }
212+
int64_t total_len() const { return header_len_ + body_len_; }
210213

211214
bool is_location() {
212215
auto location = this->get_header_value("Location"sv);
@@ -260,7 +263,7 @@ class http_parser {
260263
std::string_view msg_;
261264
size_t num_headers_ = 0;
262265
int header_len_ = 0;
263-
int body_len_ = 0;
266+
int64_t body_len_ = 0;
264267
bool has_connection_{};
265268
bool has_close_{};
266269
bool has_upgrade_{};

src/coro_http/tests/test_cinatra.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,21 @@ TEST_CASE("test request with out buffer") {
943943
}
944944
}
945945

946+
TEST_CASE("test response body greater than 2GB") {
947+
coro_http_server server(1, 8090);
948+
std::string resp_str;
949+
size_t large_size = 1024 * 1024 * 1024 + 10;
950+
detail::resize(resp_str, large_size);
951+
server.set_http_handler<GET>(
952+
"/test", [&](coro_http_request &req, coro_http_response &resp) {
953+
resp.set_status_and_content(status_type::ok, std::move(resp_str));
954+
});
955+
server.async_start();
956+
coro_http_client client;
957+
auto result = client.get("http://127.0.0.1:8090/test");
958+
CHECK(result.resp_body.length() == large_size);
959+
}
960+
946961
TEST_CASE("test pass path not entire uri") {
947962
coro_http_client client{};
948963
client.set_conn_timeout(2s);

0 commit comments

Comments
 (0)