Add http2::make_field family functions

http2::make_nv family functions are removed in favor of the new
function.
This commit is contained in:
Tatsuhiro Tsujikawa
2024-04-22 19:26:17 +09:00
parent dc969cc7f9
commit a7f588189f
7 changed files with 131 additions and 182 deletions

View File

@@ -924,29 +924,32 @@ int Http2Handler::submit_file_response(const StringRef &status, Stream *stream,
const std::string *content_type,
nghttp2_data_provider2 *data_prd) {
std::string last_modified_str;
auto nva =
std::to_array({http2::make_nv_ls_nocopy(":status", status),
http2::make_nv_ls_nocopy("server", NGHTTPD_SERVER),
http2::make_nv_ll("cache-control", "max-age=3600"),
http2::make_nv_ls("date", sessions_->get_cached_date()),
http2::make_nv_ll("", ""), http2::make_nv_ll("", ""),
http2::make_nv_ll("", ""), http2::make_nv_ll("", "")});
auto nva = std::to_array({
http2::make_field(":status"_sr, status),
http2::make_field("server"_sr, NGHTTPD_SERVER),
http2::make_field("cache-control"_sr, "max-age=3600"_sr),
http2::make_field_v("date"_sr, sessions_->get_cached_date()),
{},
{},
{},
{},
});
size_t nvlen = 4;
if (!get_config()->no_content_length) {
nva[nvlen++] = http2::make_nv_ls_nocopy(
"content-length",
nva[nvlen++] = http2::make_field(
"content-length"_sr,
util::make_string_ref_uint(stream->balloc, file_length));
}
if (last_modified != 0) {
last_modified_str = util::http_date(last_modified);
nva[nvlen++] = http2::make_nv_ls("last-modified", last_modified_str);
nva[nvlen++] = http2::make_field_v("last-modified"_sr, last_modified_str);
}
if (content_type) {
nva[nvlen++] = http2::make_nv_ls("content-type", *content_type);
nva[nvlen++] = http2::make_field_v("content-type"_sr, *content_type);
}
auto &trailer_names = get_config()->trailer_names;
if (!trailer_names.empty()) {
nva[nvlen++] = http2::make_nv_ls_nocopy("trailer", trailer_names);
nva[nvlen++] = http2::make_field("trailer"_sr, trailer_names);
}
return nghttp2_submit_response2(session_, stream->stream_id, nva.data(),
nvlen, data_prd);
@@ -957,19 +960,20 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
nghttp2_data_provider2 *data_prd) {
auto nva = std::vector<nghttp2_nv>();
nva.reserve(4 + headers.size());
nva.push_back(http2::make_nv_ls_nocopy(":status", status));
nva.push_back(http2::make_nv_ls_nocopy("server", NGHTTPD_SERVER));
nva.push_back(http2::make_nv_ls("date", sessions_->get_cached_date()));
nva.push_back(http2::make_field(":status"_sr, status));
nva.push_back(http2::make_field("server"_sr, NGHTTPD_SERVER));
nva.push_back(http2::make_field_v("date"_sr, sessions_->get_cached_date()));
if (data_prd) {
auto &trailer_names = get_config()->trailer_names;
if (!trailer_names.empty()) {
nva.push_back(http2::make_nv_ls_nocopy("trailer", trailer_names));
nva.push_back(http2::make_field("trailer"_sr, trailer_names));
}
}
for (auto &nv : headers) {
nva.push_back(http2::make_nv_nocopy(nv.name, nv.value, nv.no_index));
nva.push_back(
http2::make_field(nv.name, nv.value, http2::no_index(nv.no_index)));
}
int r = nghttp2_submit_response2(session_, stream_id, nva.data(), nva.size(),
data_prd);
@@ -978,17 +982,18 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
nghttp2_data_provider2 *data_prd) {
auto nva =
std::to_array({http2::make_nv_ls_nocopy(":status", status),
http2::make_nv_ls_nocopy("server", NGHTTPD_SERVER),
http2::make_nv_ls("date", sessions_->get_cached_date()),
http2::make_nv_ll("", "")});
auto nva = std::to_array({
http2::make_field(":status"_sr, status),
http2::make_field("server"_sr, NGHTTPD_SERVER),
http2::make_field_v("date"_sr, sessions_->get_cached_date()),
{},
});
size_t nvlen = 3;
if (data_prd) {
auto &trailer_names = get_config()->trailer_names;
if (!trailer_names.empty()) {
nva[nvlen++] = http2::make_nv_ls_nocopy("trailer", trailer_names);
nva[nvlen++] = http2::make_field("trailer"_sr, trailer_names);
}
}
@@ -998,7 +1003,7 @@ int Http2Handler::submit_response(const StringRef &status, int32_t stream_id,
int Http2Handler::submit_non_final_response(const std::string &status,
int32_t stream_id) {
auto nva = std::to_array({http2::make_nv_ls(":status", status)});
auto nva = std::to_array({http2::make_field_v(":status"_sr, status)});
return nghttp2_submit_headers(session_, NGHTTP2_FLAG_NONE, stream_id, nullptr,
nva.data(), nva.size(), nullptr);
}
@@ -1013,10 +1018,10 @@ int Http2Handler::submit_push_promise(Stream *stream,
auto scheme = get_config()->no_tls ? "http"_sr : "https"_sr;
auto nva = std::to_array({http2::make_nv_ll(":method", "GET"),
http2::make_nv_ls_nocopy(":path", push_path),
http2::make_nv_ls_nocopy(":scheme", scheme),
http2::make_nv_ls_nocopy(":authority", authority)});
auto nva = std::to_array({http2::make_field(":method"_sr, "GET"_sr),
http2::make_field(":path"_sr, push_path),
http2::make_field(":scheme"_sr, scheme),
http2::make_field(":authority"_sr, authority)});
auto promised_stream_id = nghttp2_submit_push_promise(
session_, NGHTTP2_FLAG_END_HEADERS, stream->stream_id, nva.data(),
@@ -1103,7 +1108,8 @@ nghttp2_ssize file_read_callback(nghttp2_session *session, int32_t stream_id,
std::vector<nghttp2_nv> nva;
nva.reserve(config->trailer.size());
for (auto &kv : config->trailer) {
nva.push_back(http2::make_nv(kv.name, kv.value, kv.no_index));
nva.push_back(http2::make_field_nv(kv.name, kv.value,
http2::no_index(kv.no_index)));
}
rv = nghttp2_submit_trailer(session, stream_id, nva.data(), nva.size());
if (rv != 0) {

View File

@@ -3068,15 +3068,15 @@ int main(int argc, char **argv) {
// 2 for :path, and possible content-length
nva.reserve(2 + shared_nva.size());
nva.push_back(http2::make_nv_ls(":path", req));
nva.push_back(http2::make_field_v(":path"_sr, req));
for (auto &nv : shared_nva) {
nva.push_back(http2::make_nv(nv.name, nv.value, false));
nva.push_back(http2::make_field_nv(nv.name, nv.value));
}
if (!content_length_str.empty()) {
nva.push_back(
http2::make_nv("content-length"_sr, StringRef{content_length_str}));
http2::make_field_nv("content-length"_sr, content_length_str));
}
config.nva.push_back(std::move(nva));

View File

@@ -315,56 +315,6 @@ bool non_empty_value(const HeaderRefs::value_type *nv) {
return nv && !nv->value.empty();
}
namespace {
nghttp2_nv make_nv_internal(const std::string &name, const std::string &value,
bool no_index, uint8_t nv_flags) {
uint8_t flags;
flags =
nv_flags | (no_index ? NGHTTP2_NV_FLAG_NO_INDEX : NGHTTP2_NV_FLAG_NONE);
return {(uint8_t *)name.c_str(), (uint8_t *)value.c_str(), name.size(),
value.size(), flags};
}
} // namespace
namespace {
nghttp2_nv make_nv_internal(const StringRef &name, const StringRef &value,
bool no_index, uint8_t nv_flags) {
uint8_t flags;
flags =
nv_flags | (no_index ? NGHTTP2_NV_FLAG_NO_INDEX : NGHTTP2_NV_FLAG_NONE);
return {(uint8_t *)name.data(), (uint8_t *)value.data(), name.size(),
value.size(), flags};
}
} // namespace
nghttp2_nv make_nv(const std::string &name, const std::string &value,
bool no_index) {
return make_nv_internal(name, value, no_index, NGHTTP2_NV_FLAG_NONE);
}
nghttp2_nv make_nv(const StringRef &name, const StringRef &value,
bool no_index) {
return make_nv_internal(name, value, no_index, NGHTTP2_NV_FLAG_NONE);
}
nghttp2_nv make_nv_nocopy(const std::string &name, const std::string &value,
bool no_index) {
return make_nv_internal(name, value, no_index,
NGHTTP2_NV_FLAG_NO_COPY_NAME |
NGHTTP2_NV_FLAG_NO_COPY_VALUE);
}
nghttp2_nv make_nv_nocopy(const StringRef &name, const StringRef &value,
bool no_index) {
return make_nv_internal(name, value, no_index,
NGHTTP2_NV_FLAG_NO_COPY_NAME |
NGHTTP2_NV_FLAG_NO_COPY_VALUE);
}
namespace {
void copy_headers_to_nva_internal(std::vector<nghttp2_nv> &nva,
const HeaderRefs &headers, uint8_t nv_flags,
@@ -459,8 +409,8 @@ void copy_headers_to_nva_internal(std::vector<nghttp2_nv> &nva,
it_via = it;
break;
}
nva.push_back(
make_nv_internal(kv->name, kv->value, kv->no_index, nv_flags));
nva.push_back(make_field_flags(kv->name, kv->value,
nv_flags | http2::no_index(kv->no_index)));
}
}
} // namespace

View File

@@ -132,60 +132,48 @@ const Headers::value_type *get_header(const Headers &nva, const char *name);
// Returns true if the value of |nv| is not empty.
bool non_empty_value(const HeaderRefs::value_type *nv);
// Creates nghttp2_nv using |name| and |value| and returns it. The
// returned value only references the data pointer to name.c_str() and
// value.c_str(). If |no_index| is true, nghttp2_nv flags member has
// NGHTTP2_NV_FLAG_NO_INDEX flag set.
nghttp2_nv make_nv(const std::string &name, const std::string &value,
bool no_index = false);
// Create nghttp2_nv from |name|, |value| and |flags|.
inline nghttp2_nv make_field_flags(const StringRef &name,
const StringRef &value,
uint8_t flags = NGHTTP2_NV_FLAG_NONE) {
auto ns = as_uint8_span(std::span{name});
auto vs = as_uint8_span(std::span{value});
nghttp2_nv make_nv(const StringRef &name, const StringRef &value,
bool no_index = false);
nghttp2_nv make_nv_nocopy(const std::string &name, const std::string &value,
bool no_index = false);
nghttp2_nv make_nv_nocopy(const StringRef &name, const StringRef &value,
bool no_index = false);
// Create nghttp2_nv from string literal |name| and |value|.
template <size_t N, size_t M>
constexpr nghttp2_nv make_nv_ll(const char (&name)[N], const char (&value)[M]) {
return {(uint8_t *)name, (uint8_t *)value, N - 1, M - 1,
NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE};
return {const_cast<uint8_t *>(ns.data()), const_cast<uint8_t *>(vs.data()),
ns.size(), vs.size(), flags};
}
// Create nghttp2_nv from string literal |name| and c-string |value|.
template <size_t N>
nghttp2_nv make_nv_lc(const char (&name)[N], const char *value) {
return {(uint8_t *)name, (uint8_t *)value, N - 1, strlen(value),
NGHTTP2_NV_FLAG_NO_COPY_NAME};
// Creates nghttp2_nv from |name|, |value| and |flags|. nghttp2
// library does not copy them.
inline nghttp2_nv make_field(const StringRef &name, const StringRef &value,
uint8_t flags = NGHTTP2_NV_FLAG_NONE) {
return make_field_flags(name, value,
static_cast<uint8_t>(NGHTTP2_NV_FLAG_NO_COPY_NAME |
NGHTTP2_NV_FLAG_NO_COPY_VALUE |
flags));
}
template <size_t N>
nghttp2_nv make_nv_lc_nocopy(const char (&name)[N], const char *value) {
return {(uint8_t *)name, (uint8_t *)value, N - 1, strlen(value),
NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE};
// Creates nghttp2_nv from |name|, |value| and |flags|. nghttp2
// library copies |value| unless |flags| includes
// NGHTTP2_NV_FLAG_NO_COPY_VALUE.
inline nghttp2_nv make_field_v(const StringRef &name, const StringRef &value,
uint8_t flags = NGHTTP2_NV_FLAG_NONE) {
return make_field_flags(
name, value, static_cast<uint8_t>(NGHTTP2_NV_FLAG_NO_COPY_NAME | flags));
}
// Create nghttp2_nv from string literal |name| and std::string
// |value|.
template <size_t N>
nghttp2_nv make_nv_ls(const char (&name)[N], const std::string &value) {
return {(uint8_t *)name, (uint8_t *)value.c_str(), N - 1, value.size(),
NGHTTP2_NV_FLAG_NO_COPY_NAME};
// Creates nghttp2_nv from |name|, |value| and |flags|. nghttp2
// library copies |name| and |value| unless |flags| includes
// NGHTTP2_NV_FLAG_NO_COPY_NAME or NGHTTP2_NV_FLAG_NO_COPY_VALUE.
inline nghttp2_nv make_field_nv(const StringRef &name, const StringRef &value,
uint8_t flags = NGHTTP2_NV_FLAG_NONE) {
return make_field_flags(name, value, flags);
}
template <size_t N>
nghttp2_nv make_nv_ls_nocopy(const char (&name)[N], const std::string &value) {
return {(uint8_t *)name, (uint8_t *)value.c_str(), N - 1, value.size(),
NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE};
}
template <size_t N>
nghttp2_nv make_nv_ls_nocopy(const char (&name)[N], const StringRef &value) {
return {(uint8_t *)name, (uint8_t *)value.data(), N - 1, value.size(),
NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE};
// Returns NGHTTP2_NV_FLAG_NO_INDEX if |no_index| is true, otherwise
// NGHTTP2_NV_FLAG_NONE.
inline uint8_t no_index(bool no_index) {
return no_index ? NGHTTP2_NV_FLAG_NO_INDEX : NGHTTP2_NV_FLAG_NONE;
}
enum HeaderBuildOp {

View File

@@ -500,7 +500,8 @@ int submit_request(HttpClient *client, const Headers &headers, Request *req) {
nva.reserve(build_headers.size());
for (auto &kv : build_headers) {
nva.push_back(http2::make_nv(kv.name, kv.value, kv.no_index));
nva.push_back(
http2::make_field_nv(kv.name, kv.value, http2::no_index(kv.no_index)));
}
auto method = http2::get_header(build_headers, ":method");
@@ -515,7 +516,7 @@ int submit_request(HttpClient *client, const Headers &headers, Request *req) {
trailer_names += ", ";
trailer_names += config.trailer[i].name;
}
nva.push_back(http2::make_nv_ls("trailer", trailer_names));
nva.push_back(http2::make_field_v("trailer"_sr, trailer_names));
}
int32_t stream_id;
@@ -2437,7 +2438,8 @@ nghttp2_ssize file_read_callback(nghttp2_session *session, int32_t stream_id,
std::vector<nghttp2_nv> nva;
nva.reserve(config.trailer.size());
for (auto &kv : config.trailer) {
nva.push_back(http2::make_nv(kv.name, kv.value, kv.no_index));
nva.push_back(http2::make_field_nv(kv.name, kv.value,
http2::no_index(kv.no_index)));
}
rv = nghttp2_submit_trailer(session, stream_id, nva.data(), nva.size());
if (rv != 0) {

View File

@@ -295,11 +295,11 @@ int Http2DownstreamConnection::push_request_headers() {
httpconf.add_request_headers.size());
if (req.connect_proto == ConnectProto::WEBSOCKET) {
nva.push_back(http2::make_nv_ll(":method", "CONNECT"));
nva.push_back(http2::make_nv_ll(":protocol", "websocket"));
nva.push_back(http2::make_field(":method"_sr, "CONNECT"_sr));
nva.push_back(http2::make_field(":protocol"_sr, "websocket"_sr));
} else {
nva.push_back(http2::make_nv_ls_nocopy(
":method", http2::to_method_string(req.method)));
nva.push_back(
http2::make_field(":method"_sr, http2::to_method_string(req.method)));
}
if (!req.regular_connect_method()) {
@@ -309,24 +309,24 @@ int Http2DownstreamConnection::push_request_headers() {
assert(addr);
// We will handle more protocol scheme upgrade in the future.
if (addr->tls && addr->upgrade_scheme && req.scheme == "http") {
nva.push_back(http2::make_nv_ll(":scheme", "https"));
nva.push_back(http2::make_field(":scheme"_sr, "https"_sr));
} else {
nva.push_back(http2::make_nv_ls_nocopy(":scheme", req.scheme));
nva.push_back(http2::make_field(":scheme"_sr, req.scheme));
}
if (req.method == HTTP_OPTIONS && req.path.empty()) {
nva.push_back(http2::make_nv_ll(":path", "*"));
nva.push_back(http2::make_field(":path"_sr, "*"_sr));
} else {
nva.push_back(http2::make_nv_ls_nocopy(":path", req.path));
nva.push_back(http2::make_field(":path"_sr, req.path));
}
if (!req.no_authority || req.connect_proto != ConnectProto::NONE) {
nva.push_back(http2::make_nv_ls_nocopy(":authority", authority));
nva.push_back(http2::make_field(":authority"_sr, authority));
} else {
nva.push_back(http2::make_nv_ls_nocopy("host", authority));
nva.push_back(http2::make_field("host"_sr, authority));
}
} else {
nva.push_back(http2::make_nv_ls_nocopy(":authority", authority));
nva.push_back(http2::make_field(":authority"_sr, authority));
}
auto &fwdconf = httpconf.forwarded;
@@ -354,7 +354,7 @@ int Http2DownstreamConnection::push_request_headers() {
auto conn = handler->get_connection();
if (conn->tls.ssl && !SSL_is_init_finished(conn->tls.ssl)) {
nva.push_back(http2::make_nv_ll("early-data", "1"));
nva.push_back(http2::make_field("early-data"_sr, "1"_sr));
}
#endif // NGHTTP2_GENUINE_OPENSSL || NGHTTP2_OPENSSL_IS_BORINGSSL
@@ -381,10 +381,10 @@ int Http2DownstreamConnection::push_request_headers() {
}
}
nva.push_back(http2::make_nv_ls_nocopy("forwarded", value));
nva.push_back(http2::make_field("forwarded"_sr, value));
}
} else if (fwd) {
nva.push_back(http2::make_nv_ls_nocopy("forwarded", fwd->value));
nva.push_back(http2::make_field("forwarded"_sr, fwd->value));
}
auto xff = xffconf.strip_incoming ? nullptr
@@ -398,9 +398,9 @@ int Http2DownstreamConnection::push_request_headers() {
} else {
xff_value = addr;
}
nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-for", xff_value));
nva.push_back(http2::make_field("x-forwarded-for"_sr, xff_value));
} else if (xff) {
nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-for", xff->value));
nva.push_back(http2::make_field("x-forwarded-for"_sr, xff->value));
}
if (!config->http2_proxy && !req.regular_connect_method()) {
@@ -416,16 +416,16 @@ int Http2DownstreamConnection::push_request_headers() {
} else {
xfp_value = req.scheme;
}
nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-proto", xfp_value));
nva.push_back(http2::make_field("x-forwarded-proto"_sr, xfp_value));
} else if (xfp) {
nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-proto", xfp->value));
nva.push_back(http2::make_field("x-forwarded-proto"_sr, xfp->value));
}
}
auto via = req.fs.header(http2::HD_VIA);
if (httpconf.no_via) {
if (via) {
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
nva.push_back(http2::make_field("via"_sr, (*via).value));
}
} else {
size_t vialen = 16;
@@ -443,8 +443,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_nv_ls_nocopy(
"via", StringRef{std::span{std::begin(iov), p}}));
nva.push_back(
http2::make_field("via"_sr, StringRef{std::span{std::begin(iov), p}}));
}
auto te = req.fs.header(http2::HD_TE);
@@ -452,11 +452,11 @@ int Http2DownstreamConnection::push_request_headers() {
// "trailers". We just forward "trailers".
// TODO more strict handling required here.
if (te && http2::contains_trailers(te->value)) {
nva.push_back(http2::make_nv_ll("te", "trailers"));
nva.push_back(http2::make_field("te"_sr, "trailers"_sr));
}
for (auto &p : httpconf.add_request_headers) {
nva.push_back(http2::make_nv_nocopy(p.name, p.value));
nva.push_back(http2::make_field(p.name, p.value));
}
if (LOG_ENABLED(INFO)) {

View File

@@ -1535,7 +1535,7 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body,
auto response_status = http2::stringify_status(balloc, resp.http_status);
nva.push_back(http2::make_nv_ls_nocopy(":status", response_status));
nva.push_back(http2::make_field(":status"_sr, response_status));
for (auto &kv : headers) {
if (kv.name.empty() || kv.name[0] == ':') {
@@ -1550,15 +1550,16 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body,
case http2::HD_UPGRADE:
continue;
}
nva.push_back(http2::make_nv_nocopy(kv.name, kv.value, kv.no_index));
nva.push_back(
http2::make_field(kv.name, kv.value, http2::no_index(kv.no_index)));
}
if (!resp.fs.header(http2::HD_SERVER)) {
nva.push_back(http2::make_nv_ls_nocopy("server", config->http.server_name));
nva.push_back(http2::make_field("server"_sr, config->http.server_name));
}
for (auto &p : httpconf.add_response_headers) {
nva.push_back(http2::make_nv_nocopy(p.name, p.value));
nva.push_back(http2::make_field(p.name, p.value));
}
rv = nghttp2_submit_response2(session_, downstream->get_stream_id(),
@@ -1612,11 +1613,11 @@ int Http2Upstream::error_reply(Downstream *downstream,
auto date = make_string_ref(balloc, lgconf->tstamp->time_http);
auto nva = std::to_array(
{http2::make_nv_ls_nocopy(":status", response_status),
http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
http2::make_nv_ls_nocopy("server", get_config()->http.server_name),
http2::make_nv_ls_nocopy("content-length", content_length),
http2::make_nv_ls_nocopy("date", date)});
{http2::make_field(":status"_sr, response_status),
http2::make_field("content-type"_sr, "text/html; charset=UTF-8"_sr),
http2::make_field("server"_sr, get_config()->http.server_name),
http2::make_field("content-length"_sr, content_length),
http2::make_field("date"_sr, date)});
rv = nghttp2_submit_response2(session_, downstream->get_stream_id(),
nva.data(), nva.size(), data_prd_ptr);
@@ -1758,7 +1759,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
if (downstream->get_non_final_response()) {
auto response_status = http2::stringify_status(balloc, resp.http_status);
nva.push_back(http2::make_nv_ls_nocopy(":status", response_status));
nva.push_back(http2::make_field(":status"_sr, response_status));
http2::copy_headers_to_nva_nocopy(nva, resp.fs.headers(),
http2::HDOP_STRIP_ALL);
@@ -1791,16 +1792,16 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
response_status = http2::stringify_status(balloc, resp.http_status);
}
nva.push_back(http2::make_nv_ls_nocopy(":status", response_status));
nva.push_back(http2::make_field(":status"_sr, response_status));
http2::copy_headers_to_nva_nocopy(nva, resp.fs.headers(), striphd_flags);
if (!config->http2_proxy && !httpconf.no_server_rewrite) {
nva.push_back(http2::make_nv_ls_nocopy("server", httpconf.server_name));
nva.push_back(http2::make_field("server"_sr, httpconf.server_name));
} else {
auto server = resp.fs.header(http2::HD_SERVER);
if (server) {
nva.push_back(http2::make_nv_ls_nocopy("server", (*server).value));
nva.push_back(http2::make_field("server"_sr, (*server).value));
}
}
@@ -1816,22 +1817,22 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
http::require_cookie_secure_attribute(cookieconf.secure, req.scheme);
auto cookie_str = http::create_affinity_cookie(
balloc, cookieconf.name, affinity_cookie, cookieconf.path, secure);
nva.push_back(http2::make_nv_ls_nocopy("set-cookie", cookie_str));
nva.push_back(http2::make_field("set-cookie"_sr, cookie_str));
}
}
if (!resp.fs.header(http2::HD_ALT_SVC)) {
// We won't change or alter alt-svc from backend for now
if (!httpconf.http2_altsvc_header_value.empty()) {
nva.push_back(http2::make_nv_ls_nocopy(
"alt-svc", httpconf.http2_altsvc_header_value));
nva.push_back(
http2::make_field("alt-svc"_sr, httpconf.http2_altsvc_header_value));
}
}
auto via = resp.fs.header(http2::HD_VIA);
if (httpconf.no_via) {
if (via) {
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
nva.push_back(http2::make_field("via"_sr, (*via).value));
}
} else {
// we don't create more than 16 bytes in
@@ -1850,18 +1851,18 @@ 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_nv_ls_nocopy(
"via", StringRef{std::span{std::begin(iov), p}}));
nva.push_back(
http2::make_field("via"_sr, StringRef{std::span{std::begin(iov), p}}));
}
for (auto &p : httpconf.add_response_headers) {
nva.push_back(http2::make_nv_nocopy(p.name, p.value));
nva.push_back(http2::make_field(p.name, p.value));
}
if (downstream->get_stream_id() % 2 == 0) {
// This header field is basically for human on client side to
// figure out that the resource is pushed.
nva.push_back(http2::make_nv_ll("x-http2-push", "1"));
nva.push_back(http2::make_field("x-http2-push"_sr, "1"_sr));
}
if (LOG_ENABLED(INFO)) {
@@ -2225,10 +2226,10 @@ int Http2Upstream::submit_push_promise(const StringRef &scheme,
nva.reserve(4 + req.fs.headers().size());
// just use "GET" for now
nva.push_back(http2::make_nv_ll(":method", "GET"));
nva.push_back(http2::make_nv_ls_nocopy(":scheme", scheme));
nva.push_back(http2::make_nv_ls_nocopy(":path", path));
nva.push_back(http2::make_nv_ls_nocopy(":authority", authority));
nva.push_back(http2::make_field(":method"_sr, "GET"_sr));
nva.push_back(http2::make_field(":scheme"_sr, scheme));
nva.push_back(http2::make_field(":path"_sr, path));
nva.push_back(http2::make_field(":authority"_sr, authority));
for (auto &kv : req.fs.headers()) {
switch (kv.token) {
@@ -2243,7 +2244,8 @@ int Http2Upstream::submit_push_promise(const StringRef &scheme,
case http2::HD_CACHE_CONTROL:
case http2::HD_HOST:
case http2::HD_USER_AGENT:
nva.push_back(http2::make_nv_nocopy(kv.name, kv.value, kv.no_index));
nva.push_back(
http2::make_field(kv.name, kv.value, http2::no_index(kv.no_index)));
break;
}
}
@@ -2387,7 +2389,8 @@ int Http2Upstream::on_downstream_push_promise_complete(
nva.reserve(headers.size());
for (auto &kv : headers) {
nva.push_back(http2::make_nv(kv.name, kv.value, kv.no_index));
nva.push_back(
http2::make_field_nv(kv.name, kv.value, http2::no_index(kv.no_index)));
}
auto promised_stream_id = nghttp2_submit_push_promise(