mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-09 19:48: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) {
|
struct Capitalizer {
|
||||||
buf->append(util::upcase(s[0]));
|
template <std::weakly_incrementable O>
|
||||||
for (size_t i = 1; i < s.size(); ++i) {
|
requires(std::indirectly_writable<O, char>)
|
||||||
if (s[i - 1] == '-') {
|
constexpr O operator()(const StringRef &s, O result) noexcept {
|
||||||
buf->append(util::upcase(s[i]));
|
*result++ = util::upcase(s[0]);
|
||||||
} else {
|
|
||||||
buf->append(s[i]);
|
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) {
|
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_construct_push_component),
|
||||||
munit_void_test(test_http2_contains_trailers),
|
munit_void_test(test_http2_contains_trailers),
|
||||||
munit_void_test(test_http2_check_transfer_encoding),
|
munit_void_test(test_http2_check_transfer_encoding),
|
||||||
|
munit_void_test(test_http2_capitalize),
|
||||||
munit_test_end(),
|
munit_test_end(),
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -1187,4 +1188,94 @@ void test_http2_check_transfer_encoding(void) {
|
|||||||
assert_false(http2::check_transfer_encoding(R"(chunked;foo="bar",,gzip)"_sr));
|
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
|
} // 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_construct_push_component)
|
||||||
munit_void_test_decl(test_http2_contains_trailers)
|
munit_void_test_decl(test_http2_contains_trailers)
|
||||||
munit_void_test_decl(test_http2_check_transfer_encoding)
|
munit_void_test_decl(test_http2_check_transfer_encoding)
|
||||||
|
munit_void_test_decl(test_http2_capitalize)
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user