Skip to content

Commit

Permalink
add unit tests and remove some code (#496)
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Jan 17, 2024
1 parent 93b6645 commit 80562e1
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 156 deletions.
12 changes: 12 additions & 0 deletions example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,18 @@ async_simple::coro::Lazy<void> use_websocket() {
std::cout << result.data << "\n";
}

if (result.type == ws_frame_type::WS_PING_FRAME ||
result.type == ws_frame_type::WS_PONG_FRAME) {
// ping pong frame just need to continue, no need echo anything,
// because framework has reply ping/pong msg to client
// automatically.
continue;
}
else {
// error frame
break;
}

auto ec = co_await req.get_conn()->write_websocket(result.data);
if (ec) {
break;
Expand Down
6 changes: 4 additions & 2 deletions include/cinatra/coro_http_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1828,8 +1828,10 @@ class coro_http_client : public std::enable_shared_from_this<coro_http_client> {

data_ptr = asio::buffer_cast<const char *>(read_buf.data());
if (is_close_frame) {
payload_len -= 2;
data_ptr += sizeof(uint16_t);
if (payload_len >= 2) {
payload_len -= 2;
data_ptr += sizeof(uint16_t);
}
}

data.status = 200;
Expand Down
12 changes: 8 additions & 4 deletions include/cinatra/coro_http_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ class coro_http_connection
case cinatra::ws_frame_type::WS_CLOSE_FRAME: {
close_frame close_frame =
ws_.parse_close_payload(payload.data(), payload.size());
result.eof = true;
result.data = {close_frame.message, close_frame.length};

std::string close_msg = ws_.format_close_payload(
Expand All @@ -551,16 +552,16 @@ class coro_http_connection
close();
} break;
case cinatra::ws_frame_type::WS_PING_FRAME: {
auto ec = co_await write_websocket({payload.data(), payload.size()},
opcode::pong);
result.data = {payload.data(), payload.size()};
auto ec = co_await write_websocket("pong", opcode::pong);
if (ec) {
close();
result.ec = ec;
}
} break;
case cinatra::ws_frame_type::WS_PONG_FRAME: {
result.data = {payload.data(), payload.size()};
auto ec = co_await write_websocket("ping", opcode::ping);
close();
result.ec = ec;
} break;
default:
Expand Down Expand Up @@ -599,7 +600,10 @@ class coro_http_connection

void set_ws_max_size(uint64_t max_size) { max_part_size_ = max_size; }

void set_shrink_to_fit(bool r) { need_shrink_every_time_ = r; }
void set_shrink_to_fit(bool r) {
need_shrink_every_time_ = r;
response_.set_shrink_to_fit(r);
}

template <typename AsioBuffer>
async_simple::coro::Lazy<std::pair<std::error_code, size_t>> async_read(
Expand Down
10 changes: 0 additions & 10 deletions include/cinatra/define.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,34 +35,24 @@ inline constexpr std::string_view method_name(http_method mthd) {
switch (mthd) {
case cinatra::http_method::DEL:
return "DELETE"sv;
break;
case cinatra::http_method::GET:
return "GET"sv;
break;
case cinatra::http_method::HEAD:
return "HEAD"sv;
break;
case cinatra::http_method::POST:
return "POST"sv;
break;
case cinatra::http_method::PUT:
return "PUT"sv;
break;
case cinatra::http_method::PATCH:
return "PATCH"sv;
break;
case cinatra::http_method::CONNECT:
return "CONNECT"sv;
break;
case cinatra::http_method::OPTIONS:
return "OPTIONS"sv;
break;
case cinatra::http_method::TRACE:
return "TRACE"sv;
break;
default:
return "UNKONWN"sv;
break;
}
}

Expand Down
14 changes: 0 additions & 14 deletions include/cinatra/url_encode_decode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,23 +115,9 @@ inline size_t base64_encode(char *_dst, const void *_src, size_t len,
return dst - _dst;
}

inline static std::string u8wstring_to_string(const std::wstring &wstr) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
return conv.to_bytes(wstr);
}

inline static std::wstring u8string_to_wstring(const std::string &str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
return conv.from_bytes(str);
}

inline static std::string get_string_by_urldecode(std::string_view content) {
return url_decode(std::string(content.data(), content.size()));
}

inline static bool is_url_encode(std::string_view str) {
return str.find("%") != std::string_view::npos ||
str.find("+") != std::string_view::npos;
}
} // namespace code_utils
#endif // CPPWEBSERVER_URL_ENCODE_DECODE_HPP
59 changes: 4 additions & 55 deletions include/cinatra/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ struct ci_less {
}
};

bool operator()(const std::string &s1, const std::string &s2) const {
return std::lexicographical_compare(s1.begin(), s1.end(), // source range
s2.begin(), s2.end(), // dest range
nocase_compare()); // comparison
}

bool operator()(std::string_view s1, std::string_view s2) const {
return std::lexicographical_compare(s1.begin(), s1.end(), // source range
s2.begin(), s2.end(), // dest range
Expand Down Expand Up @@ -173,10 +167,6 @@ static const std::string base64_chars =
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

static inline bool is_base64(char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}

inline std::string base64_encode(const std::string &str) {
std::string ret;
int i = 0;
Expand Down Expand Up @@ -220,51 +210,10 @@ inline std::string base64_encode(const std::string &str) {
}

// from h2o
inline const char *MAP =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

inline const char *MAP_URL_ENCODED =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789-_";
inline size_t base64_encode(char *_dst, const void *_src, size_t len,
int url_encoded) {
char *dst = _dst;
const uint8_t *src = reinterpret_cast<const uint8_t *>(_src);
const char *map = url_encoded ? MAP_URL_ENCODED : MAP;
uint32_t quad;

for (; len >= 3; src += 3, len -= 3) {
quad = ((uint32_t)src[0] << 16) | ((uint32_t)src[1] << 8) | src[2];
*dst++ = map[quad >> 18];
*dst++ = map[(quad >> 12) & 63];
*dst++ = map[(quad >> 6) & 63];
*dst++ = map[quad & 63];
}
if (len != 0) {
quad = (uint32_t)src[0] << 16;
*dst++ = map[quad >> 18];
if (len == 2) {
quad |= (uint32_t)src[1] << 8;
*dst++ = map[(quad >> 12) & 63];
*dst++ = map[(quad >> 6) & 63];
if (!url_encoded)
*dst++ = '=';
}
else {
*dst++ = map[(quad >> 12) & 63];
if (!url_encoded) {
*dst++ = '=';
*dst++ = '=';
}
}
}

*dst = '\0';
return dst - _dst;
}
// inline const char *MAP =
// "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
// "abcdefghijklmnopqrstuvwxyz"
// "0123456789+/";

inline bool is_valid_utf8(unsigned char *s, size_t length) {
for (unsigned char *e = s + length; s != e;) {
Expand Down
47 changes: 0 additions & 47 deletions include/cinatra/websocket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,58 +121,11 @@ class websocket {
return ws_frame_type::WS_BINARY_FRAME;
}

ws_frame_type parse_payload(const char *buf, size_t size,
std::string &outbuf) {
const unsigned char *inp = (const unsigned char *)(buf);
if (payload_length_ > size)
return ws_frame_type::WS_INCOMPLETE_FRAME;

if (payload_length_ > outbuf.size()) {
outbuf.resize((size_t)payload_length_);
}

if (*(uint32_t *)mask_ == 0) {
memcpy(&outbuf[0], (void *)(inp), payload_length_);
}
else {
// unmask data:
for (size_t i = 0; i < payload_length_; i++) {
outbuf[i] = inp[i] ^ mask_[i % 4];
}
}

if (msg_opcode_ == 0x0)
return (msg_fin_)
? ws_frame_type::WS_TEXT_FRAME
: ws_frame_type::WS_INCOMPLETE_TEXT_FRAME; // continuation
// frame ?
if (msg_opcode_ == 0x1)
return (msg_fin_) ? ws_frame_type::WS_TEXT_FRAME
: ws_frame_type::WS_INCOMPLETE_TEXT_FRAME;
if (msg_opcode_ == 0x2)
return (msg_fin_) ? ws_frame_type::WS_BINARY_FRAME
: ws_frame_type::WS_INCOMPLETE_BINARY_FRAME;
if (msg_opcode_ == 0x8)
return ws_frame_type::WS_CLOSE_FRAME;
if (msg_opcode_ == 0x9)
return ws_frame_type::WS_PING_FRAME;
if (msg_opcode_ == 0xA)
return ws_frame_type::WS_PONG_FRAME;
return ws_frame_type::WS_BINARY_FRAME;
}

std::string format_header(size_t length, opcode code) {
size_t header_length = encode_header(length, code);
return {msg_header_, header_length};
}

std::vector<asio::const_buffer> format_message(const char *src, size_t length,
opcode code) {
size_t header_length = encode_header(length, code);
return {asio::buffer(msg_header_, header_length),
asio::buffer(src, length)};
}

std::string encode_frame(std::span<char> &data, opcode op, bool need_mask,
bool eof = true) {
std::string header;
Expand Down
5 changes: 1 addition & 4 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests)
set(project_name test_cinatra)
add_executable(${project_name}
test_coro_http_server.cpp
test_cinatra.cpp
test_cinatra_websocket.cpp
test_cmdline.cpp
Expand Down Expand Up @@ -58,17 +59,13 @@ add_executable(test_time_util
)
add_test(NAME test_time_util COMMAND test_time_util)

add_executable(test_coro_http_server test_coro_http_server.cpp)
add_test(NAME test_coro_http_server COMMAND test_coro_http_server)

option(CINATRA_ENABLE_SSL "Enable ssl support" OFF)
if (CINATRA_ENABLE_SSL)
message(STATUS "Use SSL")
find_package(OpenSSL REQUIRED)
add_definitions(-DCINATRA_ENABLE_SSL)
target_link_libraries(test_cinatra OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(test_corofile PRIVATE OpenSSL::SSL OpenSSL::Crypto)
target_link_libraries(test_coro_http_server OpenSSL::SSL OpenSSL::Crypto)
endif ()

add_executable(test_http_parse
Expand Down
Loading

0 comments on commit 80562e1

Please sign in to comment.