xref: /trafficserver/proxy/hdrs/MIME.h (revision 8236813e)
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) & MIME_FLAGS_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() const343 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, 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) const810 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() const838 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) const855 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() const863 MIMEField::value_get_int() const
864 {
865   return mime_field_value_get_int(this);
866 }
867 
868 inline uint32_t
value_get_uint() const869 MIMEField::value_get_uint() const
870 {
871   return mime_field_value_get_uint(this);
872 }
873 
874 inline int64_t
value_get_int64() const875 MIMEField::value_get_int64() const
876 {
877   return mime_field_value_get_int64(this);
878 }
879 
880 inline time_t
value_get_date() const881 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) const887 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() const947 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() const961 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,
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() const1110 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) const1198 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,size_t max_hdr_field_size)1302 MIMEHdr::parse(MIMEParser *parser, const char **start, const char *end, bool must_copy_strs, bool eof, size_t max_hdr_field_size)
1303 {
1304   if (!m_heap)
1305     m_heap = new_HdrHeap();
1306 
1307   if (!m_mime)
1308     m_mime = mime_hdr_create(m_heap);
1309 
1310   return mime_parser_parse(parser, m_heap, m_mime, start, end, must_copy_strs, eof, max_hdr_field_size);
1311 }
1312 
1313 /*-------------------------------------------------------------------------
1314   -------------------------------------------------------------------------*/
1315 inline int
value_get_index(const char * name,int name_length,const char * value,int value_length) const1316 MIMEHdr::value_get_index(const char *name, int name_length, const char *value, int value_length) const
1317 {
1318   const MIMEField *field = field_find(name, name_length);
1319 
1320   if (field) {
1321     return field->value_get_index(value, value_length);
1322   }
1323   return -1;
1324 }
1325 
1326 /*-------------------------------------------------------------------------
1327   -------------------------------------------------------------------------*/
1328 
1329 inline const char *
value_get(const char * name,int name_length,int * value_length_return) const1330 MIMEHdr::value_get(const char *name, int name_length, int *value_length_return) const
1331 {
1332   const MIMEField *field = field_find(name, name_length);
1333 
1334   if (field) {
1335     return field->value_get(value_length_return);
1336   }
1337   return nullptr;
1338 }
1339 
1340 inline std::string_view
value_get(std::string_view const & name) const1341 MIMEHdr::value_get(std::string_view const &name) const
1342 {
1343   MIMEField const *field = field_find(name.data(), name.size());
1344 
1345   if (field) {
1346     return field->value_get();
1347   }
1348   return {};
1349 }
1350 
1351 inline int32_t
value_get_int(const char * name,int name_length) const1352 MIMEHdr::value_get_int(const char *name, int name_length) const
1353 {
1354   const MIMEField *field = field_find(name, name_length);
1355 
1356   if (field) {
1357     return mime_field_value_get_int(field);
1358   }
1359   return 0;
1360 }
1361 
1362 inline uint32_t
value_get_uint(const char * name,int name_length) const1363 MIMEHdr::value_get_uint(const char *name, int name_length) const
1364 {
1365   const MIMEField *field = field_find(name, name_length);
1366 
1367   if (field) {
1368     return mime_field_value_get_uint(field);
1369   }
1370   return 0;
1371 }
1372 
1373 inline int64_t
value_get_int64(const char * name,int name_length) const1374 MIMEHdr::value_get_int64(const char *name, int name_length) const
1375 {
1376   const MIMEField *field = field_find(name, name_length);
1377 
1378   if (field) {
1379     return mime_field_value_get_int64(field);
1380   }
1381   return 0;
1382 }
1383 
1384 inline time_t
value_get_date(const char * name,int name_length) const1385 MIMEHdr::value_get_date(const char *name, int name_length) const
1386 {
1387   const MIMEField *field = field_find(name, name_length);
1388 
1389   if (field) {
1390     return mime_field_value_get_date(field);
1391   }
1392   return 0;
1393 }
1394 
1395 inline int
value_get_comma_list(const char * name,int name_length,StrList * list) const1396 MIMEHdr::value_get_comma_list(const char *name, int name_length, StrList *list) const
1397 {
1398   const MIMEField *field = field_find(name, name_length);
1399 
1400   if (field) {
1401     return field->value_get_comma_list(list);
1402   }
1403   return 0;
1404 }
1405 
1406 /*-------------------------------------------------------------------------
1407   -------------------------------------------------------------------------*/
1408 
1409 inline bool
field_value_replace(MIMEField * field,const char * value,int value_length)1410 MIMEHdr::field_value_replace(MIMEField *field, const char *value, int value_length)
1411 {
1412   if (field->m_len_value >= value_length) {
1413     memcpy((char *)field->m_ptr_value, value, value_length);
1414     field->m_len_value = value_length;
1415     return true;
1416   }
1417   return false;
1418 }
1419 
1420 inline void
field_value_set(MIMEField * field,const char * value,int value_length,bool reuse_heaps)1421 MIMEHdr::field_value_set(MIMEField *field, const char *value, int value_length, bool reuse_heaps)
1422 {
1423   if (!reuse_heaps || !field_value_replace(field, value, value_length)) {
1424     field->value_set(m_heap, m_mime, value, value_length);
1425   }
1426 }
1427 
1428 inline void
field_value_set_int(MIMEField * field,int32_t value)1429 MIMEHdr::field_value_set_int(MIMEField *field, int32_t value)
1430 {
1431   field->value_set_int(m_heap, m_mime, value);
1432 }
1433 
1434 inline void
field_value_set_uint(MIMEField * field,uint32_t value)1435 MIMEHdr::field_value_set_uint(MIMEField *field, uint32_t value)
1436 {
1437   field->value_set_uint(m_heap, m_mime, value);
1438 }
1439 
1440 inline void
field_value_set_int64(MIMEField * field,int64_t value)1441 MIMEHdr::field_value_set_int64(MIMEField *field, int64_t value)
1442 {
1443   field->value_set_int64(m_heap, m_mime, value);
1444 }
1445 
1446 inline void
field_value_set_date(MIMEField * field,time_t value)1447 MIMEHdr::field_value_set_date(MIMEField *field, time_t value)
1448 {
1449   field->value_set_date(m_heap, m_mime, value);
1450 }
1451 
1452 /*-------------------------------------------------------------------------
1453   -------------------------------------------------------------------------*/
1454 
1455 inline void
field_value_append(MIMEField * field,const char * value_str,int value_len,bool prepend_comma,const char separator)1456 MIMEHdr::field_value_append(MIMEField *field, const char *value_str, int value_len, bool prepend_comma, const char separator)
1457 {
1458   field->value_append(m_heap, m_mime, value_str, value_len, prepend_comma, separator);
1459 }
1460 
1461 inline void
field_combine_dups(MIMEField * field,bool prepend_comma,const char separator)1462 MIMEHdr::field_combine_dups(MIMEField *field, bool prepend_comma, const char separator)
1463 {
1464   MIMEField *current = field->m_next_dup;
1465 
1466   while (current) {
1467     int value_len         = 0;
1468     const char *value_str = current->value_get(&value_len);
1469 
1470     if (value_len > 0) {
1471       HdrHeap::HeapGuard guard(m_heap, value_str); // reference count the source string so it doesn't get moved
1472       field->value_append(m_heap, m_mime, value_str, value_len, prepend_comma, separator);
1473     }
1474     field_delete(current, false); // don't delete duplicates
1475     current = field->m_next_dup;
1476   }
1477 }
1478 
1479 inline void
value_append_or_set(const char * name,const int name_length,char * value,int value_length)1480 MIMEHdr::value_append_or_set(const char *name, const int name_length, char *value, int value_length)
1481 {
1482   MIMEField *field = nullptr;
1483 
1484   if ((field = field_find(name, name_length)) != nullptr) {
1485     while (field->m_next_dup) {
1486       field = field->m_next_dup;
1487     }
1488     field_value_append(field, value, value_length, true);
1489   } else {
1490     value_set(name, name_length, value, value_length);
1491   }
1492 }
1493 
1494 /*-------------------------------------------------------------------------
1495   -------------------------------------------------------------------------*/
1496 
1497 inline void
value_set(const char * name,int name_length,const char * value,int value_length)1498 MIMEHdr::value_set(const char *name, int name_length, const char *value, int value_length)
1499 {
1500   MIMEField *field;
1501   field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1502   field->value_set(m_heap, m_mime, value, value_length);
1503 }
1504 
1505 inline void
value_set_int(const char * name,int name_length,int32_t value)1506 MIMEHdr::value_set_int(const char *name, int name_length, int32_t value)
1507 {
1508   MIMEField *field;
1509   field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1510   field->value_set_int(m_heap, m_mime, value);
1511 }
1512 
1513 inline void
value_set_uint(const char * name,int name_length,uint32_t value)1514 MIMEHdr::value_set_uint(const char *name, int name_length, uint32_t value)
1515 {
1516   MIMEField *field;
1517   field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1518   field->value_set_uint(m_heap, m_mime, value);
1519 }
1520 
1521 inline void
value_set_int64(const char * name,int name_length,int64_t value)1522 MIMEHdr::value_set_int64(const char *name, int name_length, int64_t value)
1523 {
1524   MIMEField *field;
1525   field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1526   field->value_set_int64(m_heap, m_mime, value);
1527 }
1528 
1529 inline void
value_set_date(const char * name,int name_length,time_t value)1530 MIMEHdr::value_set_date(const char *name, int name_length, time_t value)
1531 {
1532   MIMEField *field;
1533   field = mime_hdr_prepare_for_value_set(m_heap, m_mime, name, name_length);
1534   field->value_set_date(m_heap, m_mime, value);
1535 }
1536 
1537 /*-------------------------------------------------------------------------
1538   -------------------------------------------------------------------------*/
1539 
1540 inline void
value_append(const char * name,int name_length,const char * value,int value_length,bool prepend_comma,const char separator)1541 MIMEHdr::value_append(const char *name, int name_length, const char *value, int value_length, bool prepend_comma,
1542                       const char separator)
1543 {
1544   MIMEField *field;
1545 
1546   field = field_find(name, name_length);
1547   if (field) {
1548     while (field->m_next_dup)
1549       field = field->m_next_dup;
1550     field->value_append(m_heap, m_mime, value, value_length, prepend_comma, separator);
1551   } else {
1552     field = field_create(name, name_length);
1553     field_attach(field);
1554     field->value_set(m_heap, m_mime, value, value_length);
1555   }
1556 }
1557 
1558 /*-------------------------------------------------------------------------
1559   -------------------------------------------------------------------------*/
1560 inline time_t
get_age()1561 MIMEHdr::get_age()
1562 {
1563   int64_t age = value_get_int64(MIME_FIELD_AGE, MIME_LEN_AGE);
1564 
1565   if (age < 0) // We should ignore negative Age: values
1566     return 0;
1567 
1568   if ((4 == sizeof(time_t)) && (age > INT_MAX)) // Overflow
1569     return -1;
1570 
1571   return age;
1572 }
1573 
1574 /*-------------------------------------------------------------------------
1575   -------------------------------------------------------------------------*/
1576 
1577 inline int64_t
get_content_length() const1578 MIMEHdr::get_content_length() const
1579 {
1580   return value_get_int64(MIME_FIELD_CONTENT_LENGTH, MIME_LEN_CONTENT_LENGTH);
1581 }
1582 
1583 /*-------------------------------------------------------------------------
1584   -------------------------------------------------------------------------*/
1585 
1586 inline time_t
get_date()1587 MIMEHdr::get_date()
1588 {
1589   return value_get_date(MIME_FIELD_DATE, MIME_LEN_DATE);
1590 }
1591 
1592 /*-------------------------------------------------------------------------
1593   -------------------------------------------------------------------------*/
1594 
1595 inline time_t
get_expires()1596 MIMEHdr::get_expires()
1597 {
1598   return value_get_date(MIME_FIELD_EXPIRES, MIME_LEN_EXPIRES);
1599 }
1600 
1601 /*-------------------------------------------------------------------------
1602   -------------------------------------------------------------------------*/
1603 
1604 inline time_t
get_if_modified_since()1605 MIMEHdr::get_if_modified_since()
1606 {
1607   return value_get_date(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE);
1608 }
1609 
1610 /*-------------------------------------------------------------------------
1611   -------------------------------------------------------------------------*/
1612 
1613 inline time_t
get_if_unmodified_since()1614 MIMEHdr::get_if_unmodified_since()
1615 {
1616   return value_get_date(MIME_FIELD_IF_UNMODIFIED_SINCE, MIME_LEN_IF_UNMODIFIED_SINCE);
1617 }
1618 
1619 /*-------------------------------------------------------------------------
1620   -------------------------------------------------------------------------*/
1621 
1622 inline time_t
get_last_modified()1623 MIMEHdr::get_last_modified()
1624 {
1625   return value_get_date(MIME_FIELD_LAST_MODIFIED, MIME_LEN_LAST_MODIFIED);
1626 }
1627 
1628 /*-------------------------------------------------------------------------
1629   -------------------------------------------------------------------------*/
1630 
1631 inline time_t
get_if_range_date()1632 MIMEHdr::get_if_range_date()
1633 {
1634   return value_get_date(MIME_FIELD_IF_RANGE, MIME_LEN_IF_RANGE);
1635 }
1636 
1637 /*-------------------------------------------------------------------------
1638   -------------------------------------------------------------------------*/
1639 
1640 inline int32_t
get_max_forwards()1641 MIMEHdr::get_max_forwards()
1642 {
1643   return value_get_int(MIME_FIELD_MAX_FORWARDS, MIME_LEN_MAX_FORWARDS);
1644 }
1645 
1646 /*-------------------------------------------------------------------------
1647   -------------------------------------------------------------------------*/
1648 
1649 inline int32_t
get_warning(int idx)1650 MIMEHdr::get_warning(int idx)
1651 {
1652   (void)idx;
1653   // FIXME: what do we do here?
1654   ink_release_assert(!"unimplemented");
1655   return 0;
1656 }
1657 
1658 /*-------------------------------------------------------------------------
1659   -------------------------------------------------------------------------*/
1660 
1661 inline uint32_t
get_cooked_cc_mask()1662 MIMEHdr::get_cooked_cc_mask()
1663 {
1664   return m_mime->m_cooked_stuff.m_cache_control.m_mask;
1665 }
1666 
1667 /*-------------------------------------------------------------------------
1668   -------------------------------------------------------------------------*/
1669 
1670 inline int32_t
get_cooked_cc_max_age()1671 MIMEHdr::get_cooked_cc_max_age()
1672 {
1673   return m_mime->m_cooked_stuff.m_cache_control.m_secs_max_age;
1674 }
1675 
1676 /*-------------------------------------------------------------------------
1677   -------------------------------------------------------------------------*/
1678 
1679 inline int32_t
get_cooked_cc_s_maxage()1680 MIMEHdr::get_cooked_cc_s_maxage()
1681 {
1682   return m_mime->m_cooked_stuff.m_cache_control.m_secs_s_maxage;
1683 }
1684 
1685 /*-------------------------------------------------------------------------
1686   -------------------------------------------------------------------------*/
1687 
1688 inline int32_t
get_cooked_cc_max_stale()1689 MIMEHdr::get_cooked_cc_max_stale()
1690 {
1691   return m_mime->m_cooked_stuff.m_cache_control.m_secs_max_stale;
1692 }
1693 
1694 /*-------------------------------------------------------------------------
1695   -------------------------------------------------------------------------*/
1696 
1697 inline int32_t
get_cooked_cc_min_fresh()1698 MIMEHdr::get_cooked_cc_min_fresh()
1699 {
1700   return m_mime->m_cooked_stuff.m_cache_control.m_secs_min_fresh;
1701 }
1702 
1703 /*-------------------------------------------------------------------------
1704   -------------------------------------------------------------------------*/
1705 
1706 inline bool
get_cooked_pragma_no_cache()1707 MIMEHdr::get_cooked_pragma_no_cache()
1708 {
1709   return m_mime->m_cooked_stuff.m_pragma.m_no_cache;
1710 }
1711 
1712 /*-------------------------------------------------------------------------
1713   -------------------------------------------------------------------------*/
1714 
1715 inline void
set_cooked_cc_need_revalidate_once()1716 MIMEHdr::set_cooked_cc_need_revalidate_once()
1717 {
1718   m_mime->m_cooked_stuff.m_cache_control.m_mask |= MIME_COOKED_MASK_CC_NEED_REVALIDATE_ONCE;
1719 }
1720 
1721 /*-------------------------------------------------------------------------
1722   -------------------------------------------------------------------------*/
1723 
1724 inline void
unset_cooked_cc_need_revalidate_once()1725 MIMEHdr::unset_cooked_cc_need_revalidate_once()
1726 {
1727   m_mime->m_cooked_stuff.m_cache_control.m_mask &= ~((uint32_t)MIME_COOKED_MASK_CC_NEED_REVALIDATE_ONCE);
1728 }
1729 
1730 /*-------------------------------------------------------------------------
1731   -------------------------------------------------------------------------*/
1732 
1733 inline void
set_age(time_t value)1734 MIMEHdr::set_age(time_t value)
1735 {
1736   if (value < 0)
1737     value_set_uint(MIME_FIELD_AGE, MIME_LEN_AGE, (uint32_t)INT_MAX + 1);
1738   else {
1739     if (sizeof(time_t) > 4) {
1740       value_set_int64(MIME_FIELD_AGE, MIME_LEN_AGE, value);
1741     } else {
1742       value_set_uint(MIME_FIELD_AGE, MIME_LEN_AGE, value);
1743     }
1744   }
1745 }
1746 
1747 /*-------------------------------------------------------------------------
1748   -------------------------------------------------------------------------*/
1749 
1750 inline void
set_content_length(int64_t value)1751 MIMEHdr::set_content_length(int64_t value)
1752 {
1753   value_set_int64(MIME_FIELD_CONTENT_LENGTH, MIME_LEN_CONTENT_LENGTH, value);
1754 }
1755 
1756 /*-------------------------------------------------------------------------
1757   -------------------------------------------------------------------------*/
1758 
1759 inline void
set_date(time_t value)1760 MIMEHdr::set_date(time_t value)
1761 {
1762   value_set_date(MIME_FIELD_DATE, MIME_LEN_DATE, value);
1763 }
1764 
1765 /*-------------------------------------------------------------------------
1766   -------------------------------------------------------------------------*/
1767 
1768 inline void
set_expires(time_t value)1769 MIMEHdr::set_expires(time_t value)
1770 {
1771   value_set_date(MIME_FIELD_EXPIRES, MIME_LEN_EXPIRES, value);
1772 }
1773 
1774 /*-------------------------------------------------------------------------
1775   -------------------------------------------------------------------------*/
1776 
1777 inline void
set_if_modified_since(time_t value)1778 MIMEHdr::set_if_modified_since(time_t value)
1779 {
1780   value_set_date(MIME_FIELD_IF_MODIFIED_SINCE, MIME_LEN_IF_MODIFIED_SINCE, value);
1781 }
1782 
1783 /*-------------------------------------------------------------------------
1784   -------------------------------------------------------------------------*/
1785 
1786 inline void
set_if_unmodified_since(time_t value)1787 MIMEHdr::set_if_unmodified_since(time_t value)
1788 {
1789   value_set_date(MIME_FIELD_IF_UNMODIFIED_SINCE, MIME_LEN_IF_UNMODIFIED_SINCE, value);
1790 }
1791 
1792 /*-------------------------------------------------------------------------
1793   -------------------------------------------------------------------------*/
1794 
1795 inline void
set_last_modified(time_t value)1796 MIMEHdr::set_last_modified(time_t value)
1797 {
1798   value_set_date(MIME_FIELD_LAST_MODIFIED, MIME_LEN_LAST_MODIFIED, value);
1799 }
1800 
1801 /*-------------------------------------------------------------------------
1802   -------------------------------------------------------------------------*/
1803 
1804 inline void
set_max_forwards(int32_t value)1805 MIMEHdr::set_max_forwards(int32_t value)
1806 {
1807   value_set_int(MIME_FIELD_MAX_FORWARDS, MIME_LEN_MAX_FORWARDS, value);
1808 }
1809 
1810 /*-------------------------------------------------------------------------
1811   -------------------------------------------------------------------------*/
1812 
1813 inline void
set_warning(int32_t value)1814 MIMEHdr::set_warning(int32_t value)
1815 {
1816   value_set_int(MIME_FIELD_WARNING, MIME_LEN_WARNING, value);
1817 }
1818 
1819 /*-------------------------------------------------------------------------
1820   -------------------------------------------------------------------------*/
1821 
1822 inline void
set_server(const char * server_id_tag,int server_id_tag_size)1823 MIMEHdr::set_server(const char *server_id_tag, int server_id_tag_size)
1824 {
1825   value_set(MIME_FIELD_SERVER, MIME_LEN_SERVER, server_id_tag, server_id_tag_size);
1826 }
1827