1 /** @file
2
3 A brief file description
4
5 @section license License
6
7 Licensed to the Apache Software Foundation (ASF) under one
8 or more contributor license agreements. See the NOTICE file
9 distributed with this work for additional information
10 regarding copyright ownership. The ASF licenses this file
11 to you under the Apache License, Version 2.0 (the
12 "License"); you may not use this file except in compliance
13 with the License. You may obtain a copy of the License at
14
15 http://www.apache.org/licenses/LICENSE-2.0
16
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
22 */
23
24 #pragma once
25
26 #include <cassert>
27 #include <sys/types.h>
28 #include "tscore/ink_assert.h"
29 #include "tscore/ink_atomic.h"
30 #include "tscore/ink_defs.h"
31 #include "tscore/ink_string.h"
32 #include "tscore/Allocator.h"
33 #include "tscore/Regex.h"
34 #include "tscore/ink_apidefs.h"
35
36 ////////////////////////////////////////////////////////////////////////////
37 //
38 // tokenized string data
39 //
40 ////////////////////////////////////////////////////////////////////////////
41
42 #define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
43
44 enum HdrTokenType {
45 HDRTOKEN_TYPE_OTHER = 0,
46 HDRTOKEN_TYPE_FIELD = 1,
47 HDRTOKEN_TYPE_METHOD = 2,
48 HDRTOKEN_TYPE_SCHEME = 3,
49 HDRTOKEN_TYPE_CACHE_CONTROL = 4
50 };
51
52 struct HdrTokenTypeBinding {
53 const char *name;
54 HdrTokenType type;
55 };
56
57 struct HdrTokenFieldInfo {
58 const char *name;
59 int32_t slotid;
60 uint64_t mask;
61 uint32_t flags;
62 };
63
64 struct HdrTokenTypeSpecific {
65 union {
66 struct {
67 uint32_t cc_mask;
68 } cache_control;
69 } u;
70 };
71
72 struct HdrTokenHeapPrefix {
73 int wks_idx;
74 int wks_length;
75 HdrTokenType wks_token_type;
76 HdrTokenFieldInfo wks_info;
77 HdrTokenTypeSpecific wks_type_specific;
78 };
79
80 enum HdrTokenInfoFlags {
81 HTIF_NONE = 0,
82 HTIF_COMMAS = 1 << 0,
83 HTIF_MULTVALS = 1 << 1,
84 HTIF_HOPBYHOP = 1 << 2,
85 HTIF_PROXYAUTH = 1 << 3
86 };
87
88 extern DFA *hdrtoken_strs_dfa;
89 extern int hdrtoken_num_wks;
90
91 extern const char *hdrtoken_strs[];
92 extern int hdrtoken_str_lengths[];
93 extern HdrTokenType hdrtoken_str_token_types[];
94 extern int32_t hdrtoken_str_slotids[];
95 extern uint64_t hdrtoken_str_masks[];
96 extern uint32_t hdrtoken_str_flags[];
97
98 ////////////////////////////////////////////////////////////////////////////
99 //
100 // tokenized string functions
101 //
102 ////////////////////////////////////////////////////////////////////////////
103
104 extern void hdrtoken_init();
105 extern int hdrtoken_tokenize_dfa(const char *string, int string_len, const char **wks_string_out = nullptr);
106 inkcoreapi extern int hdrtoken_tokenize(const char *string, int string_len, const char **wks_string_out = nullptr);
107 extern int hdrtoken_method_tokenize(const char *string, int string_len);
108 extern const char *hdrtoken_string_to_wks(const char *string);
109 extern const char *hdrtoken_string_to_wks(const char *string, int length);
110
111 /*-------------------------------------------------------------------------
112 -------------------------------------------------------------------------*/
113
114 inline bool
hdrtoken_is_wks(const char * str)115 hdrtoken_is_wks(const char *str)
116 {
117 extern const char *_hdrtoken_strs_heap_f;
118 extern const char *_hdrtoken_strs_heap_l;
119
120 return ((str >= _hdrtoken_strs_heap_f) && (str <= _hdrtoken_strs_heap_l));
121 }
122
123 /*-------------------------------------------------------------------------
124 -------------------------------------------------------------------------*/
125
126 inline bool
hdrtoken_is_valid_wks_idx(int wks_idx)127 hdrtoken_is_valid_wks_idx(int wks_idx)
128 {
129 return ((wks_idx >= 0) && (wks_idx < hdrtoken_num_wks));
130 }
131
132 /*-------------------------------------------------------------------------
133 -------------------------------------------------------------------------*/
134
135 // ToDo: This, and dependencies / users should probably be const HdrTokenHeapPrefix * IMO.
136 inline HdrTokenHeapPrefix *
hdrtoken_wks_to_prefix(const char * wks)137 hdrtoken_wks_to_prefix(const char *wks)
138 {
139 ink_assert(hdrtoken_is_wks(wks));
140 return reinterpret_cast<HdrTokenHeapPrefix *>(const_cast<char *>(wks) - sizeof(HdrTokenHeapPrefix));
141 }
142
143 /*-------------------------------------------------------------------------
144 -------------------------------------------------------------------------*/
145
146 inline const char *
hdrtoken_index_to_wks(int wks_idx)147 hdrtoken_index_to_wks(int wks_idx)
148 {
149 ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
150 return hdrtoken_strs[wks_idx];
151 }
152
153 inline int
hdrtoken_index_to_length(int wks_idx)154 hdrtoken_index_to_length(int wks_idx)
155 {
156 ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
157 return hdrtoken_str_lengths[wks_idx];
158 }
159
160 inline HdrTokenType
hdrtoken_index_to_token_type(int wks_idx)161 hdrtoken_index_to_token_type(int wks_idx)
162 {
163 ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
164 return hdrtoken_str_token_types[wks_idx];
165 }
166
167 inline int
hdrtoken_index_to_slotid(int wks_idx)168 hdrtoken_index_to_slotid(int wks_idx)
169 {
170 ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
171 return hdrtoken_str_slotids[wks_idx];
172 }
173
174 inline uint64_t
hdrtoken_index_to_mask(int wks_idx)175 hdrtoken_index_to_mask(int wks_idx)
176 {
177 ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
178 return hdrtoken_str_masks[wks_idx];
179 }
180
181 inline int
hdrtoken_index_to_flags(int wks_idx)182 hdrtoken_index_to_flags(int wks_idx)
183 {
184 ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
185 return hdrtoken_str_flags[wks_idx];
186 }
187
188 inline HdrTokenHeapPrefix *
hdrtoken_index_to_prefix(int wks_idx)189 hdrtoken_index_to_prefix(int wks_idx)
190 {
191 ink_assert(hdrtoken_is_valid_wks_idx(wks_idx));
192 return hdrtoken_wks_to_prefix(hdrtoken_index_to_wks(wks_idx));
193 }
194
195 /*-------------------------------------------------------------------------
196 -------------------------------------------------------------------------*/
197
198 inline int
hdrtoken_wks_to_index(const char * wks)199 hdrtoken_wks_to_index(const char *wks)
200 {
201 ink_assert(hdrtoken_is_wks(wks));
202 return hdrtoken_wks_to_prefix(wks)->wks_idx;
203 }
204
205 inline int
hdrtoken_wks_to_length(const char * wks)206 hdrtoken_wks_to_length(const char *wks)
207 {
208 ink_assert(hdrtoken_is_wks(wks));
209 return hdrtoken_wks_to_prefix(wks)->wks_length;
210 }
211
212 inline int
hdrtoken_wks_to_token_type(const char * wks)213 hdrtoken_wks_to_token_type(const char *wks)
214 {
215 ink_assert(hdrtoken_is_wks(wks));
216 return hdrtoken_wks_to_prefix(wks)->wks_token_type;
217 }
218
219 inline int
hdrtoken_wks_to_slotid(const char * wks)220 hdrtoken_wks_to_slotid(const char *wks)
221 {
222 ink_assert(hdrtoken_is_wks(wks));
223 return hdrtoken_wks_to_prefix(wks)->wks_info.slotid;
224 }
225
226 inline uint64_t
hdrtoken_wks_to_mask(const char * wks)227 hdrtoken_wks_to_mask(const char *wks)
228 {
229 ink_assert(hdrtoken_is_wks(wks));
230 HdrTokenHeapPrefix *prefix = hdrtoken_wks_to_prefix(wks);
231 return prefix->wks_info.mask;
232 }
233
234 inline int
hdrtoken_wks_to_flags(const char * wks)235 hdrtoken_wks_to_flags(const char *wks)
236 {
237 ink_assert(hdrtoken_is_wks(wks));
238 return hdrtoken_wks_to_prefix(wks)->wks_info.flags;
239 }
240
241 /*-------------------------------------------------------------------------
242 -------------------------------------------------------------------------*/
243
244 ////////////////////////////////////////////////////////////////////////////
245 //
246 // tokenized string mime slot ids
247 //
248 // (up to 32 of the most common headers are allowed to be placed in
249 // special fast slots and contain presence bits and other info)
250 //
251 ////////////////////////////////////////////////////////////////////////////
252
253 #define MIME_SLOTID_ACCEPT 0
254 #define MIME_SLOTID_ACCEPT_CHARSET 1
255 #define MIME_SLOTID_ACCEPT_ENCODING 2
256 #define MIME_SLOTID_ACCEPT_LANGUAGE 3
257 #define MIME_SLOTID_AGE 4
258 #define MIME_SLOTID_AUTHORIZATION 5
259 #define MIME_SLOTID_CACHE_CONTROL 6
260 #define MIME_SLOTID_CLIENT_IP 7
261 #define MIME_SLOTID_CONNECTION 8
262 #define MIME_SLOTID_CONTENT_ENCODING 9
263 #define MIME_SLOTID_CONTENT_LANGUAGE 10
264 #define MIME_SLOTID_CONTENT_LENGTH 11
265 #define MIME_SLOTID_CONTENT_TYPE 12
266 #define MIME_SLOTID_COOKIE 13
267 #define MIME_SLOTID_DATE 14
268 #define MIME_SLOTID_EXPIRES 15
269 #define MIME_SLOTID_IF_MATCH 16
270 #define MIME_SLOTID_IF_MODIFIED_SINCE 17
271 #define MIME_SLOTID_IF_NONE_MATCH 18
272 #define MIME_SLOTID_IF_RANGE 19
273 #define MIME_SLOTID_IF_UNMODIFIED_SINCE 20
274 #define MIME_SLOTID_LAST_MODIFIED 21
275 #define MIME_SLOTID_PRAGMA 22
276 #define MIME_SLOTID_PROXY_CONNECTION 23
277 #define MIME_SLOTID_RANGE 24
278 #define MIME_SLOTID_SET_COOKIE 25
279 #define MIME_SLOTID_TE 26
280 #define MIME_SLOTID_TRANSFER_ENCODING 27
281 #define MIME_SLOTID_USER_AGENT 28
282 #define MIME_SLOTID_VARY 29
283 #define MIME_SLOTID_VIA 30
284 #define MIME_SLOTID_WWW_AUTHENTICATE 31
285
286 #define MIME_SLOTID_NONE -1
287
288 ////////////////////////////////////////////////////////////////////////////
289 //
290 // tokenized string mime presence masks
291 //
292 // (up to 64 headers get bitmasks for presence calculations)
293 //
294 ////////////////////////////////////////////////////////////////////////////
295
296 // Windows insists on doing everything it's own completely
297 // incompatible way, including integer constant subscripts.
298 // It's too easy to match a subscript to a type since everything
299 // won't break if the type is a different size. Oh no, we
300 // need to define the number of bits in our constants to make
301 // life hard
302 #define TOK_64_CONST(x) x##LL
303
304 #define MIME_PRESENCE_ACCEPT (TOK_64_CONST(1) << 0)
305 #define MIME_PRESENCE_ACCEPT_CHARSET (TOK_64_CONST(1) << 1)
306 #define MIME_PRESENCE_ACCEPT_ENCODING (TOK_64_CONST(1) << 2)
307 #define MIME_PRESENCE_ACCEPT_LANGUAGE (TOK_64_CONST(1) << 3)
308 #define MIME_PRESENCE_ACCEPT_RANGES (TOK_64_CONST(1) << 4)
309 #define MIME_PRESENCE_AGE (TOK_64_CONST(1) << 5)
310 #define MIME_PRESENCE_ALLOW (TOK_64_CONST(1) << 6)
311 #define MIME_PRESENCE_AUTHORIZATION (TOK_64_CONST(1) << 7)
312 #define MIME_PRESENCE_BYTES (TOK_64_CONST(1) << 8)
313 #define MIME_PRESENCE_CACHE_CONTROL (TOK_64_CONST(1) << 9)
314 #define MIME_PRESENCE_CLIENT_IP (TOK_64_CONST(1) << 10)
315 #define MIME_PRESENCE_CONNECTION (TOK_64_CONST(1) << 11)
316 #define MIME_PRESENCE_CONTENT_ENCODING (TOK_64_CONST(1) << 12)
317 #define MIME_PRESENCE_CONTENT_LANGUAGE (TOK_64_CONST(1) << 13)
318 #define MIME_PRESENCE_CONTENT_LENGTH (TOK_64_CONST(1) << 14)
319 #define MIME_PRESENCE_CONTENT_LOCATION (TOK_64_CONST(1) << 15)
320 #define MIME_PRESENCE_CONTENT_MD5 (TOK_64_CONST(1) << 16)
321 #define MIME_PRESENCE_CONTENT_RANGE (TOK_64_CONST(1) << 17)
322 #define MIME_PRESENCE_CONTENT_TYPE (TOK_64_CONST(1) << 18)
323 #define MIME_PRESENCE_COOKIE (TOK_64_CONST(1) << 19)
324 #define MIME_PRESENCE_DATE (TOK_64_CONST(1) << 20)
325 #define MIME_PRESENCE_ETAG (TOK_64_CONST(1) << 21)
326 #define MIME_PRESENCE_EXPIRES (TOK_64_CONST(1) << 22)
327 #define MIME_PRESENCE_FROM (TOK_64_CONST(1) << 23)
328 #define MIME_PRESENCE_HOST (TOK_64_CONST(1) << 24)
329 #define MIME_PRESENCE_IF_MATCH (TOK_64_CONST(1) << 25)
330 #define MIME_PRESENCE_IF_MODIFIED_SINCE (TOK_64_CONST(1) << 26)
331 #define MIME_PRESENCE_IF_NONE_MATCH (TOK_64_CONST(1) << 27)
332 #define MIME_PRESENCE_IF_RANGE (TOK_64_CONST(1) << 28)
333 #define MIME_PRESENCE_IF_UNMODIFIED_SINCE (TOK_64_CONST(1) << 29)
334 #define MIME_PRESENCE_KEEP_ALIVE (TOK_64_CONST(1) << 30)
335 #define MIME_PRESENCE_KEYWORDS (TOK_64_CONST(1) << 31)
336 #define MIME_PRESENCE_LAST_MODIFIED (TOK_64_CONST(1) << 32)
337 #define MIME_PRESENCE_LINES (TOK_64_CONST(1) << 33)
338 #define MIME_PRESENCE_LOCATION (TOK_64_CONST(1) << 34)
339 #define MIME_PRESENCE_MAX_FORWARDS (TOK_64_CONST(1) << 35)
340 #define MIME_PRESENCE_PATH (TOK_64_CONST(1) << 36)
341 #define MIME_PRESENCE_PRAGMA (TOK_64_CONST(1) << 37)
342 #define MIME_PRESENCE_PROXY_AUTHENTICATE (TOK_64_CONST(1) << 38)
343 #define MIME_PRESENCE_PROXY_AUTHORIZATION (TOK_64_CONST(1) << 39)
344 #define MIME_PRESENCE_PROXY_CONNECTION (TOK_64_CONST(1) << 40)
345 #define MIME_PRESENCE_PUBLIC (TOK_64_CONST(1) << 41)
346 #define MIME_PRESENCE_RANGE (TOK_64_CONST(1) << 42)
347 #define MIME_PRESENCE_REFERER (TOK_64_CONST(1) << 43)
348 #define MIME_PRESENCE_SERVER (TOK_64_CONST(1) << 44)
349 #define MIME_PRESENCE_SET_COOKIE (TOK_64_CONST(1) << 45)
350 #define MIME_PRESENCE_SUBJECT (TOK_64_CONST(1) << 46)
351 #define MIME_PRESENCE_SUMMARY (TOK_64_CONST(1) << 47)
352 #define MIME_PRESENCE_TE (TOK_64_CONST(1) << 48)
353 #define MIME_PRESENCE_TRANSFER_ENCODING (TOK_64_CONST(1) << 49)
354 #define MIME_PRESENCE_UPGRADE (TOK_64_CONST(1) << 50)
355 #define MIME_PRESENCE_USER_AGENT (TOK_64_CONST(1) << 51)
356 #define MIME_PRESENCE_VARY (TOK_64_CONST(1) << 52)
357 #define MIME_PRESENCE_VIA (TOK_64_CONST(1) << 53)
358 #define MIME_PRESENCE_WARNING (TOK_64_CONST(1) << 54)
359 #define MIME_PRESENCE_WWW_AUTHENTICATE (TOK_64_CONST(1) << 55)
360
361 // bits 56-60 were used for a benchmark hack, but are now free to be used
362 // for something else
363 #define MIME_PRESENCE_UNUSED_1 (TOK_64_CONST(1) << 56)
364 #define MIME_PRESENCE_UNUSED_2 (TOK_64_CONST(1) << 57)
365 #define MIME_PRESENCE_UNUSED_3 (TOK_64_CONST(1) << 58)
366 #define MIME_PRESENCE_UNUSED_4 (TOK_64_CONST(1) << 59)
367 #define MIME_PRESENCE_UNUSED_5 (TOK_64_CONST(1) << 60)
368
369 #define MIME_PRESENCE_XREF (TOK_64_CONST(1) << 61)
370
371 #define MIME_PRESENCE_NONE TOK_64_CONST(0)
372 #define MIME_PRESENCE_ALL ~(TOK_64_CONST(0))
373
374 /*-------------------------------------------------------------------------
375 -------------------------------------------------------------------------*/
376
377 // HTTP/2 Upgrade token
378 #define MIME_UPGRADE_H2C_TOKEN "h2c"
379
380 /*-------------------------------------------------------------------------
381 -------------------------------------------------------------------------*/
382