Add helper template for StringRef from contiguous range

This commit is contained in:
Tatsuhiro Tsujikawa
2025-05-11 16:53:09 +09:00
parent 08c0dad06f
commit 71dd4399fc
19 changed files with 85 additions and 47 deletions

View File

@@ -632,7 +632,7 @@ StringRef rewrite_location_uri(BlockAllocator &balloc, const StringRef &uri,
*p = '\0';
return StringRef{std::span{std::ranges::begin(iov), p}};
return as_string_ref(std::ranges::begin(iov), p);
}
int parse_http_status_code(const StringRef &src) {
@@ -1590,7 +1590,7 @@ int construct_push_component(BlockAllocator &balloc, StringRef &scheme,
}
*p = '\0';
authority = StringRef{std::span{std::ranges::begin(iov), p}};
authority = as_string_ref(std::ranges::begin(iov), p);
}
if (u.field_set & (1 << URLPARSE_PATH)) {
@@ -1669,12 +1669,12 @@ StringRef path_join(BlockAllocator &balloc, const StringRef &base_path,
p = std::ranges::copy(base_query, p).out;
}
*p = '\0';
return StringRef{std::span{std::ranges::begin(res), p}};
return as_string_ref(std::ranges::begin(res), p);
}
*p++ = '?';
p = std::ranges::copy(rel_query, p).out;
*p = '\0';
return StringRef{std::span{std::ranges::begin(res), p}};
return as_string_ref(std::ranges::begin(res), p);
}
auto first = std::ranges::begin(rel_path);
@@ -1736,7 +1736,7 @@ StringRef path_join(BlockAllocator &balloc, const StringRef &base_path,
p = std::ranges::copy(rel_query, p).out;
}
*p = '\0';
return StringRef{std::span{std::ranges::begin(res), p}};
return as_string_ref(std::ranges::begin(res), p);
}
StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
@@ -1783,7 +1783,7 @@ StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
*p = '\0';
return path_join(balloc, StringRef{}, StringRef{},
StringRef{std::span{std::ranges::begin(result), p}}, query);
as_string_ref(std::ranges::begin(result), p), query);
}
StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
@@ -1830,7 +1830,7 @@ StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
*p = '\0';
return path_join(balloc, StringRef{}, StringRef{},
StringRef{std::span{std::ranges::begin(result), p}}, query);
as_string_ref(std::ranges::begin(result), p), query);
}
std::string normalize_path(const StringRef &path, const StringRef &query) {
@@ -1860,7 +1860,7 @@ StringRef copy_lower(BlockAllocator &balloc, const StringRef &src) {
p = std::ranges::copy(src, p).out;
*p = '\0';
util::inp_strlower(std::ranges::begin(iov), p);
return StringRef{std::span{std::ranges::begin(iov), p}};
return as_string_ref(std::ranges::begin(iov), p);
}
bool contains_trailers(const StringRef &s) {
@@ -1900,7 +1900,7 @@ StringRef make_websocket_accept_token(uint8_t *dest, const StringRef &key) {
return StringRef{};
}
return StringRef{std::span{dest, base64::encode(h, dest)}};
return as_string_ref(dest, base64::encode(h, dest));
}
bool legacy_http1(int major, int minor) {

View File

@@ -3942,7 +3942,7 @@ int process_options(Config *config,
auto gen = util::make_mt19937();
p = util::random_alpha_digit(p, p + SHRPX_OBFUSCATED_NODE_LENGTH, gen);
*p = '\0';
fwdconf.by_obfuscated = StringRef{std::span{std::begin(iov), p}};
fwdconf.by_obfuscated = as_string_ref(std::begin(iov), p);
}
if (config->http2.upstream.debug.frame_debug) {

View File

@@ -288,8 +288,8 @@ int APIDownstreamConnection::error_method_not_allowed() {
p -= 2;
*p = '\0';
resp.fs.add_header_token("allow"_sr, StringRef{std::span{std::begin(iov), p}},
false, -1);
resp.fs.add_header_token("allow"_sr, as_string_ref(std::begin(iov), p), false,
-1);
return send_reply(405, APIStatusCode::FAILURE);
}
@@ -368,7 +368,7 @@ int APIDownstreamConnection::handle_backendconfig() {
std::set<StringRef> include_set;
std::map<StringRef, size_t> pattern_addr_indexer;
for (auto first = reinterpret_cast<const uint8_t *>(rp),
for (auto first = reinterpret_cast<const char *>(rp),
last = first + req.recv_body_length;
first != last;) {
auto eol = std::find(first, last, '\n');
@@ -387,8 +387,8 @@ int APIDownstreamConnection::handle_backendconfig() {
return 0;
}
auto opt = StringRef{std::span{first, eq}};
auto optval = StringRef{std::span{eq + 1, eol}};
auto opt = StringRef{first, eq};
auto optval = StringRef{eq + 1, eol};
auto optid = option_lookup_token(opt);

View File

@@ -498,7 +498,7 @@ ClientHandler::ClientHandler(Worker *worker, int fd, SSL *ssl,
worker_->get_randgen());
*p = '\0';
forwarded_for_ = StringRef{std::span{std::ranges::begin(buf), p}};
forwarded_for_ = as_string_ref(std::ranges::begin(buf), p);
} else {
init_forwarded_for(family, ipaddr_);
}
@@ -517,7 +517,7 @@ void ClientHandler::init_forwarded_for(int family, const StringRef &ipaddr) {
*p++ = ']';
*p = '\0';
forwarded_for_ = StringRef{std::span{std::ranges::begin(buf), p}};
forwarded_for_ = as_string_ref(std::ranges::begin(buf), p);
} else {
// family == AF_INET or family == AF_UNIX
forwarded_for_ = ipaddr;

View File

@@ -384,7 +384,7 @@ HeaderRefs::value_type parse_header(BlockAllocator &balloc,
*p = '\0';
auto nv =
HeaderRef(StringRef{std::span{std::begin(name_iov), p}},
HeaderRef(as_string_ref(std::begin(name_iov), p),
make_string_ref(balloc, StringRef{value, std::end(optarg)}));
if (!nghttp2_check_header_name(nv.name.byte(), nv.name.size()) ||
@@ -787,7 +787,7 @@ std::vector<LogFragment> parse_log_format(BlockAllocator &balloc,
std::transform(std::begin(iov), p, std::begin(iov),
[](auto c) { return c == '_' ? '-' : c; });
*p = '\0';
res.emplace_back(type, StringRef{std::span{std::begin(iov), p}});
res.emplace_back(type, as_string_ref(std::begin(iov), p));
}
}
@@ -1237,7 +1237,7 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
util::inp_strlower(std::begin(iov), p);
*p++ = '/';
*p = '\0';
pattern = StringRef{std::span{std::begin(iov), p}};
pattern = as_string_ref(std::begin(iov), p);
} else {
auto path = http2::normalize_path_colon(
downstreamconf.balloc, StringRef{slash, std::end(raw_pattern)},
@@ -1249,7 +1249,7 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
util::inp_strlower(std::begin(iov), p);
p = std::copy(std::begin(path), std::end(path), p);
*p = '\0';
pattern = StringRef{std::span{std::begin(iov), p}};
pattern = as_string_ref(std::begin(iov), p);
}
auto it = pattern_addr_indexer.find(pattern);
if (it != std::end(pattern_addr_indexer)) {
@@ -1384,7 +1384,7 @@ int parse_mapping(Config *config, DownstreamAddrConfig &addr,
auto p =
std::reverse_copy(std::begin(host), std::end(host), std::begin(iov));
*p = '\0';
auto rev_host = StringRef{std::span{std::begin(iov), p}};
auto rev_host = as_string_ref(std::begin(iov), p);
rw_router.add_route(rev_host, wildcard_patterns.size() - 1);
} else {

View File

@@ -371,7 +371,7 @@ StringRef Downstream::assemble_request_cookie() {
p -= 2;
}
return StringRef{std::span{std::ranges::begin(iov), p}};
return as_string_ref(std::ranges::begin(iov), p);
}
uint32_t Downstream::find_affinity_cookie(const StringRef &name) {
@@ -481,7 +481,7 @@ StringRef alloc_header_name(BlockAllocator &balloc, const StringRef &name) {
util::inp_strlower(std::ranges::begin(iov), p);
*p = '\0';
return StringRef{std::span{std::ranges::begin(iov), p}};
return as_string_ref(std::ranges::begin(iov), p);
}
} // namespace

View File

@@ -41,7 +41,7 @@ StringRef create_error_html(BlockAllocator &balloc, unsigned int http_status) {
const auto &error_pages = httpconf.error_pages;
for (const auto &page : error_pages) {
if (page.http_status == 0 || page.http_status == http_status) {
return StringRef{std::span{page.content}};
return as_string_ref(page.content);
}
}
@@ -123,7 +123,7 @@ StringRef create_forwarded(BlockAllocator &balloc, int params,
--p;
*p = '\0';
return StringRef{std::span{std::ranges::begin(iov), p}};
return as_string_ref(std::ranges::begin(iov), p);
}
std::string colorizeHeaders(const char *hdrs) {
@@ -199,7 +199,7 @@ StringRef create_affinity_cookie(BlockAllocator &balloc, const StringRef &name,
p = std::ranges::copy(SECURE, p).out;
}
*p = '\0';
return StringRef{std::span{std::ranges::begin(iov), p}};
return as_string_ref(std::ranges::begin(iov), p);
}
bool require_cookie_secure_attribute(SessionAffinityCookieSecure secure,
@@ -262,7 +262,7 @@ StringRef create_altsvc_header_value(BlockAllocator &balloc,
assert(static_cast<size_t>(p - std::ranges::begin(iov)) == len);
return StringRef{std::span{std::ranges::begin(iov), p}};
return as_string_ref(std::ranges::begin(iov), p);
}
bool check_http_scheme(const StringRef &scheme, bool encrypted) {

View File

@@ -444,8 +444,8 @@ int Http2DownstreamConnection::push_request_headers() {
p = http::create_via_header_value(p, req.http_major, req.http_minor);
*p = '\0';
nva.push_back(http2::make_field(
"via"_sr, StringRef{std::span{std::ranges::begin(iov), p}}));
nva.push_back(
http2::make_field("via"_sr, as_string_ref(std::ranges::begin(iov), p)));
}
auto te = req.fs.header(http2::HD_TE);

View File

@@ -1844,8 +1844,8 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
p = http::create_via_header_value(p, resp.http_major, resp.http_minor);
*p = '\0';
nva.push_back(http2::make_field(
"via"_sr, StringRef{std::span{std::ranges::begin(iov), p}}));
nva.push_back(
http2::make_field("via"_sr, as_string_ref(std::ranges::begin(iov), p)));
}
for (auto &p : httpconf.add_response_headers) {

View File

@@ -1383,8 +1383,8 @@ int Http3Upstream::on_downstream_header_complete(Downstream *downstream) {
p = http::create_via_header_value(p, resp.http_major, resp.http_minor);
*p = '\0';
nva.push_back(http3::make_field(
"via"_sr, StringRef{std::span{std::ranges::begin(iov), p}}));
nva.push_back(
http3::make_field("via"_sr, as_string_ref(std::ranges::begin(iov), p)));
}
for (auto &p : httpconf.add_response_headers) {

View File

@@ -571,7 +571,7 @@ int HttpDownstreamConnection::push_request_headers() {
auto iov = make_byte_ref(balloc, base64::encode_length(nonce.size()) + 1);
auto p = base64::encode(nonce, std::ranges::begin(iov));
*p = '\0';
auto key = StringRef{std::span{std::ranges::begin(iov), p}};
auto key = as_string_ref(std::ranges::begin(iov), p);
downstream_->set_ws_key(key);
buf->append("Sec-Websocket-Key: ");

View File

@@ -284,7 +284,7 @@ void rewrite_request_host_path_from_uri(BlockAllocator &balloc, Request &req,
}
*p = '\0';
req.authority = StringRef{std::span{std::ranges::begin(iovec), p}};
req.authority = as_string_ref(std::ranges::begin(iovec), p);
} else {
req.authority = authority;
}

View File

@@ -548,7 +548,7 @@ StringRef construct_absolute_request_uri(BlockAllocator &balloc,
p = std::ranges::copy(req.path, p).out;
*p = '\0';
return StringRef{std::span{std::ranges::begin(iov), p}};
return as_string_ref(std::ranges::begin(iov), p);
}
} // namespace

View File

@@ -1286,7 +1286,7 @@ size_t match_downstream_addr_group_host(
auto ep =
std::copy(std::begin(host) + 1, std::end(host), std::begin(rev_host_src));
std::reverse(std::begin(rev_host_src), ep);
auto rev_host = StringRef{std::span{std::begin(rev_host_src), ep}};
auto rev_host = as_string_ref(std::begin(rev_host_src), ep);
ssize_t best_group = -1;
const RNode *last_node = nullptr;
@@ -1387,7 +1387,7 @@ size_t match_downstream_addr_group(
auto ep = std::copy(std::begin(host), std::end(host), std::begin(low_host));
*ep = '\0';
util::inp_strlower(std::begin(low_host), ep);
host = StringRef{std::span{std::begin(low_host), ep}};
host = as_string_ref(std::begin(low_host), ep);
}
return match_downstream_addr_group_host(routerconf, host, path, groups,
catch_all, balloc);

View File

@@ -504,6 +504,26 @@ requires(std::ranges::contiguous_range<R> && std::ranges::sized_range<R> &&
std::ranges::size(r)};
}
// Returns StringRef over a given range |r|.
template <typename R>
requires(std::ranges::contiguous_range<R> && std::ranges::sized_range<R> &&
std::ranges::borrowed_range<R> &&
sizeof(std::ranges::range_value_t<R>) == sizeof(StringRef::value_type))
[[nodiscard]] StringRef as_string_ref(R &&r) {
return StringRef{
reinterpret_cast<StringRef::const_pointer>(std::ranges::data(r)),
std::ranges::size(r)};
}
// Returns StringRef over a given range [|first|, |last|).
template <std::contiguous_iterator I>
requires(sizeof(std::iter_value_t<I>) == sizeof(StringRef::value_type))
[[nodiscard]] StringRef as_string_ref(I first, I last) {
return StringRef{
reinterpret_cast<StringRef::const_pointer>(std::to_address(first)),
static_cast<size_t>(std::ranges::distance(first, last))};
}
inline int run_app(std::function<int(int, char **)> app, int argc,
char **argv) {
try {

View File

@@ -42,6 +42,7 @@ const MunitTest tests[]{
munit_void_test(test_template_string_ref),
munit_void_test(test_template_as_uint8_span),
munit_void_test(test_template_as_string_view),
munit_void_test(test_template_as_string_ref),
munit_test_end(),
};
} // namespace
@@ -251,4 +252,20 @@ void test_template_as_string_view(void) {
}
}
void test_template_as_string_ref(void) {
{
auto a = std::to_array<uint8_t>({'a', 'l', 'p', 'h', 'a'});
assert_stdsv_equal("alpha"sv, as_string_ref(a));
assert_stdsv_equal("alpha"sv, as_string_ref(a.begin(), a.end()));
}
{
auto s = ""s;
assert_stdsv_equal(""sv, as_string_ref(s));
assert_stdsv_equal(""sv, as_string_ref(s.begin(), s.end()));
}
}
} // namespace nghttp2

View File

@@ -41,6 +41,7 @@ munit_void_test_decl(test_template_immutable_string)
munit_void_test_decl(test_template_string_ref)
munit_void_test_decl(test_template_as_uint8_span)
munit_void_test_decl(test_template_as_string_view)
munit_void_test_decl(test_template_as_string_ref)
} // namespace nghttp2

View File

@@ -201,7 +201,7 @@ StringRef percent_encode_token(BlockAllocator &balloc,
*p = '\0';
return StringRef{std::span{std::begin(iov), p}};
return as_string_ref(std::begin(iov), p);
}
size_t percent_encode_tokenlen(const StringRef &target) {
@@ -247,7 +247,7 @@ StringRef quote_string(BlockAllocator &balloc, const StringRef &target) {
*p = '\0';
return StringRef{std::span{std::begin(iov), p}};
return as_string_ref(std::begin(iov), p);
}
size_t quote_stringlen(const StringRef &target) {
@@ -517,7 +517,7 @@ StringRef format_hex(BlockAllocator &balloc, std::span<const uint8_t> s) {
*p = '\0';
return StringRef{std::span{std::begin(iov), p}};
return as_string_ref(std::begin(iov), p);
}
void to_token68(std::string &base64str) {
@@ -560,7 +560,7 @@ StringRef to_base64(BlockAllocator &balloc, const StringRef &token68str) {
*p = '\0';
return StringRef{std::span{std::begin(iov), p}};
return as_string_ref(std::begin(iov), p);
}
namespace {
@@ -1614,7 +1614,7 @@ StringRef percent_decode(BlockAllocator &balloc, const StringRef &src) {
*p++ = *first;
}
*p = '\0';
return StringRef{std::span{std::begin(iov), p}};
return as_string_ref(std::begin(iov), p);
}
// Returns x**y

View File

@@ -401,7 +401,7 @@ StringRef make_string_ref_uint(BlockAllocator &balloc, T n) {
auto p = std::begin(iov);
p = util::utos(p, n);
*p = '\0';
return StringRef{std::span{std::begin(iov), p}};
return as_string_ref(std::begin(iov), p);
}
template <typename T> std::string utos_unit(T n) {
@@ -739,7 +739,7 @@ StringRef make_hostport(OutputIt first, const StringRef &host, uint16_t port) {
*p = '\0';
return StringRef{std::span{first, p}};
return as_string_ref(first, p);
}
// Creates "host:port" string using given |host| and |port|. If
@@ -770,7 +770,7 @@ StringRef make_http_hostport(OutputIt first, const StringRef &host,
*p = '\0';
return StringRef{std::span{first, p}};
return as_string_ref(first, p);
}
// hexdump dumps |data| of length |datalen| in the format similar to