mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-08 02:58:53 +08:00
Merge pull request #2435 from nghttp2/refactor-capitalize
Refactor http2::capitalize
This commit is contained in:
57
src/http2.cc
57
src/http2.cc
@@ -249,15 +249,58 @@ StringRef stringify_status(BlockAllocator &balloc, unsigned int status_code) {
|
||||
}
|
||||
}
|
||||
|
||||
void capitalize(DefaultMemchunks *buf, const StringRef &s) {
|
||||
buf->append(util::upcase(s[0]));
|
||||
for (size_t i = 1; i < s.size(); ++i) {
|
||||
if (s[i - 1] == '-') {
|
||||
buf->append(util::upcase(s[i]));
|
||||
} else {
|
||||
buf->append(s[i]);
|
||||
struct Capitalizer {
|
||||
template <std::weakly_incrementable O>
|
||||
requires(std::indirectly_writable<O, char>)
|
||||
constexpr O operator()(const StringRef &s, O result) noexcept {
|
||||
*result++ = util::upcase(s[0]);
|
||||
|
||||
for (size_t i = 1; i < s.size(); ++i) {
|
||||
if (s[i - 1] == '-') {
|
||||
*result++ = util::upcase(s[i]);
|
||||
} else {
|
||||
*result++ = s[i];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
void capitalize_long(DefaultMemchunks *buf, const StringRef &s) {
|
||||
buf->append(util::upcase(s[0]));
|
||||
|
||||
auto it = s.begin() + 1;
|
||||
|
||||
for (; it != s.end();) {
|
||||
auto p = std::ranges::find(it, s.end(), '-');
|
||||
p = std::ranges::find_if(p, s.end(), [](auto c) { return c != '-'; });
|
||||
|
||||
buf->append(it, p);
|
||||
|
||||
if (p == s.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf->append(util::upcase(*p));
|
||||
|
||||
it = p + 1;
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void capitalize(DefaultMemchunks *buf, const StringRef &s) {
|
||||
assert(!s.empty());
|
||||
|
||||
constexpr size_t max_namelen = 32;
|
||||
|
||||
if (s.size() > max_namelen) {
|
||||
capitalize_long(buf, s);
|
||||
return;
|
||||
}
|
||||
|
||||
buf->append(s.size(), std::bind_front(Capitalizer{}, s));
|
||||
}
|
||||
|
||||
bool lws(const char *value) {
|
||||
|
||||
@@ -65,6 +65,7 @@ const MunitTest tests[]{
|
||||
munit_void_test(test_http2_construct_push_component),
|
||||
munit_void_test(test_http2_contains_trailers),
|
||||
munit_void_test(test_http2_check_transfer_encoding),
|
||||
munit_void_test(test_http2_capitalize),
|
||||
munit_test_end(),
|
||||
};
|
||||
} // namespace
|
||||
@@ -1187,4 +1188,94 @@ void test_http2_check_transfer_encoding(void) {
|
||||
assert_false(http2::check_transfer_encoding(R"(chunked;foo="bar",,gzip)"_sr));
|
||||
}
|
||||
|
||||
void test_http2_capitalize(void) {
|
||||
MemchunkPool pool;
|
||||
DefaultMemchunks m{&pool};
|
||||
iovec iov;
|
||||
|
||||
{
|
||||
http2::capitalize(&m, "content-length"_sr);
|
||||
auto iovcnt = m.riovec(&iov, 1);
|
||||
|
||||
assert_int(1, ==, iovcnt);
|
||||
assert_stdsv_equal(
|
||||
"Content-Length"sv,
|
||||
(std::string_view{static_cast<const char *>(iov.iov_base), iov.iov_len}));
|
||||
|
||||
m.reset();
|
||||
}
|
||||
|
||||
{
|
||||
http2::capitalize(&m, "altsvc"_sr);
|
||||
auto iovcnt = m.riovec(&iov, 1);
|
||||
|
||||
assert_int(1, ==, iovcnt);
|
||||
assert_stdsv_equal(
|
||||
"Altsvc"sv,
|
||||
(std::string_view{static_cast<const char *>(iov.iov_base), iov.iov_len}));
|
||||
|
||||
m.reset();
|
||||
}
|
||||
|
||||
{
|
||||
http2::capitalize(&m, "altsvc-"_sr);
|
||||
auto iovcnt = m.riovec(&iov, 1);
|
||||
|
||||
assert_int(1, ==, iovcnt);
|
||||
assert_stdsv_equal(
|
||||
"Altsvc-"sv,
|
||||
(std::string_view{static_cast<const char *>(iov.iov_base), iov.iov_len}));
|
||||
|
||||
m.reset();
|
||||
}
|
||||
|
||||
{
|
||||
http2::capitalize(&m, "alt--svc"_sr);
|
||||
auto iovcnt = m.riovec(&iov, 1);
|
||||
|
||||
assert_int(1, ==, iovcnt);
|
||||
assert_stdsv_equal(
|
||||
"Alt--Svc"sv,
|
||||
(std::string_view{static_cast<const char *>(iov.iov_base), iov.iov_len}));
|
||||
|
||||
m.reset();
|
||||
}
|
||||
|
||||
{
|
||||
http2::capitalize(&m, "sec-websocket----------------key"_sr);
|
||||
auto iovcnt = m.riovec(&iov, 1);
|
||||
|
||||
assert_int(1, ==, iovcnt);
|
||||
assert_stdsv_equal(
|
||||
"Sec-Websocket----------------Key"sv,
|
||||
(std::string_view{static_cast<const char *>(iov.iov_base), iov.iov_len}));
|
||||
|
||||
m.reset();
|
||||
}
|
||||
|
||||
{
|
||||
http2::capitalize(&m, "content--------------------length"_sr);
|
||||
auto iovcnt = m.riovec(&iov, 1);
|
||||
|
||||
assert_int(1, ==, iovcnt);
|
||||
assert_stdsv_equal(
|
||||
"Content--------------------Length"sv,
|
||||
(std::string_view{static_cast<const char *>(iov.iov_base), iov.iov_len}));
|
||||
|
||||
m.reset();
|
||||
}
|
||||
|
||||
{
|
||||
http2::capitalize(&m, "content--------------------length-"_sr);
|
||||
auto iovcnt = m.riovec(&iov, 1);
|
||||
|
||||
assert_int(1, ==, iovcnt);
|
||||
assert_stdsv_equal(
|
||||
"Content--------------------Length-"sv,
|
||||
(std::string_view{static_cast<const char *>(iov.iov_base), iov.iov_len}));
|
||||
|
||||
m.reset();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace shrpx
|
||||
|
||||
@@ -54,6 +54,7 @@ munit_void_test_decl(test_http2_get_pure_path_component)
|
||||
munit_void_test_decl(test_http2_construct_push_component)
|
||||
munit_void_test_decl(test_http2_contains_trailers)
|
||||
munit_void_test_decl(test_http2_check_transfer_encoding)
|
||||
munit_void_test_decl(test_http2_capitalize)
|
||||
|
||||
} // namespace shrpx
|
||||
|
||||
|
||||
Reference in New Issue
Block a user