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 <sys/time.h>
27 #include <string_view>
28 #include <string>
29
30 #include "tscore/ink_assert.h"
31 #include "tscore/ink_apidefs.h"
32 #include "tscore/ink_string++.h"
33 #include "tscore/ParseRules.h"
34 #include "HdrHeap.h"
35 #include "HdrToken.h"
36
37 #include "tscpp/util/TextView.h"
38
39 /***********************************************************************
40 * *
41 * Defines *
42 * *
43 ***********************************************************************/
44
45 enum ParseResult {
46 PARSE_RESULT_ERROR = -1,
47 PARSE_RESULT_DONE = 0,
48 PARSE_RESULT_CONT = 1,
49 PARSE_RESULT_OK = 3, // This is only used internally in mime_parser_parse and not returned to the user
50 };
51
52 enum {
53 UNDEFINED_COUNT = -1,
54 };
55
56 /// Parsing state.
57 enum MimeParseState {
58 MIME_PARSE_BEFORE, ///< Before a field.
59 MIME_PARSE_FOUND_CR, ///< Before a field, found a CR.
60 MIME_PARSE_INSIDE, ///< Inside a field.
61 MIME_PARSE_AFTER, ///< After a field.
62 };
63
64 /***********************************************************************
65 * *
66 * Assertions *
67 * *
68 ***********************************************************************/
69
70 #ifdef ENABLE_MIME_SANITY_CHECK
71 #define MIME_HDR_SANITY_CHECK mime_hdr_sanity_check
72 #else
73 #define MIME_HDR_SANITY_CHECK (void)
74 #endif
75
76 #define MIME_FIELD_SLOT_READINESS_EMPTY 0
77 #define MIME_FIELD_SLOT_READINESS_DETACHED 1
78 #define MIME_FIELD_SLOT_READINESS_LIVE 2
79 #define MIME_FIELD_SLOT_READINESS_DELETED 3
80
81 #define MIME_FIELD_SLOT_FLAGS_DUP_HEAD (1 << 0)
82 #define MIME_FIELD_SLOT_FLAGS_COOKED (1 << 1)
83
84 #define MIME_FIELD_BLOCK_SLOTS 16
85
86 #define MIME_FIELD_SLOTNUM_BITS 4
87 #define MIME_FIELD_SLOTNUM_MASK ((1 << MIME_FIELD_SLOTNUM_BITS) - 1)
88 #define MIME_FIELD_SLOTNUM_MAX (MIME_FIELD_SLOTNUM_MASK - 1)
89 #define MIME_FIELD_SLOTNUM_UNKNOWN MIME_FIELD_SLOTNUM_MAX
90
91 /***********************************************************************
92 * *
93 * MIMEField & MIMEFieldBlockImpl *
94 * *
95 ***********************************************************************/
96
97 struct MIMEHdrImpl;
98
99 struct MIMEField {
100 const char *m_ptr_name; // 4
101 const char *m_ptr_value; // 4
102 MIMEField *m_next_dup; // 4
103 int16_t m_wks_idx; // 2
104 uint16_t m_len_name; // 2
105 uint32_t m_len_value : 24; // 3
106 uint8_t m_n_v_raw_printable : 1; // 1/8
107 uint8_t m_n_v_raw_printable_pad : 3; // 3/8
108 uint8_t m_readiness : 2; // 2/8
109 uint8_t m_flags : 2; // 2/8
110
111 bool
is_dup_headMIMEField112 is_dup_head() const
113 {
114 return (m_flags & MIME_FIELD_SLOT_FLAGS_DUP_HEAD);
115 }
116
117 bool
is_cookedMIMEField118 is_cooked()
119 {
120 return (m_flags & MIME_FIELD_SLOT_FLAGS_COOKED) ? true : false;
121 }
122
123 bool
is_liveMIMEField124 is_live() const
125 {
126 return (m_readiness == MIME_FIELD_SLOT_READINESS_LIVE);
127 }
128
129 bool
is_detachedMIMEField130 is_detached() const
131 {
132 return (m_readiness == MIME_FIELD_SLOT_READINESS_DETACHED);
133 }
134
135 bool
supports_commasMIMEField136 supports_commas() const
137 {
138 if (m_wks_idx >= 0) {
139 return (hdrtoken_index_to_flags(m_wks_idx) & HTIF_COMMAS);
140 }
141 return true; // by default, assume supports commas
142 }
143
144 /// @return The name of @a this field.
145 std::string_view name_get() const;
146 const char *name_get(int *length) const;
147
148 /** Find the index of the value in the multi-value field.
149
150 If @a value is one of the values in this field return the
151 0 based index of it in the list of values. If the field is
152 not multivalued the index will always be zero if found.
153 Otherwise return -1 if the @a value is not found.
154
155 @note The most common use of this is to check for the presence of a specific
156 value in a comma enabled field.
157
158 @return The index of @a value.
159 */
160 int value_get_index(const char *value, int length) const;
161
162 /// @return The value of @a this field.
163 std::string_view value_get() const;
164 const char *value_get(int *length) const;
165
166 int32_t value_get_int() const;
167 uint32_t value_get_uint() const;
168 int64_t value_get_int64() const;
169 time_t value_get_date() const;
170 int value_get_comma_list(StrList *list) const;
171
172 void name_set(HdrHeap *heap, MIMEHdrImpl *mh, const char *name, int length);
173 bool name_is_valid() const;
174
175 void value_set(HdrHeap *heap, MIMEHdrImpl *mh, const char *value, int length);
176 void value_set_int(HdrHeap *heap, MIMEHdrImpl *mh, int32_t value);
177 void value_set_uint(HdrHeap *heap, MIMEHdrImpl *mh, uint32_t value);
178 void value_set_int64(HdrHeap *heap, MIMEHdrImpl *mh, int64_t value);
179 void value_set_date(HdrHeap *heap, MIMEHdrImpl *mh, time_t value);
180 void value_clear(HdrHeap *heap, MIMEHdrImpl *mh);
181 // MIME standard separator ',' is used as the default value
182 // Other separators (e.g. ';' in Set-cookie/Cookie) are also possible
183 void value_append(HdrHeap *heap, MIMEHdrImpl *mh, const char *value, int length, bool prepend_comma = false,
184 const char separator = ',');
185 bool value_is_valid() const;
186 int has_dups() const;
187 };
188
189 struct MIMEFieldBlockImpl : public HdrHeapObjImpl {
190 // HdrHeapObjImpl is 4 bytes
191 uint32_t m_freetop;
192 MIMEFieldBlockImpl *m_next;
193 MIMEField m_field_slots[MIME_FIELD_BLOCK_SLOTS];
194 // mime_hdr_copy_onto assumes that m_field_slots is last --
195 // don't add any new fields after it.
196
197 // Marshaling Functions
198 int marshal(MarshalXlate *ptr_xlate, int num_ptr, MarshalXlate *str_xlate, int num_str);
199 void unmarshal(intptr_t offset);
200 void move_strings(HdrStrHeap *new_heap);
201 size_t strings_length();
202 bool contains(const MIMEField *field);
203
204 // Sanity Check Functions
205 void check_strings(HeapCheck *heaps, int num_heaps);
206 };
207
208 /***********************************************************************
209 * *
210 * MIMECooked *
211 * *
212 ***********************************************************************/
213
214 enum MIMECookedMask {
215 MIME_COOKED_MASK_CC_MAX_AGE = (1 << 0),
216 MIME_COOKED_MASK_CC_NO_CACHE = (1 << 1),
217 MIME_COOKED_MASK_CC_NO_STORE = (1 << 2),
218 MIME_COOKED_MASK_CC_NO_TRANSFORM = (1 << 3),
219 MIME_COOKED_MASK_CC_MAX_STALE = (1 << 4),
220 MIME_COOKED_MASK_CC_MIN_FRESH = (1 << 5),
221 MIME_COOKED_MASK_CC_ONLY_IF_CACHED = (1 << 6),
222 MIME_COOKED_MASK_CC_PUBLIC = (1 << 7),
223 MIME_COOKED_MASK_CC_PRIVATE = (1 << 8),
224 MIME_COOKED_MASK_CC_MUST_REVALIDATE = (1 << 9),
225 MIME_COOKED_MASK_CC_PROXY_REVALIDATE = (1 << 10),
226 MIME_COOKED_MASK_CC_S_MAXAGE = (1 << 11),
227 MIME_COOKED_MASK_CC_NEED_REVALIDATE_ONCE = (1 << 12),
228 MIME_COOKED_MASK_CC_EXTENSION = (1 << 13)
229 };
230
231 struct MIMECookedCacheControl {
232 uint32_t m_mask;
233 int32_t m_secs_max_age;
234 int32_t m_secs_s_maxage;
235 int32_t m_secs_max_stale;
236 int32_t m_secs_min_fresh;
237 };
238
239 struct MIMECookedPragma {
240 bool m_no_cache;
241 };
242
243 struct MIMECooked {
244 MIMECookedCacheControl m_cache_control;
245 MIMECookedPragma m_pragma;
246 };
247
248 /***********************************************************************
249 * *
250 * MIMEHdr *
251 * *
252 ***********************************************************************/
253
254 struct MIMEHdrImpl : public HdrHeapObjImpl {
255 // HdrHeapObjImpl is 4 bytes, so this will result in 4 bytes padding
256 uint64_t m_presence_bits;
257 uint32_t m_slot_accelerators[4];
258
259 MIMECooked m_cooked_stuff;
260
261 MIMEFieldBlockImpl *m_fblock_list_tail;
262 MIMEFieldBlockImpl m_first_fblock; // 1 block inline
263 // mime_hdr_copy_onto assumes that m_first_fblock is last --
264 // don't add any new fields after it.
265
266 // Marshaling Functions
267 int marshal(MarshalXlate *ptr_xlate, int num_ptr, MarshalXlate *str_xlate, int num_str);
268 void unmarshal(intptr_t offset);
269 void move_strings(HdrStrHeap *new_heap);
270 size_t strings_length();
271
272 // Sanity Check Functions
273 void check_strings(HeapCheck *heaps, int num_heaps);
274
275 // Cooked values
276 void recompute_cooked_stuff(MIMEField *changing_field_or_null = nullptr);
277 void recompute_accelerators_and_presence_bits();
278 };
279
280 /***********************************************************************
281 * *
282 * Parser *
283 * *
284 ***********************************************************************/
285
286 /** A pre-parser used to extract MIME "lines" from raw input for further parsing.
287 *
288 * This maintains an internal line buffer which is used to keeping content between calls
289 * when the parse has not yet completed.
290 *
291 */
292 struct MIMEScanner {
293 using self_type = MIMEScanner; ///< Self reference type.
294 public:
295 /// Type of input scanning.
296 enum ScanType {
297 LINE = 0, ///< Scan a single line.
298 FIELD = 1, ///< Scan with line folding enabled.
299 };
300
301 void init(); ///< Pseudo-constructor required by proxy allocation.
302 void clear(); ///< Pseudo-destructor required by proxy allocation.
303
304 /// @return The size of the internal line buffer.
305 size_t get_buffered_line_size() const;
306
307 /** Scan @a input for MIME data delimited by CR/LF end of line markers.
308 *
309 * @param input [in,out] Text to scan.
310 * @param output [out] Parsed text from @a input, if any.
311 * @param output_shares_input [out] Whether @a output is in @a input.
312 * @param eof_p [in] The source for @a input is done, no more data will ever be available.
313 * @param scan_type [in] Whether to check for line folding.
314 * @return The result of scanning.
315 *
316 * @a input is updated to remove text that was scanned. @a output is updated to be a view of the
317 * scanned @a input. This is separate because @a output may be a view of @a input or a view of the
318 * internal line buffer. Which of these cases obtains is returned in @a output_shares_input. This
319 * is @c true if @a output is a view of @a input, and @c false if @a output is a view of the
320 * internal buffer, but is only set if the result is not @c PARSE_RESULT_CONT (that is, it is not
321 * set until scanning has completed). If @a scan_type is @c FIELD then folded lines are
322 * accumulated in to a single line stored in the internal buffer. Otherwise the scanning
323 * terminates at the first CR/LF.
324 */
325 ParseResult get(ts::TextView &input, ts::TextView &output, bool &output_shares_input, bool eof_p, ScanType scan_type);
326
327 protected:
328 /** Append @a text to the internal buffer.
329 *
330 * @param text Text to append.
331 * @return @a this
332 *
333 * A copy of @a text is appended to the internal line buffer.
334 */
335 self_type &append(ts::TextView text);
336
337 static constexpr MimeParseState INITIAL_PARSE_STATE = MIME_PARSE_BEFORE;
338 std::string m_line; ///< Internally buffered line data for field coalescence.
339 MimeParseState m_state{INITIAL_PARSE_STATE}; ///< Parsing machine state.
340 };
341
342 inline size_t
get_buffered_line_size()343 MIMEScanner::get_buffered_line_size() const
344 {
345 return m_line.size();
346 }
347
348 inline void
clear()349 MIMEScanner::clear()
350 {
351 std::string empty; // GAH! @c swap isn't defined to take r-value reference!
352 std::swap(m_line, empty); // make sure the memory is released.
353 m_state = INITIAL_PARSE_STATE;
354 }
355
356 struct MIMEParser {
357 MIMEScanner m_scanner;
358 int32_t m_field;
359 int m_field_flags;
360 int m_value;
361 };
362
363 /***********************************************************************
364 * *
365 * SDK *
366 * *
367 ***********************************************************************/
368
369 /********************************************/
370 /* SDK Handles to Fields are special structures */
371 /********************************************/
372 struct MIMEFieldSDKHandle : public HdrHeapObjImpl {
373 MIMEHdrImpl *mh;
374 MIMEField *field_ptr;
375 };
376
377 /***********************************************************************
378 * *
379 * Well-Known Field Name Tokens *
380 * *
381 ***********************************************************************/
382
383 extern const char *MIME_FIELD_ACCEPT;
384 extern const char *MIME_FIELD_ACCEPT_CHARSET;
385 extern const char *MIME_FIELD_ACCEPT_ENCODING;
386 extern const char *MIME_FIELD_ACCEPT_LANGUAGE;
387 extern const char *MIME_FIELD_ACCEPT_RANGES;
388 extern const char *MIME_FIELD_AGE;
389 extern const char *MIME_FIELD_ALLOW;
390 extern const char *MIME_FIELD_APPROVED;
391 extern const char *MIME_FIELD_AUTHORIZATION;
392 extern const char *MIME_FIELD_BYTES;
393 extern const char *MIME_FIELD_CACHE_CONTROL;
394 extern const char *MIME_FIELD_CLIENT_IP;
395 extern const char *MIME_FIELD_CONNECTION;
396 extern const char *MIME_FIELD_CONTENT_BASE;
397 extern const char *MIME_FIELD_CONTENT_ENCODING;
398 extern const char *MIME_FIELD_CONTENT_LANGUAGE;
399 extern const char *MIME_FIELD_CONTENT_LENGTH;
400 extern const char *MIME_FIELD_CONTENT_LOCATION;
401 extern const char *MIME_FIELD_CONTENT_MD5;
402 extern const char *MIME_FIELD_CONTENT_RANGE;
403 extern const char *MIME_FIELD_CONTENT_TYPE;
404 extern const char *MIME_FIELD_CONTROL;
405 extern const char *MIME_FIELD_COOKIE;
406 extern const char *MIME_FIELD_DATE;
407 extern const char *MIME_FIELD_DISTRIBUTION;
408 extern const char *MIME_FIELD_ETAG;
409 extern const char *MIME_FIELD_EXPECT;
410 extern const char *MIME_FIELD_EXPIRES;
411 extern const char *MIME_FIELD_FOLLOWUP_TO;
412 extern const char *MIME_FIELD_FROM;
413 extern const char *MIME_FIELD_HOST;
414 extern const char *MIME_FIELD_IF_MATCH;
415 extern const char *MIME_FIELD_IF_MODIFIED_SINCE;
416 extern const char *MIME_FIELD_IF_NONE_MATCH;
417 extern const char *MIME_FIELD_IF_RANGE;
418 extern const char *MIME_FIELD_IF_UNMODIFIED_SINCE;
419 extern const char *MIME_FIELD_KEEP_ALIVE;
420 extern const char *MIME_FIELD_KEYWORDS;
421 extern const char *MIME_FIELD_LAST_MODIFIED;
422 extern const char *MIME_FIELD_LINES;
423 inkcoreapi extern const char *MIME_FIELD_LOCATION;
424 extern const char *MIME_FIELD_MAX_FORWARDS;
425 extern const char *MIME_FIELD_MESSAGE_ID;
426 extern const char *MIME_FIELD_NEWSGROUPS;
427 extern const char *MIME_FIELD_ORGANIZATION;
428 extern const char *MIME_FIELD_PATH;
429 extern const char *MIME_FIELD_PRAGMA;
430 extern const char *MIME_FIELD_PROXY_AUTHENTICATE;
431 extern const char *MIME_FIELD_PROXY_AUTHORIZATION;
432 extern const char *MIME_FIELD_PROXY_CONNECTION;
433 extern const char *MIME_FIELD_PUBLIC;
434 extern const char *MIME_FIELD_RANGE;
435 extern const char *MIME_FIELD_REFERENCES;
436 extern const char *MIME_FIELD_REFERER;
437 extern const char *MIME_FIELD_REPLY_TO;
438 extern const char *MIME_FIELD_RETRY_AFTER;
439 extern const char *MIME_FIELD_SENDER;
440 extern const char *MIME_FIELD_SERVER;
441 extern const char *MIME_FIELD_SET_COOKIE;
442 extern const char *MIME_FIELD_STRICT_TRANSPORT_SECURITY;
443 extern const char *MIME_FIELD_SUBJECT;
444 extern const char *MIME_FIELD_SUMMARY;
445 extern const char *MIME_FIELD_TE;
446 extern const char *MIME_FIELD_TRANSFER_ENCODING;
447 extern const char *MIME_FIELD_UPGRADE;
448 extern const char *MIME_FIELD_USER_AGENT;
449 extern const char *MIME_FIELD_VARY;
450 extern const char *MIME_FIELD_VIA;
451 extern const char *MIME_FIELD_WARNING;
452 extern const char *MIME_FIELD_WWW_AUTHENTICATE;
453 extern const char *MIME_FIELD_XREF;
454 extern const char *MIME_FIELD_ATS_INTERNAL;
455 extern const char *MIME_FIELD_X_ID;
456 extern const char *MIME_FIELD_X_FORWARDED_FOR;
457 extern const char *MIME_FIELD_FORWARDED;
458 extern const char *MIME_FIELD_SEC_WEBSOCKET_KEY;
459 extern const char *MIME_FIELD_SEC_WEBSOCKET_VERSION;
460 extern const char *MIME_FIELD_HTTP2_SETTINGS;
461 extern const char *MIME_FIELD_EARLY_DATA;
462
463 extern const char *MIME_VALUE_BYTES;
464 extern const char *MIME_VALUE_CHUNKED;
465 extern const char *MIME_VALUE_CLOSE;
466 extern const char *MIME_VALUE_COMPRESS;
467 extern const char *MIME_VALUE_DEFLATE;
468 extern const char *MIME_VALUE_GZIP;
469 extern const char *MIME_VALUE_IDENTITY;
470 extern const char *MIME_VALUE_KEEP_ALIVE;
471 extern const char *MIME_VALUE_MAX_AGE;
472 extern const char *MIME_VALUE_MAX_STALE;
473 extern const char *MIME_VALUE_MIN_FRESH;
474 extern const char *MIME_VALUE_MUST_REVALIDATE;
475 extern const char *MIME_VALUE_NONE;
476 extern const char *MIME_VALUE_NO_CACHE;
477 extern const char *MIME_VALUE_NO_STORE;
478 extern const char *MIME_VALUE_NO_TRANSFORM;
479 extern const char *MIME_VALUE_ONLY_IF_CACHED;
480 extern const char *MIME_VALUE_PRIVATE;
481 extern const char *MIME_VALUE_PROXY_REVALIDATE;
482 extern const char *MIME_VALUE_PUBLIC;
483 extern const char *MIME_VALUE_S_MAXAGE;
484 extern const char *MIME_VALUE_NEED_REVALIDATE_ONCE;
485 extern const char *MIME_VALUE_WEBSOCKET;
486 extern const char *MIME_VALUE_H2C;
487
488 extern int MIME_LEN_ACCEPT;
489 extern int MIME_LEN_ACCEPT_CHARSET;
490 extern int MIME_LEN_ACCEPT_ENCODING;
491 extern int MIME_LEN_ACCEPT_LANGUAGE;
492 extern int MIME_LEN_ACCEPT_RANGES;
493 extern int MIME_LEN_AGE;
494 extern int MIME_LEN_ALLOW;
495 extern int MIME_LEN_APPROVED;
496 extern int MIME_LEN_AUTHORIZATION;
497 extern int MIME_LEN_BYTES;
498 extern int MIME_LEN_CACHE_CONTROL;
499 extern int MIME_LEN_CLIENT_IP;
500 extern int MIME_LEN_CONNECTION;
501 extern int MIME_LEN_CONTENT_BASE;
502 extern int MIME_LEN_CONTENT_ENCODING;
503 extern int MIME_LEN_CONTENT_LANGUAGE;
504 extern int MIME_LEN_CONTENT_LENGTH;
505 extern int MIME_LEN_CONTENT_LOCATION;
506 extern int MIME_LEN_CONTENT_MD5;
507 extern int MIME_LEN_CONTENT_RANGE;
508 extern int MIME_LEN_CONTENT_TYPE;
509 extern int MIME_LEN_CONTROL;
510 extern int MIME_LEN_COOKIE;
511 extern int MIME_LEN_DATE;
512 extern int MIME_LEN_DISTRIBUTION;
513 extern int MIME_LEN_ETAG;
514 extern int MIME_LEN_EXPECT;
515 extern int MIME_LEN_EXPIRES;
516 extern int MIME_LEN_FOLLOWUP_TO;
517 extern int MIME_LEN_FROM;
518 extern int MIME_LEN_HOST;
519 extern int MIME_LEN_IF_MATCH;
520 extern int MIME_LEN_IF_MODIFIED_SINCE;
521 extern int MIME_LEN_IF_NONE_MATCH;
522 extern int MIME_LEN_IF_RANGE;
523 extern int MIME_LEN_IF_UNMODIFIED_SINCE;
524 extern int MIME_LEN_KEEP_ALIVE;
525 extern int MIME_LEN_KEYWORDS;
526 extern int MIME_LEN_LAST_MODIFIED;
527 extern int MIME_LEN_LINES;
528 inkcoreapi extern int MIME_LEN_LOCATION;
529 extern int MIME_LEN_MAX_FORWARDS;
530 extern int MIME_LEN_MESSAGE_ID;
531 extern int MIME_LEN_NEWSGROUPS;
532 extern int MIME_LEN_ORGANIZATION;
533 extern int MIME_LEN_PATH;
534 extern int MIME_LEN_PRAGMA;
535 extern int MIME_LEN_PROXY_AUTHENTICATE;
536 extern int MIME_LEN_PROXY_AUTHORIZATION;
537 extern int MIME_LEN_PROXY_CONNECTION;
538 extern int MIME_LEN_PUBLIC;
539 extern int MIME_LEN_RANGE;
540 extern int MIME_LEN_REFERENCES;
541 extern int MIME_LEN_REFERER;
542 extern int MIME_LEN_REPLY_TO;
543 extern int MIME_LEN_RETRY_AFTER;
544 extern int MIME_LEN_SENDER;
545 extern int MIME_LEN_SERVER;
546 extern int MIME_LEN_SET_COOKIE;
547 extern int MIME_LEN_STRICT_TRANSPORT_SECURITY;
548 extern int MIME_LEN_SUBJECT;
549 extern int MIME_LEN_SUMMARY;
550 extern int MIME_LEN_TE;
551 extern int MIME_LEN_TRANSFER_ENCODING;
552 extern int MIME_LEN_UPGRADE;
553 extern int MIME_LEN_USER_AGENT;
554 extern int MIME_LEN_VARY;
555 extern int MIME_LEN_VIA;
556 extern int MIME_LEN_WARNING;
557 extern int MIME_LEN_WWW_AUTHENTICATE;
558 extern int MIME_LEN_XREF;
559 extern int MIME_LEN_ATS_INTERNAL;
560 extern int MIME_LEN_X_ID;
561 extern int MIME_LEN_X_FORWARDED_FOR;
562 extern int MIME_LEN_FORWARDED;
563 extern int MIME_LEN_BYTES;
564 extern int MIME_LEN_CHUNKED;
565 extern int MIME_LEN_CLOSE;
566 extern int MIME_LEN_COMPRESS;
567 extern int MIME_LEN_DEFLATE;
568 extern int MIME_LEN_GZIP;
569 extern int MIME_LEN_IDENTITY;
570 extern int MIME_LEN_KEEP_ALIVE;
571 extern int MIME_LEN_MAX_AGE;
572 extern int MIME_LEN_MAX_STALE;
573 extern int MIME_LEN_MIN_FRESH;
574 extern int MIME_LEN_MUST_REVALIDATE;
575 extern int MIME_LEN_NONE;
576 extern int MIME_LEN_NO_CACHE;
577 extern int MIME_LEN_NO_STORE;
578 extern int MIME_LEN_NO_TRANSFORM;
579 extern int MIME_LEN_ONLY_IF_CACHED;
580 extern int MIME_LEN_PRIVATE;
581 extern int MIME_LEN_PROXY_REVALIDATE;
582 extern int MIME_LEN_PUBLIC;
583 extern int MIME_LEN_S_MAXAGE;
584 extern int MIME_LEN_NEED_REVALIDATE_ONCE;
585 extern int MIME_LEN_SEC_WEBSOCKET_KEY;
586 extern int MIME_LEN_SEC_WEBSOCKET_VERSION;
587 extern int MIME_LEN_HTTP2_SETTINGS;
588 extern int MIME_LEN_EARLY_DATA;
589
590 extern int MIME_WKSIDX_ACCEPT;
591 extern int MIME_WKSIDX_ACCEPT_CHARSET;
592 extern int MIME_WKSIDX_ACCEPT_ENCODING;
593 extern int MIME_WKSIDX_ACCEPT_LANGUAGE;
594 extern int MIME_WKSIDX_ACCEPT_RANGES;
595 extern int MIME_WKSIDX_AGE;
596 extern int MIME_WKSIDX_ALLOW;
597 extern int MIME_WKSIDX_APPROVED;
598 extern int MIME_WKSIDX_AUTHORIZATION;
599 extern int MIME_WKSIDX_BYTES;
600 extern int MIME_WKSIDX_CACHE_CONTROL;
601 extern int MIME_WKSIDX_CLIENT_IP;
602 extern int MIME_WKSIDX_CONNECTION;
603 extern int MIME_WKSIDX_CONTENT_BASE;
604 extern int MIME_WKSIDX_CONTENT_ENCODING;
605 extern int MIME_WKSIDX_CONTENT_LANGUAGE;
606 extern int MIME_WKSIDX_CONTENT_LENGTH;
607 extern int MIME_WKSIDX_CONTENT_LOCATION;
608 extern int MIME_WKSIDX_CONTENT_MD5;
609 extern int MIME_WKSIDX_CONTENT_RANGE;
610 extern int MIME_WKSIDX_CONTENT_TYPE;
611 extern int MIME_WKSIDX_CONTROL;
612 extern int MIME_WKSIDX_COOKIE;
613 extern int MIME_WKSIDX_DATE;
614 extern int MIME_WKSIDX_DISTRIBUTION;
615 extern int MIME_WKSIDX_ETAG;
616 extern int MIME_WKSIDX_EXPECT;
617 extern int MIME_WKSIDX_EXPIRES;
618 extern int MIME_WKSIDX_FOLLOWUP_TO;
619 extern int MIME_WKSIDX_FROM;
620 extern int MIME_WKSIDX_HOST;
621 extern int MIME_WKSIDX_IF_MATCH;
622 extern int MIME_WKSIDX_IF_MODIFIED_SINCE;
623 extern int MIME_WKSIDX_IF_NONE_MATCH;
624 extern int MIME_WKSIDX_IF_RANGE;
625 extern int MIME_WKSIDX_IF_UNMODIFIED_SINCE;
626 extern int MIME_WKSIDX_KEEP_ALIVE;
627 extern int MIME_WKSIDX_KEYWORDS;
628 extern int MIME_WKSIDX_LAST_MODIFIED;
629 extern int MIME_WKSIDX_LINES;
630 extern int MIME_WKSIDX_LOCATION;
631 extern int MIME_WKSIDX_MAX_FORWARDS;
632 extern int MIME_WKSIDX_MESSAGE_ID;
633 extern int MIME_WKSIDX_NEWSGROUPS;
634 extern int MIME_WKSIDX_ORGANIZATION;
635 extern int MIME_WKSIDX_PATH;
636 extern int MIME_WKSIDX_PRAGMA;
637 extern int MIME_WKSIDX_PROXY_AUTHENTICATE;
638 extern int MIME_WKSIDX_PROXY_AUTHORIZATION;
639 extern int MIME_WKSIDX_PROXY_CONNECTION;
640 extern int MIME_WKSIDX_PUBLIC;
641 extern int MIME_WKSIDX_RANGE;
642 extern int MIME_WKSIDX_REFERENCES;
643 extern int MIME_WKSIDX_REFERER;
644 extern int MIME_WKSIDX_REPLY_TO;
645 extern int MIME_WKSIDX_RETRY_AFTER;
646 extern int MIME_WKSIDX_SENDER;
647 extern int MIME_WKSIDX_SERVER;
648 extern int MIME_WKSIDX_SET_COOKIE;
649 extern int MIME_WKSIDX_STRICT_TRANSPORT_SECURITY;
650 extern int MIME_WKSIDX_SUBJECT;
651 extern int MIME_WKSIDX_SUMMARY;
652 extern int MIME_WKSIDX_TE;
653 extern int MIME_WKSIDX_TRANSFER_ENCODING;
654 extern int MIME_WKSIDX_UPGRADE;
655 extern int MIME_WKSIDX_USER_AGENT;
656 extern int MIME_WKSIDX_VARY;
657 extern int MIME_WKSIDX_VIA;
658 extern int MIME_WKSIDX_WARNING;
659 extern int MIME_WKSIDX_WWW_AUTHENTICATE;
660 extern int MIME_WKSIDX_XREF;
661 extern int MIME_WKSIDX_ATS_INTERNAL;
662 extern int MIME_WKSIDX_X_ID;
663 extern int MIME_WKSIDX_SEC_WEBSOCKET_KEY;
664 extern int MIME_WKSIDX_SEC_WEBSOCKET_VERSION;
665 extern int MIME_WKSIDX_HTTP2_SETTINGS;
666 extern int MIME_WKSIDX_EARLY_DATA;
667
668 /***********************************************************************
669 * *
670 * Internal C API *
671 * *
672 ***********************************************************************/
673
674 uint64_t mime_field_presence_mask(const char *well_known_str);
675 uint64_t mime_field_presence_mask(int well_known_str_index);
676 int mime_field_presence_get(MIMEHdrImpl *h, const char *well_known_str);
677 int mime_field_presence_get(MIMEHdrImpl *h, int well_known_str_index);
678 void mime_hdr_presence_set(MIMEHdrImpl *h, const char *well_known_str);
679 void mime_hdr_presence_set(MIMEHdrImpl *h, int well_known_str_index);
680 void mime_hdr_presence_unset(MIMEHdrImpl *h, const char *well_known_str);
681 void mime_hdr_presence_unset(MIMEHdrImpl *h, int well_known_str_index);
682
683 void mime_hdr_sanity_check(MIMEHdrImpl *mh);
684
685 void mime_init();
686 void mime_init_cache_control_cooking_masks();
687 void mime_init_date_format_table();
688
689 MIMEHdrImpl *mime_hdr_create(HdrHeap *heap);
690 void _mime_hdr_field_block_init(MIMEFieldBlockImpl *fblock);
691 void mime_hdr_cooked_stuff_init(MIMEHdrImpl *mh, MIMEField *changing_field_or_null = nullptr);
692 void mime_hdr_init(MIMEHdrImpl *mh);
693 MIMEFieldBlockImpl *_mime_field_block_copy(MIMEFieldBlockImpl *s_fblock, HdrHeap *s_heap, HdrHeap *d_heap);
694 void _mime_field_block_destroy(HdrHeap *heap, MIMEFieldBlockImpl *fblock);
695 void mime_hdr_destroy_field_block_list(HdrHeap *heap, MIMEFieldBlockImpl *head);
696 void mime_hdr_destroy(HdrHeap *heap, MIMEHdrImpl *mh);
697 void mime_hdr_copy_onto(MIMEHdrImpl *s_mh, HdrHeap *s_heap, MIMEHdrImpl *d_mh, HdrHeap *d_heap, bool inherit_strs = true);
698 MIMEHdrImpl *mime_hdr_clone(MIMEHdrImpl *s_mh, HdrHeap *s_heap, HdrHeap *d_heap, bool inherit_strs = true);
699 void mime_hdr_field_block_list_adjust(int block_count, MIMEFieldBlockImpl *old_list, MIMEFieldBlockImpl *new_list);
700 int mime_hdr_length_get(MIMEHdrImpl *mh);
701
702 void mime_hdr_fields_clear(HdrHeap *heap, MIMEHdrImpl *mh);
703
704 MIMEField *_mime_hdr_field_list_search_by_wks(MIMEHdrImpl *mh, int wks_idx);
705 MIMEField *_mime_hdr_field_list_search_by_string(MIMEHdrImpl *mh, const char *field_name_str, int field_name_len);
706 MIMEField *_mime_hdr_field_list_search_by_slotnum(MIMEHdrImpl *mh, int slotnum);
707 inkcoreapi MIMEField *mime_hdr_field_find(MIMEHdrImpl *mh, const char *field_name_str, int field_name_len);
708
709 MIMEField *mime_hdr_field_get(MIMEHdrImpl *mh, int idx);
710 MIMEField *mime_hdr_field_get_slotnum(MIMEHdrImpl *mh, int slotnum);
711 int mime_hdr_fields_count(MIMEHdrImpl *mh);
712
713 void mime_field_init(MIMEField *field);
714 MIMEField *mime_field_create(HdrHeap *heap, MIMEHdrImpl *mh);
715 MIMEField *mime_field_create_named(HdrHeap *heap, MIMEHdrImpl *mh, const char *name, int length);
716
717 void mime_hdr_field_attach(MIMEHdrImpl *mh, MIMEField *field, int check_for_dups, MIMEField *prev_dup);
718 void mime_hdr_field_detach(MIMEHdrImpl *mh, MIMEField *field, bool detach_all_dups = false);
719 void mime_hdr_field_delete(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, bool delete_all_dups = false);
720
721 /**
722 * Returned slotnum is not a persistent value. A slotnum may refer a different field after making changes to a mime header.
723 */
724 int mime_hdr_field_slotnum(MIMEHdrImpl *mh, MIMEField *field);
725 inkcoreapi MIMEField *mime_hdr_prepare_for_value_set(HdrHeap *heap, MIMEHdrImpl *mh, const char *name, int name_length);
726
727 void mime_field_destroy(MIMEHdrImpl *mh, MIMEField *field);
728
729 void mime_field_name_set(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, int16_t name_wks_idx_or_neg1, const char *name,
730 int length, bool must_copy_string);
731
732 int32_t mime_field_value_get_int(const MIMEField *field);
733 uint32_t mime_field_value_get_uint(const MIMEField *field);
734 int64_t mime_field_value_get_int64(const MIMEField *field);
735 time_t mime_field_value_get_date(const MIMEField *field);
736 const char *mime_field_value_get_comma_val(const MIMEField *field, int *length, int idx);
737 int mime_field_value_get_comma_val_count(const MIMEField *field);
738 int mime_field_value_get_comma_list(const MIMEField *field, StrList *list);
739
740 void mime_field_value_set_comma_val(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, int idx, const char *new_piece_str,
741 int new_piece_len);
742 void mime_field_value_delete_comma_val(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, int idx);
743 void mime_field_value_extend_comma_val(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, int idx, const char *new_piece_str,
744 int new_piece_len);
745 void mime_field_value_insert_comma_val(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, int idx, const char *new_piece_str,
746 int new_piece_len);
747
748 inkcoreapi void mime_field_value_set(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, const char *value, int length,
749 bool must_copy_string);
750 void mime_field_value_set_int(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, int32_t value);
751 void mime_field_value_set_uint(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, uint32_t value);
752 void mime_field_value_set_int64(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, int64_t value);
753 void mime_field_value_set_date(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, time_t value);
754 void mime_field_name_value_set(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, int16_t name_wks_idx_or_neg1, const char *name,
755 int name_length, const char *value, int value_length, int n_v_raw_printable, int n_v_raw_length,
756 bool must_copy_strings);
757
758 void mime_field_value_append(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, const char *value, int length, bool prepend_comma,
759 const char separator);
760
761 void mime_parser_init(MIMEParser *parser);
762 void mime_parser_clear(MIMEParser *parser);
763 ParseResult mime_parser_parse(MIMEParser *parser, HdrHeap *heap, MIMEHdrImpl *mh, const char **real_s, const char *real_e,
764 bool must_copy_strings, bool eof, bool remove_ws_from_field_name, size_t max_hdr_field_size = 131070);
765
766 void mime_hdr_describe(HdrHeapObjImpl *raw, bool recurse);
767 void mime_field_block_describe(HdrHeapObjImpl *raw, bool recurse);
768
769 int mime_hdr_print(HdrHeap *heap, MIMEHdrImpl *mh, char *buf_start, int buf_length, int *buf_index_inout,
770 int *buf_chars_to_skip_inout);
771 int mime_mem_print(const char *src_d, int src_l, char *buf_start, int buf_length, int *buf_index_inout,
772 int *buf_chars_to_skip_inout);
773 int mime_mem_print_lc(const char *src_d, int src_l, char *buf_start, int buf_length, int *buf_index_inout,
774 int *buf_chars_to_skip_inout);
775 int mime_field_print(MIMEField *field, char *buf_start, int buf_length, int *buf_index_inout, int *buf_chars_to_skip_inout);
776
777 const char *mime_str_u16_set(HdrHeap *heap, const char *s_str, int s_len, const char **d_str, uint16_t *d_len, bool must_copy);
778
779 int mime_field_length_get(MIMEField *field);
780 int mime_format_int(char *buf, int32_t val, size_t buf_len);
781 int mime_format_uint(char *buf, uint32_t val, size_t buf_len);
782 int mime_format_int64(char *buf, int64_t val, size_t buf_len);
783
784 void mime_days_since_epoch_to_mdy_slowcase(unsigned int days_since_jan_1_1970, int *m_return, int *d_return, int *y_return);
785 void mime_days_since_epoch_to_mdy(unsigned int days_since_jan_1_1970, int *m_return, int *d_return, int *y_return);
786 int mime_format_date(char *buffer, time_t value);
787
788 int32_t mime_parse_int(const char *buf, const char *end = nullptr);
789 uint32_t mime_parse_uint(const char *buf, const char *end = nullptr);
790 int64_t mime_parse_int64(const char *buf, const char *end = nullptr);
791 int mime_parse_rfc822_date_fastcase(const char *buf, int length, struct tm *tp);
792 time_t mime_parse_date(const char *buf, const char *end = nullptr);
793 bool mime_parse_day(const char *&buf, const char *end, int *day);
794 bool mime_parse_month(const char *&buf, const char *end, int *month);
795 bool mime_parse_mday(const char *&buf, const char *end, int *mday);
796 bool mime_parse_year(const char *&buf, const char *end, int *year);
797 bool mime_parse_time(const char *&buf, const char *end, int *hour, int *min, int *sec);
798 bool mime_parse_integer(const char *&buf, const char *end, int *integer);
799
800 /***********************************************************************
801 * *
802 * MIMEField Methods *
803 * *
804 ***********************************************************************/
805
806 /*-------------------------------------------------------------------------
807 -------------------------------------------------------------------------*/
808
809 inline const char *
name_get(int * length)810 MIMEField::name_get(int *length) const
811 {
812 auto name{this->name_get()};
813 *length = int(name.size());
814 return name.data();
815 }
816
817 /*-------------------------------------------------------------------------
818 -------------------------------------------------------------------------*/
819
820 inline void
name_set(HdrHeap * heap,MIMEHdrImpl * mh,const char * name,int length)821 MIMEField::name_set(HdrHeap *heap, MIMEHdrImpl *mh, const char *name, int length)
822 {
823 const char *name_wks;
824
825 if (hdrtoken_is_wks(name)) {
826 int16_t name_wks_idx = hdrtoken_wks_to_index(name);
827 mime_field_name_set(heap, mh, this, name_wks_idx, name, length, true);
828 } else {
829 int field_name_wks_idx = hdrtoken_tokenize(name, length, &name_wks);
830 mime_field_name_set(heap, mh, this, field_name_wks_idx, (field_name_wks_idx == -1 ? name : name_wks), length, true);
831 }
832 }
833
834 /*-------------------------------------------------------------------------
835 -------------------------------------------------------------------------*/
836
837 inline bool
name_is_valid()838 MIMEField::name_is_valid() const
839 {
840 const char *name;
841 int length;
842
843 for (name = name_get(&length); length > 0; length--) {
844 if (ParseRules::is_control(name[length - 1])) {
845 return false;
846 }
847 }
848 return true;
849 }
850
851 /*-------------------------------------------------------------------------
852 -------------------------------------------------------------------------*/
853
854 inline const char *
value_get(int * length)855 MIMEField::value_get(int *length) const
856 {
857 auto value{this->value_get()};
858 *length = int(value.size());
859 return value.data();
860 }
861
862 inline int32_t
value_get_int()863 MIMEField::value_get_int() const
864 {
865 return mime_field_value_get_int(this);
866 }
867
868 inline uint32_t
value_get_uint()869 MIMEField::value_get_uint() const
870 {
871 return mime_field_value_get_uint(this);
872 }
873
874 inline int64_t
value_get_int64()875 MIMEField::value_get_int64() const
876 {
877 return mime_field_value_get_int64(this);
878 }
879
880 inline time_t
value_get_date()881 MIMEField::value_get_date() const
882 {
883 return mime_field_value_get_date(this);
884 }
885
886 inline int
value_get_comma_list(StrList * list)887 MIMEField::value_get_comma_list(StrList *list) const
888 {
889 return mime_field_value_get_comma_list(this, list);
890 }
891
892 /*-------------------------------------------------------------------------
893 -------------------------------------------------------------------------*/
894
895 inline void
value_set(HdrHeap * heap,MIMEHdrImpl * mh,const char * value,int length)896 MIMEField::value_set(HdrHeap *heap, MIMEHdrImpl *mh, const char *value, int length)
897 {
898 mime_field_value_set(heap, mh, this, value, length, true);
899 }
900
901 inline void
value_set_int(HdrHeap * heap,MIMEHdrImpl * mh,int32_t value)902 MIMEField::value_set_int(HdrHeap *heap, MIMEHdrImpl *mh, int32_t value)
903 {
904 mime_field_value_set_int(heap, mh, this, value);
905 }
906
907 inline void
value_set_uint(HdrHeap * heap,MIMEHdrImpl * mh,uint32_t value)908 MIMEField::value_set_uint(HdrHeap *heap, MIMEHdrImpl *mh, uint32_t value)
909 {
910 mime_field_value_set_uint(heap, mh, this, value);
911 }
912
913 inline void
value_set_int64(HdrHeap * heap,MIMEHdrImpl * mh,int64_t value)914 MIMEField::value_set_int64(HdrHeap *heap, MIMEHdrImpl *mh, int64_t value)
915 {
916 mime_field_value_set_int64(heap, mh, this, value);
917 }
918
919 inline void
value_set_date(HdrHeap * heap,MIMEHdrImpl * mh,time_t value)920 MIMEField::value_set_date(HdrHeap *heap, MIMEHdrImpl *mh, time_t value)
921 {
922 mime_field_value_set_date(heap, mh, this, value);
923 }
924
925 /*-------------------------------------------------------------------------
926 -------------------------------------------------------------------------*/
927
928 inline void
value_clear(HdrHeap * heap,MIMEHdrImpl * mh)929 MIMEField::value_clear(HdrHeap *heap, MIMEHdrImpl *mh)
930 {
931 value_set(heap, mh, "", 0);
932 }
933
934 /*-------------------------------------------------------------------------
935 -------------------------------------------------------------------------*/
936
937 inline void
value_append(HdrHeap * heap,MIMEHdrImpl * mh,const char * value,int length,bool prepend_comma,const char separator)938 MIMEField::value_append(HdrHeap *heap, MIMEHdrImpl *mh, const char *value, int length, bool prepend_comma, const char separator)
939 {
940 mime_field_value_append(heap, mh, this, value, length, prepend_comma, separator);
941 }
942
943 /*-------------------------------------------------------------------------
944 -------------------------------------------------------------------------*/
945
946 inline bool
value_is_valid()947 MIMEField::value_is_valid() const
948 {
949 const char *value;
950 int length;
951
952 for (value = value_get(&length); length > 0; length--) {
953 if (ParseRules::is_control(value[length - 1])) {
954 return false;
955 }
956 }
957 return true;
958 }
959
960 inline int
has_dups()961 MIMEField::has_dups() const
962 {
963 return (m_next_dup != nullptr);
964 }
965
966 /***********************************************************************
967 * *
968 * MIMEFieldIter *
969 * *
970 ***********************************************************************/
971
972 struct MIMEFieldIter {
MIMEFieldIterMIMEFieldIter973 MIMEFieldIter() {}
974 uint32_t m_slot = 0;
975 MIMEFieldBlockImpl *m_block = nullptr;
976 };
977
978 /*-------------------------------------------------------------------------
979 -------------------------------------------------------------------------*/
980
981 /***********************************************************************
982 * *
983 * MIMEHdr Class *
984 * *
985 ***********************************************************************/
986
987 class MIMEHdr : public HdrHeapSDKHandle
988 {
989 public:
990 MIMEHdrImpl *m_mime = nullptr;
991
992 MIMEHdr() = default; // Force the creation of the default constructor
993
994 int valid() const;
995
996 void create(HdrHeap *heap = nullptr);
997 void copy(const MIMEHdr *hdr);
998
999 int length_get();
1000
1001 void fields_clear();
1002 int fields_count();
1003
1004 MIMEField *field_create(const char *name = nullptr, int length = -1);
1005 MIMEField *field_find(const char *name, int length);
1006 const MIMEField *field_find(const char *name, int length) const;
1007 void field_attach(MIMEField *field);
1008 void field_detach(MIMEField *field, bool detach_all_dups = true);
1009 void field_delete(MIMEField *field, bool delete_all_dups = true);
1010 void field_delete(const char *name, int name_length);
1011
1012 MIMEField *iter_get_first(MIMEFieldIter *iter);
1013 MIMEField *iter_get(MIMEFieldIter *iter);
1014 MIMEField *iter_get_next(MIMEFieldIter *iter);
1015
1016 uint64_t presence(uint64_t mask);
1017
1018 int print(char *buf, int bufsize, int *bufindex, int *chars_to_skip);
1019
1020 int parse(MIMEParser *parser, const char **start, const char *end, bool must_copy_strs, bool eof, bool remove_ws_from_field_name,
1021 size_t max_hdr_field_size = UINT16_MAX);
1022
1023 int value_get_index(const char *name, int name_length, const char *value, int value_length) const;
1024 const char *value_get(const char *name, int name_length, int *value_length) const;
1025 std::string_view value_get(std::string_view const &name) const; // Convenience overload.
1026 int32_t value_get_int(const char *name, int name_length) const;
1027 uint32_t value_get_uint(const char *name, int name_length) const;
1028 int64_t value_get_int64(const char *name, int name_length) const;
1029 time_t value_get_date(const char *name, int name_length) const;
1030 int value_get_comma_list(const char *name, int name_length, StrList *list) const;
1031
1032 void value_set(const char *name, int name_length, const char *value, int value_length);
1033 void value_set_int(const char *name, int name_length, int32_t value);
1034 void value_set_uint(const char *name, int name_length, uint32_t value);
1035 void value_set_int64(const char *name, int name_length, int64_t value);
1036 void value_set_date(const char *name, int name_length, time_t value);
1037 // MIME standard separator ',' is used as the default value
1038 // Other separators (e.g. ';' in Set-cookie/Cookie) are also possible
1039 void value_append(const char *name, int name_length, const char *value, int value_length, bool prepend_comma = false,
1040 const char separator = ',');
1041
1042 void field_value_set(MIMEField *field, const char *value, int value_length, bool reuse_heaps = false);
1043 void field_value_set_int(MIMEField *field, int32_t value);
1044 void field_value_set_uint(MIMEField *field, uint32_t value);
1045 void field_value_set_int64(MIMEField *field, int64_t value);
1046 void field_value_set_date(MIMEField *field, time_t value);
1047 // MIME standard separator ',' is used as the default value
1048 // Other separators (e.g. ';' in Set-cookie/Cookie) are also possible
1049 void field_value_append(MIMEField *field, const char *value, int value_length, bool prepend_comma = false,
1050 const char separator = ',');
1051 void value_append_or_set(const char *name, const int name_length, char *value, int value_length);
1052 void field_combine_dups(MIMEField *field, bool prepend_comma = false, const char separator = ',');
1053 time_t get_age();
1054 int64_t get_content_length() const;
1055 time_t get_date();
1056 time_t get_expires();
1057 time_t get_if_modified_since();
1058 time_t get_if_unmodified_since();
1059 time_t get_last_modified();
1060 time_t get_if_range_date();
1061 int32_t get_max_forwards();
1062 int32_t get_warning(int idx = 0);
1063
1064 uint32_t get_cooked_cc_mask();
1065 int32_t get_cooked_cc_max_age();
1066 int32_t get_cooked_cc_s_maxage();
1067 int32_t get_cooked_cc_max_stale();
1068 int32_t get_cooked_cc_min_fresh();
1069 bool get_cooked_pragma_no_cache();
1070
1071 /** Get the value of the host field.
1072 This parses the host field for brackets and port value.
1073 @return The mime HOST field if it has a value, @c NULL otherwise.
1074 */
1075 MIMEField *get_host_port_values(const char **host_ptr, ///< [out] Pointer to host.
1076 int *host_len, ///< [out] Length of host.
1077 const char **port_ptr, ///< [out] Pointer to port.
1078 int *port_len ///< [out] Length of port.
1079 );
1080
1081 void set_cooked_cc_need_revalidate_once();
1082 void unset_cooked_cc_need_revalidate_once();
1083
1084 void set_age(time_t value);
1085 void set_content_length(int64_t value);
1086 void set_date(time_t value);
1087 void set_expires(time_t value);
1088 void set_if_modified_since(time_t value);
1089 void set_if_unmodified_since(time_t value);
1090 void set_last_modified(time_t value);
1091 void set_max_forwards(int32_t value);
1092 void set_warning(int32_t value);
1093 void set_server(const char *server_id_tag, int server_id_tag_size);
1094
1095 // No gratuitous copies & refcounts!
1096 MIMEHdr(const MIMEHdr &m) = delete;
1097 MIMEHdr &operator=(const MIMEHdr &m) = delete;
1098
1099 private:
1100 // Interface to replace (overwrite) field value without
1101 // changing the heap as long as the new value is not longer
1102 // than the current value
1103 bool field_value_replace(MIMEField *field, const char *value, int value_length);
1104 };
1105
1106 /*-------------------------------------------------------------------------
1107 -------------------------------------------------------------------------*/
1108
1109 inline int
valid()1110 MIMEHdr::valid() const
1111 {
1112 return (m_mime && m_heap);
1113 }
1114
1115 /*-------------------------------------------------------------------------
1116 -------------------------------------------------------------------------*/
1117
1118 inline void
create(HdrHeap * heap)1119 MIMEHdr::create(HdrHeap *heap)
1120 {
1121 if (heap) {
1122 m_heap = heap;
1123 } else if (!m_heap) {
1124 m_heap = new_HdrHeap();
1125 }
1126
1127 m_mime = mime_hdr_create(m_heap);
1128 }
1129
1130 /*-------------------------------------------------------------------------
1131 -------------------------------------------------------------------------*/
1132
1133 inline void
copy(const MIMEHdr * src_hdr)1134 MIMEHdr::copy(const MIMEHdr *src_hdr)
1135 {
1136 if (valid()) {
1137 mime_hdr_copy_onto(src_hdr->m_mime, src_hdr->m_heap, m_mime, m_heap, (m_heap != src_hdr->m_heap) ? true : false);
1138 } else {
1139 m_heap = new_HdrHeap();
1140 m_mime = mime_hdr_clone(src_hdr->m_mime, src_hdr->m_heap, m_heap);
1141 }
1142 }
1143
1144 /*-------------------------------------------------------------------------
1145 -------------------------------------------------------------------------*/
1146
1147 inline int
length_get()1148 MIMEHdr::length_get()
1149 {
1150 return mime_hdr_length_get(m_mime);
1151 }
1152
1153 /*-------------------------------------------------------------------------
1154 -------------------------------------------------------------------------*/
1155
1156 inline void
fields_clear()1157 MIMEHdr::fields_clear()
1158 {
1159 mime_hdr_fields_clear(m_heap, m_mime);
1160 }
1161
1162 /*-------------------------------------------------------------------------
1163 -------------------------------------------------------------------------*/
1164
1165 inline int
fields_count()1166 MIMEHdr::fields_count()
1167 {
1168 return mime_hdr_fields_count(m_mime);
1169 }
1170
1171 /*-------------------------------------------------------------------------
1172 -------------------------------------------------------------------------*/
1173
1174 inline MIMEField *
field_create(const char * name,int length)1175 MIMEHdr::field_create(const char *name, int length)
1176 {
1177 MIMEField *field = mime_field_create(m_heap, m_mime);
1178
1179 if (name) {
1180 int field_name_wks_idx = hdrtoken_tokenize(name, length);
1181 mime_field_name_set(m_heap, m_mime, field, field_name_wks_idx, name, length, true);
1182 }
1183
1184 return field;
1185 }
1186
1187 /*-------------------------------------------------------------------------
1188 -------------------------------------------------------------------------*/
1189
1190 inline MIMEField *
field_find(const char * name,int length)1191 MIMEHdr::field_find(const char *name, int length)
1192 {
1193 // ink_assert(valid());
1194 return mime_hdr_field_find(m_mime, name, length);
1195 }
1196
1197 inline const MIMEField *
field_find(const char * name,int length)1198 MIMEHdr::field_find(const char *name, int length) const
1199 {
1200 // ink_assert(valid());
1201 MIMEField *retval = mime_hdr_field_find(const_cast<MIMEHdr *>(this)->m_mime, name, length);
1202 return retval;
1203 }
1204
1205 /*-------------------------------------------------------------------------
1206 -------------------------------------------------------------------------*/
1207
1208 inline void
field_attach(MIMEField * field)1209 MIMEHdr::field_attach(MIMEField *field)
1210 {
1211 mime_hdr_field_attach(m_mime, field, 1, nullptr);
1212 }
1213
1214 /*-------------------------------------------------------------------------
1215 -------------------------------------------------------------------------*/
1216
1217 inline void
field_detach(MIMEField * field,bool detach_all_dups)1218 MIMEHdr::field_detach(MIMEField *field, bool detach_all_dups)
1219 {
1220 mime_hdr_field_detach(m_mime, field, detach_all_dups);
1221 }
1222
1223 /*-------------------------------------------------------------------------
1224 -------------------------------------------------------------------------*/
1225
1226 inline void
field_delete(MIMEField * field,bool delete_all_dups)1227 MIMEHdr::field_delete(MIMEField *field, bool delete_all_dups)
1228 {
1229 mime_hdr_field_delete(m_heap, m_mime, field, delete_all_dups);
1230 }
1231
1232 inline void
field_delete(const char * name,int name_length)1233 MIMEHdr::field_delete(const char *name, int name_length)
1234 {
1235 MIMEField *field = field_find(name, name_length);
1236 if (field)
1237 field_delete(field);
1238 }
1239
1240 inline MIMEField *
iter_get_first(MIMEFieldIter * iter)1241 MIMEHdr::iter_get_first(MIMEFieldIter *iter)
1242 {
1243 iter->m_block = &m_mime->m_first_fblock;
1244 iter->m_slot = 0;
1245 return iter_get(iter);
1246 }
1247
1248 inline MIMEField *
iter_get(MIMEFieldIter * iter)1249 MIMEHdr::iter_get(MIMEFieldIter *iter)
1250 {
1251 MIMEField *f;
1252 MIMEFieldBlockImpl *b = iter->m_block;
1253
1254 int slot = iter->m_slot;
1255
1256 while (b) {
1257 for (; slot < (int)b->m_freetop; slot++) {
1258 f = &(b->m_field_slots[slot]);
1259 if (f->is_live()) {
1260 iter->m_slot = slot;
1261 iter->m_block = b;
1262 return f;
1263 }
1264 }
1265 b = b->m_next;
1266 slot = 0;
1267 }
1268
1269 iter->m_block = nullptr;
1270 return nullptr;
1271 }
1272
1273 inline MIMEField *
iter_get_next(MIMEFieldIter * iter)1274 MIMEHdr::iter_get_next(MIMEFieldIter *iter)
1275 {
1276 iter->m_slot++;
1277 return iter_get(iter);
1278 }
1279
1280 /*-------------------------------------------------------------------------
1281 -------------------------------------------------------------------------*/
1282
1283 inline uint64_t
presence(uint64_t mask)1284 MIMEHdr::presence(uint64_t mask)
1285 {
1286 return (m_mime->m_presence_bits & mask);
1287 }
1288
1289 /*-------------------------------------------------------------------------
1290 -------------------------------------------------------------------------*/
1291
1292 inline int
print(char * buf,int bufsize,int * bufindex,int * chars_to_skip)1293 MIMEHdr::print(char *buf, int bufsize, int *bufindex, int *chars_to_skip)
1294 {
1295 return mime_hdr_print(m_heap, m_mime, buf, bufsize, bufindex, chars_to_skip);
1296 }
1297
1298 /*-------------------------------------------------------------------------
1299 -------------------------------------------------------------------------*/
1300
1301 inline int
parse(MIMEParser * parser,const char ** start,const char * end,bool must_copy_strs,bool eof,bool remove_ws_from_field_name,size_t max_hdr_field_size)1302 MIMEHdr::parse(MIMEParser *parser, const char **start, const char *end, bool must_copy_strs, bool eof,
1303 bool remove_ws_from_field_name, size_t max_hdr_field_size)
1304 {
1305 if (!m_heap)
1306 m_heap = new_HdrHeap();
1307
1308 if (!m_mime)
1309 m_mime = mime_hdr_create(m_heap);
1310
1311 return mime_parser_parse(parser, m_heap, m_mime, start, end, must_copy_strs, eof, remove_ws_from_field_name, max_hdr_field_size);
1312 }
1313
1314 /*-------------------------------------------------------------------------
1315 -------------------------------------------------------------------------*/
1316 inline int
value_get_index(const char * name,int name_length,const char * value,int value_length)1317 MIMEHdr::value_get_index(const char *name, int name_length, const char *value, int value_length) const
1318 {
1319 const MIMEField *field = field_find(name, name_length);
1320
1321 if (field) {
1322 return field->value_get_index(value, value_length);
1323 }
1324 return -1;
1325 }
1326
1327 /*-------------------------------------------------------------------------
1328 -------------------------------------------------------------------------*/
1329
1330 inline const char *
value_get(const char * name,int name_length,int * value_length_return)1331 MIMEHdr::value_get(const char *name, int name_length, int *value_length_return) const
1332 {
1333 const MIMEField *field = field_find(name, name_length);
1334
1335 if (field) {
1336 return field->value_get(value_length_return);
1337 }
1338 return nullptr;
1339 }
1340
1341 inline std::string_view
value_get(std::string_view const & name)1342 MIMEHdr::value_get(std::string_view const &name) const
1343 {
1344 MIMEField const *field = field_find(name.data(), name.size());
1345
1346 if (field) {
1347 return field->value_get();
1348 }
1349 return {};
1350 }
1351
1352 inline int32_t
value_get_int(const char * name,int name_length)1353 MIMEHdr::value_get_int(const char *name, int name_length) const
1354 {
1355 const MIMEField *field = field_find(name, name_length);
1356
1357 if (field) {
1358 return mime_field_value_get_int(field);
1359 }
1360 return 0;
1361 }
1362
1363 inline uint32_t
value_get_uint(const char * name,int name_length)1364 MIMEHdr::value_get_uint(const char *name, int name_length) const
1365 {
1366 const MIMEField *field = field_find(name, name_length);
1367
1368 if (field) {
1369 return mime_field_value_get_uint(field);
1370 }
1371 return 0;
1372 }
1373
1374 inline int64_t
value_get_int64(const char * name,int name_length)1375 MIMEHdr::value_get_int64(const char *name, int name_length) const
1376 {
1377 const MIMEField *field = field_find(name, name_length);
1378
1379 if (field) {
1380 return mime_field_value_get_int64(field);
1381 }
1382 return 0;
1383 }
1384
1385 inline time_t
value_get_date(const char * name,int name_length)1386 MIMEHdr::value_get_date(const char *name, int name_length) const
1387 {
1388 const MIMEField *field = field_find(name, name_length);
1389
1390 if (field) {
1391 return mime_field_value_get_date(field);
1392 }
1393 return 0;
1394 }
1395
1396 inline int
value_get_comma_list(const char * name,int name_length,StrList * list)1397 MIMEHdr::value_get_comma_list(const char *name, int name_length, StrList *list) const
1398 {
1399 const MIMEField *field = field_find(name, name_length);
1400
1401 if (field) {
1402 return field->value_get_comma_list(list);
1403 }
1404 return 0;
1405 }
1406
1407 /*-------------------------------------------------------------------------
1408 -------------------------------------------------------------------------*/
1409
1410 inline bool
field_value_replace(MIMEField * field,const char * value,int value_length)1411 MIMEHdr::field_value_replace(MIMEField *field, const char *value, int value_length)
1412 {
1413 if (field->m_len_value >= value_length) {
1414 memcpy((char *)field->m_ptr_value, value, value_length);
1415 field->m_len_value = value_length;
1416 return true;
1417 }
1418 return false;
1419 }
1420
1421 inline void
field_value_set(MIMEField * field,const char * value,int value_length,bool reuse_heaps)1422 MIMEHdr::field_value_set(MIMEField *field, const char *value, int value_length, bool reuse_heaps)
1423 {
1424 if (!reuse_heaps || !field_value_replace(field, value, value_length)) {
1425 field->value_set(m_heap, m_mime, value, value_length);
1426 }
1427 }
1428
1429 inline void
field_value_set_int(MIMEField * field,int32_t value)1430 MIMEHdr::field_value_set_int(MIMEField *field, int32_t value)
1431 {
1432 field->value_set_int(m_heap, m_mime, value);
1433 }
1434
1435 inline void
field_value_set_uint(MIMEField * field,uint32_t value)1436 MIMEHdr::field_value_set_uint(MIMEField *field, uint32_t value)
1437 {
1438 field->value_set_uint(m_heap, m_mime, value);
1439 }
1440
1441 inline void
field_value_set_int64(MIMEField * field,int64_t value)1442 MIMEHdr::field_value_set_int64(MIMEField *field, int64_t value)
1443 {
1444 field->value_set_int64(m_heap, m_mime, value);
1445 }
1446
1447 inline void
field_value_set_date(MIMEField * field,time_t value)1448 MIMEHdr::field_value_set_date(MIMEField *field, time_t value)
1449 {
1450 field->value_set_date(m_heap, m_mime, value);
1451 }
1452
1453 /*-------------------------------------------------------------------------
1454 -------------------------------------------------------------------------*/
1455
1456 inline void
field_value_append(MIMEField * field,const char * value_str,int value_len,bool prepend_comma,const char separator)1457 MIMEHdr::field_value_append(MIMEField *field, const char *value_str, int value_len, bool prepend_comma, const char separator)
1458 {
1459 field->value_append(m_heap, m_mime, value_str, value_len, prepend_comma, separator);
1460 }
1461
1462 inline void
field_combine_dups(MIMEField * field,bool prepend_comma,const char separator)1463 MIMEHdr::field_combine_dups(MIMEField *field, bool prepend_comma, const char separator)
1464 {
1465 MIMEField *current = field->m_next_dup;
1466
1467 while (current) {
1468 int value_len = 0;
1469 const char *value_str = current->value_get(&value_len);
1470
1471 if (value_len > 0) {
1472 HdrHeap::HeapGuard guard(m_heap, value_str); // reference count the source string so it doesn't get moved
1473 field->value_append(m_heap, m_mime, value_str, value_len, prepend_comma, separator);
1474 }
1475 field_delete(current, false); // don't delete duplicates
1476 current = field->m_next_dup;
1477 }
1478 }
1479
1480 inline void
value_append_or_set(const char * name,const int name_length,char * value,int value_length)1481 MIMEHdr::value_append_or_set(const char *name, const int name_length, char *value, int value_length)
1482 {
1483 MIMEField *field = nullptr;
1484
1485 if ((field = field_find(name, name_length)) != nullptr) {
1486 while (field->m_next_dup) {
1487 field = field->m_next_dup;
1488 }
1489 field_value_append(field, value, value_length, true);
1490 } else {
1491 value_set(name, name_length, value, value_length);
1492 }
1493 }
1494
1495 /*-------------------------------------------------------------------------
1496 -------------------------------------------------------------------------*/
1497
1498 inline void
value_set(const char * name,int name_length,const char * value,int value_length)1499 MIMEHdr::value_set(const char *name, int name_length, const char *value, int value_length)
1500 {
1501 MIMEField *field;
1502 field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1503 field->value_set(m_heap, m_mime, value, value_length);
1504 }
1505
1506 inline void
value_set_int(const char * name,int name_length,int32_t value)1507 MIMEHdr::value_set_int(const char *name, int name_length, int32_t value)
1508 {
1509 MIMEField *field;
1510 field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1511 field->value_set_int(m_heap, m_mime, value);
1512 }
1513
1514 inline void
value_set_uint(const char * name,int name_length,uint32_t value)1515 MIMEHdr::value_set_uint(const char *name, int name_length, uint32_t value)
1516 {
1517 MIMEField *field;
1518 field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1519 field->value_set_uint(m_heap, m_mime, value);
1520 }
1521
1522 inline void
value_set_int64(const char * name,int name_length,int64_t value)1523 MIMEHdr::value_set_int64(const char *name, int name_length, int64_t value)
1524 {
1525 MIMEField *field;
1526 field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1527 field->value_set_int64(m_heap, m_mime, value);
1528 }
1529
1530 inline void
value_set_date(const char * name,int name_length,time_t value)1531 MIMEHdr::value_set_date(const char *name, int name_length, time_t value)
1532 {
1533 MIMEField *field;
1534 field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1535 field->value_set_date(m_heap, m_mime, value);
1536 }
1537
1538 /*-------------------------------------------------------------------------
1539 -------------------------------------------------------------------------*/
1540
1541 inline void
value_append(const char * name,int name_length,const char * value,int value_length,bool prepend_comma,const char separator)1542 MIMEHdr::value_append(const char *name, int name_length, const char *value, int value_length, bool prepend_comma,
1543 const char separator)
1544 {
1545 MIMEField *field;
1546
1547 field = field_find(name, name_length);
1548 if (field) {
1549 while (field->m_next_dup)
1550 field = field->m_next_dup;
1551 field->value_append(m_heap, m_mime, value, value_length, prepend_comma, separator);
1552 } else {
1553 field = field_create(name, name_length);
1554 field_attach(field);
1555 field->value_set(m_heap, m_mime, value, value_length);
1556 }
1557 }
1558
1559 /*-------------------------------------------------------------------------
1560 -------------------------------------------------------------------------*/
1561 inline time_t
get_age()1562 MIMEHdr::get_age()
1563 {
1564 int64_t age = value_get_int64(MIME_FIELD_AGE, MIME_LEN_AGE);
1565
1566 if (age < 0) // We should ignore negative Age: values
1567 return 0;
1568
1569 if ((4 == sizeof(time_t)) && (age > INT_MAX)) // Overflow
1570 return -1;
1571
1572 return age;
1573 }
1574
1575 /*-------------------------------------------------------------------------
1576 -------------------------------------------------------------------------*/
1577
1578 inline int64_t
get_content_length()1579 MIMEHdr::get_content_length() const
1580 {
1581 return value_get_int64(MIME_FIELD_CONTENT_LENGTH, MIME_LEN_CONTENT_LENGTH);
1582 }
1583
1584 /*-------------------------------------------------------------------------
1585 -------------------------------------------------------------------------*/
1586
1587 inline time_t
get_date()1588 MIMEHdr::get_date()
1589 {
1590 return value_get_date(MIME_FIELD_DATE, MIME_LEN_DATE);
1591 }
1592
1593 /*-------------------------------------------------------------------------
1594 -------------------------------------------------------------------------*/
1595
1596 inline time_t
get_expires()1597 MIMEHdr::get_expires()
1598 {
1599 return value_get_date(MIME_FIELD_EXPIRES, MIME_LEN_EXPIRES);
1600 }
1601
1602 /*-------------------------------------------------------------------------
1603 -------------------------------------------------------------------------*/
1604
1605 inline time_t
get_if_modified_since()1606 MIMEHdr::get_if_modified_since()
1607 {
1608 return value_get_date(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE);
1609 }
1610
1611 /*-------------------------------------------------------------------------
1612 -------------------------------------------------------------------------*/
1613
1614 inline time_t
get_if_unmodified_since()1615 MIMEHdr::get_if_unmodified_since()
1616 {
1617 return value_get_date(MIME_FIELD_IF_UNMODIFIED_SINCE, MIME_LEN_IF_UNMODIFIED_SINCE);
1618 }
1619
1620 /*-------------------------------------------------------------------------
1621 -------------------------------------------------------------------------*/
1622
1623 inline time_t
get_last_modified()1624 MIMEHdr::get_last_modified()
1625 {
1626 return value_get_date(MIME_FIELD_LAST_MODIFIED, MIME_LEN_LAST_MODIFIED);
1627 }
1628
1629 /*-------------------------------------------------------------------------
1630 -------------------------------------------------------------------------*/
1631
1632 inline time_t
get_if_range_date()1633 MIMEHdr::get_if_range_date()
1634 {
1635 return value_get_date(MIME_FIELD_IF_RANGE, MIME_LEN_IF_RANGE);
1636 }
1637
1638 /*-------------------------------------------------------------------------
1639 -------------------------------------------------------------------------*/
1640
1641 inline int32_t
get_max_forwards()1642 MIMEHdr::get_max_forwards()
1643 {
1644 return value_get_int(MIME_FIELD_MAX_FORWARDS, MIME_LEN_MAX_FORWARDS);
1645 }
1646
1647 /*-------------------------------------------------------------------------
1648 -------------------------------------------------------------------------*/
1649
1650 inline int32_t
get_warning(int idx)1651 MIMEHdr::get_warning(int idx)
1652 {
1653 (void)idx;
1654 // FIXME: what do we do here?
1655 ink_release_assert(!"unimplemented");
1656 return 0;
1657 }
1658
1659 /*-------------------------------------------------------------------------
1660 -------------------------------------------------------------------------*/
1661
1662 inline uint32_t
get_cooked_cc_mask()1663 MIMEHdr::get_cooked_cc_mask()
1664 {
1665 return m_mime->m_cooked_stuff.m_cache_control.m_mask;
1666 }
1667
1668 /*-------------------------------------------------------------------------
1669 -------------------------------------------------------------------------*/
1670
1671 inline int32_t
get_cooked_cc_max_age()1672 MIMEHdr::get_cooked_cc_max_age()
1673 {
1674 return m_mime->m_cooked_stuff.m_cache_control.m_secs_max_age;
1675 }
1676
1677 /*-------------------------------------------------------------------------
1678 -------------------------------------------------------------------------*/
1679
1680 inline int32_t
get_cooked_cc_s_maxage()1681 MIMEHdr::get_cooked_cc_s_maxage()
1682 {
1683 return m_mime->m_cooked_stuff.m_cache_control.m_secs_s_maxage;
1684 }
1685
1686 /*-------------------------------------------------------------------------
1687 -------------------------------------------------------------------------*/
1688
1689 inline int32_t
get_cooked_cc_max_stale()1690 MIMEHdr::get_cooked_cc_max_stale()
1691 {
1692 return m_mime->m_cooked_stuff.m_cache_control.m_secs_max_stale;
1693 }
1694
1695 /*-------------------------------------------------------------------------
1696 -------------------------------------------------------------------------*/
1697
1698 inline int32_t
get_cooked_cc_min_fresh()1699 MIMEHdr::get_cooked_cc_min_fresh()
1700 {
1701 return m_mime->m_cooked_stuff.m_cache_control.m_secs_min_fresh;
1702 }
1703
1704 /*-------------------------------------------------------------------------
1705 -------------------------------------------------------------------------*/
1706
1707 inline bool
get_cooked_pragma_no_cache()1708 MIMEHdr::get_cooked_pragma_no_cache()
1709 {
1710 return m_mime->m_cooked_stuff.m_pragma.m_no_cache;
1711 }
1712
1713 /*-------------------------------------------------------------------------
1714 -------------------------------------------------------------------------*/
1715
1716 inline void
set_cooked_cc_need_revalidate_once()1717 MIMEHdr::set_cooked_cc_need_revalidate_once()
1718 {
1719 m_mime->m_cooked_stuff.m_cache_control.m_mask |= MIME_COOKED_MASK_CC_NEED_REVALIDATE_ONCE;
1720 }
1721
1722 /*-------------------------------------------------------------------------
1723 -------------------------------------------------------------------------*/
1724
1725 inline void
unset_cooked_cc_need_revalidate_once()1726 MIMEHdr::unset_cooked_cc_need_revalidate_once()
1727 {
1728 m_mime->m_cooked_stuff.m_cache_control.m_mask &= ~((uint32_t)MIME_COOKED_MASK_CC_NEED_REVALIDATE_ONCE);
1729 }
1730
1731 /*-------------------------------------------------------------------------
1732 -------------------------------------------------------------------------*/
1733
1734 inline void
set_age(time_t value)1735 MIMEHdr::set_age(time_t value)
1736 {
1737 if (value < 0)
1738 value_set_uint(MIME_FIELD_AGE, MIME_LEN_AGE, (uint32_t)INT_MAX + 1);
1739 else {
1740 if (sizeof(time_t) > 4) {
1741 value_set_int64(MIME_FIELD_AGE, MIME_LEN_AGE, value);
1742 } else {
1743 value_set_uint(MIME_FIELD_AGE, MIME_LEN_AGE, value);
1744 }
1745 }
1746 }
1747
1748 /*-------------------------------------------------------------------------
1749 -------------------------------------------------------------------------*/
1750
1751 inline void
set_content_length(int64_t value)1752 MIMEHdr::set_content_length(int64_t value)
1753 {
1754 value_set_int64(MIME_FIELD_CONTENT_LENGTH, MIME_LEN_CONTENT_LENGTH, value);
1755 }
1756
1757 /*-------------------------------------------------------------------------
1758 -------------------------------------------------------------------------*/
1759
1760 inline void
set_date(time_t value)1761 MIMEHdr::set_date(time_t value)
1762 {
1763 value_set_date(MIME_FIELD_DATE, MIME_LEN_DATE, value);
1764 }
1765
1766 /*-------------------------------------------------------------------------
1767 -------------------------------------------------------------------------*/
1768
1769 inline void
set_expires(time_t value)1770 MIMEHdr::set_expires(time_t value)
1771 {
1772 value_set_date(MIME_FIELD_EXPIRES, MIME_LEN_EXPIRES, value);
1773 }
1774
1775 /*-------------------------------------------------------------------------
1776 -------------------------------------------------------------------------*/
1777
1778 inline void
set_if_modified_since(time_t value)1779 MIMEHdr::set_if_modified_since(time_t value)
1780 {
1781 value_set_date(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE, value);
1782 }
1783
1784 /*-------------------------------------------------------------------------
1785 -------------------------------------------------------------------------*/
1786
1787 inline void
set_if_unmodified_since(time_t value)1788 MIMEHdr::set_if_unmodified_since(time_t value)
1789 {
1790 value_set_date(MIME_FIELD_IF_UNMODIFIED_SINCE, MIME_LEN_IF_UNMODIFIED_SINCE, value);
1791 }
1792
1793 /*-------------------------------------------------------------------------
1794 -------------------------------------------------------------------------*/
1795
1796 inline void
set_last_modified(time_t value)1797 MIMEHdr::set_last_modified(time_t value)
1798 {
1799 value_set_date(MIME_FIELD_LAST_MODIFIED, MIME_LEN_LAST_MODIFIED, value);
1800 }
1801
1802 /*-------------------------------------------------------------------------
1803 -------------------------------------------------------------------------*/
1804
1805 inline void
set_max_forwards(int32_t value)1806 MIMEHdr::set_max_forwards(int32_t value)
1807 {
1808 value_set_int(MIME_FIELD_MAX_FORWARDS, MIME_LEN_MAX_FORWARDS, value);
1809 }
1810
1811 /*-------------------------------------------------------------------------
1812 -------------------------------------------------------------------------*/
1813
1814 inline void
set_warning(int32_t value)1815 MIMEHdr::set_warning(int32_t value)
1816 {
1817 value_set_int(MIME_FIELD_WARNING, MIME_LEN_WARNING, value);
1818 }
1819
1820 /*-------------------------------------------------------------------------
1821 -------------------------------------------------------------------------*/
1822
1823 inline void
set_server(const char * server_id_tag,int server_id_tag_size)1824 MIMEHdr::set_server(const char *server_id_tag, int server_id_tag_size)
1825 {
1826 value_set(MIME_FIELD_SERVER, MIME_LEN_SERVER, server_id_tag, server_id_tag_size);
1827 }
1828