LibHTTP: Ignore empty list elements when extracting token headers
It turns out that the validation of header values in db5f16f042
was a bit over aggressive. extract_token_headers previously treated
empty list elements (empty or whitespace-only after trimming) as parse
failures. This is incorrect per RFC 9110, which specifies that
recipients must ignore empty list elements in comma-separated header
values.
> A recipient MUST parse and ignore a reasonable number of empty
> list elements
This commit is contained in:
parent
cc711a6060
commit
d76330645a
2 changed files with 29 additions and 10 deletions
|
|
@ -24,17 +24,19 @@ Header Header::isomorphic_encode(StringView name, StringView value)
|
|||
return { TextCodec::isomorphic_encode(name), TextCodec::isomorphic_encode(value) };
|
||||
}
|
||||
|
||||
// https://www.rfc-editor.org/rfc/rfc9110.html#name-recipient-requirements
|
||||
static Optional<Vector<ByteString>> extract_token_headers(ByteString const& value)
|
||||
{
|
||||
auto parts = value.split(',', SplitBehavior::Nothing);
|
||||
for (auto& part : parts) {
|
||||
part = part.trim(HTTP_WHITESPACE, TrimMode::Both);
|
||||
if (part.is_empty())
|
||||
return {};
|
||||
if (!is_header_name(part))
|
||||
Vector<ByteString> result;
|
||||
for (auto& part : value.split(',', SplitBehavior::Nothing)) {
|
||||
auto trimmed = part.trim(HTTP_WHITESPACE, TrimMode::Both);
|
||||
if (trimmed.is_empty())
|
||||
continue;
|
||||
if (!is_header_name(trimmed))
|
||||
return {};
|
||||
result.append(move(trimmed));
|
||||
}
|
||||
return parts;
|
||||
return result;
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#extract-header-values
|
||||
|
|
|
|||
|
|
@ -172,13 +172,30 @@ TEST_CASE(extract_header_values)
|
|||
EXPECT_EQ(result, (Vector<ByteString> {}));
|
||||
}
|
||||
|
||||
result = HTTP::Header { header, ",,,"sv }.extract_header_values();
|
||||
// Two commas and some spaces.
|
||||
result = HTTP::Header { header, ", ,"sv }.extract_header_values();
|
||||
if (requires_at_least_one) {
|
||||
EXPECT_EQ(result, OptionalNone {});
|
||||
} else {
|
||||
EXPECT_EQ(result, (Vector<ByteString> {}));
|
||||
}
|
||||
|
||||
// Only a comma.
|
||||
result = HTTP::Header { header, ","sv }.extract_header_values();
|
||||
if (requires_at_least_one) {
|
||||
EXPECT_EQ(result, OptionalNone {});
|
||||
} else {
|
||||
EXPECT_EQ(result, (Vector<ByteString> {}));
|
||||
}
|
||||
|
||||
// Empty list element ignored.
|
||||
result = HTTP::Header { header, "foo , ,bar,charlie"sv }.extract_header_values();
|
||||
EXPECT_EQ(result, (Vector<ByteString> { "foo", "bar", "charlie" }));
|
||||
|
||||
// Leading empty list component.
|
||||
result = HTTP::Header { header, ",foo,bar"sv }.extract_header_values();
|
||||
EXPECT_EQ(result, (Vector<ByteString> { "foo", "bar" }));
|
||||
|
||||
// Space inside a token is invalid.
|
||||
result = HTTP::Header { header, "no no"sv }.extract_header_values();
|
||||
EXPECT_EQ(result, OptionalNone {});
|
||||
|
|
@ -203,9 +220,9 @@ TEST_CASE(extract_header_values)
|
|||
result = HTTP::Header { header, "bb-8,no no"sv }.extract_header_values();
|
||||
EXPECT_EQ(result, OptionalNone {});
|
||||
|
||||
// Whitespace-only item between commas fails.
|
||||
// Whitespace-only item is ignored.
|
||||
result = HTTP::Header { header, "bb-8, ,no"sv }.extract_header_values();
|
||||
EXPECT_EQ(result, OptionalNone {});
|
||||
EXPECT_EQ(result, (Vector<ByteString> { "bb-8", "no" }));
|
||||
}
|
||||
|
||||
// Other headers: returned as a single-element list regardless of content.
|
||||
|
|
|
|||
Loading…
Reference in a new issue