mirror of
https://github.com/nghttp2/nghttp2.git
synced 2025-12-06 18:18:52 +08:00
nghttpx: Tokenize trailer field as well so that we can ditch prohibited headers in HTTP/2
This commit is contained in:
@@ -330,7 +330,7 @@ void Downstream::crumble_request_cookie(std::vector<nghttp2_nv> &nva) {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
void add_header(bool &key_prev, size_t &sum, Headers &headers, std::string name,
|
void add_header(bool &key_prev, size_t &sum, Headers &headers, std::string name,
|
||||||
std::string value, int16_t token = -1) {
|
std::string value, int16_t token) {
|
||||||
key_prev = true;
|
key_prev = true;
|
||||||
sum += name.size() + value.size();
|
sum += name.size() + value.size();
|
||||||
headers.emplace_back(std::move(name), std::move(value), false, token);
|
headers.emplace_back(std::move(name), std::move(value), false, token);
|
||||||
@@ -415,11 +415,13 @@ const Headers::value_type *FieldStore::header(const StringRef &name) const {
|
|||||||
return search_header_linear_backwards(headers_, name);
|
return search_header_linear_backwards(headers_, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldStore::add_header_lower(std::string name, std::string value) {
|
void FieldStore::add_header_lower(const StringRef &name,
|
||||||
util::inp_strlower(name);
|
const StringRef &value) {
|
||||||
auto token = http2::lookup_token(name);
|
auto low_name = name.str();
|
||||||
shrpx::add_header(header_key_prev_, buffer_size_, headers_, std::move(name),
|
util::inp_strlower(low_name);
|
||||||
std::move(value), token);
|
auto token = http2::lookup_token(low_name);
|
||||||
|
shrpx::add_header(header_key_prev_, buffer_size_, headers_,
|
||||||
|
std::move(low_name), value.str(), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldStore::add_header(std::string name, std::string value,
|
void FieldStore::add_header(std::string name, std::string value,
|
||||||
@@ -450,16 +452,19 @@ void FieldStore::clear_headers() { headers_.clear(); }
|
|||||||
void FieldStore::add_trailer(const uint8_t *name, size_t namelen,
|
void FieldStore::add_trailer(const uint8_t *name, size_t namelen,
|
||||||
const uint8_t *value, size_t valuelen,
|
const uint8_t *value, size_t valuelen,
|
||||||
bool no_index, int16_t token) {
|
bool no_index, int16_t token) {
|
||||||
// we never index trailer fields. Header size limit should be
|
// Header size limit should be applied to all header and trailer
|
||||||
// applied to all header and trailer fields combined.
|
// fields combined.
|
||||||
shrpx::add_header(buffer_size_, trailers_, name, namelen, value, valuelen,
|
shrpx::add_header(buffer_size_, trailers_, name, namelen, value, valuelen,
|
||||||
no_index, -1);
|
no_index, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldStore::add_trailer_lower(std::string name, std::string value) {
|
void FieldStore::add_trailer_lower(const StringRef &name,
|
||||||
util::inp_strlower(name);
|
const StringRef &value) {
|
||||||
shrpx::add_header(trailer_key_prev_, buffer_size_, trailers_, std::move(name),
|
auto low_name = name.str();
|
||||||
std::move(value));
|
util::inp_strlower(low_name);
|
||||||
|
auto token = http2::lookup_token(low_name);
|
||||||
|
shrpx::add_header(trailer_key_prev_, buffer_size_, trailers_,
|
||||||
|
std::move(low_name), value.str(), token);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FieldStore::append_last_trailer_key(const char *data, size_t len) {
|
void FieldStore::append_last_trailer_key(const char *data, size_t len) {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public:
|
|||||||
// such header is found, returns nullptr.
|
// such header is found, returns nullptr.
|
||||||
const Headers::value_type *header(const StringRef &name) const;
|
const Headers::value_type *header(const StringRef &name) const;
|
||||||
|
|
||||||
void add_header_lower(std::string name, std::string value);
|
void add_header_lower(const StringRef &name, const StringRef &value);
|
||||||
void add_header(std::string name, std::string value, int16_t token);
|
void add_header(std::string name, std::string value, int16_t token);
|
||||||
void add_header(const uint8_t *name, size_t namelen, const uint8_t *value,
|
void add_header(const uint8_t *name, size_t namelen, const uint8_t *value,
|
||||||
size_t valuelen, bool no_index, int16_t token);
|
size_t valuelen, bool no_index, int16_t token);
|
||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
|
|
||||||
void add_trailer(const uint8_t *name, size_t namelen, const uint8_t *value,
|
void add_trailer(const uint8_t *name, size_t namelen, const uint8_t *value,
|
||||||
size_t valuelen, bool no_index, int16_t token);
|
size_t valuelen, bool no_index, int16_t token);
|
||||||
void add_trailer_lower(std::string name, std::string value);
|
void add_trailer_lower(const StringRef &name, const StringRef &value);
|
||||||
|
|
||||||
void append_last_trailer_key(const char *data, size_t len);
|
void append_last_trailer_key(const char *data, size_t len);
|
||||||
void append_last_trailer_value(const char *data, size_t len);
|
void append_last_trailer_value(const char *data, size_t len);
|
||||||
|
|||||||
@@ -735,15 +735,15 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
|||||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto token = http2::lookup_token(name, namelen);
|
||||||
|
|
||||||
if (trailer) {
|
if (trailer) {
|
||||||
// just store header fields for trailer part
|
// just store header fields for trailer part
|
||||||
resp.fs.add_trailer(name, namelen, value, valuelen,
|
resp.fs.add_trailer(name, namelen, value, valuelen,
|
||||||
flags & NGHTTP2_NV_FLAG_NO_INDEX, -1);
|
flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto token = http2::lookup_token(name, namelen);
|
|
||||||
|
|
||||||
resp.fs.add_header(name, namelen, value, valuelen,
|
resp.fs.add_header(name, namelen, value, valuelen,
|
||||||
flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
|
flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -201,15 +201,15 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto token = http2::lookup_token(name, namelen);
|
||||||
|
|
||||||
if (frame->headers.cat == NGHTTP2_HCAT_HEADERS) {
|
if (frame->headers.cat == NGHTTP2_HCAT_HEADERS) {
|
||||||
// just store header fields for trailer part
|
// just store header fields for trailer part
|
||||||
req.fs.add_trailer(name, namelen, value, valuelen,
|
req.fs.add_trailer(name, namelen, value, valuelen,
|
||||||
flags & NGHTTP2_NV_FLAG_NO_INDEX, -1);
|
flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto token = http2::lookup_token(name, namelen);
|
|
||||||
|
|
||||||
req.fs.add_header(name, namelen, value, valuelen,
|
req.fs.add_header(name, namelen, value, valuelen,
|
||||||
flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
|
flags & NGHTTP2_NV_FLAG_NO_INDEX, token);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -691,7 +691,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
|||||||
if (ensure_max_header_fields(downstream, httpconf) != 0) {
|
if (ensure_max_header_fields(downstream, httpconf) != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
resp.fs.add_header_lower(std::string(data, len), "");
|
resp.fs.add_header_lower(StringRef{data, len}, StringRef{});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// trailer part
|
// trailer part
|
||||||
@@ -704,7 +704,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
|||||||
// wrong place or crash if trailer fields are currently empty.
|
// wrong place or crash if trailer fields are currently empty.
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
resp.fs.add_trailer_lower(std::string(data, len), "");
|
resp.fs.add_trailer_lower(StringRef(data, len), StringRef{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
|||||||
Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE);
|
Downstream::HTTP1_REQUEST_HEADER_TOO_LARGE);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
req.fs.add_header_lower(std::string(data, len), "");
|
req.fs.add_header_lower(StringRef{data, len}, StringRef{});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// trailer part
|
// trailer part
|
||||||
@@ -156,7 +156,7 @@ int htp_hdr_keycb(http_parser *htp, const char *data, size_t len) {
|
|||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
req.fs.add_trailer_lower(std::string(data, len), "");
|
req.fs.add_trailer_lower(StringRef{data, len}, StringRef{});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user