mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-07 02:28:53 +08:00
Merge pull request #2341 from nghttp2/ranges-http2
http2: Adopt std::ranges
This commit is contained in:
310
src/http2.cc
310
src/http2.cc
@@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
using namespace std::literals;
|
||||||
|
|
||||||
namespace nghttp2 {
|
namespace nghttp2 {
|
||||||
|
|
||||||
namespace http2 {
|
namespace http2 {
|
||||||
@@ -280,9 +282,9 @@ void copy_url_component(std::string &dest, const urlparse_url *u, int field,
|
|||||||
|
|
||||||
Headers::value_type to_header(const StringRef &name, const StringRef &value,
|
Headers::value_type to_header(const StringRef &name, const StringRef &value,
|
||||||
bool no_index, int32_t token) {
|
bool no_index, int32_t token) {
|
||||||
return Header(std::string{std::begin(name), std::end(name)},
|
return Header(std::string{std::ranges::begin(name), std::ranges::end(name)},
|
||||||
std::string{std::begin(value), std::end(value)}, no_index,
|
std::string{std::ranges::begin(value), std::ranges::end(value)},
|
||||||
token);
|
no_index, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_header(Headers &nva, const StringRef &name, const StringRef &value,
|
void add_header(Headers &nva, const StringRef &name, const StringRef &value,
|
||||||
@@ -308,12 +310,13 @@ namespace {
|
|||||||
void copy_headers_to_nva_internal(std::vector<nghttp2_nv> &nva,
|
void copy_headers_to_nva_internal(std::vector<nghttp2_nv> &nva,
|
||||||
const HeaderRefs &headers, uint8_t nv_flags,
|
const HeaderRefs &headers, uint8_t nv_flags,
|
||||||
uint32_t flags) {
|
uint32_t flags) {
|
||||||
auto it_forwarded = std::end(headers);
|
auto it_forwarded = std::ranges::end(headers);
|
||||||
auto it_xff = std::end(headers);
|
auto it_xff = std::ranges::end(headers);
|
||||||
auto it_xfp = std::end(headers);
|
auto it_xfp = std::ranges::end(headers);
|
||||||
auto it_via = std::end(headers);
|
auto it_via = std::ranges::end(headers);
|
||||||
|
|
||||||
for (auto it = std::begin(headers); it != std::end(headers); ++it) {
|
for (auto it = std::ranges::begin(headers); it != std::ranges::end(headers);
|
||||||
|
++it) {
|
||||||
auto kv = &(*it);
|
auto kv = &(*it);
|
||||||
if (kv->name.empty() || kv->name[0] == ':') {
|
if (kv->name.empty() || kv->name[0] == ':') {
|
||||||
continue;
|
continue;
|
||||||
@@ -350,7 +353,7 @@ void copy_headers_to_nva_internal(std::vector<nghttp2_nv> &nva,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it_forwarded == std::end(headers)) {
|
if (it_forwarded == std::ranges::end(headers)) {
|
||||||
it_forwarded = it;
|
it_forwarded = it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -363,7 +366,7 @@ void copy_headers_to_nva_internal(std::vector<nghttp2_nv> &nva,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it_xff == std::end(headers)) {
|
if (it_xff == std::ranges::end(headers)) {
|
||||||
it_xff = it;
|
it_xff = it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -376,7 +379,7 @@ void copy_headers_to_nva_internal(std::vector<nghttp2_nv> &nva,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it_xfp == std::end(headers)) {
|
if (it_xfp == std::ranges::end(headers)) {
|
||||||
it_xfp = it;
|
it_xfp = it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -389,7 +392,7 @@ void copy_headers_to_nva_internal(std::vector<nghttp2_nv> &nva,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it_via == std::end(headers)) {
|
if (it_via == std::ranges::end(headers)) {
|
||||||
it_via = it;
|
it_via = it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -419,12 +422,13 @@ void copy_headers_to_nva_nocopy(std::vector<nghttp2_nv> &nva,
|
|||||||
void build_http1_headers_from_headers(DefaultMemchunks *buf,
|
void build_http1_headers_from_headers(DefaultMemchunks *buf,
|
||||||
const HeaderRefs &headers,
|
const HeaderRefs &headers,
|
||||||
uint32_t flags) {
|
uint32_t flags) {
|
||||||
auto it_forwarded = std::end(headers);
|
auto it_forwarded = std::ranges::end(headers);
|
||||||
auto it_xff = std::end(headers);
|
auto it_xff = std::ranges::end(headers);
|
||||||
auto it_xfp = std::end(headers);
|
auto it_xfp = std::ranges::end(headers);
|
||||||
auto it_via = std::end(headers);
|
auto it_via = std::ranges::end(headers);
|
||||||
|
|
||||||
for (auto it = std::begin(headers); it != std::end(headers); ++it) {
|
for (auto it = std::ranges::begin(headers); it != std::ranges::end(headers);
|
||||||
|
++it) {
|
||||||
auto kv = &(*it);
|
auto kv = &(*it);
|
||||||
if (kv->name.empty() || kv->name[0] == ':') {
|
if (kv->name.empty() || kv->name[0] == ':') {
|
||||||
continue;
|
continue;
|
||||||
@@ -454,7 +458,7 @@ void build_http1_headers_from_headers(DefaultMemchunks *buf,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it_forwarded == std::end(headers)) {
|
if (it_forwarded == std::ranges::end(headers)) {
|
||||||
it_forwarded = it;
|
it_forwarded = it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -467,7 +471,7 @@ void build_http1_headers_from_headers(DefaultMemchunks *buf,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it_xff == std::end(headers)) {
|
if (it_xff == std::ranges::end(headers)) {
|
||||||
it_xff = it;
|
it_xff = it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -480,7 +484,7 @@ void build_http1_headers_from_headers(DefaultMemchunks *buf,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it_xfp == std::end(headers)) {
|
if (it_xfp == std::ranges::end(headers)) {
|
||||||
it_xfp = it;
|
it_xfp = it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -493,7 +497,7 @@ void build_http1_headers_from_headers(DefaultMemchunks *buf,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it_via == std::end(headers)) {
|
if (it_via == std::ranges::end(headers)) {
|
||||||
it_via = it;
|
it_via = it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -577,8 +581,9 @@ StringRef rewrite_location_uri(BlockAllocator &balloc, const StringRef &uri,
|
|||||||
return StringRef{};
|
return StringRef{};
|
||||||
}
|
}
|
||||||
auto field = &u.field_data[URLPARSE_HOST];
|
auto field = &u.field_data[URLPARSE_HOST];
|
||||||
if (!util::starts_with(std::begin(match_host), std::end(match_host),
|
if (!util::starts_with(std::ranges::begin(match_host),
|
||||||
&uri[field->off], &uri[field->off] + field->len) ||
|
std::ranges::end(match_host), &uri[field->off],
|
||||||
|
&uri[field->off] + field->len) ||
|
||||||
(match_host.size() != field->len && match_host[field->len] != ':')) {
|
(match_host.size() != field->len && match_host[field->len] != ':')) {
|
||||||
return StringRef{};
|
return StringRef{};
|
||||||
}
|
}
|
||||||
@@ -604,32 +609,31 @@ StringRef rewrite_location_uri(BlockAllocator &balloc, const StringRef &uri,
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto iov = make_byte_ref(balloc, len + 1);
|
auto iov = make_byte_ref(balloc, len + 1);
|
||||||
auto p = std::begin(iov);
|
auto p = std::ranges::begin(iov);
|
||||||
|
|
||||||
if (!request_authority.empty()) {
|
if (!request_authority.empty()) {
|
||||||
p = std::copy(std::begin(upstream_scheme), std::end(upstream_scheme), p);
|
p = std::ranges::copy(upstream_scheme, p).out;
|
||||||
p = util::copy_lit(p, "://");
|
p = std::ranges::copy("://"sv, p).out;
|
||||||
p =
|
p = std::ranges::copy(request_authority, p).out;
|
||||||
std::copy(std::begin(request_authority), std::end(request_authority), p);
|
|
||||||
}
|
}
|
||||||
if (u.field_set & (1 << URLPARSE_PATH)) {
|
if (u.field_set & (1 << URLPARSE_PATH)) {
|
||||||
field = &u.field_data[URLPARSE_PATH];
|
field = &u.field_data[URLPARSE_PATH];
|
||||||
p = std::copy_n(&uri[field->off], field->len, p);
|
p = std::ranges::copy_n(&uri[field->off], field->len, p).out;
|
||||||
}
|
}
|
||||||
if (u.field_set & (1 << URLPARSE_QUERY)) {
|
if (u.field_set & (1 << URLPARSE_QUERY)) {
|
||||||
field = &u.field_data[URLPARSE_QUERY];
|
field = &u.field_data[URLPARSE_QUERY];
|
||||||
*p++ = '?';
|
*p++ = '?';
|
||||||
p = std::copy_n(&uri[field->off], field->len, p);
|
p = std::ranges::copy_n(&uri[field->off], field->len, p).out;
|
||||||
}
|
}
|
||||||
if (u.field_set & (1 << URLPARSE_FRAGMENT)) {
|
if (u.field_set & (1 << URLPARSE_FRAGMENT)) {
|
||||||
field = &u.field_data[URLPARSE_FRAGMENT];
|
field = &u.field_data[URLPARSE_FRAGMENT];
|
||||||
*p++ = '#';
|
*p++ = '#';
|
||||||
p = std::copy_n(&uri[field->off], field->len, p);
|
p = std::ranges::copy_n(&uri[field->off], field->len, p).out;
|
||||||
}
|
}
|
||||||
|
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
return StringRef{std::span{std::begin(iov), p}};
|
return StringRef{std::span{std::ranges::begin(iov), p}};
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_http_status_code(const StringRef &src) {
|
int parse_http_status_code(const StringRef &src) {
|
||||||
@@ -913,9 +917,7 @@ int lookup_token(const StringRef &name) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_hdidx(HeaderIndex &hdidx) {
|
void init_hdidx(HeaderIndex &hdidx) { std::ranges::fill(hdidx, -1); }
|
||||||
std::fill(std::begin(hdidx), std::end(hdidx), -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void index_header(HeaderIndex &hdidx, int32_t token, size_t idx) {
|
void index_header(HeaderIndex &hdidx, int32_t token, size_t idx) {
|
||||||
if (token == -1) {
|
if (token == -1) {
|
||||||
@@ -1028,43 +1030,34 @@ namespace {
|
|||||||
// Returns true if link-param does not match pattern |pat| of length
|
// Returns true if link-param does not match pattern |pat| of length
|
||||||
// |patlen| or it has empty value (""). |pat| should be parmname
|
// |patlen| or it has empty value (""). |pat| should be parmname
|
||||||
// followed by "=".
|
// followed by "=".
|
||||||
bool check_link_param_empty(const char *first, const char *last,
|
bool check_link_param_empty(const std::string_view &s,
|
||||||
const char *pat, size_t patlen) {
|
const std::string_view &pat) {
|
||||||
if (first + patlen <= last) {
|
return s.size() < pat.size() ||
|
||||||
if (std::equal(pat, pat + patlen, first, util::CaseCmp())) {
|
!std::ranges::equal(s.substr(0, pat.size()), pat, util::CaseCmp()) ||
|
||||||
// we only accept URI if pat is followed by "" (e.g.,
|
(s.size() >= pat.size() + 2 &&
|
||||||
// loadpolicy="") here.
|
// we only accept URI if pat is followed by ""
|
||||||
if (first + patlen + 2 <= last) {
|
// (e.g., loadpolicy="") here.
|
||||||
if (*(first + patlen) != '"' || *(first + patlen + 1) != '"') {
|
s[pat.size()] == '"' && s[pat.size() + 1] == '"');
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// here we got invalid production (anchor=") or anchor=?
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// Returns true if link-param consists of only parmname, and it
|
// Returns true if link-param consists of only parmname, and it
|
||||||
// matches string [pat, pat + patlen).
|
// matches string [pat, pat + patlen).
|
||||||
bool check_link_param_without_value(const char *first, const char *last,
|
bool check_link_param_without_value(const std::string_view &s,
|
||||||
const char *pat, size_t patlen) {
|
const std::string_view &pat) {
|
||||||
if (first + patlen > last) {
|
if (s.size() < pat.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first + patlen == last) {
|
if (s.size() == pat.size()) {
|
||||||
return std::equal(pat, pat + patlen, first, util::CaseCmp());
|
return std::ranges::equal(s, pat, util::CaseCmp());
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (*(first + patlen)) {
|
switch (s[pat.size()]) {
|
||||||
case ';':
|
case ';':
|
||||||
case ',':
|
case ',':
|
||||||
return std::equal(pat, pat + patlen, first, util::CaseCmp());
|
return std::ranges::equal(s.substr(0, pat.size()), pat, util::CaseCmp());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1079,7 +1072,7 @@ parse_next_link_header_once(const char *first, const char *last) {
|
|||||||
return {{StringRef{}}, last};
|
return {{StringRef{}}, last};
|
||||||
}
|
}
|
||||||
auto url_first = ++first;
|
auto url_first = ++first;
|
||||||
first = std::find(first, last, '>');
|
first = std::ranges::find(first, last, '>');
|
||||||
if (first == last) {
|
if (first == last) {
|
||||||
return {{StringRef{}}, first};
|
return {{StringRef{}}, first};
|
||||||
}
|
}
|
||||||
@@ -1110,16 +1103,15 @@ parse_next_link_header_once(const char *first, const char *last) {
|
|||||||
if (!ign) {
|
if (!ign) {
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
// rel can take several relations using quoted form.
|
// rel can take several relations using quoted form.
|
||||||
static constexpr char PLP[] = "rel=\"";
|
static constexpr auto PLP = "rel=\""sv;
|
||||||
static constexpr size_t PLPLEN = str_size(PLP);
|
static constexpr auto PLT = "preload"sv;
|
||||||
|
|
||||||
static constexpr char PLT[] = "preload";
|
if (first + PLP.size() < last && *(first + PLP.size() - 1) == '"' &&
|
||||||
static constexpr size_t PLTLEN = str_size(PLT);
|
std::ranges::equal(PLP, std::string_view{first, PLP.size()},
|
||||||
if (first + PLPLEN < last && *(first + PLPLEN - 1) == '"' &&
|
util::CaseCmp())) {
|
||||||
std::equal(PLP, PLP + PLPLEN, first, util::CaseCmp())) {
|
|
||||||
// we have to search preload in whitespace separated list:
|
// we have to search preload in whitespace separated list:
|
||||||
// rel="preload something http://example.org/foo"
|
// rel="preload something http://example.org/foo"
|
||||||
first += PLPLEN;
|
first += PLP.size();
|
||||||
auto start = first;
|
auto start = first;
|
||||||
for (; first != last;) {
|
for (; first != last;) {
|
||||||
if (*first != ' ' && *first != '"') {
|
if (*first != ' ' && *first != '"') {
|
||||||
@@ -1131,8 +1123,9 @@ parse_next_link_header_once(const char *first, const char *last) {
|
|||||||
return {{StringRef{}}, last};
|
return {{StringRef{}}, last};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ok && start + PLTLEN == first &&
|
if (!ok && start + PLT.size() == first &&
|
||||||
std::equal(PLT, PLT + PLTLEN, start, util::CaseCmp())) {
|
std::ranges::equal(PLT, std::string_view{start, PLT.size()},
|
||||||
|
util::CaseCmp())) {
|
||||||
ok = true;
|
ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1160,56 +1153,50 @@ parse_next_link_header_once(const char *first, const char *last) {
|
|||||||
}
|
}
|
||||||
// we are only interested in rel=preload parameter. Others are
|
// we are only interested in rel=preload parameter. Others are
|
||||||
// simply skipped.
|
// simply skipped.
|
||||||
static constexpr char PL[] = "rel=preload";
|
static constexpr auto PL = "rel=preload"sv;
|
||||||
static constexpr size_t PLLEN = str_size(PL);
|
if (first + PL.size() == last) {
|
||||||
if (first + PLLEN == last) {
|
if (std::ranges::equal(PL, std::string_view{first, PL.size()},
|
||||||
if (std::equal(PL, PL + PLLEN, first, util::CaseCmp())) {
|
util::CaseCmp())) {
|
||||||
// ok = true;
|
// ok = true;
|
||||||
// this is the end of sequence
|
// this is the end of sequence
|
||||||
return {{{url_first, url_last}}, last};
|
return {{{url_first, url_last}}, last};
|
||||||
}
|
}
|
||||||
} else if (first + PLLEN + 1 <= last) {
|
} else if (first + PL.size() + 1 <= last) {
|
||||||
switch (*(first + PLLEN)) {
|
switch (*(first + PL.size())) {
|
||||||
case ',':
|
case ',':
|
||||||
if (!std::equal(PL, PL + PLLEN, first, util::CaseCmp())) {
|
if (!std::ranges::equal(PL, std::string_view{first, PL.size()},
|
||||||
|
util::CaseCmp())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// ok = true;
|
// ok = true;
|
||||||
// skip including ','
|
// skip including ','
|
||||||
first += PLLEN + 1;
|
first += PL.size() + 1;
|
||||||
return {{{url_first, url_last}}, first};
|
return {{{url_first, url_last}}, first};
|
||||||
case ';':
|
case ';':
|
||||||
if (!std::equal(PL, PL + PLLEN, first, util::CaseCmp())) {
|
if (!std::ranges::equal(PL, std::string_view{first, PL.size()},
|
||||||
|
util::CaseCmp())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ok = true;
|
ok = true;
|
||||||
// skip including ';'
|
// skip including ';'
|
||||||
first += PLLEN + 1;
|
first += PL.size() + 1;
|
||||||
// continue parse next link-param
|
// continue parse next link-param
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// we have to reject URI if we have nonempty anchor parameter.
|
// we have to reject URI if we have nonempty anchor parameter.
|
||||||
static constexpr char ANCHOR[] = "anchor=";
|
if (!ign && !check_link_param_empty({first, last}, "anchor="sv)) {
|
||||||
static constexpr size_t ANCHORLEN = str_size(ANCHOR);
|
|
||||||
if (!ign && !check_link_param_empty(first, last, ANCHOR, ANCHORLEN)) {
|
|
||||||
ign = true;
|
ign = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reject URI if we have non-empty loadpolicy. This could be
|
// reject URI if we have non-empty loadpolicy. This could be
|
||||||
// tightened up to just pick up "next" or "insert".
|
// tightened up to just pick up "next" or "insert".
|
||||||
static constexpr char LOADPOLICY[] = "loadpolicy=";
|
if (!ign && !check_link_param_empty({first, last}, "loadpolicy="sv)) {
|
||||||
static constexpr size_t LOADPOLICYLEN = str_size(LOADPOLICY);
|
|
||||||
if (!ign &&
|
|
||||||
!check_link_param_empty(first, last, LOADPOLICY, LOADPOLICYLEN)) {
|
|
||||||
ign = true;
|
ign = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reject URI if we have nopush attribute.
|
// reject URI if we have nopush attribute.
|
||||||
static constexpr char NOPUSH[] = "nopush";
|
if (!ign && check_link_param_without_value({first, last}, "nopush"sv)) {
|
||||||
static constexpr size_t NOPUSHLEN = str_size(NOPUSH);
|
|
||||||
if (!ign &&
|
|
||||||
check_link_param_without_value(first, last, NOPUSH, NOPUSHLEN)) {
|
|
||||||
ign = true;
|
ign = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1304,8 +1291,8 @@ almost_done:
|
|||||||
|
|
||||||
std::vector<LinkHeader> parse_link_header(const StringRef &src) {
|
std::vector<LinkHeader> parse_link_header(const StringRef &src) {
|
||||||
std::vector<LinkHeader> res;
|
std::vector<LinkHeader> res;
|
||||||
for (auto first = std::begin(src); first != std::end(src);) {
|
for (auto first = std::ranges::begin(src); first != std::ranges::end(src);) {
|
||||||
auto rv = parse_next_link_header_once(first, std::end(src));
|
auto rv = parse_next_link_header_once(first, std::ranges::end(src));
|
||||||
first = rv.second;
|
first = rv.second;
|
||||||
auto &link = rv.first;
|
auto &link = rv.first;
|
||||||
if (!link.uri.empty()) {
|
if (!link.uri.empty()) {
|
||||||
@@ -1576,12 +1563,12 @@ int construct_push_component(BlockAllocator &balloc, StringRef &scheme,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// treat link_url as relative URI.
|
// treat link_url as relative URI.
|
||||||
auto end = std::find(std::begin(uri), std::end(uri), '#');
|
auto end = std::ranges::find(uri, '#');
|
||||||
auto q = std::find(std::begin(uri), end, '?');
|
auto q = std::ranges::find(std::ranges::begin(uri), end, '?');
|
||||||
|
|
||||||
rel = StringRef{std::begin(uri), q};
|
rel = StringRef{std::ranges::begin(uri), q};
|
||||||
if (q != end) {
|
if (q != end) {
|
||||||
relq = StringRef{q + 1, std::end(uri)};
|
relq = StringRef{q + 1, std::ranges::end(uri)};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (u.field_set & (1 << URLPARSE_SCHEMA)) {
|
if (u.field_set & (1 << URLPARSE_SCHEMA)) {
|
||||||
@@ -1596,15 +1583,15 @@ int construct_push_component(BlockAllocator &balloc, StringRef &scheme,
|
|||||||
len += 1 + str_size("65535");
|
len += 1 + str_size("65535");
|
||||||
}
|
}
|
||||||
auto iov = make_byte_ref(balloc, len + 1);
|
auto iov = make_byte_ref(balloc, len + 1);
|
||||||
auto p = std::begin(iov);
|
auto p = std::ranges::begin(iov);
|
||||||
p = std::copy(std::begin(auth), std::end(auth), p);
|
p = std::ranges::copy(auth, p).out;
|
||||||
if (port_exists) {
|
if (port_exists) {
|
||||||
*p++ = ':';
|
*p++ = ':';
|
||||||
p = util::utos(p, u.port);
|
p = util::utos(p, u.port);
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
authority = StringRef{std::span{std::begin(iov), p}};
|
authority = StringRef{std::span{std::ranges::begin(iov), p}};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u.field_set & (1 << URLPARSE_PATH)) {
|
if (u.field_set & (1 << URLPARSE_PATH)) {
|
||||||
@@ -1669,30 +1656,30 @@ StringRef path_join(BlockAllocator &balloc, const StringRef &base_path,
|
|||||||
make_byte_ref(balloc, std::max(static_cast<size_t>(1), base_path.size()) +
|
make_byte_ref(balloc, std::max(static_cast<size_t>(1), base_path.size()) +
|
||||||
rel_path.size() + 1 +
|
rel_path.size() + 1 +
|
||||||
std::max(base_query.size(), rel_query.size()) + 1);
|
std::max(base_query.size(), rel_query.size()) + 1);
|
||||||
auto p = std::begin(res);
|
auto p = std::ranges::begin(res);
|
||||||
|
|
||||||
if (rel_path.empty()) {
|
if (rel_path.empty()) {
|
||||||
if (base_path.empty()) {
|
if (base_path.empty()) {
|
||||||
*p++ = '/';
|
*p++ = '/';
|
||||||
} else {
|
} else {
|
||||||
p = std::copy(std::begin(base_path), std::end(base_path), p);
|
p = std::ranges::copy(base_path, p).out;
|
||||||
}
|
}
|
||||||
if (rel_query.empty()) {
|
if (rel_query.empty()) {
|
||||||
if (!base_query.empty()) {
|
if (!base_query.empty()) {
|
||||||
*p++ = '?';
|
*p++ = '?';
|
||||||
p = std::copy(std::begin(base_query), std::end(base_query), p);
|
p = std::ranges::copy(base_query, p).out;
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return StringRef{std::span{std::begin(res), p}};
|
return StringRef{std::span{std::ranges::begin(res), p}};
|
||||||
}
|
}
|
||||||
*p++ = '?';
|
*p++ = '?';
|
||||||
p = std::copy(std::begin(rel_query), std::end(rel_query), p);
|
p = std::ranges::copy(rel_query, p).out;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return StringRef{std::span{std::begin(res), p}};
|
return StringRef{std::span{std::ranges::begin(res), p}};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto first = std::begin(rel_path);
|
auto first = std::ranges::begin(rel_path);
|
||||||
auto last = std::end(rel_path);
|
auto last = std::ranges::end(rel_path);
|
||||||
|
|
||||||
if (rel_path[0] == '/') {
|
if (rel_path[0] == '/') {
|
||||||
*p++ = '/';
|
*p++ = '/';
|
||||||
@@ -1702,55 +1689,55 @@ StringRef path_join(BlockAllocator &balloc, const StringRef &base_path,
|
|||||||
} else if (base_path.empty()) {
|
} else if (base_path.empty()) {
|
||||||
*p++ = '/';
|
*p++ = '/';
|
||||||
} else {
|
} else {
|
||||||
p = std::copy(std::begin(base_path), std::end(base_path), p);
|
p = std::ranges::copy(base_path, p).out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; first != last;) {
|
for (; first != last;) {
|
||||||
if (*first == '.') {
|
if (*first == '.') {
|
||||||
if (first + 1 == last) {
|
if (first + 1 == last) {
|
||||||
if (*(p - 1) != '/') {
|
if (*(p - 1) != '/') {
|
||||||
p = eat_file(std::begin(res), p);
|
p = eat_file(std::ranges::begin(res), p);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*(first + 1) == '/') {
|
if (*(first + 1) == '/') {
|
||||||
if (*(p - 1) != '/') {
|
if (*(p - 1) != '/') {
|
||||||
p = eat_file(std::begin(res), p);
|
p = eat_file(std::ranges::begin(res), p);
|
||||||
}
|
}
|
||||||
first += 2;
|
first += 2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (*(first + 1) == '.') {
|
if (*(first + 1) == '.') {
|
||||||
if (first + 2 == last) {
|
if (first + 2 == last) {
|
||||||
p = eat_dir(std::begin(res), p);
|
p = eat_dir(std::ranges::begin(res), p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (*(first + 2) == '/') {
|
if (*(first + 2) == '/') {
|
||||||
p = eat_dir(std::begin(res), p);
|
p = eat_dir(std::ranges::begin(res), p);
|
||||||
first += 3;
|
first += 3;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (*(p - 1) != '/') {
|
if (*(p - 1) != '/') {
|
||||||
p = eat_file(std::begin(res), p);
|
p = eat_file(std::ranges::begin(res), p);
|
||||||
}
|
}
|
||||||
auto slash = std::find(first, last, '/');
|
auto slash = std::ranges::find(first, last, '/');
|
||||||
if (slash == last) {
|
if (slash == last) {
|
||||||
p = std::copy(first, last, p);
|
p = std::ranges::copy(first, last, p).out;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
p = std::copy(first, slash + 1, p);
|
p = std::ranges::copy(first, slash + 1, p).out;
|
||||||
first = slash + 1;
|
first = slash + 1;
|
||||||
for (; first != last && *first == '/'; ++first)
|
for (; first != last && *first == '/'; ++first)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
if (!rel_query.empty()) {
|
if (!rel_query.empty()) {
|
||||||
*p++ = '?';
|
*p++ = '?';
|
||||||
p = std::copy(std::begin(rel_query), std::end(rel_query), p);
|
p = std::ranges::copy(rel_query, p).out;
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return StringRef{std::span{std::begin(res), p}};
|
return StringRef{std::span{std::ranges::begin(res), p}};
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
|
StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
|
||||||
@@ -1760,16 +1747,16 @@ StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
|
|||||||
|
|
||||||
// We won't find %XX if length is less than 3.
|
// We won't find %XX if length is less than 3.
|
||||||
if (path.size() < 3 ||
|
if (path.size() < 3 ||
|
||||||
std::find(std::begin(path), std::end(path), '%') == std::end(path)) {
|
std::ranges::find(path, '%') == std::ranges::end(path)) {
|
||||||
return path_join(balloc, StringRef{}, StringRef{}, path, query);
|
return path_join(balloc, StringRef{}, StringRef{}, path, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
// includes last terminal NULL.
|
// includes last terminal NULL.
|
||||||
auto result = make_byte_ref(balloc, path.size() + 1);
|
auto result = make_byte_ref(balloc, path.size() + 1);
|
||||||
auto p = std::begin(result);
|
auto p = std::ranges::begin(result);
|
||||||
|
|
||||||
auto it = std::begin(path);
|
auto it = std::ranges::begin(path);
|
||||||
for (; it + 2 < std::end(path);) {
|
for (; it + 2 < std::ranges::end(path);) {
|
||||||
if (*it == '%') {
|
if (*it == '%') {
|
||||||
if (util::is_hex_digit(*(it + 1)) && util::is_hex_digit(*(it + 2))) {
|
if (util::is_hex_digit(*(it + 1)) && util::is_hex_digit(*(it + 2))) {
|
||||||
auto c =
|
auto c =
|
||||||
@@ -1793,11 +1780,11 @@ StringRef normalize_path(BlockAllocator &balloc, const StringRef &path,
|
|||||||
*p++ = *it++;
|
*p++ = *it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = std::copy(it, std::end(path), p);
|
p = std::ranges::copy(it, std::ranges::end(path), p).out;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
return path_join(balloc, StringRef{}, StringRef{},
|
return path_join(balloc, StringRef{}, StringRef{},
|
||||||
StringRef{std::span{std::begin(result), p}}, query);
|
StringRef{std::span{std::ranges::begin(result), p}}, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
|
StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
|
||||||
@@ -1807,16 +1794,16 @@ StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
|
|||||||
|
|
||||||
// We won't find %XX if length is less than 3.
|
// We won't find %XX if length is less than 3.
|
||||||
if (path.size() < 3 ||
|
if (path.size() < 3 ||
|
||||||
std::find(std::begin(path), std::end(path), '%') == std::end(path)) {
|
std::ranges::find(path, '%') == std::ranges::end(path)) {
|
||||||
return path_join(balloc, StringRef{}, StringRef{}, path, query);
|
return path_join(balloc, StringRef{}, StringRef{}, path, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
// includes last terminal NULL.
|
// includes last terminal NULL.
|
||||||
auto result = make_byte_ref(balloc, path.size() + 1);
|
auto result = make_byte_ref(balloc, path.size() + 1);
|
||||||
auto p = std::begin(result);
|
auto p = std::ranges::begin(result);
|
||||||
|
|
||||||
auto it = std::begin(path);
|
auto it = std::ranges::begin(path);
|
||||||
for (; it + 2 < std::end(path);) {
|
for (; it + 2 < std::ranges::end(path);) {
|
||||||
if (*it == '%') {
|
if (*it == '%') {
|
||||||
if (util::is_hex_digit(*(it + 1)) && util::is_hex_digit(*(it + 2))) {
|
if (util::is_hex_digit(*(it + 1)) && util::is_hex_digit(*(it + 2))) {
|
||||||
auto c =
|
auto c =
|
||||||
@@ -1840,11 +1827,11 @@ StringRef normalize_path_colon(BlockAllocator &balloc, const StringRef &path,
|
|||||||
*p++ = *it++;
|
*p++ = *it++;
|
||||||
}
|
}
|
||||||
|
|
||||||
p = std::copy(it, std::end(path), p);
|
p = std::ranges::copy(it, std::ranges::end(path), p).out;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
return path_join(balloc, StringRef{}, StringRef{},
|
return path_join(balloc, StringRef{}, StringRef{},
|
||||||
StringRef{std::span{std::begin(result), p}}, query);
|
StringRef{std::span{std::ranges::begin(result), p}}, query);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string normalize_path(const StringRef &path, const StringRef &query) {
|
std::string normalize_path(const StringRef &path, const StringRef &query) {
|
||||||
@@ -1858,44 +1845,45 @@ StringRef rewrite_clean_path(BlockAllocator &balloc, const StringRef &src) {
|
|||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
// probably, not necessary most of the case, but just in case.
|
// probably, not necessary most of the case, but just in case.
|
||||||
auto fragment = std::find(std::begin(src), std::end(src), '#');
|
auto fragment = std::ranges::find(src, '#');
|
||||||
auto raw_query = std::find(std::begin(src), fragment, '?');
|
auto raw_query = std::ranges::find(std::ranges::begin(src), fragment, '?');
|
||||||
auto query = raw_query;
|
auto query = raw_query;
|
||||||
if (query != fragment) {
|
if (query != fragment) {
|
||||||
++query;
|
++query;
|
||||||
}
|
}
|
||||||
return normalize_path(balloc, StringRef{std::begin(src), raw_query},
|
return normalize_path(balloc, StringRef{std::ranges::begin(src), raw_query},
|
||||||
StringRef{query, fragment});
|
StringRef{query, fragment});
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef copy_lower(BlockAllocator &balloc, const StringRef &src) {
|
StringRef copy_lower(BlockAllocator &balloc, const StringRef &src) {
|
||||||
auto iov = make_byte_ref(balloc, src.size() + 1);
|
auto iov = make_byte_ref(balloc, src.size() + 1);
|
||||||
auto p = std::begin(iov);
|
auto p = std::ranges::begin(iov);
|
||||||
p = std::copy(std::begin(src), std::end(src), p);
|
p = std::ranges::copy(src, p).out;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
util::inp_strlower(std::begin(iov), p);
|
util::inp_strlower(std::ranges::begin(iov), p);
|
||||||
return StringRef{std::span{std::begin(iov), p}};
|
return StringRef{std::span{std::ranges::begin(iov), p}};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool contains_trailers(const StringRef &s) {
|
bool contains_trailers(const StringRef &s) {
|
||||||
constexpr auto trailers = "trailers"_sr;
|
constexpr auto trailers = "trailers"_sr;
|
||||||
|
|
||||||
for (auto p = std::begin(s), end = std::end(s);; ++p) {
|
for (auto p = std::ranges::begin(s), end = std::ranges::end(s);; ++p) {
|
||||||
p = std::find_if(p, end, [](char c) { return c != ' ' && c != '\t'; });
|
p = std::ranges::find_if(p, end,
|
||||||
|
[](char c) { return c != ' ' && c != '\t'; });
|
||||||
if (p == end || static_cast<size_t>(end - p) < trailers.size()) {
|
if (p == end || static_cast<size_t>(end - p) < trailers.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (util::strieq(trailers, StringRef{p, p + trailers.size()})) {
|
if (util::strieq(trailers, StringRef{p, p + trailers.size()})) {
|
||||||
// Make sure that there is no character other than white spaces
|
// Make sure that there is no character other than white spaces
|
||||||
// before next "," or end of string.
|
// before next "," or end of string.
|
||||||
p = std::find_if(p + trailers.size(), end,
|
p = std::ranges::find_if(p + trailers.size(), end,
|
||||||
[](char c) { return c != ' ' && c != '\t'; });
|
[](char c) { return c != ' ' && c != '\t'; });
|
||||||
if (p == end || *p == ',') {
|
if (p == end || *p == ',') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Skip to next ",".
|
// Skip to next ",".
|
||||||
p = std::find_if(p, end, [](char c) { return c == ','; });
|
p = std::ranges::find_if(p, end, [](char c) { return c == ','; });
|
||||||
if (p == end) {
|
if (p == end) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1903,17 +1891,17 @@ bool contains_trailers(const StringRef &s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
StringRef make_websocket_accept_token(uint8_t *dest, const StringRef &key) {
|
StringRef make_websocket_accept_token(uint8_t *dest, const StringRef &key) {
|
||||||
static constexpr char magic[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
static constexpr auto magic = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"sv;
|
||||||
std::array<char, base64::encode_length(16) + str_size(magic)> s;
|
std::array<char, base64::encode_length(16) + magic.size()> s;
|
||||||
auto p = std::copy(std::begin(key), std::end(key), std::begin(s));
|
auto p = std::ranges::copy(key, std::ranges::begin(s)).out;
|
||||||
std::copy_n(magic, str_size(magic), p);
|
std::ranges::copy(magic, p);
|
||||||
|
|
||||||
std::array<uint8_t, 20> h;
|
std::array<uint8_t, 20> h;
|
||||||
if (util::sha1(h.data(), StringRef{s}) != 0) {
|
if (util::sha1(h.data(), StringRef{s}) != 0) {
|
||||||
return StringRef{};
|
return StringRef{};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto end = base64::encode(std::begin(h), std::end(h), dest);
|
auto end = base64::encode(std::ranges::begin(h), std::ranges::end(h), dest);
|
||||||
return StringRef{std::span{dest, end}};
|
return StringRef{std::span{dest, end}};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1926,7 +1914,7 @@ bool check_transfer_encoding(const StringRef &s) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = std::begin(s);
|
auto it = std::ranges::begin(s);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// token
|
// token
|
||||||
@@ -1936,25 +1924,25 @@ bool check_transfer_encoding(const StringRef &s) {
|
|||||||
|
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
for (; it != std::end(s) && util::in_token(*it); ++it)
|
for (; it != std::ranges::end(s) && util::in_token(*it); ++it)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (it == std::end(s)) {
|
if (it == std::ranges::end(s)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// OWS
|
// OWS
|
||||||
it = skip_lws(it, std::end(s));
|
it = skip_lws(it, std::ranges::end(s));
|
||||||
if (it == std::end(s)) {
|
if (it == std::ranges::end(s)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*it == ',') {
|
if (*it == ',') {
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
it = skip_lws(it, std::end(s));
|
it = skip_lws(it, std::ranges::end(s));
|
||||||
if (it == std::end(s)) {
|
if (it == std::ranges::end(s)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1970,8 +1958,8 @@ bool check_transfer_encoding(const StringRef &s) {
|
|||||||
// transfer-parameter follows
|
// transfer-parameter follows
|
||||||
|
|
||||||
// OWS
|
// OWS
|
||||||
it = skip_lws(it, std::end(s));
|
it = skip_lws(it, std::ranges::end(s));
|
||||||
if (it == std::end(s)) {
|
if (it == std::ranges::end(s)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1982,10 +1970,10 @@ bool check_transfer_encoding(const StringRef &s) {
|
|||||||
|
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
for (; it != std::end(s) && util::in_token(*it); ++it)
|
for (; it != std::ranges::end(s) && util::in_token(*it); ++it)
|
||||||
;
|
;
|
||||||
|
|
||||||
if (it == std::end(s)) {
|
if (it == std::ranges::end(s)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2000,14 +1988,14 @@ bool check_transfer_encoding(const StringRef &s) {
|
|||||||
// token
|
// token
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
for (; it != std::end(s) && util::in_token(*it); ++it)
|
for (; it != std::ranges::end(s) && util::in_token(*it); ++it)
|
||||||
;
|
;
|
||||||
} else if (*it == '"') {
|
} else if (*it == '"') {
|
||||||
// quoted-string
|
// quoted-string
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
it = skip_to_right_dquote(it, std::end(s));
|
it = skip_to_right_dquote(it, std::ranges::end(s));
|
||||||
if (it == std::end(s)) {
|
if (it == std::ranges::end(s)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2016,7 +2004,7 @@ bool check_transfer_encoding(const StringRef &s) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it == std::end(s)) {
|
if (it == std::ranges::end(s)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user