]> git.ipfire.org Git - thirdparty/squid.git/blob - src/HttpHeader.h
Boilerplate: update copyright blurbs on src/
[thirdparty/squid.git] / src / HttpHeader.h
1 /*
2 * Copyright (C) 1996-2014 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_HTTPHEADER_H
10 #define SQUID_HTTPHEADER_H
11
12 /* because we pass a spec by value */
13 #include "HttpHeaderMask.h"
14 #include "MemPool.h"
15 #include "SquidString.h"
16
17 #include <vector>
18
19 /* class forward declarations */
20 class HttpHdrCc;
21 class HttpHdrContRange;
22 class HttpHdrRange;
23 class HttpHdrSc;
24 class Packer;
25 class StoreEntry;
26 class SBuf;
27
28 /* constant attributes of http header fields */
29
30 /// recognized or "known" header fields; and the RFC which defines them (or not)
31 /// http://www.iana.org/assignments/message-headers/message-headers.xhtml
32 typedef enum {
33 HDR_BAD_HDR = -1,
34 HDR_ACCEPT = 0, /**< RFC 7231 */
35 HDR_ACCEPT_CHARSET, /**< RFC 7231 */
36 HDR_ACCEPT_ENCODING, /**< RFC 7231 */
37 /*HDR_ACCEPT_FEATURES,*/ /* RFC 2295 */
38 HDR_ACCEPT_LANGUAGE, /**< RFC 7231 */
39 HDR_ACCEPT_RANGES, /**< RFC 7233 */
40 HDR_AGE, /**< RFC 7234 */
41 HDR_ALLOW, /**< RFC 7231 */
42 HDR_AUTHENTICATION_INFO, /**< RFC 2617 */
43 HDR_AUTHORIZATION, /**< RFC 7235, 4559 */
44 HDR_CACHE_CONTROL, /**< RFC 7234 */
45 HDR_CONNECTION, /**< RFC 7230 */
46 HDR_CONTENT_BASE, /**< obsoleted RFC 2068 */
47 HDR_CONTENT_DISPOSITION, /**< RFC 2183, 6266 */
48 HDR_CONTENT_ENCODING, /**< RFC 7231 */
49 HDR_CONTENT_LANGUAGE, /**< RFC 7231 */
50 HDR_CONTENT_LENGTH, /**< RFC 7230 */
51 HDR_CONTENT_LOCATION, /**< RFC 7231 */
52 HDR_CONTENT_MD5, /**< deprecated, RFC 2616 */
53 HDR_CONTENT_RANGE, /**< RFC 7233 */
54 HDR_CONTENT_TYPE, /**< RFC 7231 */
55 HDR_COOKIE, /**< RFC 6265 header we may need to erase */
56 HDR_COOKIE2, /**< obsolete RFC 2965 header we may need to erase */
57 HDR_DATE, /**< RFC 7231 */
58 /*HDR_DAV,*/ /* RFC 2518 */
59 /*HDR_DEPTH,*/ /* RFC 2518 */
60 /*HDR_DERIVED_FROM,*/ /* deprecated RFC 2068 */
61 /*HDR_DESTINATION,*/ /* RFC 2518 */
62 HDR_ETAG, /**< RFC 7232 */
63 HDR_EXPECT, /**< RFC 7231 */
64 HDR_EXPIRES, /**< RFC 7234 */
65 HDR_FORWARDED, /**< RFC 7239 */
66 HDR_FROM, /**< RFC 7231 */
67 HDR_HOST, /**< RFC 7230 */
68 HDR_HTTP2_SETTINGS, /**< HTTP/2.0 upgrade header. see draft-ietf-httpbis-http2-13 */
69 /*HDR_IF,*/ /* RFC 2518 */
70 HDR_IF_MATCH, /**< RFC 7232 */
71 HDR_IF_MODIFIED_SINCE, /**< RFC 7232 */
72 HDR_IF_NONE_MATCH, /**< RFC 7232 */
73 HDR_IF_RANGE, /**< RFC 7233 */
74 HDR_IF_UNMODIFIED_SINCE, /**< RFC 7232 */
75 HDR_KEEP_ALIVE, /**< obsoleted RFC 2068 header we may need to erase */
76 HDR_KEY, /**< experimental RFC Draft draft-fielding-http-key-02 */
77 HDR_LAST_MODIFIED, /**< RFC 7232 */
78 HDR_LINK, /**< RFC 5988 */
79 HDR_LOCATION, /**< RFC 7231 */
80 /*HDR_LOCK_TOKEN,*/ /* RFC 2518 */
81 HDR_MAX_FORWARDS, /**< RFC 7231 */
82 HDR_MIME_VERSION, /**< RFC 2045, 7231 */
83 HDR_NEGOTIATE, /**< experimental RFC 2295. Why only this one from 2295? */
84 /*HDR_OVERWRITE,*/ /* RFC 2518 */
85 HDR_ORIGIN, /* CORS Draft specification (see http://www.w3.org/TR/cors/) */
86 HDR_PRAGMA, /**< RFC 7234 */
87 HDR_PROXY_AUTHENTICATE, /**< RFC 7235 */
88 HDR_PROXY_AUTHENTICATION_INFO, /**< RFC 2617 */
89 HDR_PROXY_AUTHORIZATION, /**< RFC 7235 */
90 HDR_PROXY_CONNECTION, /**< obsolete Netscape header we may need to erase. */
91 HDR_PROXY_SUPPORT, /**< RFC 4559 */
92 HDR_PUBLIC, /**< RFC 2068 */
93 HDR_RANGE, /**< RFC 7233 */
94 HDR_REFERER, /**< RFC 7231 */
95 HDR_REQUEST_RANGE, /**< some clients use this, sigh */
96 HDR_RETRY_AFTER, /**< RFC 7231 */
97 HDR_SERVER, /**< RFC 7231 */
98 HDR_SET_COOKIE, /**< RFC 6265 header we may need to erase */
99 HDR_SET_COOKIE2, /**< obsoleted RFC 2965 header we may need to erase */
100 /*HDR_STATUS_URI,*/ /* RFC 2518 */
101 /*HDR_TCN,*/ /* experimental RFC 2295 */
102 HDR_TE, /**< RFC 7230 */
103 /*HDR_TIMEOUT,*/ /* RFC 2518 */
104 HDR_TITLE, /* obsolete draft suggested header */
105 HDR_TRAILER, /**< RFC 7230 */
106 HDR_TRANSFER_ENCODING, /**< RFC 7230 */
107 HDR_TRANSLATE, /**< IIS custom header we may need to erase */
108 HDR_UNLESS_MODIFIED_SINCE, /**< IIS custom header we may need to erase */
109 HDR_UPGRADE, /**< RFC 7230 */
110 HDR_USER_AGENT, /**< RFC 7231 */
111 /*HDR_VARIANT_VARY,*/ /* experimental RFC 2295 */
112 HDR_VARY, /**< RFC 7231 */
113 HDR_VIA, /**< RFC 7230 */
114 HDR_WARNING, /**< RFC 7234 */
115 HDR_WWW_AUTHENTICATE, /**< RFC 7235, 4559 */
116 HDR_X_CACHE, /**< Squid custom header */
117 HDR_X_CACHE_LOOKUP, /**< Squid custom header. temporary hack that became de-facto. TODO remove */
118 HDR_X_FORWARDED_FOR, /**< obsolete Squid custom header, RFC 7239 */
119 HDR_X_REQUEST_URI, /**< Squid custom header appended if ADD_X_REQUEST_URI is defined */
120 HDR_X_SQUID_ERROR, /**< Squid custom header on generated error responses */
121 #if X_ACCELERATOR_VARY
122 HDR_X_ACCELERATOR_VARY, /**< obsolete Squid custom header. */
123 #endif
124 #if USE_ADAPTATION
125 HDR_X_NEXT_SERVICES, /**< Squid custom ICAP header */
126 #endif
127 HDR_SURROGATE_CAPABILITY, /**< Edge Side Includes (ESI) header */
128 HDR_SURROGATE_CONTROL, /**< Edge Side Includes (ESI) header */
129 HDR_FRONT_END_HTTPS, /**< MS Exchange custom header we may have to add */
130 HDR_FTP_COMMAND, /**< Internal header for FTP command */
131 HDR_FTP_ARGUMENTS, /**< Internal header for FTP command arguments */
132 HDR_FTP_PRE, /**< Internal header containing leading FTP control response lines */
133 HDR_FTP_STATUS, /**< Internal header for FTP reply status */
134 HDR_FTP_REASON, /**< Internal header for FTP reply reason */
135 HDR_OTHER, /**< internal tag value for "unknown" headers */
136 HDR_ENUM_END
137 } http_hdr_type;
138
139 /** possible types for http header fields */
140 typedef enum {
141 ftInvalid = HDR_ENUM_END, /**< to catch nasty errors with hdr_id<->fld_type clashes */
142 ftInt,
143 ftInt64,
144 ftStr,
145 ftDate_1123,
146 ftETag,
147 ftPCc,
148 ftPContRange,
149 ftPRange,
150 ftPSc,
151 ftDate_1123_or_ETag
152 } field_type;
153
154 /** Possible owners of http header */
155 typedef enum {
156 hoNone =0,
157 #if USE_HTCP
158 hoHtcpReply,
159 #endif
160 hoRequest,
161 hoReply,
162 #if USE_OPENSSL
163 hoErrorDetail,
164 #endif
165 hoEnd
166 } http_hdr_owner_type;
167
168 // currently a POD
169 class HttpHeaderFieldAttrs
170 {
171 public:
172 const char *name;
173 http_hdr_type id;
174 field_type type;
175 };
176
177 /** Iteration for headers; use HttpHeaderPos as opaque type, do not interpret */
178 typedef ssize_t HttpHeaderPos;
179
180 /* use this and only this to initialize HttpHeaderPos */
181 #define HttpHeaderInitPos (-1)
182
183 class HttpHeaderEntry
184 {
185
186 public:
187 HttpHeaderEntry(http_hdr_type id, const char *name, const char *value);
188 ~HttpHeaderEntry();
189 static HttpHeaderEntry *parse(const char *field_start, const char *field_end);
190 HttpHeaderEntry *clone() const;
191 void packInto(Packer *p) const;
192 int getInt() const;
193 int64_t getInt64() const;
194 MEMPROXY_CLASS(HttpHeaderEntry);
195 http_hdr_type id;
196 String name;
197 String value;
198 };
199
200 MEMPROXY_CLASS_INLINE(HttpHeaderEntry);
201
202 class ETag;
203 class TimeOrTag;
204
205 class HttpHeader
206 {
207
208 public:
209 HttpHeader();
210 explicit HttpHeader(const http_hdr_owner_type owner);
211 HttpHeader(const HttpHeader &other);
212 ~HttpHeader();
213
214 HttpHeader &operator =(const HttpHeader &other);
215
216 /* Interface functions */
217 void clean();
218 void append(const HttpHeader * src);
219 void update (HttpHeader const *fresh, HttpHeaderMask const *denied_mask);
220 void compact();
221 int reset();
222 int parse(const char *header_start, const char *header_end);
223 void packInto(Packer * p, bool mask_sensitive_info=false) const;
224 HttpHeaderEntry *getEntry(HttpHeaderPos * pos) const;
225 HttpHeaderEntry *findEntry(http_hdr_type id) const;
226 int delByName(const char *name);
227 int delById(http_hdr_type id);
228 void delAt(HttpHeaderPos pos, int &headers_deleted);
229 void refreshMask();
230 void addEntry(HttpHeaderEntry * e);
231 void insertEntry(HttpHeaderEntry * e);
232 String getList(http_hdr_type id) const;
233 bool getList(http_hdr_type id, String *s) const;
234 String getStrOrList(http_hdr_type id) const;
235 String getByName(const char *name) const;
236 /// sets value and returns true iff a [possibly empty] named field is there
237 bool getByNameIfPresent(const char *name, String &value) const;
238 String getByNameListMember(const char *name, const char *member, const char separator) const;
239 String getListMember(http_hdr_type id, const char *member, const char separator) const;
240 int has(http_hdr_type id) const;
241 void putInt(http_hdr_type id, int number);
242 void putInt64(http_hdr_type id, int64_t number);
243 void putTime(http_hdr_type id, time_t htime);
244 void insertTime(http_hdr_type id, time_t htime);
245 void putStr(http_hdr_type id, const char *str);
246 void putAuth(const char *auth_scheme, const char *realm);
247 void putCc(const HttpHdrCc * cc);
248 void putContRange(const HttpHdrContRange * cr);
249 void putRange(const HttpHdrRange * range);
250 void putSc(HttpHdrSc *sc);
251 void putWarning(const int code, const char *const text); ///< add a Warning header
252 void putExt(const char *name, const char *value);
253 int getInt(http_hdr_type id) const;
254 int64_t getInt64(http_hdr_type id) const;
255 time_t getTime(http_hdr_type id) const;
256 const char *getStr(http_hdr_type id) const;
257 const char *getLastStr(http_hdr_type id) const;
258 HttpHdrCc *getCc() const;
259 HttpHdrRange *getRange() const;
260 HttpHdrSc *getSc() const;
261 HttpHdrContRange *getContRange() const;
262 const char *getAuth(http_hdr_type id, const char *auth_scheme) const;
263 ETag getETag(http_hdr_type id) const;
264 TimeOrTag getTimeOrTag(http_hdr_type id) const;
265 int hasListMember(http_hdr_type id, const char *member, const char separator) const;
266 int hasByNameListMember(const char *name, const char *member, const char separator) const;
267 void removeHopByHopEntries();
268 inline bool chunked() const; ///< whether message uses chunked Transfer-Encoding
269
270 /* protected, do not use these, use interface functions instead */
271 std::vector<HttpHeaderEntry *> entries; /**< parsed fields in raw format */
272 HttpHeaderMask mask; /**< bit set <=> entry present */
273 http_hdr_owner_type owner; /**< request or reply */
274 int len; /**< length when packed, not counting terminating null-byte */
275
276 protected:
277 /** \deprecated Public access replaced by removeHopByHopEntries() */
278 void removeConnectionHeaderEntries();
279
280 private:
281 HttpHeaderEntry *findLastEntry(http_hdr_type id) const;
282 };
283
284 int httpHeaderParseQuotedString(const char *start, const int len, String *val);
285
286 /// quotes string using RFC 7230 quoted-string rules
287 SBuf httpHeaderQuoteString(const char *raw);
288
289 int httpHeaderHasByNameListMember(const HttpHeader * hdr, const char *name, const char *member, const char separator);
290 void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask);
291 void httpHeaderCalcMask(HttpHeaderMask * mask, http_hdr_type http_hdr_type_enums[], size_t count);
292
293 inline bool
294 HttpHeader::chunked() const
295 {
296 return has(HDR_TRANSFER_ENCODING) &&
297 hasListMember(HDR_TRANSFER_ENCODING, "chunked", ',');
298 }
299
300 void httpHeaderInitModule(void);
301 void httpHeaderCleanModule(void);
302
303 #endif /* SQUID_HTTPHEADER_H */