1  
//
1  
//
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
3  
// Copyright (c) 2025 Mohammad Nejati
3  
// Copyright (c) 2025 Mohammad Nejati
4  
//
4  
//
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  
//
7  
//
8  
// Official repository: https://github.com/cppalliance/http
8  
// Official repository: https://github.com/cppalliance/http
9  
//
9  
//
10  

10  

11  
#include <boost/http/field.hpp>
11  
#include <boost/http/field.hpp>
12  
#include <boost/assert.hpp>
12  
#include <boost/assert.hpp>
13  
#include <boost/core/detail/string_view.hpp>
13  
#include <boost/core/detail/string_view.hpp>
14  
#include <array>
14  
#include <array>
15  
#include <cstdint>
15  
#include <cstdint>
16  
#include <cstring>
16  
#include <cstring>
17  
#include <ostream>
17  
#include <ostream>
18  

18  

19  
namespace boost {
19  
namespace boost {
20  
namespace http {
20  
namespace http {
21  

21  

22  
namespace detail {
22  
namespace detail {
23  

23  

24  
struct field_table
24  
struct field_table
25  
{
25  
{
26  
    static
26  
    static
27  
    std::uint32_t
27  
    std::uint32_t
28  
    get_chars(
28  
    get_chars(
29  
        unsigned char const* p) noexcept
29  
        unsigned char const* p) noexcept
30  
    {
30  
    {
31  
        // VFALCO memcpy is endian-dependent
31  
        // VFALCO memcpy is endian-dependent
32  
        //std::memcpy(&v, p, 4);
32  
        //std::memcpy(&v, p, 4);
33  
        // Compiler should be smart enough to
33  
        // Compiler should be smart enough to
34  
        // optimize this down to one instruction.
34  
        // optimize this down to one instruction.
35  
        return
35  
        return
36  
             p[0] |
36  
             p[0] |
37  
            (p[1] <<  8) |
37  
            (p[1] <<  8) |
38  
            (p[2] << 16) |
38  
            (p[2] << 16) |
39  
            (p[3] << 24);
39  
            (p[3] << 24);
40  
    }
40  
    }
41  

41  

42  
    using array_type = std::array<
42  
    using array_type = std::array<
43  
        core::string_view, 357>;
43  
        core::string_view, 357>;
44  

44  

45  
    // Strings are converted to lowercase
45  
    // Strings are converted to lowercase
46  
    static
46  
    static
47  
    std::uint32_t
47  
    std::uint32_t
48  
    digest(core::string_view s)
48  
    digest(core::string_view s)
49  
    {
49  
    {
50  
        std::uint32_t r = 0;
50  
        std::uint32_t r = 0;
51  
        std::size_t n = s.size();
51  
        std::size_t n = s.size();
52  
        auto p = reinterpret_cast<
52  
        auto p = reinterpret_cast<
53  
            unsigned char const*>(s.data());
53  
            unsigned char const*>(s.data());
54  
        // consume N characters at a time
54  
        // consume N characters at a time
55  
        // VFALCO Can we do 8 on 64-bit systems?
55  
        // VFALCO Can we do 8 on 64-bit systems?
56  
        while(n >= 4)
56  
        while(n >= 4)
57  
        {
57  
        {
58  
            auto const v = get_chars(p);
58  
            auto const v = get_chars(p);
59  
            r = (r * 5 + (
59  
            r = (r * 5 + (
60  
                v | 0x20202020 )); // convert to lower
60  
                v | 0x20202020 )); // convert to lower
61  
            p += 4;
61  
            p += 4;
62  
            n -= 4;
62  
            n -= 4;
63  
        }
63  
        }
64  
        // handle remaining characters
64  
        // handle remaining characters
65  
        while( n > 0 )
65  
        while( n > 0 )
66  
        {
66  
        {
67  
            r = r * 5 + ( *p | 0x20 );
67  
            r = r * 5 + ( *p | 0x20 );
68  
            ++p;
68  
            ++p;
69  
            --n;
69  
            --n;
70  
        }
70  
        }
71  
        return r;
71  
        return r;
72  
    }
72  
    }
73  

73  

74  
    // This comparison is case-insensitive, and the
74  
    // This comparison is case-insensitive, and the
75  
    // strings must contain only valid http field characters.
75  
    // strings must contain only valid http field characters.
76  
    static
76  
    static
77  
    bool
77  
    bool
78  
    equals(
78  
    equals(
79  
        core::string_view lhs,
79  
        core::string_view lhs,
80  
        core::string_view rhs)
80  
        core::string_view rhs)
81  
    {
81  
    {
82  
        using Int = std::uint32_t; // VFALCO std::size_t?
82  
        using Int = std::uint32_t; // VFALCO std::size_t?
83  
        auto n = lhs.size();
83  
        auto n = lhs.size();
84  
        if(n != rhs.size())
84  
        if(n != rhs.size())
85  
            return false;
85  
            return false;
86  
        auto p1 = reinterpret_cast<
86  
        auto p1 = reinterpret_cast<
87  
            unsigned char const*>(lhs.data());
87  
            unsigned char const*>(lhs.data());
88  
        auto p2 = reinterpret_cast<
88  
        auto p2 = reinterpret_cast<
89  
            unsigned char const*>(rhs.data());
89  
            unsigned char const*>(rhs.data());
90  
        auto constexpr S = sizeof(Int);
90  
        auto constexpr S = sizeof(Int);
91  
        auto constexpr Mask = static_cast<Int>(
91  
        auto constexpr Mask = static_cast<Int>(
92  
            0xDFDFDFDFDFDFDFDF & ~Int{0});
92  
            0xDFDFDFDFDFDFDFDF & ~Int{0});
93  
        for(; n >= S; p1 += S, p2 += S, n -= S)
93  
        for(; n >= S; p1 += S, p2 += S, n -= S)
94  
        {
94  
        {
95  
            Int const v1 = get_chars(p1);
95  
            Int const v1 = get_chars(p1);
96  
            Int const v2 = get_chars(p2);
96  
            Int const v2 = get_chars(p2);
97  
            if((v1 ^ v2) & Mask)
97  
            if((v1 ^ v2) & Mask)
98  
                return false;
98  
                return false;
99  
        }
99  
        }
100  
        for(; n; ++p1, ++p2, --n)
100  
        for(; n; ++p1, ++p2, --n)
101  
            if(( *p1 ^ *p2) & 0xDF)
101  
            if(( *p1 ^ *p2) & 0xDF)
102  
                return false;
102  
                return false;
103  
        return true;
103  
        return true;
104  
    }
104  
    }
105  

105  

106  
    array_type by_name_;
106  
    array_type by_name_;
107  

107  

108  
    enum { N = 5155 };
108  
    enum { N = 5155 };
109  
    unsigned char map_[ N ][ 2 ] = {};
109  
    unsigned char map_[ N ][ 2 ] = {};
110  

110  

111  
/*
111  
/*
112  
    From:
112  
    From:
113  
    
113  
    
114  
    https://www.iana.org/assignments/message-headers/message-headers.xhtml
114  
    https://www.iana.org/assignments/message-headers/message-headers.xhtml
115  
*/
115  
*/
116  
    field_table()
116  
    field_table()
117  
        : by_name_({{
117  
        : by_name_({{
118  
// string constants
118  
// string constants
119  
"<unknown-field>",
119  
"<unknown-field>",
120  
"A-IM",
120  
"A-IM",
121  
"Accept",
121  
"Accept",
122  
"Accept-Additions",
122  
"Accept-Additions",
123  
"Accept-Charset",
123  
"Accept-Charset",
124  
"Accept-Datetime",
124  
"Accept-Datetime",
125  
"Accept-Encoding",
125  
"Accept-Encoding",
126  
"Accept-Features",
126  
"Accept-Features",
127  
"Accept-Language",
127  
"Accept-Language",
128  
"Accept-Patch",
128  
"Accept-Patch",
129  
"Accept-Post",
129  
"Accept-Post",
130  
"Accept-Ranges",
130  
"Accept-Ranges",
131  
"Access-Control",
131  
"Access-Control",
132  
"Access-Control-Allow-Credentials",
132  
"Access-Control-Allow-Credentials",
133  
"Access-Control-Allow-Headers",
133  
"Access-Control-Allow-Headers",
134  
"Access-Control-Allow-Methods",
134  
"Access-Control-Allow-Methods",
135  
"Access-Control-Allow-Origin",
135  
"Access-Control-Allow-Origin",
136  
"Access-Control-Expose-Headers",
136  
"Access-Control-Expose-Headers",
137  
"Access-Control-Max-Age",
137  
"Access-Control-Max-Age",
138  
"Access-Control-Request-Headers",
138  
"Access-Control-Request-Headers",
139  
"Access-Control-Request-Method",
139  
"Access-Control-Request-Method",
140  
"Age",
140  
"Age",
141  
"Allow",
141  
"Allow",
142  
"ALPN",
142  
"ALPN",
143  
"Also-Control",
143  
"Also-Control",
144  
"Alt-Svc",
144  
"Alt-Svc",
145  
"Alt-Used",
145  
"Alt-Used",
146  
"Alternate-Recipient",
146  
"Alternate-Recipient",
147  
"Alternates",
147  
"Alternates",
148  
"Apparently-To",
148  
"Apparently-To",
149  
"Apply-To-Redirect-Ref",
149  
"Apply-To-Redirect-Ref",
150  
"Approved",
150  
"Approved",
151  
"Archive",
151  
"Archive",
152  
"Archived-At",
152  
"Archived-At",
153  
"Article-Names",
153  
"Article-Names",
154  
"Article-Updates",
154  
"Article-Updates",
155  
"Authentication-Control",
155  
"Authentication-Control",
156  
"Authentication-Info",
156  
"Authentication-Info",
157  
"Authentication-Results",
157  
"Authentication-Results",
158  
"Authorization",
158  
"Authorization",
159  
"Auto-Submitted",
159  
"Auto-Submitted",
160  
"Autoforwarded",
160  
"Autoforwarded",
161  
"Autosubmitted",
161  
"Autosubmitted",
162  
"Base",
162  
"Base",
163  
"Bcc",
163  
"Bcc",
164  
"Body",
164  
"Body",
165  
"C-Ext",
165  
"C-Ext",
166  
"C-Man",
166  
"C-Man",
167  
"C-Opt",
167  
"C-Opt",
168  
"C-PEP",
168  
"C-PEP",
169  
"C-PEP-Info",
169  
"C-PEP-Info",
170  
"Cache-Control",
170  
"Cache-Control",
171  
"CalDAV-Timezones",
171  
"CalDAV-Timezones",
172  
"Cancel-Key",
172  
"Cancel-Key",
173  
"Cancel-Lock",
173  
"Cancel-Lock",
174  
"Cc",
174  
"Cc",
175  
"Close",
175  
"Close",
176  
"Comments",
176  
"Comments",
177  
"Compliance",
177  
"Compliance",
178  
"Connection",
178  
"Connection",
179  
"Content-Alternative",
179  
"Content-Alternative",
180  
"Content-Base",
180  
"Content-Base",
181  
"Content-Description",
181  
"Content-Description",
182  
"Content-Disposition",
182  
"Content-Disposition",
183  
"Content-Duration",
183  
"Content-Duration",
184  
"Content-Encoding",
184  
"Content-Encoding",
185  
"Content-features",
185  
"Content-features",
186  
"Content-ID",
186  
"Content-ID",
187  
"Content-Identifier",
187  
"Content-Identifier",
188  
"Content-Language",
188  
"Content-Language",
189  
"Content-Length",
189  
"Content-Length",
190  
"Content-Location",
190  
"Content-Location",
191  
"Content-MD5",
191  
"Content-MD5",
192  
"Content-Range",
192  
"Content-Range",
193  
"Content-Return",
193  
"Content-Return",
194  
"Content-Script-Type",
194  
"Content-Script-Type",
195  
"Content-Style-Type",
195  
"Content-Style-Type",
196  
"Content-Transfer-Encoding",
196  
"Content-Transfer-Encoding",
197  
"Content-Type",
197  
"Content-Type",
198  
"Content-Version",
198  
"Content-Version",
199  
"Control",
199  
"Control",
200  
"Conversion",
200  
"Conversion",
201  
"Conversion-With-Loss",
201  
"Conversion-With-Loss",
202  
"Cookie",
202  
"Cookie",
203  
"Cookie2",
203  
"Cookie2",
204  
"Cost",
204  
"Cost",
205  
"DASL",
205  
"DASL",
206  
"Date",
206  
"Date",
207  
"Date-Received",
207  
"Date-Received",
208  
"DAV",
208  
"DAV",
209  
"Default-Style",
209  
"Default-Style",
210  
"Deferred-Delivery",
210  
"Deferred-Delivery",
211  
"Delivery-Date",
211  
"Delivery-Date",
212  
"Delta-Base",
212  
"Delta-Base",
213  
"Depth",
213  
"Depth",
214  
"Derived-From",
214  
"Derived-From",
215  
"Destination",
215  
"Destination",
216  
"Differential-ID",
216  
"Differential-ID",
217  
"Digest",
217  
"Digest",
218  
"Discarded-X400-IPMS-Extensions",
218  
"Discarded-X400-IPMS-Extensions",
219  
"Discarded-X400-MTS-Extensions",
219  
"Discarded-X400-MTS-Extensions",
220  
"Disclose-Recipients",
220  
"Disclose-Recipients",
221  
"Disposition-Notification-Options",
221  
"Disposition-Notification-Options",
222  
"Disposition-Notification-To",
222  
"Disposition-Notification-To",
223  
"Distribution",
223  
"Distribution",
224  
"DKIM-Signature",
224  
"DKIM-Signature",
225  
"DL-Expansion-History",
225  
"DL-Expansion-History",
226  
"Downgraded-Bcc",
226  
"Downgraded-Bcc",
227  
"Downgraded-Cc",
227  
"Downgraded-Cc",
228  
"Downgraded-Disposition-Notification-To",
228  
"Downgraded-Disposition-Notification-To",
229  
"Downgraded-Final-Recipient",
229  
"Downgraded-Final-Recipient",
230  
"Downgraded-From",
230  
"Downgraded-From",
231  
"Downgraded-In-Reply-To",
231  
"Downgraded-In-Reply-To",
232  
"Downgraded-Mail-From",
232  
"Downgraded-Mail-From",
233  
"Downgraded-Message-Id",
233  
"Downgraded-Message-Id",
234  
"Downgraded-Original-Recipient",
234  
"Downgraded-Original-Recipient",
235  
"Downgraded-Rcpt-To",
235  
"Downgraded-Rcpt-To",
236  
"Downgraded-References",
236  
"Downgraded-References",
237  
"Downgraded-Reply-To",
237  
"Downgraded-Reply-To",
238  
"Downgraded-Resent-Bcc",
238  
"Downgraded-Resent-Bcc",
239  
"Downgraded-Resent-Cc",
239  
"Downgraded-Resent-Cc",
240  
"Downgraded-Resent-From",
240  
"Downgraded-Resent-From",
241  
"Downgraded-Resent-Reply-To",
241  
"Downgraded-Resent-Reply-To",
242  
"Downgraded-Resent-Sender",
242  
"Downgraded-Resent-Sender",
243  
"Downgraded-Resent-To",
243  
"Downgraded-Resent-To",
244  
"Downgraded-Return-Path",
244  
"Downgraded-Return-Path",
245  
"Downgraded-Sender",
245  
"Downgraded-Sender",
246  
"Downgraded-To",
246  
"Downgraded-To",
247  
"EDIINT-Features",
247  
"EDIINT-Features",
248  
"Eesst-Version",
248  
"Eesst-Version",
249  
"Encoding",
249  
"Encoding",
250  
"Encrypted",
250  
"Encrypted",
251  
"Errors-To",
251  
"Errors-To",
252  
"ETag",
252  
"ETag",
253  
"Expect",
253  
"Expect",
254  
"Expires",
254  
"Expires",
255  
"Expiry-Date",
255  
"Expiry-Date",
256  
"Ext",
256  
"Ext",
257  
"Followup-To",
257  
"Followup-To",
258  
"Forwarded",
258  
"Forwarded",
259  
"From",
259  
"From",
260  
"Generate-Delivery-Report",
260  
"Generate-Delivery-Report",
261  
"GetProfile",
261  
"GetProfile",
262  
"Hobareg",
262  
"Hobareg",
263  
"Host",
263  
"Host",
264  
"HTTP2-Settings",
264  
"HTTP2-Settings",
265  
"If",
265  
"If",
266  
"If-Match",
266  
"If-Match",
267  
"If-Modified-Since",
267  
"If-Modified-Since",
268  
"If-None-Match",
268  
"If-None-Match",
269  
"If-Range",
269  
"If-Range",
270  
"If-Schedule-Tag-Match",
270  
"If-Schedule-Tag-Match",
271  
"If-Unmodified-Since",
271  
"If-Unmodified-Since",
272  
"IM",
272  
"IM",
273  
"Importance",
273  
"Importance",
274  
"In-Reply-To",
274  
"In-Reply-To",
275  
"Incomplete-Copy",
275  
"Incomplete-Copy",
276  
"Injection-Date",
276  
"Injection-Date",
277  
"Injection-Info",
277  
"Injection-Info",
278  
"Jabber-ID",
278  
"Jabber-ID",
279  
"Keep-Alive",
279  
"Keep-Alive",
280  
"Keywords",
280  
"Keywords",
281  
"Label",
281  
"Label",
282  
"Language",
282  
"Language",
283  
"Last-Modified",
283  
"Last-Modified",
284  
"Latest-Delivery-Time",
284  
"Latest-Delivery-Time",
285  
"Lines",
285  
"Lines",
286  
"Link",
286  
"Link",
287  
"List-Archive",
287  
"List-Archive",
288  
"List-Help",
288  
"List-Help",
289  
"List-ID",
289  
"List-ID",
290  
"List-Owner",
290  
"List-Owner",
291  
"List-Post",
291  
"List-Post",
292  
"List-Subscribe",
292  
"List-Subscribe",
293  
"List-Unsubscribe",
293  
"List-Unsubscribe",
294  
"List-Unsubscribe-Post",
294  
"List-Unsubscribe-Post",
295  
"Location",
295  
"Location",
296  
"Lock-Token",
296  
"Lock-Token",
297  
"Man",
297  
"Man",
298  
"Max-Forwards",
298  
"Max-Forwards",
299  
"Memento-Datetime",
299  
"Memento-Datetime",
300  
"Message-Context",
300  
"Message-Context",
301  
"Message-ID",
301  
"Message-ID",
302  
"Message-Type",
302  
"Message-Type",
303  
"Meter",
303  
"Meter",
304  
"Method-Check",
304  
"Method-Check",
305  
"Method-Check-Expires",
305  
"Method-Check-Expires",
306  
"MIME-Version",
306  
"MIME-Version",
307  
"MMHS-Acp127-Message-Identifier",
307  
"MMHS-Acp127-Message-Identifier",
308  
"MMHS-Authorizing-Users",
308  
"MMHS-Authorizing-Users",
309  
"MMHS-Codress-Message-Indicator",
309  
"MMHS-Codress-Message-Indicator",
310  
"MMHS-Copy-Precedence",
310  
"MMHS-Copy-Precedence",
311  
"MMHS-Exempted-Address",
311  
"MMHS-Exempted-Address",
312  
"MMHS-Extended-Authorisation-Info",
312  
"MMHS-Extended-Authorisation-Info",
313  
"MMHS-Handling-Instructions",
313  
"MMHS-Handling-Instructions",
314  
"MMHS-Message-Instructions",
314  
"MMHS-Message-Instructions",
315  
"MMHS-Message-Type",
315  
"MMHS-Message-Type",
316  
"MMHS-Originator-PLAD",
316  
"MMHS-Originator-PLAD",
317  
"MMHS-Originator-Reference",
317  
"MMHS-Originator-Reference",
318  
"MMHS-Other-Recipients-Indicator-CC",
318  
"MMHS-Other-Recipients-Indicator-CC",
319  
"MMHS-Other-Recipients-Indicator-To",
319  
"MMHS-Other-Recipients-Indicator-To",
320  
"MMHS-Primary-Precedence",
320  
"MMHS-Primary-Precedence",
321  
"MMHS-Subject-Indicator-Codes",
321  
"MMHS-Subject-Indicator-Codes",
322  
"MT-Priority",
322  
"MT-Priority",
323  
"Negotiate",
323  
"Negotiate",
324  
"Newsgroups",
324  
"Newsgroups",
325  
"NNTP-Posting-Date",
325  
"NNTP-Posting-Date",
326  
"NNTP-Posting-Host",
326  
"NNTP-Posting-Host",
327  
"Non-Compliance",
327  
"Non-Compliance",
328  
"Obsoletes",
328  
"Obsoletes",
329  
"Opt",
329  
"Opt",
330  
"Optional",
330  
"Optional",
331  
"Optional-WWW-Authenticate",
331  
"Optional-WWW-Authenticate",
332  
"Ordering-Type",
332  
"Ordering-Type",
333  
"Organization",
333  
"Organization",
334  
"Origin",
334  
"Origin",
335  
"Original-Encoded-Information-Types",
335  
"Original-Encoded-Information-Types",
336  
"Original-From",
336  
"Original-From",
337  
"Original-Message-ID",
337  
"Original-Message-ID",
338  
"Original-Recipient",
338  
"Original-Recipient",
339  
"Original-Sender",
339  
"Original-Sender",
340  
"Original-Subject",
340  
"Original-Subject",
341  
"Originator-Return-Address",
341  
"Originator-Return-Address",
342  
"Overwrite",
342  
"Overwrite",
343  
"P3P",
343  
"P3P",
344  
"Path",
344  
"Path",
345  
"PEP",
345  
"PEP",
346  
"Pep-Info",
346  
"Pep-Info",
347  
"PICS-Label",
347  
"PICS-Label",
348  
"Position",
348  
"Position",
349  
"Posting-Version",
349  
"Posting-Version",
350  
"Pragma",
350  
"Pragma",
351  
"Prefer",
351  
"Prefer",
352  
"Preference-Applied",
352  
"Preference-Applied",
353  
"Prevent-NonDelivery-Report",
353  
"Prevent-NonDelivery-Report",
354  
"Priority",
354  
"Priority",
355  
"Privicon",
355  
"Privicon",
356  
"ProfileObject",
356  
"ProfileObject",
357  
"Protocol",
357  
"Protocol",
358  
"Protocol-Info",
358  
"Protocol-Info",
359  
"Protocol-Query",
359  
"Protocol-Query",
360  
"Protocol-Request",
360  
"Protocol-Request",
361  
"Proxy-Authenticate",
361  
"Proxy-Authenticate",
362  
"Proxy-Authentication-Info",
362  
"Proxy-Authentication-Info",
363  
"Proxy-Authorization",
363  
"Proxy-Authorization",
364  
"Proxy-Connection",
364  
"Proxy-Connection",
365  
"Proxy-Features",
365  
"Proxy-Features",
366  
"Proxy-Instruction",
366  
"Proxy-Instruction",
367  
"Public",
367  
"Public",
368  
"Public-Key-Pins",
368  
"Public-Key-Pins",
369  
"Public-Key-Pins-Report-Only",
369  
"Public-Key-Pins-Report-Only",
370  
"Range",
370  
"Range",
371  
"Received",
371  
"Received",
372  
"Received-SPF",
372  
"Received-SPF",
373  
"Redirect-Ref",
373  
"Redirect-Ref",
374  
"References",
374  
"References",
375  
"Referer",
375  
"Referer",
376  
"Referer-Root",
376  
"Referer-Root",
377  
"Relay-Version",
377  
"Relay-Version",
378  
"Reply-By",
378  
"Reply-By",
379  
"Reply-To",
379  
"Reply-To",
380  
"Require-Recipient-Valid-Since",
380  
"Require-Recipient-Valid-Since",
381  
"Resent-Bcc",
381  
"Resent-Bcc",
382  
"Resent-Cc",
382  
"Resent-Cc",
383  
"Resent-Date",
383  
"Resent-Date",
384  
"Resent-From",
384  
"Resent-From",
385  
"Resent-Message-ID",
385  
"Resent-Message-ID",
386  
"Resent-Reply-To",
386  
"Resent-Reply-To",
387  
"Resent-Sender",
387  
"Resent-Sender",
388  
"Resent-To",
388  
"Resent-To",
389  
"Resolution-Hint",
389  
"Resolution-Hint",
390  
"Resolver-Location",
390  
"Resolver-Location",
391  
"Retry-After",
391  
"Retry-After",
392  
"Return-Path",
392  
"Return-Path",
393  
"Safe",
393  
"Safe",
394  
"Schedule-Reply",
394  
"Schedule-Reply",
395  
"Schedule-Tag",
395  
"Schedule-Tag",
396  
"Sec-Fetch-Dest",
396  
"Sec-Fetch-Dest",
397  
"Sec-Fetch-Mode",
397  
"Sec-Fetch-Mode",
398  
"Sec-Fetch-Site",
398  
"Sec-Fetch-Site",
399  
"Sec-Fetch-User",
399  
"Sec-Fetch-User",
400  
"Sec-WebSocket-Accept",
400  
"Sec-WebSocket-Accept",
401  
"Sec-WebSocket-Extensions",
401  
"Sec-WebSocket-Extensions",
402  
"Sec-WebSocket-Key",
402  
"Sec-WebSocket-Key",
403  
"Sec-WebSocket-Protocol",
403  
"Sec-WebSocket-Protocol",
404  
"Sec-WebSocket-Version",
404  
"Sec-WebSocket-Version",
405  
"Security-Scheme",
405  
"Security-Scheme",
406  
"See-Also",
406  
"See-Also",
407  
"Sender",
407  
"Sender",
408  
"Sensitivity",
408  
"Sensitivity",
409  
"Server",
409  
"Server",
410  
"Set-Cookie",
410  
"Set-Cookie",
411  
"Set-Cookie2",
411  
"Set-Cookie2",
412  
"SetProfile",
412  
"SetProfile",
413  
"SIO-Label",
413  
"SIO-Label",
414  
"SIO-Label-History",
414  
"SIO-Label-History",
415  
"SLUG",
415  
"SLUG",
416  
"SoapAction",
416  
"SoapAction",
417  
"Solicitation",
417  
"Solicitation",
418  
"Status-URI",
418  
"Status-URI",
419  
"Strict-Transport-Security",
419  
"Strict-Transport-Security",
420  
"Subject",
420  
"Subject",
421  
"SubOK",
421  
"SubOK",
422  
"Subst",
422  
"Subst",
423  
"Summary",
423  
"Summary",
424  
"Supersedes",
424  
"Supersedes",
425  
"Surrogate-Capability",
425  
"Surrogate-Capability",
426  
"Surrogate-Control",
426  
"Surrogate-Control",
427  
"TCN",
427  
"TCN",
428  
"TE",
428  
"TE",
429  
"Timeout",
429  
"Timeout",
430  
"Title",
430  
"Title",
431  
"To",
431  
"To",
432  
"Topic",
432  
"Topic",
433  
"Trailer",
433  
"Trailer",
434  
"Transfer-Encoding",
434  
"Transfer-Encoding",
435  
"TTL",
435  
"TTL",
436  
"UA-Color",
436  
"UA-Color",
437  
"UA-Media",
437  
"UA-Media",
438  
"UA-Pixels",
438  
"UA-Pixels",
439  
"UA-Resolution",
439  
"UA-Resolution",
440  
"UA-Windowpixels",
440  
"UA-Windowpixels",
441  
"Upgrade",
441  
"Upgrade",
442  
"Urgency",
442  
"Urgency",
443  
"URI",
443  
"URI",
444  
"User-Agent",
444  
"User-Agent",
445  
"Variant-Vary",
445  
"Variant-Vary",
446  
"Vary",
446  
"Vary",
447  
"VBR-Info",
447  
"VBR-Info",
448  
"Version",
448  
"Version",
449  
"Via",
449  
"Via",
450  
"Want-Digest",
450  
"Want-Digest",
451  
"Warning",
451  
"Warning",
452  
"WWW-Authenticate",
452  
"WWW-Authenticate",
453  
"X-Archived-At",
453  
"X-Archived-At",
454  
"X-Device-Accept",
454  
"X-Device-Accept",
455  
"X-Device-Accept-Charset",
455  
"X-Device-Accept-Charset",
456  
"X-Device-Accept-Encoding",
456  
"X-Device-Accept-Encoding",
457  
"X-Device-Accept-Language",
457  
"X-Device-Accept-Language",
458  
"X-Device-User-Agent",
458  
"X-Device-User-Agent",
459  
"X-Frame-Options",
459  
"X-Frame-Options",
460  
"X-Mittente",
460  
"X-Mittente",
461  
"X-PGP-Sig",
461  
"X-PGP-Sig",
462  
"X-Ricevuta",
462  
"X-Ricevuta",
463  
"X-Riferimento-Message-ID",
463  
"X-Riferimento-Message-ID",
464  
"X-TipoRicevuta",
464  
"X-TipoRicevuta",
465  
"X-Trasporto",
465  
"X-Trasporto",
466  
"X-VerificaSicurezza",
466  
"X-VerificaSicurezza",
467  
"X400-Content-Identifier",
467  
"X400-Content-Identifier",
468  
"X400-Content-Return",
468  
"X400-Content-Return",
469  
"X400-Content-Type",
469  
"X400-Content-Type",
470  
"X400-MTS-Identifier",
470  
"X400-MTS-Identifier",
471  
"X400-Originator",
471  
"X400-Originator",
472  
"X400-Received",
472  
"X400-Received",
473  
"X400-Recipients",
473  
"X400-Recipients",
474  
"X400-Trace",
474  
"X400-Trace",
475  
"Xref"
475  
"Xref"
476  
        }})
476  
        }})
477  
    {
477  
    {
478  
        for(std::size_t i = 1, n = 256; i < n; ++i)
478  
        for(std::size_t i = 1, n = 256; i < n; ++i)
479  
        {
479  
        {
480  
            auto sv = by_name_[ i ];
480  
            auto sv = by_name_[ i ];
481  
            auto h = digest(sv);
481  
            auto h = digest(sv);
482  
            auto j = h % N;
482  
            auto j = h % N;
483  
            BOOST_ASSERT(map_[j][0] == 0);
483  
            BOOST_ASSERT(map_[j][0] == 0);
484  
            map_[j][0] = static_cast<unsigned char>(i);
484  
            map_[j][0] = static_cast<unsigned char>(i);
485  
        }
485  
        }
486  

486  

487  
        for(std::size_t i = 256, n = by_name_.size(); i < n; ++i)
487  
        for(std::size_t i = 256, n = by_name_.size(); i < n; ++i)
488  
        {
488  
        {
489  
            auto sv = by_name_[i];
489  
            auto sv = by_name_[i];
490  
            auto h = digest(sv);
490  
            auto h = digest(sv);
491  
            auto j = h % N;
491  
            auto j = h % N;
492  
            BOOST_ASSERT(map_[j][1] == 0);
492  
            BOOST_ASSERT(map_[j][1] == 0);
493  
            map_[j][1] = static_cast<unsigned char>(i - 255);
493  
            map_[j][1] = static_cast<unsigned char>(i - 255);
494  
        }
494  
        }
495  
    }
495  
    }
496  

496  

497  
    optional<field>
497  
    optional<field>
498  
    string_to_field(
498  
    string_to_field(
499  
        core::string_view s) const noexcept
499  
        core::string_view s) const noexcept
500  
    {
500  
    {
501  
        auto h = digest(s);
501  
        auto h = digest(s);
502  
        auto j = h % N;
502  
        auto j = h % N;
503  
        int i = map_[j][0];
503  
        int i = map_[j][0];
504  
        core::string_view s2 = by_name_[i];
504  
        core::string_view s2 = by_name_[i];
505  
        if(i != 0 && equals(s, s2))
505  
        if(i != 0 && equals(s, s2))
506  
            return static_cast<field>(i);
506  
            return static_cast<field>(i);
507  
        i = map_[j][1];
507  
        i = map_[j][1];
508  
        if(i == 0)
508  
        if(i == 0)
509  
            return boost::none;
509  
            return boost::none;
510  
        i += 255;
510  
        i += 255;
511  
        s2 = by_name_[i];
511  
        s2 = by_name_[i];
512  

512  

513  
        if(equals(s, s2))
513  
        if(equals(s, s2))
514  
            return static_cast<field>(i);
514  
            return static_cast<field>(i);
515  
        return boost::none;
515  
        return boost::none;
516  
    }
516  
    }
517  

517  

518  
    //
518  
    //
519  
    // Deprecated
519  
    // Deprecated
520  
    //
520  
    //
521  

521  

522  
    using const_iterator =
522  
    using const_iterator =
523  
    array_type::const_iterator; 
523  
    array_type::const_iterator; 
524  

524  

525  
    std::size_t
525  
    std::size_t
526  
    size() const
526  
    size() const
527  
    {
527  
    {
528  
        return by_name_.size();
528  
        return by_name_.size();
529  
    }
529  
    }
530  

530  

531  
    const_iterator
531  
    const_iterator
532  
    begin() const
532  
    begin() const
533  
    {
533  
    {
534  
        return by_name_.begin();
534  
        return by_name_.begin();
535  
    }
535  
    }
536  

536  

537  
    const_iterator
537  
    const_iterator
538  
    end() const
538  
    end() const
539  
    {
539  
    {
540  
        return by_name_.end();
540  
        return by_name_.end();
541  
    }
541  
    }
542  
};
542  
};
543  

543  

544  
static
544  
static
545  
field_table const&
545  
field_table const&
546  
get_field_table() noexcept
546  
get_field_table() noexcept
547  
{
547  
{
548  
    static field_table const tab;
548  
    static field_table const tab;
549  
    return tab;
549  
    return tab;
550  
}
550  
}
551  

551  

552  
} // detail
552  
} // detail
553  

553  

554  
core::string_view
554  
core::string_view
555  
to_string(field f)
555  
to_string(field f)
556  
{
556  
{
557  
    auto const& v = detail::get_field_table();
557  
    auto const& v = detail::get_field_table();
558  
    BOOST_ASSERT(static_cast<unsigned>(f) < v.size());
558  
    BOOST_ASSERT(static_cast<unsigned>(f) < v.size());
559  
    return v.begin()[static_cast<unsigned>(f)];
559  
    return v.begin()[static_cast<unsigned>(f)];
560  
}
560  
}
561  

561  

562  
boost::optional<field>
562  
boost::optional<field>
563  
string_to_field(
563  
string_to_field(
564  
    core::string_view s) noexcept
564  
    core::string_view s) noexcept
565  
{
565  
{
566  
    return detail::get_field_table().string_to_field(s);
566  
    return detail::get_field_table().string_to_field(s);
567  
}
567  
}
568  

568  

569  
std::ostream&
569  
std::ostream&
570  
operator<<(std::ostream& os, field f)
570  
operator<<(std::ostream& os, field f)
571  
{
571  
{
572  
    return os << to_string(f);
572  
    return os << to_string(f);
573  
}
573  
}
574  

574  

575  
} // http
575  
} // http
576  
} // boost
576  
} // boost