]>
Commit | Line | Data |
---|---|---|
e6ccf245 | 1 | /* |
262a0e14 | 2 | * $Id$ |
e6ccf245 | 3 | * |
4 | * | |
5 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
6 | * ---------------------------------------------------------- | |
7 | * | |
8 | * Squid is the result of efforts by numerous individuals from | |
9 | * the Internet community; see the CONTRIBUTORS file for full | |
10 | * details. Many organizations have provided support for Squid's | |
11 | * development; see the SPONSORS file for full details. Squid is | |
12 | * Copyrighted (C) 2001 by the Regents of the University of | |
13 | * California; see the COPYRIGHT file for full details. Squid | |
14 | * incorporates software developed and/or copyrighted by other | |
15 | * sources; see the CREDITS file for full details. | |
16 | * | |
17 | * This program is free software; you can redistribute it and/or modify | |
18 | * it under the terms of the GNU General Public License as published by | |
19 | * the Free Software Foundation; either version 2 of the License, or | |
20 | * (at your option) any later version. | |
26ac0430 | 21 | * |
e6ccf245 | 22 | * This program is distributed in the hope that it will be useful, |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | * GNU General Public License for more details. | |
26ac0430 | 26 | * |
e6ccf245 | 27 | * You should have received a copy of the GNU General Public License |
28 | * along with this program; if not, write to the Free Software | |
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
30 | * | |
31 | */ | |
32 | ||
33 | #ifndef SQUID_HTTPHEADER_H | |
34 | #define SQUID_HTTPHEADER_H | |
35 | ||
528b2c61 | 36 | /* because we pass a spec by value */ |
37 | #include "HttpHeaderRange.h" | |
25b6a907 | 38 | /* HttpHeader holds a HttpHeaderMask */ |
39 | #include "HttpHeaderMask.h" | |
e6ccf245 | 40 | |
696a257c | 41 | /* class forward declarations */ |
696a257c FC |
42 | class HttpHdrContRange; |
43 | class HttpHdrCc; | |
44 | class HttpHdrSc; | |
45 | class HttpHdrRange; | |
46 | class String; | |
47 | ||
e6ccf245 | 48 | /* constant attributes of http header fields */ |
62e76326 | 49 | |
759fac4b | 50 | /// recognized or "known" header fields; and the RFC which defines them (or not) |
25b6a907 | 51 | typedef enum { |
52 | HDR_BAD_HDR = -1, | |
759fac4b AJ |
53 | HDR_ACCEPT = 0, /**< RFC 2608, 2616 */ |
54 | HDR_ACCEPT_CHARSET, /**< RFC 2608, 2616 */ | |
55 | HDR_ACCEPT_ENCODING, /**< RFC 2608, 2616 */ | |
56 | /*HDR_ACCEPT_FEATURES,*/ /* experimental RFC 2295 */ | |
57 | HDR_ACCEPT_LANGUAGE, /**< RFC 2608, 2616 */ | |
58 | HDR_ACCEPT_RANGES, /**< RFC 2608, 2616 */ | |
59 | HDR_AGE, /**< RFC 2608, 2616 */ | |
60 | HDR_ALLOW, /**< RFC 2608, 2616 */ | |
61 | /*HDR_ALTERNATES,*/ /* deprecated RFC 2068, 2295 */ | |
62 | HDR_AUTHORIZATION, /**< RFC 2608, 2616, 4559 */ | |
63 | HDR_CACHE_CONTROL, /**< RFC 2608, 2616 */ | |
64 | HDR_CONNECTION, /**< RFC 2608, 2616 */ | |
65 | HDR_CONTENT_BASE, /**< RFC 2608 */ | |
66 | HDR_CONTENT_DISPOSITION, /**< RFC 2183, 2616 */ | |
67 | HDR_CONTENT_ENCODING, /**< RFC 2608, 2616 */ | |
68 | HDR_CONTENT_LANGUAGE, /**< RFC 2608, 2616 */ | |
69 | HDR_CONTENT_LENGTH, /**< RFC 2608, 2616 */ | |
70 | HDR_CONTENT_LOCATION, /**< RFC 2608, 2616 */ | |
71 | HDR_CONTENT_MD5, /**< RFC 2608, 2616 */ | |
72 | HDR_CONTENT_RANGE, /**< RFC 2608, 2616 */ | |
73 | HDR_CONTENT_TYPE, /**< RFC 2608, 2616 */ | |
74 | /*HDR_CONTENT_VERSION,*/ /* deprecated RFC 2608 header. */ | |
75 | HDR_COOKIE, /**< de-facto and RFC 2965 header we may need to erase */ | |
76 | HDR_COOKIE2, /**< obsolete RFC 2965 header we may need to erase */ | |
77 | HDR_DATE, /**< RFC 2608, 2616 */ | |
78 | /*HDR_DAV,*/ /* RFC 2518 */ | |
79 | /*HDR_DEPTH,*/ /* RFC 2518 */ | |
80 | /*HDR_DERIVED_FROM,*/ /* deprecated RFC 2608 */ | |
81 | /*HDR_DESTINATION,*/ /* RFC 2518 */ | |
82 | HDR_ETAG, /**< RFC 2608, 2616 */ | |
83 | HDR_EXPECT, /**< RFC 2616, 2616 */ | |
84 | HDR_EXPIRES, /**< RFC 2608, 2616 */ | |
85 | HDR_FROM, /**< RFC 2608, 2616 */ | |
86 | HDR_HOST, /**< RFC 2608, 2616 */ | |
87 | /*HDR_IF,*/ /* RFC 2518 */ | |
88 | HDR_IF_MATCH, /**< RFC 2608, 2616 */ | |
89 | HDR_IF_MODIFIED_SINCE, /**< RFC 2608, 2616 */ | |
90 | HDR_IF_NONE_MATCH, /**< RFC 2608, 2616 */ | |
91 | HDR_IF_RANGE, /**< RFC 2608, 2616 */ | |
debd58cb | 92 | /*HDR_IF_UNMODIFIED_SINCE,*/ /**< RFC 2608, 2616 */ |
759fac4b AJ |
93 | HDR_KEEP_ALIVE, /**< obsolete HTTP/1.0 header we may need to erase */ |
94 | HDR_LAST_MODIFIED, /**< RFC 2608, 2616 */ | |
95 | HDR_LINK, /**< RFC 2068 */ | |
96 | HDR_LOCATION, /**< RFC 2608, 2616 */ | |
97 | /*HDR_LOCK_TOKEN,*/ /* RFC 2518 */ | |
98 | HDR_MAX_FORWARDS, /**< RFC 2608, 2616 */ | |
99 | HDR_MIME_VERSION, /**< RFC 2626 */ | |
100 | HDR_NEGOTIATE, /**< experimental RFC 2295. Why only this one from 2295? */ | |
101 | /*HDR_OVERWRITE,*/ /* RFC 2518 */ | |
3865965d | 102 | HDR_ORIGIN, /* CORS Draft specification (see http://www.w3.org/TR/cors/) */ |
759fac4b AJ |
103 | HDR_PRAGMA, /**< deprecated RFC 2068,2616 header we may need to erase */ |
104 | HDR_PROXY_AUTHENTICATE, /**< RFC 2608, 2616, 2617 */ | |
105 | HDR_PROXY_AUTHENTICATION_INFO, /**< RFC 2617 */ | |
106 | HDR_PROXY_AUTHORIZATION, /**< RFC 2608, 2616, 2617 */ | |
107 | HDR_PROXY_CONNECTION, /**< obsolete Netscape header we may need to erase. */ | |
108 | HDR_PROXY_SUPPORT, /**< RFC 4559 */ | |
109 | HDR_PUBLIC, /**< RFC 2608 */ | |
110 | HDR_RANGE, /**< RFC 2608, 2616 */ | |
759fac4b | 111 | HDR_REFERER, /**< RFC 2608, 2616 */ |
debd58cb | 112 | HDR_REQUEST_RANGE, /**< some clients use this, sigh */ |
759fac4b AJ |
113 | HDR_RETRY_AFTER, /**< RFC 2608, 2616 */ |
114 | HDR_SERVER, /**< RFC 2608, 2616 */ | |
115 | HDR_SET_COOKIE, /**< de-facto standard header we may need to erase */ | |
116 | HDR_SET_COOKIE2, /**< obsolete RFC 2965 header we may need to erase */ | |
117 | /*HDR_STATUS_URI,*/ /* RFC 2518 */ | |
118 | /*HDR_TCN,*/ /* experimental RFC 2295 */ | |
119 | HDR_TE, /**< RFC 2616 */ | |
120 | /*HDR_TIMEOUT,*/ /* RFC 2518 */ | |
121 | HDR_TITLE, /* obsolete draft suggested header */ | |
122 | HDR_TRAILER, /**< RFC 2616 */ | |
123 | HDR_TRANSFER_ENCODING, /**< RFC 2608, 2616 */ | |
124 | HDR_TRANSLATE, /**< IIS custom header we may need to erase */ | |
125 | HDR_UNLESS_MODIFIED_SINCE, /**< IIS custom header we may need to erase */ | |
126 | HDR_UPGRADE, /**< RFC 2608, 2616 */ | |
127 | /*HDR_URI,*/ /* obsolete RFC 2068 header */ | |
128 | HDR_USER_AGENT, /**< RFC 2608, 2616 */ | |
129 | /*HDR_VARIANT_VARY,*/ /* experimental RFC 2295 */ | |
130 | HDR_VARY, /**< RFC 2608, 2616 */ | |
131 | HDR_VIA, /**< RFC 2608, 2616 */ | |
132 | HDR_WARNING, /**< RFC 2608, 2616 */ | |
133 | HDR_WWW_AUTHENTICATE, /**< RFC 2608, 2616, 2617, 4559 */ | |
134 | HDR_AUTHENTICATION_INFO, /**< RFC 2617 */ | |
135 | HDR_X_CACHE, /**< Squid custom header */ | |
136 | HDR_X_CACHE_LOOKUP, /**< Squid custom header. temporary hack that became de-facto. TODO remove */ | |
137 | HDR_X_FORWARDED_FOR, /**< Squid custom header */ | |
138 | HDR_X_REQUEST_URI, /**< Squid custom header appended if ADD_X_REQUEST_URI is defined */ | |
139 | HDR_X_SQUID_ERROR, /**< Squid custom header on generated error responses */ | |
25b6a907 | 140 | #if X_ACCELERATOR_VARY |
759fac4b | 141 | HDR_X_ACCELERATOR_VARY, /**< obsolete Squid custom header. */ |
a22e6cd3 AR |
142 | #endif |
143 | #if USE_ADAPTATION | |
759fac4b | 144 | HDR_X_NEXT_SERVICES, /**< Squid custom ICAP header */ |
25b6a907 | 145 | #endif |
759fac4b AJ |
146 | HDR_SURROGATE_CAPABILITY, /**< Edge Side Includes (ESI) header */ |
147 | HDR_SURROGATE_CONTROL, /**< Edge Side Includes (ESI) header */ | |
148 | HDR_FRONT_END_HTTPS, /**< MS Exchange custom header we may have to add */ | |
149 | HDR_OTHER, /**< internal tag value for "unknown" headers */ | |
25b6a907 | 150 | HDR_ENUM_END |
151 | } http_hdr_type; | |
152 | ||
63be0a78 | 153 | /** possible types for http header fields */ |
25b6a907 | 154 | typedef enum { |
63be0a78 | 155 | ftInvalid = HDR_ENUM_END, /**< to catch nasty errors with hdr_id<->fld_type clashes */ |
25b6a907 | 156 | ftInt, |
47f6e231 | 157 | ftInt64, |
25b6a907 | 158 | ftStr, |
159 | ftDate_1123, | |
160 | ftETag, | |
161 | ftPCc, | |
162 | ftPContRange, | |
163 | ftPRange, | |
164 | ftPSc, | |
165 | ftDate_1123_or_ETag | |
166 | } field_type; | |
167 | ||
63be0a78 | 168 | /** Possible owners of http header */ |
25b6a907 | 169 | typedef enum { |
0b57cb3d | 170 | hoNone =0, |
25b6a907 | 171 | #if USE_HTCP |
172 | hoHtcpReply, | |
173 | #endif | |
174 | hoRequest, | |
02259ff8 CT |
175 | hoReply, |
176 | #if USE_SSL | |
177 | hoErrorDetail, | |
178 | #endif | |
179 | hoEnd | |
25b6a907 | 180 | } http_hdr_owner_type; |
181 | ||
26ac0430 | 182 | struct _HttpHeaderFieldAttrs { |
e6ccf245 | 183 | const char *name; |
184 | http_hdr_type id; | |
185 | field_type type; | |
186 | }; | |
187 | ||
63be0a78 | 188 | /** Iteration for headers; use HttpHeaderPos as opaque type, do not interpret */ |
985c86bc | 189 | typedef ssize_t HttpHeaderPos; |
190 | ||
191 | /* use this and only this to initialize HttpHeaderPos */ | |
192 | #define HttpHeaderInitPos (-1) | |
193 | ||
eede25e7 | 194 | class HttpHeaderEntry |
195 | { | |
196 | ||
197 | public: | |
eede25e7 | 198 | HttpHeaderEntry(http_hdr_type id, const char *name, const char *value); |
199 | ~HttpHeaderEntry(); | |
cdce6c61 | 200 | static HttpHeaderEntry *parse(const char *field_start, const char *field_end); |
eede25e7 | 201 | HttpHeaderEntry *clone() const; |
202 | void packInto(Packer *p) const; | |
203 | int getInt() const; | |
47f6e231 | 204 | int64_t getInt64() const; |
eede25e7 | 205 | MEMPROXY_CLASS(HttpHeaderEntry); |
206 | http_hdr_type id; | |
30abd221 | 207 | String name; |
208 | String value; | |
eede25e7 | 209 | }; |
210 | ||
63be0a78 | 211 | MEMPROXY_CLASS_INLINE(HttpHeaderEntry); |
eede25e7 | 212 | |
81a94152 AJ |
213 | class ETag; |
214 | class TimeOrTag; | |
215 | ||
924f73bc | 216 | class HttpHeader |
217 | { | |
218 | ||
219 | public: | |
75faaa7a | 220 | HttpHeader(); |
5e5fa5b1 AR |
221 | explicit HttpHeader(const http_hdr_owner_type owner); |
222 | HttpHeader(const HttpHeader &other); | |
75faaa7a | 223 | ~HttpHeader(); |
5e5fa5b1 AR |
224 | |
225 | HttpHeader &operator =(const HttpHeader &other); | |
226 | ||
924f73bc | 227 | /* Interface functions */ |
519e0948 | 228 | void clean(); |
a9925b40 | 229 | void append(const HttpHeader * src); |
230 | void update (HttpHeader const *fresh, HttpHeaderMask const *denied_mask); | |
394499bd | 231 | void compact(); |
a9925b40 | 232 | int reset(); |
233 | int parse(const char *header_start, const char *header_end); | |
d8f6c79c | 234 | void packInto(Packer * p, bool mask_sensitive_info=false) const; |
a9925b40 | 235 | HttpHeaderEntry *getEntry(HttpHeaderPos * pos) const; |
236 | HttpHeaderEntry *findEntry(http_hdr_type id) const; | |
237 | int delByName(const char *name); | |
238 | int delById(http_hdr_type id); | |
ba9fb01d | 239 | void delAt(HttpHeaderPos pos, int &headers_deleted); |
240 | void refreshMask(); | |
a9925b40 | 241 | void addEntry(HttpHeaderEntry * e); |
242 | void insertEntry(HttpHeaderEntry * e); | |
30abd221 | 243 | String getList(http_hdr_type id) const; |
244 | bool getList(http_hdr_type id, String *s) const; | |
245 | String getStrOrList(http_hdr_type id) const; | |
246 | String getByName(const char *name) const; | |
247 | String getByNameListMember(const char *name, const char *member, const char separator) const; | |
248 | String getListMember(http_hdr_type id, const char *member, const char separator) const; | |
a9925b40 | 249 | int has(http_hdr_type id) const; |
250 | void putInt(http_hdr_type id, int number); | |
47f6e231 | 251 | void putInt64(http_hdr_type id, int64_t number); |
a9925b40 | 252 | void putTime(http_hdr_type id, time_t htime); |
253 | void insertTime(http_hdr_type id, time_t htime); | |
254 | void putStr(http_hdr_type id, const char *str); | |
255 | void putAuth(const char *auth_scheme, const char *realm); | |
256 | void putCc(const HttpHdrCc * cc); | |
257 | void putContRange(const HttpHdrContRange * cr); | |
258 | void putRange(const HttpHdrRange * range); | |
259 | void putSc(HttpHdrSc *sc); | |
bcfba8bd | 260 | void putWarning(const int code, const char *const text); ///< add a Warning header |
a9925b40 | 261 | void putExt(const char *name, const char *value); |
262 | int getInt(http_hdr_type id) const; | |
47f6e231 | 263 | int64_t getInt64(http_hdr_type id) const; |
a9925b40 | 264 | time_t getTime(http_hdr_type id) const; |
265 | const char *getStr(http_hdr_type id) const; | |
266 | const char *getLastStr(http_hdr_type id) const; | |
267 | HttpHdrCc *getCc() const; | |
268 | HttpHdrRange *getRange() const; | |
269 | HttpHdrSc *getSc() const; | |
270 | HttpHdrContRange *getContRange() const; | |
271 | const char *getAuth(http_hdr_type id, const char *auth_scheme) const; | |
272 | ETag getETag(http_hdr_type id) const; | |
273 | TimeOrTag getTimeOrTag(http_hdr_type id) const; | |
274 | int hasListMember(http_hdr_type id, const char *member, const char separator) const; | |
275 | int hasByNameListMember(const char *name, const char *member, const char separator) const; | |
2cdeea82 | 276 | void removeHopByHopEntries(); |
c3d0ba0c | 277 | inline bool chunked() const; ///< whether message uses chunked Transfer-Encoding |
63be0a78 | 278 | |
924f73bc | 279 | /* protected, do not use these, use interface functions instead */ |
63be0a78 | 280 | Vector<HttpHeaderEntry *> entries; /**< parsed fields in raw format */ |
281 | HttpHeaderMask mask; /**< bit set <=> entry present */ | |
282 | http_hdr_owner_type owner; /**< request or reply */ | |
d85b8894 | 283 | int len; /**< length when packed, not counting terminating null-byte */ |
a9925b40 | 284 | |
2cdeea82 | 285 | protected: |
63be0a78 | 286 | /** \deprecated Public access replaced by removeHopByHopEntries() */ |
2cdeea82 | 287 | void removeConnectionHeaderEntries(); |
63be0a78 | 288 | |
a9925b40 | 289 | private: |
290 | HttpHeaderEntry *findLastEntry(http_hdr_type id) const; | |
924f73bc | 291 | }; |
528b2c61 | 292 | |
34460e19 | 293 | extern int httpHeaderParseQuotedString(const char *start, const int len, String *val); |
25b6a907 | 294 | SQUIDCEXTERN int httpHeaderHasByNameListMember(const HttpHeader * hdr, const char *name, const char *member, const char separator); |
295 | SQUIDCEXTERN void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask); | |
25b6a907 | 296 | SQUIDCEXTERN void httpHeaderCalcMask(HttpHeaderMask * mask, http_hdr_type http_hdr_type_enums[], size_t count); |
297 | ||
c3d0ba0c AR |
298 | inline bool |
299 | HttpHeader::chunked() const | |
300 | { | |
301 | return has(HDR_TRANSFER_ENCODING) && | |
f673997d | 302 | hasListMember(HDR_TRANSFER_ENCODING, "chunked", ','); |
c3d0ba0c AR |
303 | } |
304 | ||
e6ccf245 | 305 | #endif /* SQUID_HTTPHEADER_H */ |