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