blob: 415bc4d74411ae54e5f0886503576a48fd457727 [file] [log] [blame]
QUICHE teamd7a507e2022-04-15 14:35:46 -07001#include "quiche/common/balsa/header_properties.h"
2
3#include <array>
4
5#include "absl/container/flat_hash_set.h"
6#include "absl/strings/string_view.h"
7#include "quiche/common/quiche_text_utils.h"
8
9namespace quiche::header_properties {
10
11namespace {
12
13using MultivaluedHeadersSet =
14 absl::flat_hash_set<absl::string_view, StringPieceCaseHash,
15 StringPieceCaseEqual>;
16
17MultivaluedHeadersSet* buildMultivaluedHeaders() {
18 return new MultivaluedHeadersSet({
19 "accept",
20 "accept-charset",
21 "accept-encoding",
22 "accept-language",
23 "accept-ranges",
24 // The follow four headers are all CORS standard headers
25 "access-control-allow-headers",
26 "access-control-allow-methods",
27 "access-control-expose-headers",
28 "access-control-request-headers",
29 "allow",
30 "cache-control",
31 // IETF draft makes this have cache-control syntax
32 "cdn-cache-control",
33 "connection",
34 "content-encoding",
35 "content-language",
36 "expect",
37 "if-match",
38 "if-none-match",
39 // See RFC 5988 section 5
40 "link",
41 "pragma",
42 "proxy-authenticate",
43 "te",
44 // Used in the opening handshake of the WebSocket protocol.
45 "sec-websocket-extensions",
46 // Not mentioned in RFC 2616, but it can have multiple values.
47 "set-cookie",
48 "trailer",
49 "transfer-encoding",
50 "upgrade",
51 "vary",
52 "via",
53 "warning",
54 "www-authenticate",
55 // De facto standard not in the RFCs
56 "x-forwarded-for",
57 // Internal Google usage gives this cache-control syntax
58 "x-go" /**/ "ogle-cache-control",
59 });
60}
61
62std::array<bool, 256> buildInvalidCharLookupTable() {
63 std::array<bool, 256> invalidCharTable;
64 invalidCharTable.fill(false);
65 for (char c : kInvalidHeaderCharList) {
66 invalidCharTable[c] = true;
67 }
68 return invalidCharTable;
69}
70
71} // anonymous namespace
72
73bool IsMultivaluedHeader(absl::string_view header) {
74 static const MultivaluedHeadersSet* const multivalued_headers =
75 buildMultivaluedHeaders();
76 return multivalued_headers->contains(header);
77}
78
79bool IsInvalidHeaderChar(char c) {
80 static const std::array<bool, 256> invalidCharTable =
81 buildInvalidCharLookupTable();
82
83 return invalidCharTable[c];
84}
85
86bool HasInvalidHeaderChars(absl::string_view value) {
87 for (const char c : value) {
88 if (IsInvalidHeaderChar(c)) {
89 return true;
90 }
91 }
92 return false;
93}
94
95} // namespace quiche::header_properties