diff --git a/CHANGELOG.md b/CHANGELOG.md
index cc0f1698..fe6ee02c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
Version 50
* parser is constructible from other body types
+* Add field enumeration
API Changes:
diff --git a/doc/quickref.xml b/doc/quickref.xml
index 339413c6..3a290303 100644
--- a/doc/quickref.xml
+++ b/doc/quickref.xml
@@ -66,6 +66,7 @@
read
read_header
read_some
+ string_to_field
string_to_verb
swap
to_string
@@ -86,6 +87,7 @@
connection
error
+ field
status
status_class
verb
diff --git a/include/beast/http/buffer_body.hpp b/include/beast/http/buffer_body.hpp
index 35cf4cae..1f6fc1f1 100644
--- a/include/beast/http/buffer_body.hpp
+++ b/include/beast/http/buffer_body.hpp
@@ -8,6 +8,7 @@
#ifndef BEAST_HTTP_BUFFER_BODY_HPP
#define BEAST_HTTP_BUFFER_BODY_HPP
+#include
#include
#include
#include
diff --git a/include/beast/http/field.hpp b/include/beast/http/field.hpp
new file mode 100644
index 00000000..252f685d
--- /dev/null
+++ b/include/beast/http/field.hpp
@@ -0,0 +1,354 @@
+//
+// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BEAST_HTTP_FIELD_HPP
+#define BEAST_HTTP_FIELD_HPP
+
+#include
+#include
+#include
+
+namespace beast {
+namespace http {
+
+enum class field : unsigned short
+{
+ unknown = 0,
+
+ a_im,
+ accept,
+ accept_additions,
+ accept_charset,
+ accept_datetime,
+ accept_encoding,
+ accept_features,
+ accept_language,
+ accept_patch,
+ accept_post,
+ accept_ranges,
+ age,
+ allow,
+ alpn,
+ also_control,
+ alt_svc,
+ alt_used,
+ alternate_recipient,
+ alternates,
+ apply_to_redirect_ref,
+ approved,
+ archive,
+ archived_at,
+ article_names,
+ article_updates,
+ authentication_control,
+ authentication_info,
+ authentication_results,
+ authorization,
+ auto_submitted,
+ autoforwarded,
+ autosubmitted,
+ base,
+ bcc,
+ body,
+ c_ext,
+ c_man,
+ c_opt,
+ c_pep,
+ c_pep_info,
+ cache_control,
+ caldav_timezones,
+ cc,
+ close,
+ comments,
+ connection,
+ content_alternative,
+ content_base,
+ content_description,
+ content_disposition,
+ content_duration,
+ content_encoding,
+ content_features,
+ content_id,
+ content_identifier,
+ content_language,
+ content_length,
+ content_location,
+ content_md5,
+ content_range,
+ content_return,
+ content_script_type,
+ content_style_type,
+ content_transfer_encoding,
+ content_type,
+ content_version,
+ control,
+ conversion,
+ conversion_with_loss,
+ cookie,
+ cookie2,
+ dasl,
+ date,
+ date_received,
+ dav,
+ default_style,
+ deferred_delivery,
+ delivery_date,
+ delta_base,
+ depth,
+ derived_from,
+ destination,
+ differential_id,
+ digest,
+ discarded_x400_ipms_extensions,
+ discarded_x400_mts_extensions,
+ disclose_recipients,
+ disposition_notification_options,
+ disposition_notification_to,
+ distribution,
+ dkim_signature,
+ dl_expansion_history,
+ downgraded_bcc,
+ downgraded_cc,
+ downgraded_disposition_notification_to,
+ downgraded_final_recipient,
+ downgraded_from,
+ downgraded_in_reply_to,
+ downgraded_mail_from,
+ downgraded_message_id,
+ downgraded_original_recipient,
+ downgraded_rcpt_to,
+ downgraded_references,
+ downgraded_reply_to,
+ downgraded_resent_bcc,
+ downgraded_resent_cc,
+ downgraded_resent_from,
+ downgraded_resent_reply_to,
+ downgraded_resent_sender,
+ downgraded_resent_to,
+ downgraded_return_path,
+ downgraded_sender,
+ downgraded_to,
+ encoding,
+ encrypted,
+ etag,
+ expect,
+ expires,
+ expiry_date,
+ ext,
+ followup_to,
+ forwarded,
+ from,
+ generate_delivery_report,
+ getprofile,
+ hobareg,
+ host,
+ http2_settings,
+ if_,
+ if_match,
+ if_modified_since,
+ if_none_match,
+ if_range,
+ if_schedule_tag_match,
+ if_unmodified_since,
+ im,
+ importance,
+ in_reply_to,
+ incomplete_copy,
+ injection_date,
+ injection_info,
+ keep_alive,
+ keywords,
+ label,
+ language,
+ last_modified,
+ latest_delivery_time,
+ lines,
+ link,
+ list_archive,
+ list_help,
+ list_id,
+ list_owner,
+ list_post,
+ list_subscribe,
+ list_unsubscribe,
+ list_unsubscribe_post,
+ location,
+ lock_token,
+ man,
+ max_forwards,
+ memento_datetime,
+ message_context,
+ message_id,
+ message_type,
+ meter,
+ mime_version,
+ mmhs_acp127_message_identifier,
+ mmhs_codress_message_indicator,
+ mmhs_copy_precedence,
+ mmhs_exempted_address,
+ mmhs_extended_authorisation_info,
+ mmhs_handling_instructions,
+ mmhs_message_instructions,
+ mmhs_message_type,
+ mmhs_originator_plad,
+ mmhs_originator_reference,
+ mmhs_other_recipients_indicator_cc,
+ mmhs_other_recipients_indicator_to,
+ mmhs_primary_precedence,
+ mmhs_subject_indicator_codes,
+ mt_priority,
+ negotiate,
+ newsgroups,
+ nntp_posting_date,
+ nntp_posting_host,
+ obsoletes,
+ opt,
+ optional_www_authenticate,
+ ordering_type,
+ organization,
+ origin,
+ original_encoded_information_types,
+ original_from,
+ original_message_id,
+ original_recipient,
+ original_sender,
+ original_subject,
+ originator_return_address,
+ overwrite,
+ p3p,
+ path,
+ pep,
+ pep_info,
+ pics_label,
+ position,
+ posting_version,
+ pragma,
+ prefer,
+ preference_applied,
+ prevent_nondelivery_report,
+ priority,
+ profileobject,
+ protocol,
+ protocol_info,
+ protocol_query,
+ protocol_request,
+ proxy_authenticate,
+ proxy_authentication_info,
+ proxy_authorization,
+ proxy_features,
+ proxy_instruction,
+ public_,
+ public_key_pins,
+ public_key_pins_report_only,
+ range,
+ received,
+ received_spf,
+ redirect_ref,
+ references,
+ referer,
+ relay_version,
+ reply_by,
+ reply_to,
+ require_recipient_valid_since,
+ resent_bcc,
+ resent_cc,
+ resent_date,
+ resent_from,
+ resent_message_id,
+ resent_reply_to,
+ resent_sender,
+ resent_to,
+ retry_after,
+ return_path,
+ safe,
+ schedule_reply,
+ schedule_tag,
+ sec_websocket_accept,
+ sec_websocket_extensions,
+ sec_websocket_key,
+ sec_websocket_protocol,
+ sec_websocket_version,
+ security_scheme,
+ see_also,
+ sender,
+ sensitivity,
+ server,
+ set_cookie,
+ set_cookie2,
+ setprofile,
+ slug,
+ soapaction,
+ solicitation,
+ status_uri,
+ strict_transport_security,
+ subject,
+ summary,
+ supersedes,
+ surrogate_capability,
+ surrogate_control,
+ tcn,
+ te,
+ timeout,
+ to,
+ topic,
+ trailer,
+ transfer_encoding,
+ ttl,
+ upgrade,
+ urgency,
+ uri,
+ user_agent,
+ variant_vary,
+ vary,
+ vbr_info,
+ via,
+ want_digest,
+ warning,
+ www_authenticate,
+ x_frame_options,
+ x400_content_identifier,
+ x400_content_return,
+ x400_content_type,
+ x400_mts_identifier,
+ x400_originator,
+ x400_received,
+ x400_recipients,
+ x400_trace,
+ xref,
+};
+
+/** Convert a field enum to a string.
+
+ @param f The field to convert
+*/
+string_view
+to_string(field f);
+
+/** Attempt to convert a string to a field enum.
+
+ The string comparison is case-insensitive.
+
+ @return The corresponding field, or @ref field::unknown
+ if no known field matches.
+*/
+field
+string_to_field(string_view s);
+
+/// Write the text for a field name to an output stream.
+inline
+std::ostream&
+operator<<(std::ostream& os, field f)
+{
+ return os << to_string(f);
+}
+
+} // http
+} // beast
+
+#include
+
+#endif
diff --git a/include/beast/http/impl/field.ipp b/include/beast/http/impl/field.ipp
new file mode 100644
index 00000000..c88d36ad
--- /dev/null
+++ b/include/beast/http/impl/field.ipp
@@ -0,0 +1,416 @@
+//
+// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BEAST_HTTP_IMPL_FIELD_IPP
+#define BEAST_HTTP_IMPL_FIELD_IPP
+
+#include
+#include
+#include
+#include
+
+namespace beast {
+namespace http {
+
+namespace detail {
+
+class field_strings
+{
+ using array_type =
+ std::array;
+
+ array_type v_;
+
+public:
+ using const_iterator =
+ array_type::const_iterator;
+
+/*
+ From:
+
+ https://www.iana.org/assignments/message-headers/message-headers.xhtml
+*/
+ field_strings()
+ : v_({{
+ "",
+ "A-IM",
+ "Accept",
+ "Accept-Additions",
+ "Accept-Charset",
+ "Accept-Datetime",
+ "Accept-Encoding",
+ "Accept-Features",
+ "Accept-Language",
+ "Accept-Patch",
+ "Accept-Post",
+ "Accept-Ranges",
+ "Age",
+ "Allow",
+ "ALPN",
+ "Also-Control",
+ "Alt-Svc",
+ "Alt-Used",
+ "Alternate-Recipient",
+ "Alternates",
+ "Apply-To-Redirect-Ref",
+ "Approved",
+ "Archive",
+ "Archived-At",
+ "Article-Names",
+ "Article-Updates",
+ "Authentication-Control",
+ "Authentication-Info",
+ "Authentication-Results",
+ "Authorization",
+ "Auto-Submitted",
+ "Autoforwarded",
+ "Autosubmitted",
+ "Base",
+ "Bcc",
+ "Body",
+ "C-Ext",
+ "C-Man",
+ "C-Opt",
+ "C-PEP",
+ "C-PEP-Info",
+ "Cache-Control",
+ "CalDAV-Timezones",
+ "Cc",
+ "Close",
+ "Comments",
+ "Connection",
+ "Content-Alternative",
+ "Content-Base",
+ "Content-Description",
+ "Content-Disposition",
+ "Content-Duration",
+ "Content-Encoding",
+ "Content-features",
+ "Content-ID",
+ "Content-Identifier",
+ "Content-Language",
+ "Content-Length",
+ "Content-Location",
+ "Content-MD5",
+ "Content-Range",
+ "Content-Return",
+ "Content-Script-Type",
+ "Content-Style-Type",
+ "Content-Transfer-Encoding",
+ "Content-Type",
+ "Content-Version",
+ "Control",
+ "Conversion",
+ "Conversion-With-Loss",
+ "Cookie",
+ "Cookie2",
+ "DASL",
+ "Date",
+ "Date-Received",
+ "DAV",
+ "Default-Style",
+ "Deferred-Delivery",
+ "Delivery-Date",
+ "Delta-Base",
+ "Depth",
+ "Derived-From",
+ "Destination",
+ "Differential-ID",
+ "Digest",
+ "Discarded-X400-IPMS-Extensions",
+ "Discarded-X400-MTS-Extensions",
+ "Disclose-Recipients",
+ "Disposition-Notification-Options",
+ "Disposition-Notification-To",
+ "Distribution",
+ "DKIM-Signature",
+ "DL-Expansion-History",
+ "Downgraded-Bcc",
+ "Downgraded-Cc",
+ "Downgraded-Disposition-Notification-To",
+ "Downgraded-Final-Recipient",
+ "Downgraded-From",
+ "Downgraded-In-Reply-To",
+ "Downgraded-Mail-From",
+ "Downgraded-Message-Id",
+ "Downgraded-Original-Recipient",
+ "Downgraded-Rcpt-To",
+ "Downgraded-References",
+ "Downgraded-Reply-To",
+ "Downgraded-Resent-Bcc",
+ "Downgraded-Resent-Cc",
+ "Downgraded-Resent-From",
+ "Downgraded-Resent-Reply-To",
+ "Downgraded-Resent-Sender",
+ "Downgraded-Resent-To",
+ "Downgraded-Return-Path",
+ "Downgraded-Sender",
+ "Downgraded-To",
+ "Encoding",
+ "Encrypted",
+ "ETag",
+ "Expect",
+ "Expires",
+ "Expiry-Date",
+ "Ext",
+ "Followup-To",
+ "Forwarded",
+ "From",
+ "Generate-Delivery-Report",
+ "GetProfile",
+ "Hobareg",
+ "Host",
+ "HTTP2-Settings",
+ "If",
+ "If-Match",
+ "If-Modified-Since",
+ "If-None-Match",
+ "If-Range",
+ "If-Schedule-Tag-Match",
+ "If-Unmodified-Since",
+ "IM",
+ "Importance",
+ "In-Reply-To",
+ "Incomplete-Copy",
+ "Injection-Date",
+ "Injection-Info",
+ "Keep-Alive",
+ "Keywords",
+ "Label",
+ "Language",
+ "Last-Modified",
+ "Latest-Delivery-Time",
+ "Lines",
+ "Link",
+ "List-Archive",
+ "List-Help",
+ "List-ID",
+ "List-Owner",
+ "List-Post",
+ "List-Subscribe",
+ "List-Unsubscribe",
+ "List-Unsubscribe-Post",
+ "Location",
+ "Lock-Token",
+ "Man",
+ "Max-Forwards",
+ "Memento-Datetime",
+ "Message-Context",
+ "Message-ID",
+ "Message-Type",
+ "Meter",
+ "MIME-Version",
+ "MMHS-Acp127-Message-Identifier",
+ "MMHS-Codress-Message-Indicator",
+ "MMHS-Copy-Precedence",
+ "MMHS-Exempted-Address",
+ "MMHS-Extended-Authorisation-Info",
+ "MMHS-Handling-Instructions",
+ "MMHS-Message-Instructions",
+ "MMHS-Message-Type",
+ "MMHS-Originator-PLAD",
+ "MMHS-Originator-Reference",
+ "MMHS-Other-Recipients-Indicator-CC",
+ "MMHS-Other-Recipients-Indicator-To",
+ "MMHS-Primary-Precedence",
+ "MMHS-Subject-Indicator-Codes",
+ "MT-Priority",
+ "Negotiate",
+ "Newsgroups",
+ "NNTP-Posting-Date",
+ "NNTP-Posting-Host",
+ "Obsoletes",
+ "Opt",
+ "Optional-WWW-Authenticate",
+ "Ordering-Type",
+ "Organization",
+ "Origin",
+ "Original-Encoded-Information-Types",
+ "Original-From",
+ "Original-Message-ID",
+ "Original-Recipient",
+ "Original-Sender",
+ "Original-Subject",
+ "Originator-Return-Address",
+ "Overwrite",
+ "P3P",
+ "Path",
+ "PEP",
+ "Pep-Info",
+ "PICS-Label",
+ "Position",
+ "Posting-Version",
+ "Pragma",
+ "Prefer",
+ "Preference-Applied",
+ "Prevent-NonDelivery-Report",
+ "Priority",
+ "ProfileObject",
+ "Protocol",
+ "Protocol-Info",
+ "Protocol-Query",
+ "Protocol-Request",
+ "Proxy-Authenticate",
+ "Proxy-Authentication-Info",
+ "Proxy-Authorization",
+ "Proxy-Features",
+ "Proxy-Instruction",
+ "Public",
+ "Public-Key-Pins",
+ "Public-Key-Pins-Report-Only",
+ "Range",
+ "Received",
+ "Received-SPF",
+ "Redirect-Ref",
+ "References",
+ "Referer",
+ "Relay-Version",
+ "Reply-By",
+ "Reply-To",
+ "Require-Recipient-Valid-Since",
+ "Resent-Bcc",
+ "Resent-Cc",
+ "Resent-Date",
+ "Resent-From",
+ "Resent-Message-ID",
+ "Resent-Reply-To",
+ "Resent-Sender",
+ "Resent-To",
+ "Retry-After",
+ "Return-Path",
+ "Safe",
+ "Schedule-Reply",
+ "Schedule-Tag",
+ "Sec-WebSocket-Accept",
+ "Sec-WebSocket-Extensions",
+ "Sec-WebSocket-Key",
+ "Sec-WebSocket-Protocol",
+ "Sec-WebSocket-Version",
+ "Security-Scheme",
+ "See-Also",
+ "Sender",
+ "Sensitivity",
+ "Server",
+ "Set-Cookie",
+ "Set-Cookie2",
+ "SetProfile",
+ "SLUG",
+ "SoapAction",
+ "Solicitation",
+ "Status-URI",
+ "Strict-Transport-Security",
+ "Subject",
+ "Summary",
+ "Supersedes",
+ "Surrogate-Capability",
+ "Surrogate-Control",
+ "TCN",
+ "TE",
+ "Timeout",
+ "To",
+ "Topic",
+ "Trailer",
+ "Transfer-Encoding",
+ "TTL",
+ "Upgrade",
+ "Urgency",
+ "URI",
+ "User-Agent",
+ "Variant-Vary",
+ "Vary",
+ "VBR-Info",
+ "Via",
+ "Want-Digest",
+ "Warning",
+ "WWW-Authenticate",
+ "X-Frame-Options",
+ "X400-Content-Identifier",
+ "X400-Content-Return",
+ "X400-Content-Type",
+ "X400-MTS-Identifier",
+ "X400-Originator",
+ "X400-Received",
+ "X400-Recipients",
+ "X400-Trace",
+ "Xref",
+ }})
+ {
+ }
+
+ std::size_t
+ size() const
+ {
+ return v_.size();
+ }
+
+ const_iterator
+ begin() const
+ {
+ return v_.begin();
+ }
+
+ const_iterator
+ end() const
+ {
+ return v_.end();
+ }
+};
+
+inline
+field_strings const&
+get_field_strings()
+{
+ static field_strings const fs;
+ return fs;
+}
+
+template
+string_view
+to_string(field f)
+{
+ auto const& v = get_field_strings();
+ BOOST_ASSERT(static_cast(f) < v.size());
+ return v.begin()[static_cast(f)];
+}
+
+template
+field
+string_to_field(string_view s)
+{
+ auto const& v = get_field_strings();
+ auto const it = std::lower_bound(
+ v.begin(), v.end(), s,
+ beast::detail::ci_less{});
+ if(it == v.end())
+ return field::unknown;
+ if(! beast::detail::ci_equal(s, *it))
+ return field::unknown;
+ BOOST_ASSERT(beast::detail::ci_equal(s,
+ to_string(static_cast(it - v.begin()))));
+ return static_cast(it - v.begin());
+}
+
+} // detail
+
+inline
+string_view
+to_string(field f)
+{
+ return detail::to_string(f);
+}
+
+inline
+field
+string_to_field(string_view s)
+{
+ return detail::string_to_field(s);
+}
+
+} // http
+} // beast
+
+#endif
diff --git a/scripts/field.txt b/scripts/field.txt
new file mode 100644
index 00000000..46cc43ae
--- /dev/null
+++ b/scripts/field.txt
@@ -0,0 +1,327 @@
+A-IM
+Accept
+Accept-Additions
+Accept-Charset
+Accept-Datetime
+Accept-Encoding
+Accept-Features
+Accept-Language
+Accept-Language
+Accept-Patch
+Accept-Post
+Accept-Ranges
+Age
+Allow
+ALPN
+Also-Control
+Alt-Svc
+Alt-Used
+Alternate-Recipient
+Alternates
+Apply-To-Redirect-Ref
+Approved
+Archive
+Archived-At
+Archived-At
+Article-Names
+Article-Updates
+Authentication-Control
+Authentication-Info
+Authentication-Results
+Authorization
+Auto-Submitted
+Autoforwarded
+Autosubmitted
+Base
+Bcc
+Body
+C-Ext
+C-Man
+C-Opt
+C-PEP
+C-PEP-Info
+Cache-Control
+CalDAV-Timezones
+Cc
+Close
+Comments
+Comments
+Connection
+Content-Alternative
+Content-Base
+Content-Base
+Content-Description
+Content-Disposition
+Content-Disposition
+Content-Duration
+Content-Encoding
+Content-features
+Content-ID
+Content-ID
+Content-Identifier
+Content-Language
+Content-Language
+Content-Length
+Content-Location
+Content-Location
+Content-MD5
+Content-MD5
+Content-Range
+Content-Return
+Content-Script-Type
+Content-Style-Type
+Content-Transfer-Encoding
+Content-Type
+Content-Type
+Content-Version
+Control
+Conversion
+Conversion-With-Loss
+Cookie
+Cookie2
+DASL
+DAV
+DL-Expansion-History
+Date
+Date
+Date
+Date-Received
+Default-Style
+Deferred-Delivery
+Delivery-Date
+Delta-Base
+Depth
+Derived-From
+Destination
+Differential-ID
+Digest
+Discarded-X400-IPMS-Extensions
+Discarded-X400-MTS-Extensions
+Disclose-Recipients
+Disposition-Notification-Options
+Disposition-Notification-To
+Distribution
+DKIM-Signature
+Downgraded-Bcc
+Downgraded-Cc
+Downgraded-Disposition-Notification-To
+Downgraded-Final-Recipient
+Downgraded-From
+Downgraded-In-Reply-To
+Downgraded-Mail-From
+Downgraded-Message-Id
+Downgraded-Original-Recipient
+Downgraded-Rcpt-To
+Downgraded-References
+Downgraded-Reply-To
+Downgraded-Resent-Bcc
+Downgraded-Resent-Cc
+Downgraded-Resent-From
+Downgraded-Resent-Reply-To
+Downgraded-Resent-Sender
+Downgraded-Resent-To
+Downgraded-Return-Path
+Downgraded-Sender
+Downgraded-To
+Encoding
+Encrypted
+ETag
+Expect
+Expires
+Expires
+Expires
+Expiry-Date
+Ext
+Followup-To
+Forwarded
+From
+From
+From
+Generate-Delivery-Report
+GetProfile
+Hobareg
+Host
+HTTP2-Settings
+IM
+If
+If-Match
+If-Modified-Since
+If-None-Match
+If-Range
+If-Schedule-Tag-Match
+If-Unmodified-Since
+Importance
+In-Reply-To
+Incomplete-Copy
+Injection-Date
+Injection-Info
+Keep-Alive
+Keywords
+Keywords
+Label
+Language
+Last-Modified
+Latest-Delivery-Time
+Lines
+Link
+List-Archive
+List-Help
+List-ID
+List-Owner
+List-Post
+List-Subscribe
+List-Unsubscribe
+List-Unsubscribe-Post
+Location
+Lock-Token
+Man
+Max-Forwards
+Memento-Datetime
+Message-Context
+Message-ID
+Message-ID
+Message-Type
+Meter
+MIME-Version
+MIME-Version
+MMHS-Exempted-Address
+MMHS-Extended-Authorisation-Info
+MMHS-Subject-Indicator-Codes
+MMHS-Handling-Instructions
+MMHS-Message-Instructions
+MMHS-Codress-Message-Indicator
+MMHS-Originator-Reference
+MMHS-Primary-Precedence
+MMHS-Copy-Precedence
+MMHS-Message-Type
+MMHS-Other-Recipients-Indicator-To
+MMHS-Other-Recipients-Indicator-CC
+MMHS-Acp127-Message-Identifier
+MMHS-Originator-PLAD
+MT-Priority
+Negotiate
+Newsgroups
+NNTP-Posting-Date
+NNTP-Posting-Host
+Obsoletes
+Opt
+Optional-WWW-Authenticate
+Ordering-Type
+Organization
+Organization
+Origin
+Original-Encoded-Information-Types
+Original-From
+Original-Message-ID
+Original-Recipient
+Original-Sender
+Originator-Return-Address
+Original-Subject
+Overwrite
+P3P
+Path
+PEP
+PICS-Label
+PICS-Label
+Pep-Info
+Position
+Posting-Version
+Pragma
+Prefer
+Preference-Applied
+Prevent-NonDelivery-Report
+Priority
+ProfileObject
+Protocol
+Protocol-Info
+Protocol-Query
+Protocol-Request
+Proxy-Authenticate
+Proxy-Authentication-Info
+Proxy-Authorization
+Proxy-Features
+Proxy-Instruction
+Public
+Public-Key-Pins
+Public-Key-Pins-Report-Only
+Range
+Received
+Received-SPF
+Redirect-Ref
+References
+References
+Referer
+Relay-Version
+Reply-By
+Reply-To
+Reply-To
+Require-Recipient-Valid-Since
+Resent-Bcc
+Resent-Cc
+Resent-Date
+Resent-From
+Resent-Message-ID
+Resent-Reply-To
+Resent-Sender
+Resent-To
+Retry-After
+Return-Path
+Safe
+Schedule-Reply
+Schedule-Tag
+Sec-WebSocket-Accept
+Sec-WebSocket-Extensions
+Sec-WebSocket-Key
+Sec-WebSocket-Protocol
+Sec-WebSocket-Version
+Security-Scheme
+See-Also
+Sender
+Sender
+Sensitivity
+Server
+Set-Cookie
+Set-Cookie2
+SetProfile
+SLUG
+SoapAction
+Solicitation
+Status-URI
+Strict-Transport-Security
+Subject
+Subject
+Summary
+Supersedes
+Supersedes
+Surrogate-Capability
+Surrogate-Control
+TCN
+TE
+Timeout
+To
+Topic
+Trailer
+Transfer-Encoding
+TTL
+Urgency
+URI
+Upgrade
+User-Agent
+User-Agent
+Variant-Vary
+Vary
+VBR-Info
+Via
+WWW-Authenticate
+Want-Digest
+Warning
+X400-Content-Identifier
+X400-Content-Return
+X400-Content-Type
+X400-MTS-Identifier
+X400-Originator
+X400-Received
+X400-Recipients
+X400-Trace
+X-Frame-Options
+Xref
diff --git a/scripts/make_field.sh b/scripts/make_field.sh
new file mode 100644
index 00000000..78773734
--- /dev/null
+++ b/scripts/make_field.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+export LC_COLLATE=C
+
+echo "// string constants"
+echo ' "",'
+cat $1 | uniq | sort -f | sed 's/^/ \"/; s/$/\",/'
+echo
+
+echo "enum class field : unsigned short"
+echo "{"
+echo " unknown = 0,"
+echo
+#cat $1 | uniq | sort -f | sed 's/./\L&/g; s/^/\t/; s/$/,/'
+cat $1 | uniq | sort -f | sed 's/\(.*\)/ \L\1,/; s/-/_/g'
+echo "};"
+echo
+
+echo "// pairs"
+#cat $1 | uniq | sort -f | sed 's/\(.*\)/\tmatch\(field::\L\1, \"\E\1\"\);/; s/-/_/'
+cat $1 | uniq | sort -f | perl -nE 'chomp; $a=lc($_); $a=~s/-/_/g; say " match(field::$a, \"$_\");";' | tr -d "\015"
+
diff --git a/test/Jamfile b/test/Jamfile
index 4ce09dc7..2af8bdc0 100644
--- a/test/Jamfile
+++ b/test/Jamfile
@@ -46,6 +46,7 @@ unit-test http-tests :
http/doc_http_samples.cpp
http/dynamic_body.cpp
http/error.cpp
+ http/field.cpp
http/fields.cpp
http/message.cpp
http/parser.cpp
diff --git a/test/http/CMakeLists.txt b/test/http/CMakeLists.txt
index 999a3467..d19dd1cb 100644
--- a/test/http/CMakeLists.txt
+++ b/test/http/CMakeLists.txt
@@ -18,6 +18,7 @@ add_executable (http-tests
dynamic_body.cpp
empty_body.cpp
error.cpp
+ field.cpp
fields.cpp
message.cpp
parser.cpp
diff --git a/test/http/field.cpp b/test/http/field.cpp
new file mode 100644
index 00000000..b9eabb5b
--- /dev/null
+++ b/test/http/field.cpp
@@ -0,0 +1,356 @@
+//
+// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+// Test that header file is self-contained.
+#include
+
+#include
+#include
+
+namespace beast {
+namespace http {
+
+class field_test : public beast::unit_test::suite
+{
+public:
+ void
+ testField()
+ {
+ auto const match =
+ [&](field f, string_view s)
+ {
+ BEAST_EXPECT(
+ beast::detail::ci_equal(to_string(f), s));
+ BEAST_EXPECT(string_to_field(s) == f);
+ };
+
+ match(field::accept, "accept");
+ match(field::accept, "aCcept");
+ match(field::accept, "ACCEPT");
+
+
+ match(field::a_im, "A-IM");
+ match(field::accept, "Accept");
+ match(field::accept_additions, "Accept-Additions");
+ match(field::accept_charset, "Accept-Charset");
+ match(field::accept_datetime, "Accept-Datetime");
+ match(field::accept_encoding, "Accept-Encoding");
+ match(field::accept_features, "Accept-Features");
+ match(field::accept_language, "Accept-Language");
+ match(field::accept_patch, "Accept-Patch");
+ match(field::accept_post, "Accept-Post");
+ match(field::accept_ranges, "Accept-Ranges");
+ match(field::age, "Age");
+ match(field::allow, "Allow");
+ match(field::alpn, "ALPN");
+ match(field::also_control, "Also-Control");
+ match(field::alt_svc, "Alt-Svc");
+ match(field::alt_used, "Alt-Used");
+ match(field::alternate_recipient, "Alternate-Recipient");
+ match(field::alternates, "Alternates");
+ match(field::apply_to_redirect_ref, "Apply-To-Redirect-Ref");
+ match(field::approved, "Approved");
+ match(field::archive, "Archive");
+ match(field::archived_at, "Archived-At");
+ match(field::article_names, "Article-Names");
+ match(field::article_updates, "Article-Updates");
+ match(field::authentication_control, "Authentication-Control");
+ match(field::authentication_info, "Authentication-Info");
+ match(field::authentication_results, "Authentication-Results");
+ match(field::authorization, "Authorization");
+ match(field::auto_submitted, "Auto-Submitted");
+ match(field::autoforwarded, "Autoforwarded");
+ match(field::autosubmitted, "Autosubmitted");
+ match(field::base, "Base");
+ match(field::bcc, "Bcc");
+ match(field::body, "Body");
+ match(field::c_ext, "C-Ext");
+ match(field::c_man, "C-Man");
+ match(field::c_opt, "C-Opt");
+ match(field::c_pep, "C-PEP");
+ match(field::c_pep_info, "C-PEP-Info");
+ match(field::cache_control, "Cache-Control");
+ match(field::caldav_timezones, "CalDAV-Timezones");
+ match(field::cc, "Cc");
+ match(field::close, "Close");
+ match(field::comments, "Comments");
+ match(field::connection, "Connection");
+ match(field::content_alternative, "Content-Alternative");
+ match(field::content_base, "Content-Base");
+ match(field::content_description, "Content-Description");
+ match(field::content_disposition, "Content-Disposition");
+ match(field::content_duration, "Content-Duration");
+ match(field::content_encoding, "Content-Encoding");
+ match(field::content_features, "Content-features");
+ match(field::content_id, "Content-ID");
+ match(field::content_identifier, "Content-Identifier");
+ match(field::content_language, "Content-Language");
+ match(field::content_length, "Content-Length");
+ match(field::content_location, "Content-Location");
+ match(field::content_md5, "Content-MD5");
+ match(field::content_range, "Content-Range");
+ match(field::content_return, "Content-Return");
+ match(field::content_script_type, "Content-Script-Type");
+ match(field::content_style_type, "Content-Style-Type");
+ match(field::content_transfer_encoding, "Content-Transfer-Encoding");
+ match(field::content_type, "Content-Type");
+ match(field::content_version, "Content-Version");
+ match(field::control, "Control");
+ match(field::conversion, "Conversion");
+ match(field::conversion_with_loss, "Conversion-With-Loss");
+ match(field::cookie, "Cookie");
+ match(field::cookie2, "Cookie2");
+ match(field::dasl, "DASL");
+ match(field::date, "Date");
+ match(field::date_received, "Date-Received");
+ match(field::dav, "DAV");
+ match(field::default_style, "Default-Style");
+ match(field::deferred_delivery, "Deferred-Delivery");
+ match(field::delivery_date, "Delivery-Date");
+ match(field::delta_base, "Delta-Base");
+ match(field::depth, "Depth");
+ match(field::derived_from, "Derived-From");
+ match(field::destination, "Destination");
+ match(field::differential_id, "Differential-ID");
+ match(field::digest, "Digest");
+ match(field::discarded_x400_ipms_extensions, "Discarded-X400-IPMS-Extensions");
+ match(field::discarded_x400_mts_extensions, "Discarded-X400-MTS-Extensions");
+ match(field::disclose_recipients, "Disclose-Recipients");
+ match(field::disposition_notification_options, "Disposition-Notification-Options");
+ match(field::disposition_notification_to, "Disposition-Notification-To");
+ match(field::distribution, "Distribution");
+ match(field::dkim_signature, "DKIM-Signature");
+ match(field::dl_expansion_history, "DL-Expansion-History");
+ match(field::downgraded_bcc, "Downgraded-Bcc");
+ match(field::downgraded_cc, "Downgraded-Cc");
+ match(field::downgraded_disposition_notification_to, "Downgraded-Disposition-Notification-To");
+ match(field::downgraded_final_recipient, "Downgraded-Final-Recipient");
+ match(field::downgraded_from, "Downgraded-From");
+ match(field::downgraded_in_reply_to, "Downgraded-In-Reply-To");
+ match(field::downgraded_mail_from, "Downgraded-Mail-From");
+ match(field::downgraded_message_id, "Downgraded-Message-Id");
+ match(field::downgraded_original_recipient, "Downgraded-Original-Recipient");
+ match(field::downgraded_rcpt_to, "Downgraded-Rcpt-To");
+ match(field::downgraded_references, "Downgraded-References");
+ match(field::downgraded_reply_to, "Downgraded-Reply-To");
+ match(field::downgraded_resent_bcc, "Downgraded-Resent-Bcc");
+ match(field::downgraded_resent_cc, "Downgraded-Resent-Cc");
+ match(field::downgraded_resent_from, "Downgraded-Resent-From");
+ match(field::downgraded_resent_reply_to, "Downgraded-Resent-Reply-To");
+ match(field::downgraded_resent_sender, "Downgraded-Resent-Sender");
+ match(field::downgraded_resent_to, "Downgraded-Resent-To");
+ match(field::downgraded_return_path, "Downgraded-Return-Path");
+ match(field::downgraded_sender, "Downgraded-Sender");
+ match(field::downgraded_to, "Downgraded-To");
+ match(field::encoding, "Encoding");
+ match(field::encrypted, "Encrypted");
+ match(field::etag, "ETag");
+ match(field::expect, "Expect");
+ match(field::expires, "Expires");
+ match(field::expiry_date, "Expiry-Date");
+ match(field::ext, "Ext");
+ match(field::followup_to, "Followup-To");
+ match(field::forwarded, "Forwarded");
+ match(field::from, "From");
+ match(field::generate_delivery_report, "Generate-Delivery-Report");
+ match(field::getprofile, "GetProfile");
+ match(field::hobareg, "Hobareg");
+ match(field::host, "Host");
+ match(field::http2_settings, "HTTP2-Settings");
+ match(field::if_, "If");
+ match(field::if_match, "If-Match");
+ match(field::if_modified_since, "If-Modified-Since");
+ match(field::if_none_match, "If-None-Match");
+ match(field::if_range, "If-Range");
+ match(field::if_schedule_tag_match, "If-Schedule-Tag-Match");
+ match(field::if_unmodified_since, "If-Unmodified-Since");
+ match(field::im, "IM");
+ match(field::importance, "Importance");
+ match(field::in_reply_to, "In-Reply-To");
+ match(field::incomplete_copy, "Incomplete-Copy");
+ match(field::injection_date, "Injection-Date");
+ match(field::injection_info, "Injection-Info");
+ match(field::keep_alive, "Keep-Alive");
+ match(field::keywords, "Keywords");
+ match(field::label, "Label");
+ match(field::language, "Language");
+ match(field::last_modified, "Last-Modified");
+ match(field::latest_delivery_time, "Latest-Delivery-Time");
+ match(field::lines, "Lines");
+ match(field::link, "Link");
+ match(field::list_archive, "List-Archive");
+ match(field::list_help, "List-Help");
+ match(field::list_id, "List-ID");
+ match(field::list_owner, "List-Owner");
+ match(field::list_post, "List-Post");
+ match(field::list_subscribe, "List-Subscribe");
+ match(field::list_unsubscribe, "List-Unsubscribe");
+ match(field::list_unsubscribe_post, "List-Unsubscribe-Post");
+ match(field::location, "Location");
+ match(field::lock_token, "Lock-Token");
+ match(field::man, "Man");
+ match(field::max_forwards, "Max-Forwards");
+ match(field::memento_datetime, "Memento-Datetime");
+ match(field::message_context, "Message-Context");
+ match(field::message_id, "Message-ID");
+ match(field::message_type, "Message-Type");
+ match(field::meter, "Meter");
+ match(field::mime_version, "MIME-Version");
+ match(field::mmhs_acp127_message_identifier, "MMHS-Acp127-Message-Identifier");
+ match(field::mmhs_codress_message_indicator, "MMHS-Codress-Message-Indicator");
+ match(field::mmhs_copy_precedence, "MMHS-Copy-Precedence");
+ match(field::mmhs_exempted_address, "MMHS-Exempted-Address");
+ match(field::mmhs_extended_authorisation_info, "MMHS-Extended-Authorisation-Info");
+ match(field::mmhs_handling_instructions, "MMHS-Handling-Instructions");
+ match(field::mmhs_message_instructions, "MMHS-Message-Instructions");
+ match(field::mmhs_message_type, "MMHS-Message-Type");
+ match(field::mmhs_originator_plad, "MMHS-Originator-PLAD");
+ match(field::mmhs_originator_reference, "MMHS-Originator-Reference");
+ match(field::mmhs_other_recipients_indicator_cc, "MMHS-Other-Recipients-Indicator-CC");
+ match(field::mmhs_other_recipients_indicator_to, "MMHS-Other-Recipients-Indicator-To");
+ match(field::mmhs_primary_precedence, "MMHS-Primary-Precedence");
+ match(field::mmhs_subject_indicator_codes, "MMHS-Subject-Indicator-Codes");
+ match(field::mt_priority, "MT-Priority");
+ match(field::negotiate, "Negotiate");
+ match(field::newsgroups, "Newsgroups");
+ match(field::nntp_posting_date, "NNTP-Posting-Date");
+ match(field::nntp_posting_host, "NNTP-Posting-Host");
+ match(field::obsoletes, "Obsoletes");
+ match(field::opt, "Opt");
+ match(field::optional_www_authenticate, "Optional-WWW-Authenticate");
+ match(field::ordering_type, "Ordering-Type");
+ match(field::organization, "Organization");
+ match(field::origin, "Origin");
+ match(field::original_encoded_information_types, "Original-Encoded-Information-Types");
+ match(field::original_from, "Original-From");
+ match(field::original_message_id, "Original-Message-ID");
+ match(field::original_recipient, "Original-Recipient");
+ match(field::original_sender, "Original-Sender");
+ match(field::original_subject, "Original-Subject");
+ match(field::originator_return_address, "Originator-Return-Address");
+ match(field::overwrite, "Overwrite");
+ match(field::p3p, "P3P");
+ match(field::path, "Path");
+ match(field::pep, "PEP");
+ match(field::pep_info, "Pep-Info");
+ match(field::pics_label, "PICS-Label");
+ match(field::position, "Position");
+ match(field::posting_version, "Posting-Version");
+ match(field::pragma, "Pragma");
+ match(field::prefer, "Prefer");
+ match(field::preference_applied, "Preference-Applied");
+ match(field::prevent_nondelivery_report, "Prevent-NonDelivery-Report");
+ match(field::priority, "Priority");
+ match(field::profileobject, "ProfileObject");
+ match(field::protocol, "Protocol");
+ match(field::protocol_info, "Protocol-Info");
+ match(field::protocol_query, "Protocol-Query");
+ match(field::protocol_request, "Protocol-Request");
+ match(field::proxy_authenticate, "Proxy-Authenticate");
+ match(field::proxy_authentication_info, "Proxy-Authentication-Info");
+ match(field::proxy_authorization, "Proxy-Authorization");
+ match(field::proxy_features, "Proxy-Features");
+ match(field::proxy_instruction, "Proxy-Instruction");
+ match(field::public_, "Public");
+ match(field::public_key_pins, "Public-Key-Pins");
+ match(field::public_key_pins_report_only, "Public-Key-Pins-Report-Only");
+ match(field::range, "Range");
+ match(field::received, "Received");
+ match(field::received_spf, "Received-SPF");
+ match(field::redirect_ref, "Redirect-Ref");
+ match(field::references, "References");
+ match(field::referer, "Referer");
+ match(field::relay_version, "Relay-Version");
+ match(field::reply_by, "Reply-By");
+ match(field::reply_to, "Reply-To");
+ match(field::require_recipient_valid_since, "Require-Recipient-Valid-Since");
+ match(field::resent_bcc, "Resent-Bcc");
+ match(field::resent_cc, "Resent-Cc");
+ match(field::resent_date, "Resent-Date");
+ match(field::resent_from, "Resent-From");
+ match(field::resent_message_id, "Resent-Message-ID");
+ match(field::resent_reply_to, "Resent-Reply-To");
+ match(field::resent_sender, "Resent-Sender");
+ match(field::resent_to, "Resent-To");
+ match(field::retry_after, "Retry-After");
+ match(field::return_path, "Return-Path");
+ match(field::safe, "Safe");
+ match(field::schedule_reply, "Schedule-Reply");
+ match(field::schedule_tag, "Schedule-Tag");
+ match(field::sec_websocket_accept, "Sec-WebSocket-Accept");
+ match(field::sec_websocket_extensions, "Sec-WebSocket-Extensions");
+ match(field::sec_websocket_key, "Sec-WebSocket-Key");
+ match(field::sec_websocket_protocol, "Sec-WebSocket-Protocol");
+ match(field::sec_websocket_version, "Sec-WebSocket-Version");
+ match(field::security_scheme, "Security-Scheme");
+ match(field::see_also, "See-Also");
+ match(field::sender, "Sender");
+ match(field::sensitivity, "Sensitivity");
+ match(field::server, "Server");
+ match(field::set_cookie, "Set-Cookie");
+ match(field::set_cookie2, "Set-Cookie2");
+ match(field::setprofile, "SetProfile");
+ match(field::slug, "SLUG");
+ match(field::soapaction, "SoapAction");
+ match(field::solicitation, "Solicitation");
+ match(field::status_uri, "Status-URI");
+ match(field::strict_transport_security, "Strict-Transport-Security");
+ match(field::subject, "Subject");
+ match(field::summary, "Summary");
+ match(field::supersedes, "Supersedes");
+ match(field::surrogate_capability, "Surrogate-Capability");
+ match(field::surrogate_control, "Surrogate-Control");
+ match(field::tcn, "TCN");
+ match(field::te, "TE");
+ match(field::timeout, "Timeout");
+ match(field::to, "To");
+ match(field::topic, "Topic");
+ match(field::trailer, "Trailer");
+ match(field::transfer_encoding, "Transfer-Encoding");
+ match(field::ttl, "TTL");
+ match(field::upgrade, "Upgrade");
+ match(field::urgency, "Urgency");
+ match(field::uri, "URI");
+ match(field::user_agent, "User-Agent");
+ match(field::variant_vary, "Variant-Vary");
+ match(field::vary, "Vary");
+ match(field::vbr_info, "VBR-Info");
+ match(field::via, "Via");
+ match(field::want_digest, "Want-Digest");
+ match(field::warning, "Warning");
+ match(field::www_authenticate, "WWW-Authenticate");
+ match(field::x_frame_options, "X-Frame-Options");
+ match(field::x400_content_identifier, "X400-Content-Identifier");
+ match(field::x400_content_return, "X400-Content-Return");
+ match(field::x400_content_type, "X400-Content-Type");
+ match(field::x400_mts_identifier, "X400-MTS-Identifier");
+ match(field::x400_originator, "X400-Originator");
+ match(field::x400_received, "X400-Received");
+ match(field::x400_recipients, "X400-Recipients");
+ match(field::x400_trace, "X400-Trace");
+ match(field::xref, "Xref");
+
+ auto const unknown =
+ [&](string_view s)
+ {
+ BEAST_EXPECT(string_to_field(s) == field::unknown);
+ };
+ unknown("");
+ unknown("x");
+ }
+
+ void run() override
+ {
+ testField();
+ pass();
+ }
+};
+
+BEAST_DEFINE_TESTSUITE(field,http,beast);
+
+} // http
+} // beast