RESTinio
Loading...
Searching...
No Matches
http_headers.hpp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
9#pragma once
10
12
14
18
19#include <llhttp.h>
20
21#include <iosfwd>
22#include <ostream>
23#include <string>
24#include <vector>
25#include <algorithm>
26#include <optional>
27
28namespace restinio
29{
30
31
32// Adopted header fields
33// (https://www.iana.org/assignments/message-headers/message-headers.xml#perm-headers).
34// Fields `Connection` and `Content-Length` are specieal cases, thus they are excluded from the list.
35#define RESTINIO_HTTP_FIELDS_MAP( RESTINIO_GEN ) \
36 RESTINIO_GEN( a_im, A-IM ) \
37 RESTINIO_GEN( accept, Accept ) \
38 RESTINIO_GEN( accept_additions, Accept-Additions ) \
39 RESTINIO_GEN( accept_charset, Accept-Charset ) \
40 RESTINIO_GEN( accept_datetime, Accept-Datetime ) \
41 RESTINIO_GEN( accept_encoding, Accept-Encoding ) \
42 RESTINIO_GEN( accept_features, Accept-Features ) \
43 RESTINIO_GEN( accept_language, Accept-Language ) \
44 RESTINIO_GEN( accept_patch, Accept-Patch ) \
45 RESTINIO_GEN( accept_post, Accept-Post ) \
46 RESTINIO_GEN( accept_ranges, Accept-Ranges ) \
47 RESTINIO_GEN( age, Age ) \
48 RESTINIO_GEN( allow, Allow ) \
49 RESTINIO_GEN( alpn, ALPN ) \
50 RESTINIO_GEN( alt_svc, Alt-Svc ) \
51 RESTINIO_GEN( alt_used, Alt-Used ) \
52 RESTINIO_GEN( alternates, Alternates ) \
53 RESTINIO_GEN( apply_to_redirect_ref, Apply-To-Redirect-Ref ) \
54 RESTINIO_GEN( authentication_control, Authentication-Control ) \
55 RESTINIO_GEN( authentication_info, Authentication-Info ) \
56 RESTINIO_GEN( authorization, Authorization ) \
57 RESTINIO_GEN( c_ext, C-Ext ) \
58 RESTINIO_GEN( c_man, C-Man ) \
59 RESTINIO_GEN( c_opt, C-Opt ) \
60 RESTINIO_GEN( c_pep, C-PEP ) \
61 RESTINIO_GEN( c_pep_info, C-PEP-Info ) \
62 RESTINIO_GEN( cache_control, Cache-Control ) \
63 RESTINIO_GEN( caldav_timezones, CalDAV-Timezones ) \
64 RESTINIO_GEN( close, Close ) \
65 RESTINIO_GEN( content_base, Content-Base ) \
66 RESTINIO_GEN( content_disposition, Content-Disposition ) \
67 RESTINIO_GEN( content_encoding, Content-Encoding ) \
68 RESTINIO_GEN( content_id, Content-ID ) \
69 RESTINIO_GEN( content_language, Content-Language ) \
70 RESTINIO_GEN( content_location, Content-Location ) \
71 RESTINIO_GEN( content_md5, Content-MD5 ) \
72 RESTINIO_GEN( content_range, Content-Range ) \
73 RESTINIO_GEN( content_script_type, Content-Script-Type ) \
74 RESTINIO_GEN( content_style_type, Content-Style-Type ) \
75 RESTINIO_GEN( content_type, Content-Type ) \
76 RESTINIO_GEN( content_version, Content-Version ) \
77 RESTINIO_GEN( cookie, Cookie ) \
78 RESTINIO_GEN( cookie2, Cookie2 ) \
79 RESTINIO_GEN( dasl, DASL ) \
80 RESTINIO_GEN( dav, DAV ) \
81 RESTINIO_GEN( date, Date ) \
82 RESTINIO_GEN( default_style, Default-Style ) \
83 RESTINIO_GEN( delta_base, Delta-Base ) \
84 RESTINIO_GEN( depth, Depth ) \
85 RESTINIO_GEN( derived_from, Derived-From ) \
86 RESTINIO_GEN( destination, Destination ) \
87 RESTINIO_GEN( differential_id, Differential-ID ) \
88 RESTINIO_GEN( digest, Digest ) \
89 RESTINIO_GEN( etag, ETag ) \
90 RESTINIO_GEN( expect, Expect ) \
91 RESTINIO_GEN( expires, Expires ) \
92 RESTINIO_GEN( ext, Ext ) \
93 RESTINIO_GEN( forwarded, Forwarded ) \
94 RESTINIO_GEN( from, From ) \
95 RESTINIO_GEN( getprofile, GetProfile ) \
96 RESTINIO_GEN( hobareg, Hobareg ) \
97 RESTINIO_GEN( host, Host ) \
98 RESTINIO_GEN( http2_settings, HTTP2-Settings ) \
99 RESTINIO_GEN( im, IM ) \
100 RESTINIO_GEN( if_, If ) \
101 RESTINIO_GEN( if_match, If-Match ) \
102 RESTINIO_GEN( if_modified_since, If-Modified-Since ) \
103 RESTINIO_GEN( if_none_match, If-None-Match ) \
104 RESTINIO_GEN( if_range, If-Range ) \
105 RESTINIO_GEN( if_schedule_tag_match, If-Schedule-Tag-Match ) \
106 RESTINIO_GEN( if_unmodified_since, If-Unmodified-Since ) \
107 RESTINIO_GEN( keep_alive, Keep-Alive ) \
108 RESTINIO_GEN( label, Label ) \
109 RESTINIO_GEN( last_modified, Last-Modified ) \
110 RESTINIO_GEN( link, Link ) \
111 RESTINIO_GEN( location, Location ) \
112 RESTINIO_GEN( lock_token, Lock-Token ) \
113 RESTINIO_GEN( man, Man ) \
114 RESTINIO_GEN( max_forwards, Max-Forwards ) \
115 RESTINIO_GEN( memento_datetime, Memento-Datetime ) \
116 RESTINIO_GEN( meter, Meter ) \
117 RESTINIO_GEN( mime_version, MIME-Version ) \
118 RESTINIO_GEN( negotiate, Negotiate ) \
119 RESTINIO_GEN( opt, Opt ) \
120 RESTINIO_GEN( optional_www_authenticate, Optional-WWW-Authenticate ) \
121 RESTINIO_GEN( ordering_type, Ordering-Type ) \
122 RESTINIO_GEN( origin, Origin ) \
123 RESTINIO_GEN( overwrite, Overwrite ) \
124 RESTINIO_GEN( p3p, P3P ) \
125 RESTINIO_GEN( pep, PEP ) \
126 RESTINIO_GEN( pics_label, PICS-Label ) \
127 RESTINIO_GEN( pep_info, Pep-Info ) \
128 RESTINIO_GEN( position, Position ) \
129 RESTINIO_GEN( pragma, Pragma ) \
130 RESTINIO_GEN( prefer, Prefer ) \
131 RESTINIO_GEN( preference_applied, Preference-Applied ) \
132 RESTINIO_GEN( profileobject, ProfileObject ) \
133 RESTINIO_GEN( protocol, Protocol ) \
134 RESTINIO_GEN( protocol_info, Protocol-Info ) \
135 RESTINIO_GEN( protocol_query, Protocol-Query ) \
136 RESTINIO_GEN( protocol_request, Protocol-Request ) \
137 RESTINIO_GEN( proxy_authenticate, Proxy-Authenticate ) \
138 RESTINIO_GEN( proxy_authentication_info, Proxy-Authentication-Info ) \
139 RESTINIO_GEN( proxy_authorization, Proxy-Authorization ) \
140 RESTINIO_GEN( proxy_features, Proxy-Features ) \
141 RESTINIO_GEN( proxy_instruction, Proxy-Instruction ) \
142 RESTINIO_GEN( public_, Public ) \
143 RESTINIO_GEN( public_key_pins, Public-Key-Pins ) \
144 RESTINIO_GEN( public_key_pins_report_only, Public-Key-Pins-Report-Only ) \
145 RESTINIO_GEN( range, Range ) \
146 RESTINIO_GEN( redirect_ref, Redirect-Ref ) \
147 RESTINIO_GEN( referer, Referer ) \
148 RESTINIO_GEN( retry_after, Retry-After ) \
149 RESTINIO_GEN( safe, Safe ) \
150 RESTINIO_GEN( schedule_reply, Schedule-Reply ) \
151 RESTINIO_GEN( schedule_tag, Schedule-Tag ) \
152 RESTINIO_GEN( sec_websocket_accept, Sec-WebSocket-Accept ) \
153 RESTINIO_GEN( sec_websocket_extensions, Sec-WebSocket-Extensions ) \
154 RESTINIO_GEN( sec_websocket_key, Sec-WebSocket-Key ) \
155 RESTINIO_GEN( sec_websocket_protocol, Sec-WebSocket-Protocol ) \
156 RESTINIO_GEN( sec_websocket_version, Sec-WebSocket-Version ) \
157 RESTINIO_GEN( security_scheme, Security-Scheme ) \
158 RESTINIO_GEN( server, Server ) \
159 RESTINIO_GEN( set_cookie, Set-Cookie ) \
160 RESTINIO_GEN( set_cookie2, Set-Cookie2 ) \
161 RESTINIO_GEN( setprofile, SetProfile ) \
162 RESTINIO_GEN( slug, SLUG ) \
163 RESTINIO_GEN( soapaction, SoapAction ) \
164 RESTINIO_GEN( status_uri, Status-URI ) \
165 RESTINIO_GEN( strict_transport_security, Strict-Transport-Security ) \
166 RESTINIO_GEN( surrogate_capability, Surrogate-Capability ) \
167 RESTINIO_GEN( surrogate_control, Surrogate-Control ) \
168 RESTINIO_GEN( tcn, TCN ) \
169 RESTINIO_GEN( te, TE ) \
170 RESTINIO_GEN( timeout, Timeout ) \
171 RESTINIO_GEN( topic, Topic ) \
172 RESTINIO_GEN( trailer, Trailer ) \
173 RESTINIO_GEN( transfer_encoding, Transfer-Encoding ) \
174 RESTINIO_GEN( ttl, TTL ) \
175 RESTINIO_GEN( urgency, Urgency ) \
176 RESTINIO_GEN( uri, URI ) \
177 RESTINIO_GEN( upgrade, Upgrade ) \
178 RESTINIO_GEN( user_agent, User-Agent ) \
179 RESTINIO_GEN( variant_vary, Variant-Vary ) \
180 RESTINIO_GEN( vary, Vary ) \
181 RESTINIO_GEN( via, Via ) \
182 RESTINIO_GEN( www_authenticate, WWW-Authenticate ) \
183 RESTINIO_GEN( want_digest, Want-Digest ) \
184 RESTINIO_GEN( warning, Warning ) \
185 RESTINIO_GEN( x_frame_options, X-Frame-Options ) \
186\
187 RESTINIO_GEN( access_control, Access-Control ) \
188 RESTINIO_GEN( access_control_allow_credentials, Access-Control-Allow-Credentials ) \
189 RESTINIO_GEN( access_control_allow_headers, Access-Control-Allow-Headers )\
190 RESTINIO_GEN( access_control_allow_methods, Access-Control-Allow-Methods )\
191 RESTINIO_GEN( access_control_allow_origin, Access-Control-Allow-Origin ) \
192 RESTINIO_GEN( access_control_max_age, Access-Control-Max-Age ) \
193 RESTINIO_GEN( access_control_request_method, Access-Control-Request-Method ) \
194 RESTINIO_GEN( access_control_request_headers, Access-Control-Request-Headers ) \
195 RESTINIO_GEN( compliance, Compliance ) \
196 RESTINIO_GEN( content_transfer_encoding, Content-Transfer-Encoding ) \
197 RESTINIO_GEN( cost, Cost ) \
198 RESTINIO_GEN( ediint_features, EDIINT-Features ) \
199 RESTINIO_GEN( message_id, Message-ID ) \
200 RESTINIO_GEN( method_check, Method-Check ) \
201 RESTINIO_GEN( method_check_expires, Method-Check-Expires ) \
202 RESTINIO_GEN( non_compliance, Non-Compliance ) \
203 RESTINIO_GEN( optional, Optional ) \
204 RESTINIO_GEN( referer_root, Referer-Root ) \
205 RESTINIO_GEN( resolution_hint, Resolution-Hint ) \
206 RESTINIO_GEN( resolver_location, Resolver-Location ) \
207 RESTINIO_GEN( subok, SubOK ) \
208 RESTINIO_GEN( subst, Subst ) \
209 RESTINIO_GEN( title, Title ) \
210 RESTINIO_GEN( ua_color, UA-Color ) \
211 RESTINIO_GEN( ua_media, UA-Media ) \
212 RESTINIO_GEN( ua_pixels, UA-Pixels ) \
213 RESTINIO_GEN( ua_resolution, UA-Resolution ) \
214 RESTINIO_GEN( ua_windowpixels, UA-Windowpixels ) \
215 RESTINIO_GEN( version, Version ) \
216 RESTINIO_GEN( x_device_accept, X-Device-Accept ) \
217 RESTINIO_GEN( x_device_accept_charset, X-Device-Accept-Charset ) \
218 RESTINIO_GEN( x_device_accept_encoding, X-Device-Accept-Encoding ) \
219 RESTINIO_GEN( x_device_accept_language, X-Device-Accept-Language ) \
220 RESTINIO_GEN( x_device_user_agent, X-Device-User-Agent )
221 // SPECIAL CASE: RESTINIO_GEN( connection, Connection )
222 // SPECIAL CASE: RESTINIO_GEN( content_length, Content-Length )
223
224//
225// http_field_t
226//
227
229
233enum class http_field_t : std::uint8_t //By now 152 + 34 + 1 items fits to uint8_t
234{
235#define RESTINIO_HTTP_FIELD_GEN( name, ignored ) name,
237#undef RESTINIO_HTTP_FIELD_GEN
238 // Unspecified field.
240};
241
244
245//
246// string_to_field()
247//
248
251inline http_field_t
253{
254 const char * field_name = field.data();
255 const std::size_t field_name_size = field.size();
256
257#define RESTINIO_HTTP_CHECK_FOR_FIELD( field_id, candidate_field_name ) \
258 if( impl::is_equal_caseless(field_name, #candidate_field_name , field_name_size ) ) \
259 return http_field_t:: field_id;
260
261 // TODO: make most popular fields to be checked first.
262
263 switch( field_name_size )
264 {
265 case 2:
269 break;
270
271 case 3:
283 break;
284
285 case 4:
286 // Known to be more used first:
288
300 break;
301
302 case 5:
317 break;
318
319 case 6:
320 // Known to be more used first:
324
331 break;
332
333 case 7:
345 break;
346
347 case 8:
358 break;
359
360 case 9:
365 break;
366
367 case 10:
383 break;
384
385 case 11:
392 break;
393
394 case 12:
395 // Known to be more used first:
397
408 break;
409
410 case 13:
422 break;
423
424 case 14:
432 break;
433
434 case 15:
448 break;
449
450 case 16:
459 break;
460
461 case 17:
468 break;
469
470 case 18:
474 break;
475
476 case 19:
483 break;
484
485 case 20:
489 break;
490
491 case 21:
495 break;
496
497 case 22:
501 break;
502
503 case 23:
505 break;
506
507 case 24:
511 break;
512
513 case 25:
518 break;
519
520 case 27:
523 break;
524
525 case 28:
528 break;
529
530 case 29:
532 break;
533
534 case 30:
536 break;
537
538 case 32:
540 break;
541 }
542
543#undef RESTINIO_HTTP_CHECK_FOR_FIELD
544
546}
547
548//
549// field_to_string()
550//
551
553inline const char *
555{
556 const char * result = "";
557 switch( f )
558 {
559 #define RESTINIO_HTTP_FIELD_STR_GEN( name, string_name ) \
560 case http_field_t::name: result = #string_name; break;
561
563 #undef RESTINIO_HTTP_FIELD_STR_GEN
564
565 case http_field_t::field_unspecified: break; // Ignore.
566 }
567
568 return result;
569}
570
571//
572// http_header_field_t
573//
574
576
584{
585 public:
589
591 std::string name,
592 std::string value )
593 : m_name{ std::move( name ) }
594 , m_value{ std::move( value ) }
596 {}
597
601 : m_name{ name.data(), name.size() }
602 , m_value{ value.data(), value.size() }
604 {}
605
608 std::string value )
610 , m_value{ std::move( value ) }
612 {}
613
621
622 const std::string & name() const noexcept { return m_name; }
623 const std::string & value() const noexcept { return m_value; }
625
626 void
627 name( std::string n )
628 {
629 m_name = std::move( n );
631 }
632
633 void
634 value( std::string v )
635 {
636 m_value = std::move( v );
637 }
638
639 void
641 {
642 m_value.append( v.data(), v.size() );
643 }
644
645 void
651
652 private:
653 std::string m_name;
654 std::string m_value;
656};
657
658// Make neccessary forward declarations.
660namespace impl
661{
662
663void
665
666} /* namespace impl */
667
668#if !defined( RESTINIO_HEADER_FIELDS_DEFAULT_RESERVE_COUNT )
669 #define RESTINIO_HEADER_FIELDS_DEFAULT_RESERVE_COUNT 4
670#endif
671
672//
673// http_header_fields_t
674//
675
677
704{
705 friend void
707
708 public:
709 using fields_container_t = std::vector< http_header_field_t >;
710
712 using const_iterator = fields_container_t::const_iterator;
713
715
729
732
735
743
746
747 void
752
754 bool
756 {
757 return m_fields.cend() != cfind( field_name );
758 }
759
761
766 bool
767 has_field( http_field_t field_id ) const noexcept
768 {
769 return m_fields.cend() != cfind( field_id );
770 }
771
773 void
775 {
776 fields_container_t::iterator it;
778 {
779 // Field has a standard name.
780 // Search it by id.
781 it = find( http_header_field.field_id() );
782 }
783 else
784 {
785 // Field has a non standard name.
786 // Search it by name.
787 it = find( http_header_field.name() );
788 }
789
790 if( m_fields.end() != it )
791 {
792 *it = std::move( http_header_field );
793 }
794 else
795 {
796 m_fields.emplace_back( std::move( http_header_field ) );
797 }
798 }
799
801 void
803 std::string field_name,
804 std::string field_value )
805 {
806 const auto it = find( field_name );
807
808 if( m_fields.end() != it )
809 {
810 it->name( std::move( field_name ) );
811 it->value( std::move( field_value ) );
812 }
813 else
814 {
815 m_fields.emplace_back(
816 std::move( field_name ),
817 std::move( field_value ) );
818 }
819 }
820
822
826 void
828 http_field_t field_id,
829 std::string field_value )
830 {
831 if( http_field_t::field_unspecified != field_id )
832 {
833 const auto it = find( field_id );
834
835 if( m_fields.end() != it )
836 {
837 it->value( std::move( field_value ) );
838 }
839 else
840 {
841 m_fields.emplace_back(
842 field_id,
843 std::move( field_value ) );
844 }
845 }
846 }
847
860 void
862 http_field_t field_id,
863 std::string field_value )
864 {
865 if( http_field_t::field_unspecified != field_id )
866 {
867 m_fields.emplace_back(
868 field_id,
869 std::move( field_value ) );
870 }
871 }
872
882 void
884 std::string field_name,
885 std::string field_value )
886 {
887 m_fields.emplace_back(
888 std::move( field_name ),
889 std::move( field_value ) );
890 }
891
901 void
903 {
904 m_fields.push_back( std::move(http_header_field) );
905 }
906
908 void
912 {
913 const auto it = find( field_name );
914
915 if( m_fields.end() != it )
916 {
917 it->append_value( field_value );
918 }
919 else
920 {
921 m_fields.emplace_back( field_name, field_value );
922 }
923 }
924
926
930 void
932 http_field_t field_id,
934 {
935 if( http_field_t::field_unspecified != field_id )
936 {
937 const auto it = find( field_id );
938
939 if( m_fields.end() != it )
940 {
941 it->append_value( field_value );
942 }
943 else
944 {
945 m_fields.emplace_back( field_id, field_value );
946 }
947 }
948 }
949
951 const std::string &
953 {
954 const auto it = cfind( field_name );
955
956 if( m_fields.end() == it )
957 throw exception_t{
958 fmt::format(
959 RESTINIO_FMT_FORMAT_STRING( "field '{}' doesn't exist" ),
961
962 return it->value();
963 }
964
966
979 {
980 const auto it = cfind( field_name );
981 if( m_fields.end() == it )
982 return nullptr;
983 else
984 return std::addressof(it->value());
985 }
986
988 const std::string &
989 get_field( http_field_t field_id ) const
990 {
991 if( http_field_t::field_unspecified == field_id )
992 {
993 throw exception_t{
994 "unspecified fields cannot be searched by id" };
995 }
996
997 const auto it = cfind( field_id );
998
999 if( m_fields.end() == it )
1000 {
1001 throw exception_t{
1002 fmt::format(
1003 RESTINIO_FMT_FORMAT_STRING( "field '{}' doesn't exist" ),
1004 field_to_string( field_id ) ) };
1005 }
1006
1007 return it->value();
1008 }
1009
1011
1023 try_get_field( http_field_t field_id ) const noexcept
1024 {
1025 if( http_field_t::field_unspecified != field_id )
1026 {
1027 const auto it = cfind( field_id );
1028 if( m_fields.end() != it )
1029 return std::addressof(it->value());
1030 }
1031
1032 return nullptr;
1033 }
1034
1036
1041 std::string
1045 {
1046 const auto it = cfind( field_name );
1047
1048 if( m_fields.end() == it )
1049 return std::string( default_value.data(), default_value.size() );
1050
1051 return it->value();
1052 }
1053
1055
1060 std::string
1063 std::string && default_value ) const
1064 {
1065 const auto it = cfind( field_name );
1066
1067 if( m_fields.end() == it )
1068 return std::move(default_value);
1069
1070 return it->value();
1071 }
1072
1074
1077 auto
1080 const char * default_value ) const
1081 {
1082 return this->get_field_or( field_name, string_view_t{ default_value } );
1083 }
1084
1086
1089 auto
1092 const std::string & default_value ) const
1093 {
1094 return this->get_field_or( field_name, string_view_t{ default_value } );
1095 }
1096
1098
1103 std::string
1105 http_field_t field_id,
1107 {
1108 if( http_field_t::field_unspecified != field_id )
1109 {
1110 const auto it = cfind( field_id );
1111
1112 if( m_fields.end() != it )
1113 return it->value();
1114 }
1115
1116 return std::string( default_value.data(), default_value.size() );
1117 }
1118
1120
1123 auto
1125 http_field_t field_id,
1126 const char * default_value ) const
1127 {
1128 return this->get_field_or( field_id, string_view_t{ default_value } );
1129 }
1130
1132
1135 auto
1137 http_field_t field_id,
1138 const std::string & default_value ) const
1139 {
1140 return this->get_field_or( field_id, string_view_t{ default_value } );
1141 }
1142
1144
1149 std::string
1151 http_field_t field_id,
1152 std::string && default_value ) const
1153 {
1154 if( http_field_t::field_unspecified != field_id )
1155 {
1156 const auto it = cfind( field_id );
1157
1158 if( m_fields.end() != it )
1159 return it->value();
1160 }
1161
1162 return std::move( default_value );
1163 }
1164
1166
1175 bool
1177 {
1178 const auto it = find( field_name );
1179
1180 if( m_fields.end() != it )
1181 {
1182 m_fields.erase( it );
1183 return true;
1184 }
1185
1186 return false;
1187 }
1188
1190
1199 bool
1200 remove_field( http_field_t field_id ) noexcept
1201 {
1202 if( http_field_t::field_unspecified != field_id )
1203 {
1204 const auto it = find( field_id );
1205
1206 if( m_fields.end() != it )
1207 {
1208 m_fields.erase( it );
1209 return true;
1210 }
1211 }
1212
1213 return false;
1214 }
1215
1217
1222 std::size_t
1224 {
1225 std::size_t count{};
1226 for( auto it = m_fields.begin(); it != m_fields.end(); )
1227 {
1228 if( impl::is_equal_caseless( it->name(), field_name ) )
1229 {
1230 it = m_fields.erase( it );
1231 ++count;
1232 }
1233 else
1234 ++it;
1235 }
1236
1237 return count;
1238 }
1239
1241
1246 std::size_t
1247 remove_all_of( http_field_t field_id ) noexcept
1248 {
1249 std::size_t count{};
1250 if( http_field_t::field_unspecified != field_id )
1251 {
1252 for( auto it = m_fields.begin(); it != m_fields.end(); )
1253 {
1254 if( it->field_id() == field_id )
1255 {
1256 it = m_fields.erase( it );
1257 ++count;
1258 }
1259 else
1260 ++it;
1261 }
1262 }
1263
1264 return count;
1265 }
1266
1275 string_view_t name ) const
1276 {
1277 return { this->get_field(name) };
1278 }
1279
1284 http_field_t field_id ) const
1285 {
1286 return { this->get_field(field_id) };
1287 }
1288
1290
1301 std::optional< string_view_t >
1304 string_view_t name ) const noexcept
1305 {
1306 std::optional< string_view_t > result;
1307
1308 if( auto * ptr = this->try_get_field(name) )
1309 result = string_view_t{ *ptr };
1310
1311 return result;
1312 }
1313
1315
1326 std::optional< string_view_t >
1329 http_field_t field_id ) const noexcept
1330 {
1331 std::optional< string_view_t > result;
1332
1333 if( auto * ptr = this->try_get_field(field_id) )
1334 result = string_view_t{ *ptr };
1335
1336 return result;
1337 }
1343
1361 template< typename Lambda >
1362 void
1364 noexcept(noexcept(lambda(
1365 std::declval<const http_header_field_t &>())))
1366 {
1367 for( const auto & f : m_fields )
1368 lambda( f );
1369 }
1370
1372
1401 template< typename Lambda >
1402 void
1404 http_field_t field_id,
1405 Lambda && lambda ) const
1406 noexcept(noexcept(lambda(
1407 std::declval<const string_view_t &>())))
1408 {
1409 static_assert(
1410 std::is_same<
1412 decltype(lambda(std::declval<const string_view_t &>()))
1413 >::value,
1414 "lambda should return restinio::http_header_fields_t::handling_result_t" );
1415
1416 for( const auto & f : m_fields )
1417 {
1418 if( field_id == f.field_id() )
1419 {
1420 const handling_result_t r = lambda( f.value() );
1421 if( stop_enumeration() == r )
1422 break;
1423 }
1424 }
1425 }
1426
1428
1457 template< typename Lambda >
1458 void
1461 Lambda && lambda ) const
1462 noexcept(noexcept(lambda(
1463 std::declval<const string_view_t &>())))
1464 {
1465 static_assert(
1466 std::is_same<
1468 decltype(lambda(std::declval<const string_view_t &>()))
1469 >::value,
1470 "lambda should return restinio::http_header_fields_t::handling_result_t" );
1471
1472 for( const auto & f : m_fields )
1473 {
1474 if( impl::is_equal_caseless( f.name(), field_name ) )
1475 {
1476 const handling_result_t r = lambda( f.value() );
1477 if( stop_enumeration() == r )
1478 break;
1479 }
1480 }
1481 }
1482
1485 {
1486 return m_fields.cbegin();
1487 }
1488
1491 {
1492 return m_fields.cend();
1493 }
1494
1496 {
1497 return m_fields.size();
1498 }
1499
1500 private:
1502
1510 void
1512 {
1513 m_fields.back().append_value( field_value );
1514 }
1515
1516 fields_container_t::iterator
1518 {
1519 return std::find_if(
1520 m_fields.begin(),
1521 m_fields.end(),
1522 [&]( const auto & f ){
1523 return impl::is_equal_caseless( f.name(), field_name );
1524 } );
1525 }
1526
1527 fields_container_t::const_iterator
1529 {
1530 return std::find_if(
1531 m_fields.cbegin(),
1532 m_fields.cend(),
1533 [&]( const auto & f ){
1534 return impl::is_equal_caseless( f.name(), field_name );
1535 } );
1536 }
1537
1538 fields_container_t::iterator
1539 find( http_field_t field_id ) noexcept
1540 {
1541 return std::find_if(
1542 m_fields.begin(),
1543 m_fields.end(),
1544 [&]( const auto & f ){
1545 return f.field_id() == field_id;
1546 } );
1547 }
1548
1549 fields_container_t::const_iterator
1550 cfind( http_field_t field_id ) const noexcept
1551 {
1552 return std::find_if(
1553 m_fields.cbegin(),
1554 m_fields.cend(),
1555 [&]( const auto & f ){
1556 return f.field_id() == field_id;
1557 } );
1558 }
1559
1561};
1562
1563//
1564// http_connection_header_t
1565//
1566
1568enum class http_connection_header_t : std::uint8_t
1569{
1570 keep_alive,
1571 close,
1572 upgrade
1573};
1574
1575//
1576// http_header_common_t
1577//
1578
1581 : public http_header_fields_t
1582{
1583 public:
1586 std::uint16_t
1589
1590 void
1591 http_major( std::uint16_t v ) noexcept
1592 { m_http_major = v; }
1593
1594 std::uint16_t
1597
1598 void
1599 http_minor( std::uint16_t v ) noexcept
1600 { m_http_minor = v; }
1602
1604 std::uint64_t
1607
1608 void
1609 content_length( std::uint64_t l ) noexcept
1610 { m_content_length = l; }
1611
1612 bool
1617
1618 void
1625
1629 {
1631 }
1632
1634 void
1639
1640 private:
1643 std::uint16_t m_http_major{1};
1644 std::uint16_t m_http_minor{1};
1646
1648 std::uint64_t m_content_length{ 0 };
1649
1651};
1652
1654#define RESTINIO_HTTP_METHOD_MAP(RESTINIO_GEN) \
1655 RESTINIO_GEN( http_method_delete, HTTP_DELETE, DELETE ) \
1656 RESTINIO_GEN( http_method_get, HTTP_GET, GET ) \
1657 RESTINIO_GEN( http_method_head, HTTP_HEAD, HEAD ) \
1658 RESTINIO_GEN( http_method_post, HTTP_POST, POST ) \
1659 RESTINIO_GEN( http_method_put, HTTP_PUT, PUT ) \
1660 /* pathological */ \
1661 RESTINIO_GEN( http_method_connect, HTTP_CONNECT, CONNECT ) \
1662 RESTINIO_GEN( http_method_options, HTTP_OPTIONS, OPTIONS ) \
1663 RESTINIO_GEN( http_method_trace, HTTP_TRACE, TRACE ) \
1664 /* WebDAV */ \
1665 RESTINIO_GEN( http_method_copy, HTTP_COPY, COPY ) \
1666 RESTINIO_GEN( http_method_lock, HTTP_LOCK, LOCK ) \
1667 RESTINIO_GEN( http_method_mkcol, HTTP_MKCOL, MKCOL ) \
1668 RESTINIO_GEN( http_method_move, HTTP_MOVE, MOVE ) \
1669 RESTINIO_GEN( http_method_propfind, HTTP_PROPFIND, PROPFIND ) \
1670 RESTINIO_GEN( http_method_proppatch, HTTP_PROPPATCH, PROPPATCH ) \
1671 RESTINIO_GEN( http_method_search, HTTP_SEARCH, SEARCH ) \
1672 RESTINIO_GEN( http_method_unlock, HTTP_UNLOCK, UNLOCK ) \
1673 RESTINIO_GEN( http_method_bind, HTTP_BIND, BIND ) \
1674 RESTINIO_GEN( http_method_rebind, HTTP_REBIND, REBIND ) \
1675 RESTINIO_GEN( http_method_unbind, HTTP_UNBIND, UNBIND ) \
1676 RESTINIO_GEN( http_method_acl, HTTP_ACL, ACL ) \
1677 /* subversion */ \
1678 RESTINIO_GEN( http_method_report, HTTP_REPORT, REPORT ) \
1679 RESTINIO_GEN( http_method_mkactivity, HTTP_MKACTIVITY, MKACTIVITY ) \
1680 RESTINIO_GEN( http_method_checkout, HTTP_CHECKOUT, CHECKOUT ) \
1681 RESTINIO_GEN( http_method_merge, HTTP_MERGE, MERGE ) \
1682 /* upnp */ \
1683 RESTINIO_GEN( http_method_msearch, HTTP_MSEARCH, M-SEARCH) \
1684 RESTINIO_GEN( http_method_notify, HTTP_NOTIFY, NOTIFY ) \
1685 RESTINIO_GEN( http_method_subscribe, HTTP_SUBSCRIBE, SUBSCRIBE ) \
1686 RESTINIO_GEN( http_method_unsubscribe, HTTP_UNSUBSCRIBE, UNSUBSCRIBE ) \
1687 /* RFC-5789 */ \
1688 RESTINIO_GEN( http_method_patch, HTTP_PATCH, PATCH ) \
1689 RESTINIO_GEN( http_method_purge, HTTP_PURGE, PURGE ) \
1690 /* CalDAV */ \
1691 RESTINIO_GEN( http_method_mkcalendar, HTTP_MKCALENDAR, MKCALENDAR ) \
1692 /* RFC-2068, section 19.6.1.2 */ \
1693 RESTINIO_GEN( http_method_link, HTTP_LINK, LINK ) \
1694 RESTINIO_GEN( http_method_unlink, HTTP_UNLINK, UNLINK )
1695
1696//
1697// http_method_id_t
1698//
1746{
1748 const char * m_name;
1749
1750public:
1751 static constexpr const int unknown_method = -1;
1752
1755 , m_name{ "<undefined>" }
1756 {}
1758 int value,
1759 const char * name ) noexcept
1760 : m_value{ value }
1761 , m_name{ name }
1762 {}
1763
1764 constexpr http_method_id_t( const http_method_id_t & ) noexcept = default;
1765 constexpr http_method_id_t &
1766 operator=( const http_method_id_t & ) noexcept = default;
1767
1771
1774
1775 constexpr const char *
1777
1778 friend constexpr bool
1779 operator==( const http_method_id_t & a, const http_method_id_t & b ) noexcept {
1780 return a.raw_id() == b.raw_id();
1781 }
1782
1783 friend constexpr bool
1784 operator!=( const http_method_id_t & a, const http_method_id_t & b ) noexcept {
1785 return a.raw_id() != b.raw_id();
1786 }
1787
1788 friend constexpr bool
1789 operator<( const http_method_id_t & a, const http_method_id_t & b ) noexcept {
1790 return a.raw_id() < b.raw_id();
1791 }
1792};
1793
1794inline std::ostream &
1795operator<<( std::ostream & to, const http_method_id_t & m )
1796{
1797 return to << m.c_str();
1798}
1799
1800// Generate helper funcs.
1801#define RESTINIO_HTTP_METHOD_FUNC_GEN( func_name, nodejs_code, method_name ) \
1802 inline constexpr http_method_id_t func_name() { \
1803 return { nodejs_code, #method_name }; \
1804 }
1805
1807#undef RESTINIO_HTTP_METHOD_FUNC_GEN
1808
1809inline constexpr http_method_id_t
1811{
1812 return http_method_id_t{};
1813}
1814
1815//
1816// default_http_methods_t
1817//
1834{
1835public :
1836 inline static constexpr http_method_id_t
1837 from_nodejs( int value ) noexcept
1838 {
1840 switch( value )
1841 {
1842#define RESTINIO_HTTP_METHOD_FUNC_GEN( func_name, nodejs_code, method_name ) \
1843 case nodejs_code : result = func_name(); break;
1844
1846#undef RESTINIO_HTTP_METHOD_FUNC_GEN
1847 default : ; // Nothing to do.
1848 }
1849
1850 return result;
1851 }
1852};
1853
1854//
1855// http_request_header
1856//
1857
1860 : public http_header_common_t
1861{
1862 static std::size_t
1863 memchr_helper( int chr , const char * from, std::size_t size )
1864 {
1865 const char * result = static_cast< const char * >(
1866 std::memchr( from, chr, size ) );
1867
1868 return result ? static_cast< std::size_t >( result - from ) : size;
1869 }
1870
1871 public:
1873
1876 std::string request_target_ )
1877 : m_method{ method }
1878 {
1879 request_target( std::move( request_target_ ) );
1880 }
1881
1884 { return m_method; }
1885
1886 void
1888 { m_method = m; }
1889
1890 const std::string &
1893
1894 void
1895 request_target( std::string t )
1896 {
1897 m_request_target.assign( std::move( t ) );
1898
1900 memchr_helper( '#', m_request_target.data(), m_request_target.size() );
1901
1904 }
1905
1908
1910
1919
1921
1935
1936
1938
1943 fragment() const
1944 {
1945 return
1947 string_view_t{ nullptr, 0 } :
1951 }
1953
1955 void
1956 append_request_target( const char * at, size_t length )
1957 {
1959 {
1960 // If fragment separator hadn't already appeared,
1961 // search for it in a new block.
1962
1963 const auto fragment_separator_pos_inc =
1964 memchr_helper( '#', at, length );
1965
1967
1969 {
1970 // If request separator hadn't already appeared,
1971 // search for it in a new block.
1974 }
1975 }
1976 // Else fragment separator appeared
1977 // (req separator is either already defined or does not exist)
1978
1979 m_request_target.append( at, length );
1980 }
1981
1982 private:
1984 std::string m_request_target;
1985 std::size_t m_query_separator_pos{ 0 };
1987};
1988
1989//
1990// http_status_code_t
1991//
1992
1995{
1996 public:
1998 {}
1999
2000 constexpr explicit http_status_code_t( std::uint16_t status_code ) noexcept
2001 : m_status_code{ status_code }
2002 {}
2003
2004 constexpr auto
2006 {
2007 return m_status_code;
2008 }
2009
2010 constexpr bool
2011 operator == ( const http_status_code_t & sc ) const noexcept
2012 {
2013 return raw_code() == sc.raw_code();
2014 }
2015
2016 constexpr bool
2017 operator != ( const http_status_code_t & sc ) const noexcept
2018 {
2019 return sc.raw_code() != sc.raw_code();
2020 }
2021
2022 constexpr bool
2023 operator < ( const http_status_code_t & sc ) const noexcept
2024 {
2025 return sc.raw_code() < sc.raw_code();
2026 }
2027
2028 private:
2030 std::uint16_t m_status_code{ 0 };
2031};
2032
2034
2037template< typename CharT, typename Traits >
2038inline std::basic_ostream<CharT, Traits> &
2040 std::basic_ostream<CharT, Traits> & to,
2041 const http_status_code_t & status_code )
2042{
2043 return to << status_code.raw_code();
2044}
2045
2046namespace status_code
2047{
2048
2053
2054// Add '_', because 'continue is reserved word.'
2056
2058constexpr http_status_code_t ok{ 200 };
2067constexpr http_status_code_t found{ 302 };
2082constexpr http_status_code_t gone{ 410 };
2085
2086//413 Payload Too Large (RFC 7231)
2087// The request is larger than the server is willing or able to process.
2088// Previously called "Request Entity Too Large".[44]
2090
2091// 414 URI Too Long (RFC 7231)
2092// The URI provided was too long for the server to process.
2093// Often the result of too much data being encoded as a query-string of a GET request,
2094// in which case it should be converted to a POST request.
2095// Called "Request-URI Too Long" previously.[46]
2097
2108
2113 // RFC 7538
2115
2116 // RFC 2518
2123
2124 // RFC 6585
2130
2131} /* namespace status_code */
2132
2133//
2134// http_status_line_t
2135//
2136
2139{
2140 public:
2143
2146 std::string reason_phrase )
2147 : m_status_code{ sc }
2149 {}
2150
2154
2155 void
2158
2159 const std::string &
2162
2163 void
2164 reason_phrase( std::string r )
2165 { m_reason_phrase.assign( std::move( r ) ); }
2166
2167 private:
2169 std::string m_reason_phrase;
2170};
2171
2172inline std::ostream &
2173operator << ( std::ostream & o, const http_status_line_t & status_line )
2174{
2175 return o << "{" << status_line.status_code().raw_code() << ", "
2176 << status_line.reason_phrase() << "}";
2177}
2178
2183
2186
2189
2192
2195
2198
2201
2204
2207
2210
2213
2216
2219
2222
2225
2228
2231
2234
2237
2240
2243
2246
2249
2252
2255
2258
2261
2264
2267
2270
2273
2276
2279
2282
2285
2288
2291
2294
2297
2300
2304
2309 // RFC 7538
2312
2313 // RFC 2518
2316
2319
2322
2325
2328
2331
2332 // RFC 6585
2335
2338
2341
2345
2346//
2347// http_response_header_t
2348//
2349
2352 : public http_header_common_t
2353{
2354 public:
2357
2361
2365
2366 void
2369
2370 const std::string &
2373
2374 void
2375 reason_phrase( std::string r )
2376 { m_status_line.reason_phrase( std::move( r ) ); }
2377
2378 const http_status_line_t &
2380 {
2381 return m_status_line;
2382 }
2383
2384 void
2386 {
2387 m_status_line = std::move( sl );
2388 }
2389
2390 private:
2392};
2393
2394} /* namespace restinio */
The default implementation for http_method_mapper.
static constexpr http_method_id_t from_nodejs(int value) noexcept
Exception class for all exceptions thrown by RESTinio.
Definition exception.hpp:26
A single header field.
http_header_field_t(http_field_t field_id, string_view_t value)
void field_id(http_field_t field_id)
http_header_field_t(std::string name, std::string value)
const std::string & value() const noexcept
http_header_field_t(string_view_t name, string_view_t value)
const std::string & name() const noexcept
http_field_t field_id() const noexcept
http_header_field_t(http_field_t field_id, std::string value)
void append_value(string_view_t v)
bool has_field(string_view_t field_name) const noexcept
Check field by name.
string_view_t value_of(string_view_t name) const
Get the value of a field or throw if the field not found.
void add_field(http_header_field_t http_header_field)
Add a field in the form of http_header_field object.
http_header_fields_t(const http_header_fields_t &)=default
std::optional< string_view_t > opt_value_of(http_field_t field_id) const noexcept
Get optional value of a field.
void add_field(http_field_t field_id, std::string field_value)
Add a field in the form of id-value pair.
string_view_t value_of(http_field_t field_id) const
Get the value of a field or throw if the field not found.
fields_container_t::iterator find(string_view_t field_name) noexcept
nullable_pointer_t< const std::string > try_get_field(http_field_t field_id) const noexcept
Try to get the value of a field by field ID.
std::size_t remove_all_of(string_view_t field_name) noexcept
Remove all occurences of a field with specified name.
http_header_fields_t(http_header_fields_t &&)=default
fields_container_t::const_iterator const_iterator
Type of const_iterator for enumeration of fields.
static constexpr handling_result_t stop_enumeration() noexcept
void swap_fields(http_header_fields_t &http_header_fields)
auto get_field_or(string_view_t field_name, const char *default_value) const
Get field by name or default value if the field not found.
std::vector< http_header_field_t > fields_container_t
static constexpr handling_result_t continue_enumeration() noexcept
fields_container_t::const_iterator cfind(string_view_t field_name) const noexcept
void for_each_value_of(http_field_t field_id, Lambda &&lambda) const noexcept(noexcept(lambda(std::declval< const string_view_t & >())))
Enumeration of each value of a field.
void add_field(std::string field_name, std::string field_value)
Add a field in the form of name-value pair.
void for_each_value_of(string_view_t field_name, Lambda &&lambda) const noexcept(noexcept(lambda(std::declval< const string_view_t & >())))
Enumeration of each value of a field.
bool remove_field(http_field_t field_id) noexcept
Remove field by id.
http_header_fields_t & operator=(const http_header_fields_t &)=default
const std::string & get_field(http_field_t field_id) const
Get field by id.
void set_field(std::string field_name, std::string field_value)
Set field with string pair.
std::string get_field_or(string_view_t field_name, std::string &&default_value) const
Get field value by field name or default value if the field not found.
void set_field(http_field_t field_id, std::string field_value)
Set field with id-value pair.
http_header_fields_t & operator=(http_header_fields_t &&)=default
std::string get_field_or(http_field_t field_id, std::string &&default_value) const
Get field by id or default value if the field not found.
handling_result_t
The result of handling yet another field value.
@ stop_enumeration
The loop on field values should be stopped.
@ continue_enumeration
Next value of field should be found and passed to the next invocation of handler.
nullable_pointer_t< const std::string > try_get_field(string_view_t field_name) const noexcept
Try to get the value of a field by field name.
void append_last_field(string_view_t field_value)
Appends last added field.
std::string get_field_or(http_field_t field_id, string_view_t default_value) const
Get field by id or default value if the field not found.
void set_field(http_header_field_t http_header_field)
Set header field via http_header_field_t.
void for_each_field(Lambda &&lambda) const noexcept(noexcept(lambda(std::declval< const http_header_field_t & >())))
Enumeration of fields.
void append_field(string_view_t field_name, string_view_t field_value)
Append field with name.
std::optional< string_view_t > opt_value_of(string_view_t name) const noexcept
Get optional value of a field.
auto get_field_or(http_field_t field_id, const char *default_value) const
Get field by id or default value if the field not found.
const_iterator end() const noexcept
const std::string & get_field(string_view_t field_name) const
Get field by name.
auto fields_count() const noexcept
auto get_field_or(string_view_t field_name, const std::string &default_value) const
Get field by name or default value if the field not found.
const_iterator begin() const noexcept
bool remove_field(string_view_t field_name) noexcept
Remove field by name.
std::string get_field_or(string_view_t field_name, string_view_t default_value) const
Get field value by field name or default value if the field not found.
bool has_field(http_field_t field_id) const noexcept
Check field by field-id.
fields_container_t::const_iterator cfind(http_field_t field_id) const noexcept
auto get_field_or(http_field_t field_id, const std::string &default_value) const
Get field by id or default value if the field not found.
std::size_t remove_all_of(http_field_t field_id) noexcept
Remove all occurences of a field with specified id.
fields_container_t::iterator find(http_field_t field_id) noexcept
void append_field(http_field_t field_id, string_view_t field_value)
Append field with id.
A type for representation of HTTP method ID.
friend constexpr bool operator<(const http_method_id_t &a, const http_method_id_t &b) noexcept
static constexpr const int unknown_method
constexpr http_method_id_t(const http_method_id_t &) noexcept=default
friend constexpr bool operator!=(const http_method_id_t &a, const http_method_id_t &b) noexcept
constexpr http_method_id_t() noexcept
constexpr http_method_id_t(http_method_id_t &&) noexcept=default
constexpr auto raw_id() const noexcept
constexpr http_method_id_t & operator=(const http_method_id_t &) noexcept=default
constexpr http_method_id_t(int value, const char *name) noexcept
friend constexpr bool operator==(const http_method_id_t &a, const http_method_id_t &b) noexcept
constexpr const char * c_str() const noexcept
A handy wrapper for HTTP response status code.
constexpr auto raw_code() const noexcept
constexpr bool operator==(const http_status_code_t &sc) const noexcept
constexpr bool operator!=(const http_status_code_t &sc) const noexcept
constexpr http_status_code_t() noexcept
constexpr bool operator<(const http_status_code_t &sc) const noexcept
constexpr http_status_code_t(std::uint16_t status_code) noexcept
std::uint16_t m_status_code
Status code value.
HTTP response header status line.
void reason_phrase(std::string r)
void status_code(http_status_code_t c) noexcept
http_status_line_t(http_status_code_t sc, std::string reason_phrase)
http_status_code_t status_code() const noexcept
http_status_code_t m_status_code
const std::string & reason_phrase() const noexcept
#define RESTINIO_HTTP_METHOD_MAP(RESTINIO_GEN)
HTTP methods mapping with nodejs http methods.
#define RESTINIO_HEADER_FIELDS_DEFAULT_RESERVE_COUNT
#define RESTINIO_HTTP_METHOD_FUNC_GEN(func_name, nodejs_code, method_name)
#define RESTINIO_HTTP_FIELD_STR_GEN(name, string_name)
#define RESTINIO_HTTP_FIELDS_MAP(RESTINIO_GEN)
#define RESTINIO_HTTP_CHECK_FOR_FIELD(field_id, candidate_field_name)
A special wrapper around fmtlib include files.
#define RESTINIO_FMT_FORMAT_STRING(s)
decltype(auto) streamed(T &&v) noexcept
bool is_equal_caseless(const char *a, const char *b, std::size_t size) noexcept
Comparator for fields names.
void append_last_field_accessor(http_header_fields_t &, string_view_t)
constexpr http_status_code_t switching_protocols
constexpr http_status_code_t gone
constexpr http_status_code_t precondition_failed
constexpr http_status_code_t ok
constexpr http_status_code_t unauthorized
constexpr http_status_code_t bad_request
constexpr http_status_code_t see_other
constexpr http_status_code_t multiple_choices
constexpr http_status_code_t not_acceptable
constexpr http_status_code_t not_found
constexpr http_status_code_t forbidden
constexpr http_status_code_t gateway_time_out
constexpr http_status_code_t uri_too_long
constexpr http_status_code_t partial_content
constexpr http_status_code_t requested_range_not_satisfiable
constexpr http_status_code_t unsupported_media_type
constexpr http_status_code_t locked
constexpr http_status_code_t not_implemented
constexpr http_status_code_t request_header_fields_too_large
constexpr http_status_code_t payload_too_large
constexpr http_status_code_t failed_dependency
constexpr http_status_code_t unprocessable_entity
constexpr http_status_code_t conflict
constexpr http_status_code_t network_authentication_required
constexpr http_status_code_t not_modified
constexpr http_status_code_t no_content
constexpr http_status_code_t accepted
constexpr http_status_code_t created
constexpr http_status_code_t http_version_not_supported
constexpr http_status_code_t multi_status
constexpr http_status_code_t processing
constexpr http_status_code_t bad_gateway
constexpr http_status_code_t use_proxy
constexpr http_status_code_t found
constexpr http_status_code_t continue_
constexpr http_status_code_t temporary_redirect
constexpr http_status_code_t method_not_allowed
constexpr http_status_code_t permanent_redirect
constexpr http_status_code_t length_required
constexpr http_status_code_t insufficient_storage
constexpr http_status_code_t service_unavailable
constexpr http_status_code_t precondition_required
constexpr http_status_code_t request_time_out
constexpr http_status_code_t internal_server_error
constexpr http_status_code_t too_many_requests
constexpr http_status_code_t proxy_authentication_required
constexpr http_status_code_t payment_required
constexpr http_status_code_t moved_permanently
constexpr http_status_code_t reset_content
constexpr http_status_code_t expectation_failed
constexpr http_status_code_t non_authoritative_information
http_status_line_t status_gone()
http_status_line_t status_not_acceptable()
http_status_line_t status_non_authoritative_information()
http_status_line_t status_locked()
http_status_line_t status_not_implemented()
http_status_line_t status_unprocessable_entity()
http_status_line_t status_http_version_not_supported()
http_status_line_t status_payment_required()
run_on_this_thread_settings_t< Traits > on_this_thread()
A special marker for the case when http_server must be run on the context of the current thread.
http_status_line_t status_conflict()
http_status_line_t status_permanent_redirect()
http_status_line_t status_partial_content()
http_status_line_t status_no_content()
http_status_line_t status_network_authentication_required()
http_status_line_t status_not_modified()
http_status_line_t status_failed_dependency()
http_status_line_t status_moved_permanently()
http_status_line_t status_forbidden()
http_connection_header_t
Values for conection header field.
std::ostream & operator<<(std::ostream &o, response_parts_attr_t attr)
std::string_view string_view_t
http_status_line_t status_continue()
http_status_line_t status_requested_range_not_satisfiable()
http_status_line_t status_internal_server_error()
http_status_line_t status_use_proxy()
http_status_line_t status_request_time_out()
http_status_line_t status_created()
http_status_line_t status_unauthorized()
http_status_line_t status_temporary_redirect()
http_status_line_t status_gateway_time_out()
http_status_line_t status_found()
http_status_line_t status_multiple_choices()
constexpr http_method_id_t http_method_unknown()
http_status_line_t status_insufficient_storage()
http_status_line_t status_unsupported_media_type()
http_status_line_t status_too_many_requests()
http_status_line_t status_bad_gateway()
http_status_line_t status_expectation_failed()
http_status_line_t status_see_other()
http_field_t string_to_field(string_view_t field) noexcept
Helper function to get method string name.
const char * field_to_string(http_field_t f) noexcept
Helper sunction to get method string name.
http_status_line_t status_reset_content()
T * nullable_pointer_t
Type for pointer that can be nullptr.
http_status_line_t status_ok()
http_field_t
C++ enum that repeats nodejs c-style enum.
RESTINIO_HTTP_FIELD_GEN(name, ignored)
http_status_line_t status_switching_protocols()
http_status_line_t status_payload_too_large()
http_status_line_t status_uri_too_long()
http_status_line_t status_request_header_fields_too_large()
http_status_line_t status_processing()
http_status_line_t status_precondition_failed()
http_status_line_t status_method_not_allowed()
http_status_line_t status_accepted()
http_status_line_t status_proxy_authentication_required()
http_status_line_t status_precondition_required()
http_status_line_t status_bad_request()
http_status_line_t status_not_found()
http_status_line_t status_multi_status()
http_status_line_t status_service_unavailable()
http_status_line_t status_length_required()
Helpers for caseless comparison of strings.
Req/Resp headers common data.
void should_keep_alive(bool keep_alive) noexcept
void content_length(std::uint64_t l) noexcept
void http_major(std::uint16_t v) noexcept
bool should_keep_alive() const noexcept
http_connection_header_t m_http_connection_header_field_value
std::uint16_t http_major() const noexcept
Http version.
http_connection_header_t connection() const
Get the value of 'connection' header field.
std::uint16_t m_http_major
Http version.
std::uint64_t m_content_length
Length of body of an http-message.
std::uint64_t content_length() const noexcept
Length of body of an http-message.
void http_minor(std::uint16_t v) noexcept
std::uint16_t http_minor() const noexcept
void connection(http_connection_header_t ch) noexcept
Set the value of 'connection' header field.
void method(http_method_id_t m) noexcept
string_view_t fragment() const
Get the fragment part of the request URL.
string_view_t path() const noexcept
Request URL-structure.
const std::string & request_target() const noexcept
void append_request_target(const char *at, size_t length)
Helpfull function for using in parser callback.
static std::size_t memchr_helper(int chr, const char *from, std::size_t size)
http_method_id_t method() const noexcept
string_view_t query() const noexcept
Get the query part of the request URL.
http_request_header_t(http_method_id_t method, std::string request_target_)
void status_code(http_status_code_t c) noexcept
const http_status_line_t & status_line() const noexcept
void status_line(http_status_line_t sl)
http_status_code_t status_code() const noexcept
http_response_header_t(http_status_line_t status_line)
const std::string & reason_phrase() const noexcept