Coverage Report

Created: 2026-02-10 06:42

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