nghttpx: Fix te request header handling
Checking against "trailers" is enough for now.
This commit is contained in:
parent
1883bdaf1d
commit
2a56a3d9ea
|
@ -317,16 +317,16 @@ func TestH2H1AssembleCookies(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestH2H1TETrailer tests that server accepts TE request header field
|
// TestH2H1TETrailers tests that server accepts TE request header
|
||||||
// if it has trailer only.
|
// field if it has trailers only.
|
||||||
func TestH2H1TETrailer(t *testing.T) {
|
func TestH2H1TETrailers(t *testing.T) {
|
||||||
st := newServerTester(nil, t, noopHandler)
|
st := newServerTester(nil, t, noopHandler)
|
||||||
defer st.Close()
|
defer st.Close()
|
||||||
|
|
||||||
res, err := st.http2(requestParam{
|
res, err := st.http2(requestParam{
|
||||||
name: "TestH2H1TETrailer",
|
name: "TestH2H1TETrailers",
|
||||||
header: []hpack.HeaderField{
|
header: []hpack.HeaderField{
|
||||||
pair("te", "trailer"),
|
pair("te", "trailers"),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -337,8 +337,8 @@ func TestH2H1TETrailer(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestH2H1TEGzip tests that server reset stream if TE request
|
// TestH2H1TEGzip tests that server resets stream if TE request header
|
||||||
// header field contains gzip.
|
// field contains gzip.
|
||||||
func TestH2H1TEGzip(t *testing.T) {
|
func TestH2H1TEGzip(t *testing.T) {
|
||||||
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
st := newServerTester(nil, t, func(w http.ResponseWriter, r *http.Request) {
|
||||||
t.Error("server should not forward bad request")
|
t.Error("server should not forward bad request")
|
||||||
|
|
32
src/http2.cc
32
src/http2.cc
|
@ -664,38 +664,6 @@ const Headers::value_type *get_header(const int *hdidx, int token,
|
||||||
return &nva[i];
|
return &nva[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool check_http2_te(const uint8_t *value, size_t valuelen) {
|
|
||||||
auto first = value;
|
|
||||||
auto last = first + valuelen;
|
|
||||||
for (;;) {
|
|
||||||
if (first == last) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
auto end_param = std::find(first, last, ',');
|
|
||||||
auto len = end_param - first;
|
|
||||||
if (!util::istartsWith(reinterpret_cast<const char *>(first), len,
|
|
||||||
"trailer")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (len == sizeof("trailer") - 1) {
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
switch (first[sizeof("trailer") - 1]) {
|
|
||||||
case ' ':
|
|
||||||
case ';':
|
|
||||||
goto next;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
next:
|
|
||||||
if (end_param == last) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
first = std::find_if_not(end_param + 1, last, [](uint8_t c) {
|
|
||||||
return c == ' ' || c == '\t' || c == ',';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace http2
|
} // namespace http2
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
|
@ -244,12 +244,6 @@ bool http2_mandatory_request_headers_presence(const int *hdidx);
|
||||||
const Headers::value_type *get_header(const int *hdidx, int token,
|
const Headers::value_type *get_header(const int *hdidx, int token,
|
||||||
const Headers &nva);
|
const Headers &nva);
|
||||||
|
|
||||||
// Returns true if TE request header field value |value| of length
|
|
||||||
// |valuelen| is empty or only contains "trailers". The valid header
|
|
||||||
// field value is "trailer" and optionally followed by "," or OWS for
|
|
||||||
// simplicity.
|
|
||||||
bool check_http2_te(const uint8_t *value, size_t valuelen);
|
|
||||||
|
|
||||||
} // namespace http2
|
} // namespace http2
|
||||||
|
|
||||||
} // namespace nghttp2
|
} // namespace nghttp2
|
||||||
|
|
|
@ -290,60 +290,4 @@ void test_http2_mandatory_request_headers_presence(void) {
|
||||||
CU_ASSERT(http2::http2_mandatory_request_headers_presence(hdidx));
|
CU_ASSERT(http2::http2_mandatory_request_headers_presence(hdidx));
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_http2_check_http2_te(void) {
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "Trailer";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer,";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer,,";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer, ,";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer, , ";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer; q=0.9";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer ; q=0.9";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer ; q=0.9, trailer";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer ; q=0.9, trailer";
|
|
||||||
CU_ASSERT(http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
// failure cases
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailer; q=0.9, gzip";
|
|
||||||
CU_ASSERT(!http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "traile";
|
|
||||||
CU_ASSERT(!http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
{
|
|
||||||
const uint8_t v[] = "trailerr";
|
|
||||||
CU_ASSERT(!http2::check_http2_te(v, sizeof(v) - 1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
|
@ -39,7 +39,6 @@ void test_http2_lookup_token(void);
|
||||||
void test_http2_check_http2_pseudo_header(void);
|
void test_http2_check_http2_pseudo_header(void);
|
||||||
void test_http2_http2_header_allowed(void);
|
void test_http2_http2_header_allowed(void);
|
||||||
void test_http2_mandatory_request_headers_presence(void);
|
void test_http2_mandatory_request_headers_presence(void);
|
||||||
void test_http2_check_http2_te(void);
|
|
||||||
|
|
||||||
} // namespace shrpx
|
} // namespace shrpx
|
||||||
|
|
||||||
|
|
|
@ -93,8 +93,6 @@ int main(int argc, char *argv[]) {
|
||||||
shrpx::test_http2_http2_header_allowed) ||
|
shrpx::test_http2_http2_header_allowed) ||
|
||||||
!CU_add_test(pSuite, "http2_mandatory_request_headers_presence",
|
!CU_add_test(pSuite, "http2_mandatory_request_headers_presence",
|
||||||
shrpx::test_http2_mandatory_request_headers_presence) ||
|
shrpx::test_http2_mandatory_request_headers_presence) ||
|
||||||
!CU_add_test(pSuite, "http2_check_http2_te",
|
|
||||||
shrpx::test_http2_check_http2_te) ||
|
|
||||||
!CU_add_test(pSuite, "downstream_index_request_headers",
|
!CU_add_test(pSuite, "downstream_index_request_headers",
|
||||||
shrpx::test_downstream_index_request_headers) ||
|
shrpx::test_downstream_index_request_headers) ||
|
||||||
!CU_add_test(pSuite, "downstream_index_response_headers",
|
!CU_add_test(pSuite, "downstream_index_response_headers",
|
||||||
|
|
|
@ -226,7 +226,7 @@ int on_header_callback(nghttp2_session *session, const nghttp2_frame *frame,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case http2::HD_TE:
|
case http2::HD_TE:
|
||||||
if (!http2::check_http2_te(value, valuelen)) {
|
if (!util::strieq("trailers", value, valuelen)) {
|
||||||
upstream->rst_stream(downstream, NGHTTP2_PROTOCOL_ERROR);
|
upstream->rst_stream(downstream, NGHTTP2_PROTOCOL_ERROR);
|
||||||
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue