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