]> git.ipfire.org Git - thirdparty/squid.git/blob - src/http/RegisteredHeaders.h
Use ERR_ACCESS_DENIED for HTTP 403 (Forbidden) errors (#1899)
[thirdparty/squid.git] / src / http / RegisteredHeaders.h
1 /*
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
9 #ifndef SQUID_SRC_HTTP_REGISTEREDHEADERS_H
10 #define SQUID_SRC_HTTP_REGISTEREDHEADERS_H
11
12 #include "base/LookupTable.h"
13
14 #include <iosfwd>
15 #include <vector>
16
17 namespace Http
18 {
19 /// recognized or "known" header fields; and the RFC which defines them (or not)
20 /// http://www.iana.org/assignments/message-headers/message-headers.xhtml
21 enum HdrType {
22 enumBegin_ = 0, // service value for WholeEnum iteration
23 ACCEPT = enumBegin_, /**< RFC 7231 */ /* MUST BE FIRST */
24 ACCEPT_CHARSET, /**< RFC 7231 */
25 ACCEPT_ENCODING, /**< RFC 7231 */
26 /*ACCEPT_FEATURES,*/ /* RFC 2295 */
27 ACCEPT_LANGUAGE, /**< RFC 7231 */
28 ACCEPT_RANGES, /**< RFC 7233 */
29 AGE, /**< RFC 9111 */
30 ALLOW, /**< RFC 7231 */
31 ALTERNATE_PROTOCOL, /**< GFE custom header we may have to erase */
32 AUTHENTICATION_INFO, /**< RFC 2617 */
33 AUTHORIZATION, /**< RFC 7235, 4559 */
34 CACHE_CONTROL, /**< RFC 9111 */
35 CACHE_STATUS, /**< draft-ietf-httpbis-cache-header */
36 CDN_LOOP, /**< RFC 8586 */
37 CONNECTION, /**< RFC 7230 */
38 CONTENT_BASE, /**< obsoleted RFC 2068 */
39 CONTENT_DISPOSITION, /**< RFC 2183, 6266 */
40 CONTENT_ENCODING, /**< RFC 7231 */
41 CONTENT_LANGUAGE, /**< RFC 7231 */
42 CONTENT_LENGTH, /**< RFC 7230 */
43 CONTENT_LOCATION, /**< RFC 7231 */
44 CONTENT_MD5, /**< deprecated, RFC 2616 */
45 CONTENT_RANGE, /**< RFC 7233 */
46 CONTENT_TYPE, /**< RFC 7231 */
47 COOKIE, /**< RFC 6265 header we may need to erase */
48 COOKIE2, /**< obsolete RFC 2965 header we may need to erase */
49 DATE, /**< RFC 7231 */
50 /*DAV,*/ /* RFC 2518 */
51 /*DEPTH,*/ /* RFC 2518 */
52 /*DERIVED_FROM,*/ /* deprecated RFC 2068 */
53 /*DESTINATION,*/ /* RFC 2518 */
54 ETAG, /**< RFC 7232 */
55 EXPECT, /**< RFC 7231 */
56 EXPIRES, /**< RFC 9111 */
57 FORWARDED, /**< RFC 7239 */
58 FROM, /**< RFC 7231 */
59 HOST, /**< RFC 7230 */
60 /*HTTP2_SETTINGS,*/ /* obsolete RFC 7540 */
61 /*IF,*/ /* RFC 2518 */
62 IF_MATCH, /**< RFC 7232 */
63 IF_MODIFIED_SINCE, /**< RFC 7232 */
64 IF_NONE_MATCH, /**< RFC 7232 */
65 IF_RANGE, /**< RFC 7233 */
66 IF_UNMODIFIED_SINCE, /**< RFC 7232 */
67 KEEP_ALIVE, /**< obsoleted RFC 2068 header we may need to erase */
68 KEY, /**< experimental RFC Draft draft-fielding-http-key-02 */
69 LAST_MODIFIED, /**< RFC 7232 */
70 LINK, /**< RFC 5988 */
71 LOCATION, /**< RFC 7231 */
72 /*LOCK_TOKEN,*/ /* RFC 2518 */
73 MAX_FORWARDS, /**< RFC 7231 */
74 MIME_VERSION, /**< RFC 2045, 7231 */
75 NEGOTIATE, /**< experimental RFC 2295. Why only this one from 2295? */
76 /*OVERWRITE,*/ /* RFC 2518 */
77 ORIGIN, /* CORS Draft specification (see http://www.w3.org/TR/cors/) */
78 PRAGMA, /**< deprecated RFC 7234 header */
79 PRIORITY, /**< RFC 9218 */
80 PROXY_AUTHENTICATE, /**< RFC 7235 */
81 PROXY_AUTHENTICATION_INFO, /**< RFC 2617 */
82 PROXY_AUTHORIZATION, /**< RFC 7235 */
83 PROXY_CONNECTION, /**< obsolete Netscape header we may need to erase. */
84 PROXY_SUPPORT, /**< RFC 4559 */
85 PUBLIC, /**< RFC 2068 */
86 RANGE, /**< RFC 7233 */
87 REFERER, /**< RFC 7231 */
88 REQUEST_RANGE, /**< some clients use this, sigh */
89 RETRY_AFTER, /**< RFC 7231 */
90 SERVER, /**< RFC 7231 */
91 SET_COOKIE, /**< RFC 6265 header we may need to erase */
92 SET_COOKIE2, /**< obsoleted RFC 2965 header we may need to erase */
93 /*STATUS_URI,*/ /* RFC 2518 */
94 /*TCN,*/ /* experimental RFC 2295 */
95 TE, /**< RFC 7230 */
96 /*TIMEOUT,*/ /* RFC 2518 */
97 TITLE, /* obsolete draft suggested header */
98 TRAILER, /**< RFC 7230 */
99 TRANSFER_ENCODING, /**< RFC 7230 */
100 TRANSLATE, /**< IIS custom header we may need to erase */
101 UNLESS_MODIFIED_SINCE, /**< IIS custom header we may need to erase */
102 UPGRADE, /**< RFC 7230 */
103 USER_AGENT, /**< RFC 7231 */
104 /*VARIANT_VARY,*/ /* experimental RFC 2295 */
105 VARY, /**< RFC 7231 */
106 VIA, /**< RFC 7230 */
107 WWW_AUTHENTICATE, /**< RFC 7235, 4559 */
108 X_FORWARDED_FOR, /**< obsolete Squid custom header, RFC 7239 */
109 X_SQUID_ERROR, /**< Squid custom header on generated error responses */
110 HDR_X_ACCELERATOR_VARY, /**< obsolete Squid custom header. */
111 X_NEXT_SERVICES, /**< Squid custom ICAP header */
112 SURROGATE_CAPABILITY, /**< Edge Side Includes (ESI) header */
113 SURROGATE_CONTROL, /**< Edge Side Includes (ESI) header */
114 FRONT_END_HTTPS, /**< MS Exchange custom header we may have to add */
115 FTP_COMMAND, /**< Internal header for FTP command */
116 FTP_ARGUMENTS, /**< Internal header for FTP command arguments */
117 FTP_PRE, /**< Internal header containing leading FTP control response lines */
118 FTP_STATUS, /**< Internal header for FTP reply status */
119 FTP_REASON, /**< Internal header for FTP reply reason */
120 OTHER, /**< internal tag value for "unknown" headers */
121 BAD_HDR, /**< Invalid header */
122 enumEnd_ // internal tag for end-of-headers
123 };
124
125 /** possible types for http header fields */
126 enum class HdrFieldType {
127 ftInvalid, /**< to catch nasty errors with hdr_id<->fld_type clashes */
128 ftInt,
129 ftInt64,
130 ftStr,
131 ftDate_1123,
132 ftETag,
133 ftPCc,
134 ftPContRange,
135 ftPRange,
136 ftPSc,
137 ftDate_1123_or_ETag
138 };
139
140 enum HdrKind {
141 None = 0,
142 ListHeader = 1,
143 RequestHeader = 1 << 1,
144 ReplyHeader = 1 << 2,
145 HopByHopHeader = 1 << 3,
146 Denied304Header = 1 << 4, //see comment in HttpReply.cc for meaning
147 GeneralHeader = RequestHeader | ReplyHeader,
148 EntityHeader = RequestHeader | ReplyHeader
149 };
150
151 /* POD for HeaderTable */
152 class HeaderTableRecord {
153 public:
154 HeaderTableRecord() = default;
155 HeaderTableRecord(const char *n);
156 HeaderTableRecord(const char *, Http::HdrType, Http::HdrFieldType, int /* HdrKind */);
157
158 const char *name = "";
159 Http::HdrType id = HdrType::BAD_HDR;
160 Http::HdrFieldType type = HdrFieldType::ftInvalid;
161 // flags set by constructor from HdrKind parameter
162 bool list = false;; ///< header with field values defined as #(values) in HTTP/1.1
163 bool request = false; ///< header is a request header
164 bool reply = false; ///< header is a reply header
165 bool hopbyhop = false; ///< header is hop by hop
166 bool denied304 = false; ///< header is not to be updated on receiving a 304 in cache revalidation (see HttpReply.cc)
167 };
168
169 /** Class for looking up registered header definitions
170 *
171 * Look up HeaderTableRecord's by name or registered header ID.
172 *
173 * Actual records are defined in file RegisteredHeadersHash.gperf, which is
174 * compiled using gperf to RegisteredHeadersHash.cci which is then included
175 * in RegisteredHeaders.cc.
176 */
177 class HeaderLookupTable_t {
178 public:
179 HeaderLookupTable_t();
180 /// look record type up by name (C-string and length)
181 const HeaderTableRecord& lookup (const char *buf, const std::size_t len) const;
182 /// look record type up by name (std::string)
183 const HeaderTableRecord& lookup (const std::string &key) const {
184 return lookup(key.data(), key.length());
185 }
186 /// look record type up by name (SBuf)
187 const HeaderTableRecord& lookup (const SBuf &key) const {
188 return lookup(key.rawContent(), key.length());
189 }
190 /// look record type up by header ID
191 const HeaderTableRecord& lookup (Http::HdrType id) const {
192 return *(idCache[static_cast<int>(id)]);
193 }
194
195 private:
196 void initCache();
197 std::vector<const HeaderTableRecord *> idCache;
198 static const HeaderTableRecord BadHdr; ///<used to signal "not found" from lookups
199 };
200 extern const HeaderLookupTable_t HeaderLookupTable;
201
202 /// match any known header type, including OTHER and BAD
203 inline bool
204 any_HdrType_enum_value (const Http::HdrType id)
205 {
206 return (id >= Http::HdrType::enumBegin_ && id < Http::HdrType::enumEnd_);
207 }
208
209 /// match any valid header type, including OTHER but not BAD
210 inline bool
211 any_valid_header (const Http::HdrType id)
212 {
213 return (id >= Http::HdrType::ACCEPT && id < Http::HdrType::BAD_HDR);
214 }
215
216 /// match any registered header type (headers squid knows how to handle),
217 /// thus excluding OTHER and BAD
218 inline bool
219 any_registered_header (const Http::HdrType id)
220 {
221 return (id >= Http::HdrType::ACCEPT && id < Http::HdrType::OTHER);
222 }
223
224 std::ostream &operator <<(std::ostream &, HdrType);
225
226 }; /* namespace Http */
227
228 #endif /* SQUID_SRC_HTTP_REGISTEREDHEADERS_H */
229