RESTinio
http_headers.hpp
Go to the documentation of this file.
1/*
2 restinio
3*/
4
9#pragma once
10
12
14
17#include <restinio/optional.hpp>
19
20#include <http_parser.h>
21
22#include <iosfwd>
23#include <string>
24#include <vector>
25#include <algorithm>
26
27namespace restinio
28{
29
30
31// Adopted header fields
32// (https://www.iana.org/assignments/message-headers/message-headers.xml#perm-headers).
33// Fields `Connection` and `Content-Length` are specieal cases, thus they are excluded from the list.
34#define RESTINIO_HTTP_FIELDS_MAP( RESTINIO_GEN ) \
35 RESTINIO_GEN( a_im, A-IM ) \
36 RESTINIO_GEN( accept, Accept ) \
37 RESTINIO_GEN( accept_additions, Accept-Additions ) \
38 RESTINIO_GEN( accept_charset, Accept-Charset ) \
39 RESTINIO_GEN( accept_datetime, Accept-Datetime ) \
40 RESTINIO_GEN( accept_encoding, Accept-Encoding ) \
41 RESTINIO_GEN( accept_features, Accept-Features ) \
42 RESTINIO_GEN( accept_language, Accept-Language ) \
43 RESTINIO_GEN( accept_patch, Accept-Patch ) \
44 RESTINIO_GEN( accept_post, Accept-Post ) \
45 RESTINIO_GEN( accept_ranges, Accept-Ranges ) \
46 RESTINIO_GEN( age, Age ) \
47 RESTINIO_GEN( allow, Allow ) \
48 RESTINIO_GEN( alpn, ALPN ) \
49 RESTINIO_GEN( alt_svc, Alt-Svc ) \
50 RESTINIO_GEN( alt_used, Alt-Used ) \
51 RESTINIO_GEN( alternates, Alternates ) \
52 RESTINIO_GEN( apply_to_redirect_ref, Apply-To-Redirect-Ref ) \
53 RESTINIO_GEN( authentication_control, Authentication-Control ) \
54 RESTINIO_GEN( authentication_info, Authentication-Info ) \
55 RESTINIO_GEN( authorization, Authorization ) \
56 RESTINIO_GEN( c_ext, C-Ext ) \
57 RESTINIO_GEN( c_man, C-Man ) \
58 RESTINIO_GEN( c_opt, C-Opt ) \
59 RESTINIO_GEN( c_pep, C-PEP ) \
60 RESTINIO_GEN( c_pep_info, C-PEP-Info ) \
61 RESTINIO_GEN( cache_control, Cache-Control ) \
62 RESTINIO_GEN( caldav_timezones, CalDAV-Timezones ) \
63 RESTINIO_GEN( close, Close ) \
64 RESTINIO_GEN( content_base, Content-Base ) \
65 RESTINIO_GEN( content_disposition, Content-Disposition ) \
66 RESTINIO_GEN( content_encoding, Content-Encoding ) \
67 RESTINIO_GEN( content_id, Content-ID ) \
68 RESTINIO_GEN( content_language, Content-Language ) \
69 RESTINIO_GEN( content_location, Content-Location ) \
70 RESTINIO_GEN( content_md5, Content-MD5 ) \
71 RESTINIO_GEN( content_range, Content-Range ) \
72 RESTINIO_GEN( content_script_type, Content-Script-Type ) \
73 RESTINIO_GEN( content_style_type, Content-Style-Type ) \
74 RESTINIO_GEN( content_type, Content-Type ) \
75 RESTINIO_GEN( content_version, Content-Version ) \
76 RESTINIO_GEN( cookie, Cookie ) \
77 RESTINIO_GEN( cookie2, Cookie2 ) \
78 RESTINIO_GEN( dasl, DASL ) \
79 RESTINIO_GEN( dav, DAV ) \
80 RESTINIO_GEN( date, Date ) \
81 RESTINIO_GEN( default_style, Default-Style ) \
82 RESTINIO_GEN( delta_base, Delta-Base ) \
83 RESTINIO_GEN( depth, Depth ) \
84 RESTINIO_GEN( derived_from, Derived-From ) \
85 RESTINIO_GEN( destination, Destination ) \
86 RESTINIO_GEN( differential_id, Differential-ID ) \
87 RESTINIO_GEN( digest, Digest ) \
88 RESTINIO_GEN( etag, ETag ) \
89 RESTINIO_GEN( expect, Expect ) \
90 RESTINIO_GEN( expires, Expires ) \
91 RESTINIO_GEN( ext, Ext ) \
92 RESTINIO_GEN( forwarded, Forwarded ) \
93 RESTINIO_GEN( from, From ) \
94 RESTINIO_GEN( getprofile, GetProfile ) \
95 RESTINIO_GEN( hobareg, Hobareg ) \
96 RESTINIO_GEN( host, Host ) \
97 RESTINIO_GEN( http2_settings, HTTP2-Settings ) \
98 RESTINIO_GEN( im, IM ) \
99 RESTINIO_GEN( if_, If ) \
100 RESTINIO_GEN( if_match, If-Match ) \
101 RESTINIO_GEN( if_modified_since, If-Modified-Since ) \
102 RESTINIO_GEN( if_none_match, If-None-Match ) \
103 RESTINIO_GEN( if_range, If-Range ) \
104 RESTINIO_GEN( if_schedule_tag_match, If-Schedule-Tag-Match ) \
105 RESTINIO_GEN( if_unmodified_since, If-Unmodified-Since ) \
106 RESTINIO_GEN( keep_alive, Keep-Alive ) \
107 RESTINIO_GEN( label, Label ) \
108 RESTINIO_GEN( last_modified, Last-Modified ) \
109 RESTINIO_GEN( link, Link ) \
110 RESTINIO_GEN( location, Location ) \
111 RESTINIO_GEN( lock_token, Lock-Token ) \
112 RESTINIO_GEN( man, Man ) \
113 RESTINIO_GEN( max_forwards, Max-Forwards ) \
114 RESTINIO_GEN( memento_datetime, Memento-Datetime ) \
115 RESTINIO_GEN( meter, Meter ) \
116 RESTINIO_GEN( mime_version, MIME-Version ) \
117 RESTINIO_GEN( negotiate, Negotiate ) \
118 RESTINIO_GEN( opt, Opt ) \
119 RESTINIO_GEN( optional_www_authenticate, Optional-WWW-Authenticate ) \
120 RESTINIO_GEN( ordering_type, Ordering-Type ) \
121 RESTINIO_GEN( origin, Origin ) \
122 RESTINIO_GEN( overwrite, Overwrite ) \
123 RESTINIO_GEN( p3p, P3P ) \
124 RESTINIO_GEN( pep, PEP ) \
125 RESTINIO_GEN( pics_label, PICS-Label ) \
126 RESTINIO_GEN( pep_info, Pep-Info ) \
127 RESTINIO_GEN( position, Position ) \
128 RESTINIO_GEN( pragma, Pragma ) \
129 RESTINIO_GEN( prefer, Prefer ) \
130 RESTINIO_GEN( preference_applied, Preference-Applied ) \
131 RESTINIO_GEN( profileobject, ProfileObject ) \
132 RESTINIO_GEN( protocol, Protocol ) \
133 RESTINIO_GEN( protocol_info, Protocol-Info ) \
134 RESTINIO_GEN( protocol_query, Protocol-Query ) \
135 RESTINIO_GEN( protocol_request, Protocol-Request ) \
136 RESTINIO_GEN( proxy_authenticate, Proxy-Authenticate ) \
137 RESTINIO_GEN( proxy_authentication_info, Proxy-Authentication-Info ) \
138 RESTINIO_GEN( proxy_authorization, Proxy-Authorization ) \
139 RESTINIO_GEN( proxy_features, Proxy-Features ) \
140 RESTINIO_GEN( proxy_instruction, Proxy-Instruction ) \
141 RESTINIO_GEN( public_, Public ) \
142 RESTINIO_GEN( public_key_pins, Public-Key-Pins ) \
143 RESTINIO_GEN( public_key_pins_report_only, Public-Key-Pins-Report-Only ) \
144 RESTINIO_GEN( range, Range ) \
145 RESTINIO_GEN( redirect_ref, Redirect-Ref ) \
146 RESTINIO_GEN( referer, Referer ) \
147 RESTINIO_GEN( retry_after, Retry-After ) \
148 RESTINIO_GEN( safe, Safe ) \
149 RESTINIO_GEN( schedule_reply, Schedule-Reply ) \
150 RESTINIO_GEN( schedule_tag, Schedule-Tag ) \
151 RESTINIO_GEN( sec_websocket_accept, Sec-WebSocket-Accept ) \
152 RESTINIO_GEN( sec_websocket_extensions, Sec-WebSocket-Extensions ) \
153 RESTINIO_GEN( sec_websocket_key, Sec-WebSocket-Key ) \
154 RESTINIO_GEN( sec_websocket_protocol, Sec-WebSocket-Protocol ) \
155 RESTINIO_GEN( sec_websocket_version, Sec-WebSocket-Version ) \
156 RESTINIO_GEN( security_scheme, Security-Scheme ) \
157 RESTINIO_GEN( server, Server ) \
158 RESTINIO_GEN( set_cookie, Set-Cookie ) \
159 RESTINIO_GEN( set_cookie2, Set-Cookie2 ) \
160 RESTINIO_GEN( setprofile, SetProfile ) \
161 RESTINIO_GEN( slug, SLUG ) \
162 RESTINIO_GEN( soapaction, SoapAction ) \
163 RESTINIO_GEN( status_uri, Status-URI ) \
164 RESTINIO_GEN( strict_transport_security, Strict-Transport-Security ) \
165 RESTINIO_GEN( surrogate_capability, Surrogate-Capability ) \
166 RESTINIO_GEN( surrogate_control, Surrogate-Control ) \
167 RESTINIO_GEN( tcn, TCN ) \
168 RESTINIO_GEN( te, TE ) \
169 RESTINIO_GEN( timeout, Timeout ) \
170 RESTINIO_GEN( topic, Topic ) \
171 RESTINIO_GEN( trailer, Trailer ) \
172 RESTINIO_GEN( transfer_encoding, Transfer-Encoding ) \
173 RESTINIO_GEN( ttl, TTL ) \
174 RESTINIO_GEN( urgency, Urgency ) \
175 RESTINIO_GEN( uri, URI ) \
176 RESTINIO_GEN( upgrade, Upgrade ) \
177 RESTINIO_GEN( user_agent, User-Agent ) \
178 RESTINIO_GEN( variant_vary, Variant-Vary ) \
179 RESTINIO_GEN( vary, Vary ) \
180 RESTINIO_GEN( via, Via ) \
181 RESTINIO_GEN( www_authenticate, WWW-Authenticate ) \
182 RESTINIO_GEN( want_digest, Want-Digest ) \
183 RESTINIO_GEN( warning, Warning ) \
184 RESTINIO_GEN( x_frame_options, X-Frame-Options ) \
185\
186 RESTINIO_GEN( access_control, Access-Control ) \
187 RESTINIO_GEN( access_control_allow_credentials, Access-Control-Allow-Credentials ) \
188 RESTINIO_GEN( access_control_allow_headers, Access-Control-Allow-Headers )\
189 RESTINIO_GEN( access_control_allow_methods, Access-Control-Allow-Methods )\
190 RESTINIO_GEN( access_control_allow_origin, Access-Control-Allow-Origin ) \
191 RESTINIO_GEN( access_control_max_age, Access-Control-Max-Age ) \
192 RESTINIO_GEN( access_control_request_method, Access-Control-Request-Method ) \
193 RESTINIO_GEN( access_control_request_headers, Access-Control-Request-Headers ) \
194 RESTINIO_GEN( compliance, Compliance ) \
195 RESTINIO_GEN( content_transfer_encoding, Content-Transfer-Encoding ) \
196 RESTINIO_GEN( cost, Cost ) \
197 RESTINIO_GEN( ediint_features, EDIINT-Features ) \
198 RESTINIO_GEN( message_id, Message-ID ) \
199 RESTINIO_GEN( method_check, Method-Check ) \
200 RESTINIO_GEN( method_check_expires, Method-Check-Expires ) \
201 RESTINIO_GEN( non_compliance, Non-Compliance ) \
202 RESTINIO_GEN( optional, Optional ) \
203 RESTINIO_GEN( referer_root, Referer-Root ) \
204 RESTINIO_GEN( resolution_hint, Resolution-Hint ) \
205 RESTINIO_GEN( resolver_location, Resolver-Location ) \
206 RESTINIO_GEN( subok, SubOK ) \
207 RESTINIO_GEN( subst, Subst ) \
208 RESTINIO_GEN( title, Title ) \
209 RESTINIO_GEN( ua_color, UA-Color ) \
210 RESTINIO_GEN( ua_media, UA-Media ) \
211 RESTINIO_GEN( ua_pixels, UA-Pixels ) \
212 RESTINIO_GEN( ua_resolution, UA-Resolution ) \
213 RESTINIO_GEN( ua_windowpixels, UA-Windowpixels ) \
214 RESTINIO_GEN( version, Version ) \
215 RESTINIO_GEN( x_device_accept, X-Device-Accept ) \
216 RESTINIO_GEN( x_device_accept_charset, X-Device-Accept-Charset ) \
217 RESTINIO_GEN( x_device_accept_encoding, X-Device-Accept-Encoding ) \
218 RESTINIO_GEN( x_device_accept_language, X-Device-Accept-Language ) \
219 RESTINIO_GEN( x_device_user_agent, X-Device-User-Agent )
220 // SPECIAL CASE: RESTINIO_GEN( connection, Connection )
221 // SPECIAL CASE: RESTINIO_GEN( content_length, Content-Length )
222
223//
224// http_field_t
225//
226
228
232enum class http_field_t : std::uint8_t //By now 152 + 34 + 1 items fits to uint8_t
233{
234#define RESTINIO_HTTP_FIELD_GEN( name, ignored ) name,
235 RESTINIO_HTTP_FIELDS_MAP( RESTINIO_HTTP_FIELD_GEN )
236#undef RESTINIO_HTTP_FIELD_GEN
237 // Unspecified field.
238 field_unspecified
239};
240
243
244//
245// string_to_field()
246//
247
250inline http_field_t
252{
253 const char * field_name = field.data();
254 const std::size_t field_name_size = field.size();
255
256#define RESTINIO_HTTP_CHECK_FOR_FIELD( field_id, candidate_field_name ) \
257 if( impl::is_equal_caseless(field_name, #candidate_field_name , field_name_size ) ) \
258 return http_field_t:: field_id;
259
260 // TODO: make most popular fields to be checked first.
261
262 switch( field_name_size )
263 {
264 case 2:
268 break;
269
270 case 3:
282 break;
283
284 case 4:
285 // Known to be more used first:
287
299 break;
300
301 case 5:
302 RESTINIO_HTTP_CHECK_FOR_FIELD( allow, Allow )
303 RESTINIO_HTTP_CHECK_FOR_FIELD( c_ext, C-Ext )
304 RESTINIO_HTTP_CHECK_FOR_FIELD( c_man, C-Man )
305 RESTINIO_HTTP_CHECK_FOR_FIELD( c_opt, C-Opt )
306 RESTINIO_HTTP_CHECK_FOR_FIELD( c_pep, C-PEP )
308 RESTINIO_HTTP_CHECK_FOR_FIELD( depth, Depth )
309 RESTINIO_HTTP_CHECK_FOR_FIELD( label, Label )
310 RESTINIO_HTTP_CHECK_FOR_FIELD( meter, Meter )
311 RESTINIO_HTTP_CHECK_FOR_FIELD( range, Range )
312 RESTINIO_HTTP_CHECK_FOR_FIELD( topic, Topic )
313 RESTINIO_HTTP_CHECK_FOR_FIELD( subok, SubOK )
314 RESTINIO_HTTP_CHECK_FOR_FIELD( subst, Subst )
315 RESTINIO_HTTP_CHECK_FOR_FIELD( title, Title )
316 break;
317
318 case 6:
319 // Known to be more used first:
320 RESTINIO_HTTP_CHECK_FOR_FIELD( accept, Accept )
321 RESTINIO_HTTP_CHECK_FOR_FIELD( cookie, Cookie )
322 RESTINIO_HTTP_CHECK_FOR_FIELD( server, Server )
323
324 RESTINIO_HTTP_CHECK_FOR_FIELD( digest, Digest )
325 RESTINIO_HTTP_CHECK_FOR_FIELD( expect, Expect )
326 RESTINIO_HTTP_CHECK_FOR_FIELD( origin, Origin )
327 RESTINIO_HTTP_CHECK_FOR_FIELD( pragma, Pragma )
328 RESTINIO_HTTP_CHECK_FOR_FIELD( prefer, Prefer )
329 RESTINIO_HTTP_CHECK_FOR_FIELD( public_, Public )
330 break;
331
332 case 7:
333 RESTINIO_HTTP_CHECK_FOR_FIELD( alt_svc, Alt-Svc )
334 RESTINIO_HTTP_CHECK_FOR_FIELD( cookie2, Cookie2 )
335 RESTINIO_HTTP_CHECK_FOR_FIELD( expires, Expires )
336 RESTINIO_HTTP_CHECK_FOR_FIELD( hobareg, Hobareg )
337 RESTINIO_HTTP_CHECK_FOR_FIELD( referer, Referer )
338 RESTINIO_HTTP_CHECK_FOR_FIELD( timeout, Timeout )
339 RESTINIO_HTTP_CHECK_FOR_FIELD( trailer, Trailer )
340 RESTINIO_HTTP_CHECK_FOR_FIELD( urgency, Urgency )
341 RESTINIO_HTTP_CHECK_FOR_FIELD( upgrade, Upgrade )
342 RESTINIO_HTTP_CHECK_FOR_FIELD( warning, Warning )
343 RESTINIO_HTTP_CHECK_FOR_FIELD( version, Version )
344 break;
345
346 case 8:
347 RESTINIO_HTTP_CHECK_FOR_FIELD( alt_used, Alt-Used )
348 RESTINIO_HTTP_CHECK_FOR_FIELD( if_match, If-Match )
349 RESTINIO_HTTP_CHECK_FOR_FIELD( if_range, If-Range )
350 RESTINIO_HTTP_CHECK_FOR_FIELD( location, Location )
351 RESTINIO_HTTP_CHECK_FOR_FIELD( pep_info, Pep-Info )
352 RESTINIO_HTTP_CHECK_FOR_FIELD( position, Position )
353 RESTINIO_HTTP_CHECK_FOR_FIELD( protocol, Protocol )
354 RESTINIO_HTTP_CHECK_FOR_FIELD( optional, Optional )
355 RESTINIO_HTTP_CHECK_FOR_FIELD( ua_color, UA-Color )
356 RESTINIO_HTTP_CHECK_FOR_FIELD( ua_media, UA-Media )
357 break;
358
359 case 9:
360 RESTINIO_HTTP_CHECK_FOR_FIELD( forwarded, Forwarded )
361 RESTINIO_HTTP_CHECK_FOR_FIELD( negotiate, Negotiate )
362 RESTINIO_HTTP_CHECK_FOR_FIELD( overwrite, Overwrite )
363 RESTINIO_HTTP_CHECK_FOR_FIELD( ua_pixels, UA-Pixels )
364 break;
365
366 case 10:
367 RESTINIO_HTTP_CHECK_FOR_FIELD( alternates, Alternates )
368 RESTINIO_HTTP_CHECK_FOR_FIELD( c_pep_info, C-PEP-Info )
369 RESTINIO_HTTP_CHECK_FOR_FIELD( content_id, Content-ID )
370 RESTINIO_HTTP_CHECK_FOR_FIELD( delta_base, Delta-Base )
371 RESTINIO_HTTP_CHECK_FOR_FIELD( getprofile, GetProfile )
373 RESTINIO_HTTP_CHECK_FOR_FIELD( lock_token, Lock-Token )
374 RESTINIO_HTTP_CHECK_FOR_FIELD( pics_label, PICS-Label )
375 RESTINIO_HTTP_CHECK_FOR_FIELD( set_cookie, Set-Cookie )
376 RESTINIO_HTTP_CHECK_FOR_FIELD( setprofile, SetProfile )
377 RESTINIO_HTTP_CHECK_FOR_FIELD( soapaction, SoapAction )
378 RESTINIO_HTTP_CHECK_FOR_FIELD( status_uri, Status-URI )
379 RESTINIO_HTTP_CHECK_FOR_FIELD( user_agent, User-Agent )
380 RESTINIO_HTTP_CHECK_FOR_FIELD( compliance, Compliance )
381 RESTINIO_HTTP_CHECK_FOR_FIELD( message_id, Message-ID )
382 break;
383
384 case 11:
385 RESTINIO_HTTP_CHECK_FOR_FIELD( accept_post, Accept-Post )
386 RESTINIO_HTTP_CHECK_FOR_FIELD( content_md5, Content-MD5 )
387 RESTINIO_HTTP_CHECK_FOR_FIELD( destination, Destination )
388 RESTINIO_HTTP_CHECK_FOR_FIELD( retry_after, Retry-After )
389 RESTINIO_HTTP_CHECK_FOR_FIELD( set_cookie2, Set-Cookie2 )
390 RESTINIO_HTTP_CHECK_FOR_FIELD( want_digest, Want-Digest )
391 break;
392
393 case 12:
394 // Known to be more used first:
395 RESTINIO_HTTP_CHECK_FOR_FIELD( content_type, Content-Type )
396
397 RESTINIO_HTTP_CHECK_FOR_FIELD( accept_patch, Accept-Patch )
398 RESTINIO_HTTP_CHECK_FOR_FIELD( content_base, Content-Base )
399 RESTINIO_HTTP_CHECK_FOR_FIELD( derived_from, Derived-From )
400 RESTINIO_HTTP_CHECK_FOR_FIELD( max_forwards, Max-Forwards )
401 RESTINIO_HTTP_CHECK_FOR_FIELD( mime_version, MIME-Version )
402 RESTINIO_HTTP_CHECK_FOR_FIELD( schedule_tag, Schedule-Tag )
403 RESTINIO_HTTP_CHECK_FOR_FIELD( redirect_ref, Redirect-Ref )
404 RESTINIO_HTTP_CHECK_FOR_FIELD( variant_vary, Variant-Vary )
405 RESTINIO_HTTP_CHECK_FOR_FIELD( method_check, Method-Check )
406 RESTINIO_HTTP_CHECK_FOR_FIELD( referer_root, Referer-Root )
407 break;
408
409 case 13:
410 RESTINIO_HTTP_CHECK_FOR_FIELD( accept_ranges, Accept-Ranges )
411 RESTINIO_HTTP_CHECK_FOR_FIELD( authorization, Authorization )
412 RESTINIO_HTTP_CHECK_FOR_FIELD( cache_control, Cache-Control )
413 RESTINIO_HTTP_CHECK_FOR_FIELD( content_range, Content-Range )
414 RESTINIO_HTTP_CHECK_FOR_FIELD( default_style, Default-Style )
415 RESTINIO_HTTP_CHECK_FOR_FIELD( if_none_match, If-None-Match )
416 RESTINIO_HTTP_CHECK_FOR_FIELD( last_modified, Last-Modified )
417 RESTINIO_HTTP_CHECK_FOR_FIELD( ordering_type, Ordering-Type )
418 RESTINIO_HTTP_CHECK_FOR_FIELD( profileobject, ProfileObject )
419 RESTINIO_HTTP_CHECK_FOR_FIELD( protocol_info, Protocol-Info )
420 RESTINIO_HTTP_CHECK_FOR_FIELD( ua_resolution, UA-Resolution )
421 break;
422
423 case 14:
424 RESTINIO_HTTP_CHECK_FOR_FIELD( accept_charset, Accept-Charset )
425 RESTINIO_HTTP_CHECK_FOR_FIELD( http2_settings, HTTP2-Settings )
426 RESTINIO_HTTP_CHECK_FOR_FIELD( protocol_query, Protocol-Query )
427 RESTINIO_HTTP_CHECK_FOR_FIELD( proxy_features, Proxy-Features )
428 RESTINIO_HTTP_CHECK_FOR_FIELD( schedule_reply, Schedule-Reply )
429 RESTINIO_HTTP_CHECK_FOR_FIELD( non_compliance, Non-Compliance )
430 RESTINIO_HTTP_CHECK_FOR_FIELD( access_control, Access-Control )
431 break;
432
433 case 15:
434 RESTINIO_HTTP_CHECK_FOR_FIELD( accept_encoding, Accept-Encoding )
435 RESTINIO_HTTP_CHECK_FOR_FIELD( accept_features, Accept-Features )
436 RESTINIO_HTTP_CHECK_FOR_FIELD( accept_language, Accept-Language )
437 RESTINIO_HTTP_CHECK_FOR_FIELD( accept_datetime, Accept-Datetime )
438 RESTINIO_HTTP_CHECK_FOR_FIELD( content_version, Content-Version )
439 RESTINIO_HTTP_CHECK_FOR_FIELD( differential_id, Differential-ID )
440 RESTINIO_HTTP_CHECK_FOR_FIELD( public_key_pins, Public-Key-Pins )
441 RESTINIO_HTTP_CHECK_FOR_FIELD( security_scheme, Security-Scheme )
442 RESTINIO_HTTP_CHECK_FOR_FIELD( x_frame_options, X-Frame-Options )
443 RESTINIO_HTTP_CHECK_FOR_FIELD( x_device_accept, X-Device-Accept )
444 RESTINIO_HTTP_CHECK_FOR_FIELD( resolution_hint, Resolution-Hint )
445 RESTINIO_HTTP_CHECK_FOR_FIELD( ediint_features, EDIINT-Features )
446 RESTINIO_HTTP_CHECK_FOR_FIELD( ua_windowpixels, UA-Windowpixels )
447 break;
448
449 case 16:
450 RESTINIO_HTTP_CHECK_FOR_FIELD( accept_additions, Accept-Additions )
451 RESTINIO_HTTP_CHECK_FOR_FIELD( caldav_timezones, CalDAV-Timezones )
452 RESTINIO_HTTP_CHECK_FOR_FIELD( content_encoding, Content-Encoding )
453 RESTINIO_HTTP_CHECK_FOR_FIELD( content_language, Content-Language )
454 RESTINIO_HTTP_CHECK_FOR_FIELD( content_location, Content-Location )
455 RESTINIO_HTTP_CHECK_FOR_FIELD( memento_datetime, Memento-Datetime )
456 RESTINIO_HTTP_CHECK_FOR_FIELD( protocol_request, Protocol-Request )
457 RESTINIO_HTTP_CHECK_FOR_FIELD( www_authenticate, WWW-Authenticate )
458 break;
459
460 case 17:
461 RESTINIO_HTTP_CHECK_FOR_FIELD( if_modified_since, If-Modified-Since )
462 RESTINIO_HTTP_CHECK_FOR_FIELD( proxy_instruction, Proxy-Instruction )
463 RESTINIO_HTTP_CHECK_FOR_FIELD( sec_websocket_key, Sec-WebSocket-Key )
464 RESTINIO_HTTP_CHECK_FOR_FIELD( surrogate_control, Surrogate-Control )
465 RESTINIO_HTTP_CHECK_FOR_FIELD( transfer_encoding, Transfer-Encoding )
466 RESTINIO_HTTP_CHECK_FOR_FIELD( resolver_location, Resolver-Location )
467 break;
468
469 case 18:
470 RESTINIO_HTTP_CHECK_FOR_FIELD( content_style_type, Content-Style-Type )
471 RESTINIO_HTTP_CHECK_FOR_FIELD( preference_applied, Preference-Applied )
472 RESTINIO_HTTP_CHECK_FOR_FIELD( proxy_authenticate, Proxy-Authenticate )
473 break;
474
475 case 19:
476 RESTINIO_HTTP_CHECK_FOR_FIELD( authentication_info, Authentication-Info )
477 RESTINIO_HTTP_CHECK_FOR_FIELD( content_disposition, Content-Disposition )
478 RESTINIO_HTTP_CHECK_FOR_FIELD( content_script_type, Content-Script-Type )
479 RESTINIO_HTTP_CHECK_FOR_FIELD( if_unmodified_since, If-Unmodified-Since )
480 RESTINIO_HTTP_CHECK_FOR_FIELD( proxy_authorization, Proxy-Authorization )
481 RESTINIO_HTTP_CHECK_FOR_FIELD( x_device_user_agent, X-Device-User-Agent )
482 break;
483
484 case 20:
485 RESTINIO_HTTP_CHECK_FOR_FIELD( sec_websocket_accept, Sec-WebSocket-Accept )
486 RESTINIO_HTTP_CHECK_FOR_FIELD( surrogate_capability, Surrogate-Capability )
487 RESTINIO_HTTP_CHECK_FOR_FIELD( method_check_expires, Method-Check-Expires )
488 break;
489
490 case 21:
491 RESTINIO_HTTP_CHECK_FOR_FIELD( apply_to_redirect_ref, Apply-To-Redirect-Ref )
492 RESTINIO_HTTP_CHECK_FOR_FIELD( if_schedule_tag_match, If-Schedule-Tag-Match )
493 RESTINIO_HTTP_CHECK_FOR_FIELD( sec_websocket_version, Sec-WebSocket-Version )
494 break;
495
496 case 22:
497 RESTINIO_HTTP_CHECK_FOR_FIELD( authentication_control, Authentication-Control )
498 RESTINIO_HTTP_CHECK_FOR_FIELD( sec_websocket_protocol, Sec-WebSocket-Protocol )
499 RESTINIO_HTTP_CHECK_FOR_FIELD( access_control_max_age, Access-Control-Max-Age )
500 break;
501
502 case 23:
503 RESTINIO_HTTP_CHECK_FOR_FIELD( x_device_accept_charset, X-Device-Accept-Charset )
504 break;
505
506 case 24:
507 RESTINIO_HTTP_CHECK_FOR_FIELD( sec_websocket_extensions, Sec-WebSocket-Extensions )
508 RESTINIO_HTTP_CHECK_FOR_FIELD( x_device_accept_encoding, X-Device-Accept-Encoding )
509 RESTINIO_HTTP_CHECK_FOR_FIELD( x_device_accept_language, X-Device-Accept-Language )
510 break;
511
512 case 25:
513 RESTINIO_HTTP_CHECK_FOR_FIELD( optional_www_authenticate, Optional-WWW-Authenticate )
514 RESTINIO_HTTP_CHECK_FOR_FIELD( proxy_authentication_info, Proxy-Authentication-Info )
515 RESTINIO_HTTP_CHECK_FOR_FIELD( strict_transport_security, Strict-Transport-Security )
516 RESTINIO_HTTP_CHECK_FOR_FIELD( content_transfer_encoding, Content-Transfer-Encoding )
517 break;
518
519 case 27:
520 RESTINIO_HTTP_CHECK_FOR_FIELD( public_key_pins_report_only, Public-Key-Pins-Report-Only )
521 RESTINIO_HTTP_CHECK_FOR_FIELD( access_control_allow_origin, Access-Control-Allow-Origin )
522 break;
523
524 case 28:
525 RESTINIO_HTTP_CHECK_FOR_FIELD( access_control_allow_headers, Access-Control-Allow-Headers )
526 RESTINIO_HTTP_CHECK_FOR_FIELD( access_control_allow_methods, Access-Control-Allow-Methods )
527 break;
528
529 case 29:
530 RESTINIO_HTTP_CHECK_FOR_FIELD( access_control_request_method, Access-Control-Request-Method )
531 break;
532
533 case 30:
534 RESTINIO_HTTP_CHECK_FOR_FIELD( access_control_request_headers, Access-Control-Request-Headers )
535 break;
536
537 case 32:
538 RESTINIO_HTTP_CHECK_FOR_FIELD( access_control_allow_credentials, Access-Control-Allow-Credentials )
539 break;
540 }
541
542#undef RESTINIO_HTTP_CHECK_FOR_FIELD
543
545}
546
547//
548// field_to_string()
549//
550
552inline const char *
554{
555 const char * result = "";
556 switch( f )
557 {
558 #define RESTINIO_HTTP_FIELD_STR_GEN( name, string_name ) \
559 case http_field_t::name: result = #string_name; break;
560
562 #undef RESTINIO_HTTP_FIELD_STR_GEN
563
564 case http_field_t::field_unspecified: break; // Ignore.
565 }
566
567 return result;
568}
569
570//
571// http_header_field_t
572//
573
575
583{
584 public:
587 {}
588
590 std::string name,
591 std::string value )
592 : m_name{ std::move( name ) }
593 , m_value{ std::move( value ) }
595 {}
596
600 : m_name{ name.data(), name.size() }
601 , m_value{ value.data(), value.size() }
603 {}
604
607 std::string value )
609 , m_value{ std::move( value ) }
611 {}
612
617 , m_value{ std::move( value ) }
619 {}
620
621 const std::string & name() const noexcept { return m_name; }
622 const std::string & value() const noexcept { return m_value; }
623 http_field_t field_id() const noexcept { return m_field_id; }
624
625 void
626 name( std::string n )
627 {
628 m_name = std::move( n );
630 }
631
632 void
633 value( std::string v )
634 {
635 m_value = std::move( v );
636 }
637
638 void
640 {
641 m_value.append( v.data(), v.size() );
642 }
643
644 void
646 {
649 }
650
651 private:
652 std::string m_name;
653 std::string m_value;
655};
656
657// Make neccessary forward declarations.
659namespace impl
660{
661
662void
664
665} /* namespace impl */
666
667#if !defined( RESTINIO_HEADER_FIELDS_DEFAULT_RESERVE_COUNT )
668 #define RESTINIO_HEADER_FIELDS_DEFAULT_RESERVE_COUNT 4
669#endif
670
671//
672// http_header_fields_t
673//
674
676
703{
704 friend void
706
707 public:
708 using fields_container_t = std::vector< http_header_field_t >;
709
711 using const_iterator = fields_container_t::const_iterator;
712
714
721 {
727 };
728
729 constexpr static handling_result_t continue_enumeration() noexcept
731
732 constexpr static handling_result_t stop_enumeration() noexcept
734
736 {
738 }
742
745
746 void
747 swap_fields( http_header_fields_t & http_header_fields )
748 {
749 std::swap( m_fields, http_header_fields.m_fields );
750 }
751
753 bool
754 has_field( string_view_t field_name ) const noexcept
755 {
756 return m_fields.cend() != cfind( field_name );
757 }
758
760
765 bool
766 has_field( http_field_t field_id ) const noexcept
767 {
768 return m_fields.cend() != cfind( field_id );
769 }
770
772 void
773 set_field( http_header_field_t http_header_field )
774 {
775 fields_container_t::iterator it;
776 if( http_field_t::field_unspecified != http_header_field.field_id() )
777 {
778 // Field has a standard name.
779 // Search it by id.
780 it = find( http_header_field.field_id() );
781 }
782 else
783 {
784 // Field has a non standard name.
785 // Search it by name.
786 it = find( http_header_field.name() );
787 }
788
789 if( m_fields.end() != it )
790 {
791 *it = std::move( http_header_field );
792 }
793 else
794 {
795 m_fields.emplace_back( std::move( http_header_field ) );
796 }
797 }
798
800 void
802 std::string field_name,
803 std::string field_value )
804 {
805 const auto it = find( field_name );
806
807 if( m_fields.end() != it )
808 {
809 it->name( std::move( field_name ) );
810 it->value( std::move( field_value ) );
811 }
812 else
813 {
814 m_fields.emplace_back(
815 std::move( field_name ),
816 std::move( field_value ) );
817 }
818 }
819
821
825 void
827 http_field_t field_id,
828 std::string field_value )
829 {
830 if( http_field_t::field_unspecified != field_id )
831 {
832 const auto it = find( field_id );
833
834 if( m_fields.end() != it )
835 {
836 it->value( std::move( field_value ) );
837 }
838 else
839 {
840 m_fields.emplace_back(
841 field_id,
842 std::move( field_value ) );
843 }
844 }
845 }
846
859 void
861 http_field_t field_id,
862 std::string field_value )
863 {
864 if( http_field_t::field_unspecified != field_id )
865 {
866 m_fields.emplace_back(
867 field_id,
868 std::move( field_value ) );
869 }
870 }
871
881 void
883 std::string field_name,
884 std::string field_value )
885 {
886 m_fields.emplace_back(
887 std::move( field_name ),
888 std::move( field_value ) );
889 }
890
900 void
901 add_field( http_header_field_t http_header_field )
902 {
903 m_fields.push_back( std::move(http_header_field) );
904 }
905
907 void
909 string_view_t field_name,
910 string_view_t field_value )
911 {
912 const auto it = find( field_name );
913
914 if( m_fields.end() != it )
915 {
916 it->append_value( field_value );
917 }
918 else
919 {
920 m_fields.emplace_back( field_name, field_value );
921 }
922 }
923
925
929 void
931 http_field_t field_id,
932 string_view_t field_value )
933 {
934 if( http_field_t::field_unspecified != field_id )
935 {
936 const auto it = find( field_id );
937
938 if( m_fields.end() != it )
939 {
940 it->append_value( field_value );
941 }
942 else
943 {
944 m_fields.emplace_back( field_id, field_value );
945 }
946 }
947 }
948
950 const std::string &
951 get_field( string_view_t field_name ) const
952 {
953 const auto it = cfind( field_name );
954
955 if( m_fields.end() == it )
956 throw exception_t{
957 fmt::format( "field '{}' doesn't exist", field_name ) };
958
959 return it->value();
960 }
961
963
975 try_get_field( string_view_t field_name ) const noexcept
976 {
977 const auto it = cfind( field_name );
978 if( m_fields.end() == it )
979 return nullptr;
980 else
981 return std::addressof(it->value());
982 }
983
985 const std::string &
986 get_field( http_field_t field_id ) const
987 {
988 if( http_field_t::field_unspecified == field_id )
989 {
990 throw exception_t{
991 fmt::format(
992 "unspecified fields cannot be searched by id" ) };
993 }
994
995 const auto it = cfind( field_id );
996
997 if( m_fields.end() == it )
998 {
999 throw exception_t{
1000 fmt::format(
1001 "field '{}' doesn't exist",
1002 field_to_string( field_id ) ) };
1003 }
1004
1005 return it->value();
1006 }
1007
1009
1021 try_get_field( http_field_t field_id ) const noexcept
1022 {
1023 if( http_field_t::field_unspecified != field_id )
1024 {
1025 const auto it = cfind( field_id );
1026 if( m_fields.end() != it )
1027 return std::addressof(it->value());
1028 }
1029
1030 return nullptr;
1031 }
1032
1034
1039 std::string
1041 string_view_t field_name,
1042 string_view_t default_value ) const
1043 {
1044 const auto it = cfind( field_name );
1045
1046 if( m_fields.end() == it )
1047 return std::string( default_value.data(), default_value.size() );
1048
1049 return it->value();
1050 }
1051
1053
1058 std::string
1060 string_view_t field_name,
1061 std::string && default_value ) const
1062 {
1063 const auto it = cfind( field_name );
1064
1065 if( m_fields.end() == it )
1066 return std::move(default_value);
1067
1068 return it->value();
1069 }
1070
1072
1075 auto
1077 string_view_t field_name,
1078 const char * default_value ) const
1079 {
1080 return this->get_field_or( field_name, string_view_t{ default_value } );
1081 }
1082
1084
1087 auto
1089 string_view_t field_name,
1090 const std::string & default_value ) const
1091 {
1092 return this->get_field_or( field_name, string_view_t{ default_value } );
1093 }
1094
1096
1101 std::string
1103 http_field_t field_id,
1104 string_view_t default_value ) const
1105 {
1106 if( http_field_t::field_unspecified != field_id )
1107 {
1108 const auto it = cfind( field_id );
1109
1110 if( m_fields.end() != it )
1111 return it->value();
1112 }
1113
1114 return std::string( default_value.data(), default_value.size() );
1115 }
1116
1118
1121 auto
1123 http_field_t field_id,
1124 const char * default_value ) const
1125 {
1126 return this->get_field_or( field_id, string_view_t{ default_value } );
1127 }
1128
1130
1133 auto
1135 http_field_t field_id,
1136 const std::string & default_value ) const
1137 {
1138 return this->get_field_or( field_id, string_view_t{ default_value } );
1139 }
1140
1142
1147 std::string
1149 http_field_t field_id,
1150 std::string && default_value ) const
1151 {
1152 if( http_field_t::field_unspecified != field_id )
1153 {
1154 const auto it = cfind( field_id );
1155
1156 if( m_fields.end() != it )
1157 return it->value();
1158 }
1159
1160 return std::move( default_value );
1161 }
1162
1164
1173 bool
1174 remove_field( string_view_t field_name ) noexcept
1175 {
1176 const auto it = find( field_name );
1177
1178 if( m_fields.end() != it )
1179 {
1180 m_fields.erase( it );
1181 return true;
1182 }
1183
1184 return false;
1185 }
1186
1188
1197 bool
1198 remove_field( http_field_t field_id ) noexcept
1199 {
1200 if( http_field_t::field_unspecified != field_id )
1201 {
1202 const auto it = find( field_id );
1203
1204 if( m_fields.end() != it )
1205 {
1206 m_fields.erase( it );
1207 return true;
1208 }
1209 }
1210
1211 return false;
1212 }
1213
1215
1220 std::size_t
1221 remove_all_of( string_view_t field_name ) noexcept
1222 {
1223 std::size_t count{};
1224 for( auto it = m_fields.begin(); it != m_fields.end(); )
1225 {
1226 if( impl::is_equal_caseless( it->name(), field_name ) )
1227 {
1228 it = m_fields.erase( it );
1229 ++count;
1230 }
1231 else
1232 ++it;
1233 }
1234
1235 return count;
1236 }
1237
1239
1244 std::size_t
1245 remove_all_of( http_field_t field_id ) noexcept
1246 {
1247 std::size_t count{};
1248 if( http_field_t::field_unspecified != field_id )
1249 {
1250 for( auto it = m_fields.begin(); it != m_fields.end(); )
1251 {
1252 if( it->field_id() == field_id )
1253 {
1254 it = m_fields.erase( it );
1255 ++count;
1256 }
1257 else
1258 ++it;
1259 }
1260 }
1261
1262 return count;
1263 }
1264
1273 string_view_t name ) const
1274 {
1275 return { this->get_field(name) };
1276 }
1277
1282 http_field_t field_id ) const
1283 {
1284 return { this->get_field(field_id) };
1285 }
1286
1288
1302 string_view_t name ) const noexcept
1303 {
1305
1306 if( auto * ptr = this->try_get_field(name) )
1307 result = string_view_t{ *ptr };
1308
1309 return result;
1310 }
1311
1313
1327 http_field_t field_id ) const noexcept
1328 {
1330
1331 if( auto * ptr = this->try_get_field(field_id) )
1332 result = string_view_t{ *ptr };
1333
1334 return result;
1335 }
1341
1359 template< typename Lambda >
1360 void
1361 for_each_field( Lambda && lambda ) const
1362 noexcept(noexcept(lambda(
1363 std::declval<const http_header_field_t &>())))
1364 {
1365 for( const auto & f : m_fields )
1366 lambda( f );
1367 }
1368
1370
1399 template< typename Lambda >
1400 void
1402 http_field_t field_id,
1403 Lambda && lambda ) const
1404 noexcept(noexcept(lambda(
1405 std::declval<const string_view_t &>())))
1406 {
1407 static_assert(
1408 std::is_same<
1410 decltype(lambda(std::declval<const string_view_t &>()))
1411 >::value,
1412 "lambda should return restinio::http_header_fields_t::handling_result_t" );
1413
1414 for( const auto & f : m_fields )
1415 {
1416 if( field_id == f.field_id() )
1417 {
1418 const handling_result_t r = lambda( f.value() );
1419 if( stop_enumeration() == r )
1420 break;
1421 }
1422 }
1423 }
1424
1426
1455 template< typename Lambda >
1456 void
1458 string_view_t field_name,
1459 Lambda && lambda ) const
1460 noexcept(noexcept(lambda(
1461 std::declval<const string_view_t &>())))
1462 {
1463 static_assert(
1464 std::is_same<
1466 decltype(lambda(std::declval<const string_view_t &>()))
1467 >::value,
1468 "lambda should return restinio::http_header_fields_t::handling_result_t" );
1469
1470 for( const auto & f : m_fields )
1471 {
1472 if( impl::is_equal_caseless( f.name(), field_name ) )
1473 {
1474 const handling_result_t r = lambda( f.value() );
1475 if( stop_enumeration() == r )
1476 break;
1477 }
1478 }
1479 }
1480
1482 begin() const noexcept
1483 {
1484 return m_fields.cbegin();
1485 }
1486
1488 end() const noexcept
1489 {
1490 return m_fields.cend();
1491 }
1492
1493 auto fields_count() const noexcept
1494 {
1495 return m_fields.size();
1496 }
1497
1498 private:
1500
1508 void
1510 {
1511 m_fields.back().append_value( field_value );
1512 }
1513
1514 fields_container_t::iterator
1515 find( string_view_t field_name ) noexcept
1516 {
1517 return std::find_if(
1518 m_fields.begin(),
1519 m_fields.end(),
1520 [&]( const auto & f ){
1521 return impl::is_equal_caseless( f.name(), field_name );
1522 } );
1523 }
1524
1525 fields_container_t::const_iterator
1526 cfind( string_view_t field_name ) const noexcept
1527 {
1528 return std::find_if(
1529 m_fields.cbegin(),
1530 m_fields.cend(),
1531 [&]( const auto & f ){
1532 return impl::is_equal_caseless( f.name(), field_name );
1533 } );
1534 }
1535
1536 fields_container_t::iterator
1537 find( http_field_t field_id ) noexcept
1538 {
1539 return std::find_if(
1540 m_fields.begin(),
1541 m_fields.end(),
1542 [&]( const auto & f ){
1543 return f.field_id() == field_id;
1544 } );
1545 }
1546
1547 fields_container_t::const_iterator
1548 cfind( http_field_t field_id ) const noexcept
1549 {
1550 return std::find_if(
1551 m_fields.cbegin(),
1552 m_fields.cend(),
1553 [&]( const auto & f ){
1554 return f.field_id() == field_id;
1555 } );
1556 }
1557
1559};
1560
1561//
1562// http_connection_header_t
1563//
1564
1566enum class http_connection_header_t : std::uint8_t
1567{
1568 keep_alive,
1569 close,
1570 upgrade
1571};
1572
1573//
1574// http_header_common_t
1575//
1576
1579 : public http_header_fields_t
1580{
1581 public:
1584 std::uint16_t
1586 { return m_http_major; }
1587
1588 void
1589 http_major( std::uint16_t v ) noexcept
1590 { m_http_major = v; }
1591
1592 std::uint16_t
1594 { return m_http_minor; }
1595
1596 void
1597 http_minor( std::uint16_t v ) noexcept
1598 { m_http_minor = v; }
1600
1602 std::uint64_t
1604 { return m_content_length; }
1605
1606 void
1607 content_length( std::uint64_t l ) noexcept
1608 { m_content_length = l; }
1609
1610 bool
1612 {
1614 }
1615
1616 void
1617 should_keep_alive( bool keep_alive ) noexcept
1618 {
1622 }
1623
1627 {
1629 }
1630
1632 void
1634 {
1636 }
1637
1638 private:
1641 std::uint16_t m_http_major{1};
1642 std::uint16_t m_http_minor{1};
1644
1646 std::uint64_t m_content_length{ 0 };
1647
1649};
1650
1652#define RESTINIO_HTTP_METHOD_MAP(RESTINIO_GEN) \
1653 RESTINIO_GEN( http_method_delete, HTTP_DELETE, DELETE ) \
1654 RESTINIO_GEN( http_method_get, HTTP_GET, GET ) \
1655 RESTINIO_GEN( http_method_head, HTTP_HEAD, HEAD ) \
1656 RESTINIO_GEN( http_method_post, HTTP_POST, POST ) \
1657 RESTINIO_GEN( http_method_put, HTTP_PUT, PUT ) \
1658 /* pathological */ \
1659 RESTINIO_GEN( http_method_connect, HTTP_CONNECT, CONNECT ) \
1660 RESTINIO_GEN( http_method_options, HTTP_OPTIONS, OPTIONS ) \
1661 RESTINIO_GEN( http_method_trace, HTTP_TRACE, TRACE ) \
1662 /* WebDAV */ \
1663 RESTINIO_GEN( http_method_copy, HTTP_COPY, COPY ) \
1664 RESTINIO_GEN( http_method_lock, HTTP_LOCK, LOCK ) \
1665 RESTINIO_GEN( http_method_mkcol, HTTP_MKCOL, MKCOL ) \
1666 RESTINIO_GEN( http_method_move, HTTP_MOVE, MOVE ) \
1667 RESTINIO_GEN( http_method_propfind, HTTP_PROPFIND, PROPFIND ) \
1668 RESTINIO_GEN( http_method_proppatch, HTTP_PROPPATCH, PROPPATCH ) \
1669 RESTINIO_GEN( http_method_search, HTTP_SEARCH, SEARCH ) \
1670 RESTINIO_GEN( http_method_unlock, HTTP_UNLOCK, UNLOCK ) \
1671 RESTINIO_GEN( http_method_bind, HTTP_BIND, BIND ) \
1672 RESTINIO_GEN( http_method_rebind, HTTP_REBIND, REBIND ) \
1673 RESTINIO_GEN( http_method_unbind, HTTP_UNBIND, UNBIND ) \
1674 RESTINIO_GEN( http_method_acl, HTTP_ACL, ACL ) \
1675 /* subversion */ \
1676 RESTINIO_GEN( http_method_report, HTTP_REPORT, REPORT ) \
1677 RESTINIO_GEN( http_method_mkactivity, HTTP_MKACTIVITY, MKACTIVITY ) \
1678 RESTINIO_GEN( http_method_checkout, HTTP_CHECKOUT, CHECKOUT ) \
1679 RESTINIO_GEN( http_method_merge, HTTP_MERGE, MERGE ) \
1680 /* upnp */ \
1681 RESTINIO_GEN( http_method_msearch, HTTP_MSEARCH, M-SEARCH) \
1682 RESTINIO_GEN( http_method_notify, HTTP_NOTIFY, NOTIFY ) \
1683 RESTINIO_GEN( http_method_subscribe, HTTP_SUBSCRIBE, SUBSCRIBE ) \
1684 RESTINIO_GEN( http_method_unsubscribe, HTTP_UNSUBSCRIBE, UNSUBSCRIBE ) \
1685 /* RFC-5789 */ \
1686 RESTINIO_GEN( http_method_patch, HTTP_PATCH, PATCH ) \
1687 RESTINIO_GEN( http_method_purge, HTTP_PURGE, PURGE ) \
1688 /* CalDAV */ \
1689 RESTINIO_GEN( http_method_mkcalendar, HTTP_MKCALENDAR, MKCALENDAR ) \
1690 /* RFC-2068, section 19.6.1.2 */ \
1691 RESTINIO_GEN( http_method_link, HTTP_LINK, LINK ) \
1692 RESTINIO_GEN( http_method_unlink, HTTP_UNLINK, UNLINK )
1693
1694//
1695// http_method_id_t
1696//
1744{
1746 const char * m_name;
1747
1748public:
1749 static constexpr const int unknown_method = -1;
1750
1751 constexpr http_method_id_t() noexcept
1753 , m_name{ "<undefined>" }
1754 {}
1756 int value,
1757 const char * name ) noexcept
1758 : m_value{ value }
1759 , m_name{ name }
1760 {}
1761
1762 constexpr http_method_id_t( const http_method_id_t & ) noexcept = default;
1763 constexpr http_method_id_t &
1764 operator=( const http_method_id_t & ) noexcept = default;
1765
1766 constexpr http_method_id_t( http_method_id_t && ) noexcept = default;
1767 constexpr http_method_id_t &
1768 operator=( http_method_id_t && ) noexcept = default;
1769
1770 constexpr auto
1771 raw_id() const noexcept { return m_value; }
1772
1773 constexpr const char *
1774 c_str() const noexcept { return m_name; }
1775
1776 friend constexpr bool
1777 operator==( const http_method_id_t & a, const http_method_id_t & b ) noexcept {
1778 return a.raw_id() == b.raw_id();
1779 }
1780
1781 friend constexpr bool
1782 operator!=( const http_method_id_t & a, const http_method_id_t & b ) noexcept {
1783 return a.raw_id() != b.raw_id();
1784 }
1785
1786 friend constexpr bool
1787 operator<( const http_method_id_t & a, const http_method_id_t & b ) noexcept {
1788 return a.raw_id() < b.raw_id();
1789 }
1790};
1791
1792inline std::ostream &
1793operator<<( std::ostream & to, const http_method_id_t & m )
1794{
1795 return to << m.c_str();
1796}
1797
1798// Generate helper funcs.
1799#define RESTINIO_HTTP_METHOD_FUNC_GEN( func_name, nodejs_code, method_name ) \
1800 inline constexpr http_method_id_t func_name() { \
1801 return { nodejs_code, #method_name }; \
1802 }
1803
1805#undef RESTINIO_HTTP_METHOD_FUNC_GEN
1806
1807inline constexpr http_method_id_t
1809{
1810 return http_method_id_t{};
1811}
1812
1813//
1814// default_http_methods_t
1815//
1832{
1833public :
1834 inline static constexpr http_method_id_t
1835 from_nodejs( int value ) noexcept
1836 {
1837 http_method_id_t result;
1838 switch( value )
1839 {
1840#define RESTINIO_HTTP_METHOD_FUNC_GEN( func_name, nodejs_code, method_name ) \
1841 case nodejs_code : result = func_name(); break;
1842
1844#undef RESTINIO_HTTP_METHOD_FUNC_GEN
1845 default : ; // Nothing to do.
1846 }
1847
1848 return result;
1849 }
1850};
1851
1852//
1853// http_request_header
1854//
1855
1858 : public http_header_common_t
1859{
1860 static std::size_t
1861 memchr_helper( int chr , const char * from, std::size_t size )
1862 {
1863 const char * result = static_cast< const char * >(
1864 std::memchr( from, chr, size ) );
1865
1866 return result ? static_cast< std::size_t >( result - from ) : size;
1867 }
1868
1869 public:
1871
1874 std::string request_target_ )
1875 : m_method{ method }
1876 {
1877 request_target( std::move( request_target_ ) );
1878 }
1879
1881 method() const noexcept
1882 { return m_method; }
1883
1884 void
1886 { m_method = m; }
1887
1888 const std::string &
1890 { return m_request_target; }
1891
1892 void
1893 request_target( std::string t )
1894 {
1895 m_request_target.assign( std::move( t ) );
1896
1898 memchr_helper( '#', m_request_target.data(), m_request_target.size() );
1899
1902 }
1903
1906
1908
1913 path() const noexcept
1914 {
1916 }
1917
1919
1924 query() const noexcept
1925 {
1926 return
1928 string_view_t{ nullptr, 0 } :
1932 }
1933
1934
1936
1941 fragment() const
1942 {
1943 return
1945 string_view_t{ nullptr, 0 } :
1949 }
1951
1953 void
1954 append_request_target( const char * at, size_t length )
1955 {
1957 {
1958 // If fragment separator hadn't already appeared,
1959 // search for it in a new block.
1960
1961 const auto fragment_separator_pos_inc =
1962 memchr_helper( '#', at, length );
1963
1964 m_fragment_separator_pos += fragment_separator_pos_inc;
1965
1967 {
1968 // If request separator hadn't already appeared,
1969 // search for it in a new block.
1971 memchr_helper( '?', at, fragment_separator_pos_inc );
1972 }
1973 }
1974 // Else fragment separator appeared
1975 // (req separator is either already defined or does not exist)
1976
1977 m_request_target.append( at, length );
1978 }
1979
1980 private:
1981 http_method_id_t m_method{ http_method_get() };
1982 std::string m_request_target;
1983 std::size_t m_query_separator_pos{ 0 };
1985};
1986
1987//
1988// http_status_code_t
1989//
1990
1993{
1994 public:
1995 constexpr http_status_code_t() noexcept
1996 {}
1997
1998 constexpr explicit http_status_code_t( std::uint16_t status_code ) noexcept
1999 : m_status_code{ status_code }
2000 {}
2001
2002 constexpr auto
2003 raw_code() const noexcept
2004 {
2005 return m_status_code;
2006 }
2007
2008 constexpr bool
2009 operator == ( const http_status_code_t & sc ) const noexcept
2010 {
2011 return raw_code() == sc.raw_code();
2012 }
2013
2014 constexpr bool
2015 operator != ( const http_status_code_t & sc ) const noexcept
2016 {
2017 return sc.raw_code() != sc.raw_code();
2018 }
2019
2020 constexpr bool
2021 operator < ( const http_status_code_t & sc ) const noexcept
2022 {
2023 return sc.raw_code() < sc.raw_code();
2024 }
2025
2026 private:
2028 std::uint16_t m_status_code{ 0 };
2029};
2030
2031namespace status_code
2032{
2033
2038
2039// Add '_', because 'continue is reserved word.'
2041
2043constexpr http_status_code_t ok{ 200 };
2052constexpr http_status_code_t found{ 302 };
2067constexpr http_status_code_t gone{ 410 };
2070
2071//413 Payload Too Large (RFC 7231)
2072// The request is larger than the server is willing or able to process.
2073// Previously called "Request Entity Too Large".[44]
2075
2076// 414 URI Too Long (RFC 7231)
2077// The URI provided was too long for the server to process.
2078// Often the result of too much data being encoded as a query-string of a GET request,
2079// in which case it should be converted to a POST request.
2080// Called "Request-URI Too Long" previously.[46]
2082
2093
2098 // RFC 7538
2100
2101 // RFC 2518
2108
2109 // RFC 6585
2115
2116} /* namespace status_code */
2117
2118//
2119// http_status_line_t
2120//
2121
2124{
2125 public:
2127 {}
2128
2131 std::string reason_phrase )
2132 : m_status_code{ sc }
2134 {}
2135
2138 { return m_status_code; }
2139
2140 void
2142 { m_status_code = c; }
2143
2144 const std::string &
2146 { return m_reason_phrase; }
2147
2148 void
2149 reason_phrase( std::string r )
2150 { m_reason_phrase.assign( std::move( r ) ); }
2151
2152 private:
2154 std::string m_reason_phrase;
2155};
2156
2157inline std::ostream &
2158operator << ( std::ostream & o, const http_status_line_t & status_line )
2159{
2160 return o << "{" << status_line.status_code().raw_code() << ", "
2161 << status_line.reason_phrase() << "}";
2162}
2163
2168
2170{ return http_status_line_t{ status_code::continue_, "Continue" }; }
2171
2173{ return http_status_line_t{ status_code::switching_protocols, "Switching Protocols" }; }
2174
2176{ return http_status_line_t{ status_code::ok, "OK" }; }
2177
2179{ return http_status_line_t{ status_code::created, "Created" }; }
2180
2182{ return http_status_line_t{ status_code::accepted, "Accepted" }; }
2183
2185{ return http_status_line_t{ status_code::non_authoritative_information, "Non-Authoritative Information" }; }
2186
2188{ return http_status_line_t{ status_code::no_content, "No Content" }; }
2189
2191{ return http_status_line_t{ status_code::reset_content, "Reset Content" }; }
2192
2194{ return http_status_line_t{ status_code::partial_content, "Partial Content" }; }
2195
2197{ return http_status_line_t{ status_code::multiple_choices, "Multiple Choices" }; }
2198
2200{ return http_status_line_t{ status_code::moved_permanently, "Moved Permanently" }; }
2201
2203{ return http_status_line_t{ status_code::found, "Found" }; }
2204
2206{ return http_status_line_t{ status_code::see_other, "See Other" }; }
2207
2209{ return http_status_line_t{ status_code::not_modified, "Not Modified" }; }
2210
2212{ return http_status_line_t{ status_code::use_proxy, "Use Proxy" }; }
2213
2215{ return http_status_line_t{ status_code::temporary_redirect, "Temporary Redirect" }; }
2216
2218{ return http_status_line_t{ status_code::bad_request, "Bad Request" }; }
2219
2221{ return http_status_line_t{ status_code::unauthorized, "Unauthorized" }; }
2222
2224{ return http_status_line_t{ status_code::payment_required, "Payment Required" }; }
2225
2227{ return http_status_line_t{ status_code::forbidden, "Forbidden" }; }
2228
2230{ return http_status_line_t{ status_code::not_found, "Not Found" }; }
2231
2233{ return http_status_line_t{ status_code::method_not_allowed, "Method Not Allowed" }; }
2234
2236{ return http_status_line_t{ status_code::not_acceptable, "Not Acceptable" }; }
2237
2239{ return http_status_line_t{status_code::proxy_authentication_required, "Proxy Authentication Required" }; }
2240
2242{ return http_status_line_t{ status_code::request_time_out, "Request Timeout" }; }
2243
2245{ return http_status_line_t{ status_code::conflict, "Conflict" }; }
2246
2248{ return http_status_line_t{ status_code::gone, "Gone" }; }
2249
2251{ return http_status_line_t{ status_code::length_required, "Length Required" }; }
2252
2254{ return http_status_line_t{ status_code::precondition_failed, "Precondition Failed" }; }
2255
2257{ return http_status_line_t{ status_code::payload_too_large, "Payload Too Large" }; }
2258
2260{ return http_status_line_t{ status_code::uri_too_long, "URI Too Long" }; }
2261
2263{ return http_status_line_t{ status_code::unsupported_media_type, "Unsupported Media Type" }; }
2264
2266{ return http_status_line_t{ status_code::requested_range_not_satisfiable, "Requested Range Not Satisfiable" }; }
2267
2269{ return http_status_line_t{ status_code::expectation_failed, "Expectation Failed" }; }
2270
2272{ return http_status_line_t{ status_code::internal_server_error, "Internal Server Error" }; }
2273
2275{ return http_status_line_t{ status_code::not_implemented, "Not Implemented" }; }
2276
2278{ return http_status_line_t{ status_code::bad_gateway, "Bad Gateway" }; }
2279
2281{ return http_status_line_t{ status_code::service_unavailable, "Service Unavailable" }; }
2282
2284{ return http_status_line_t{ status_code::gateway_time_out, "Gateway Timeout" }; }
2285
2287{ return http_status_line_t{ status_code::http_version_not_supported, "HTTP Version not supported" }; }
2289
2294 // RFC 7538
2296{ return http_status_line_t{ status_code::permanent_redirect, "Permanent Redirect" }; }
2297
2298 // RFC 2518
2300{ return http_status_line_t{ status_code::processing, "Processing" }; }
2301
2303{ return http_status_line_t{ status_code::multi_status, "Multi-Status" }; }
2304
2306{ return http_status_line_t{ status_code::unprocessable_entity, "Unprocessable Entity" }; }
2307
2309{ return http_status_line_t{ status_code::locked, "Locked" }; }
2310
2312{ return http_status_line_t{ status_code::failed_dependency, "Failed Dependency" }; }
2313
2315{ return http_status_line_t{ status_code::insufficient_storage, "Insufficient Storage" }; }
2316
2317 // RFC 6585
2319{ return http_status_line_t{ status_code::precondition_required, "Precondition Required" }; }
2320
2322{ return http_status_line_t{ status_code::too_many_requests, "Too Many Requests" }; }
2323
2325{ return http_status_line_t{ status_code::request_header_fields_too_large, "Request Header Fields Too Large" }; }
2326
2328{ return http_status_line_t{ status_code::network_authentication_required, "Network Authentication Required" }; }
2330
2331//
2332// http_response_header_t
2333//
2334
2337 : public http_header_common_t
2338{
2339 public:
2341 {}
2342
2345 {}
2346
2349 { return m_status_line.status_code(); }
2350
2351 void
2353 { m_status_line.status_code( c ); }
2354
2355 const std::string &
2357 { return m_status_line.reason_phrase(); }
2358
2359 void
2360 reason_phrase( std::string r )
2362
2363 const http_status_line_t &
2365 {
2366 return m_status_line;
2367 }
2368
2369 void
2371 {
2372 m_status_line = std::move( sl );
2373 }
2374
2375 private:
2377};
2378
2379} /* 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
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
optional_t< string_view_t > opt_value_of(string_view_t name) const noexcept
Get optional value of a field.
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.
optional_t< string_view_t > opt_value_of(http_field_t field_id) const noexcept
Get optional value of a 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.
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.
void swap(optional< T > &x, optional< T > &y)
Definition: optional.hpp:1705
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()
T * nullable_pointer_t
Type for pointer that can be nullptr.
http_status_line_t status_http_version_not_supported()
http_status_line_t status_payment_required()
http_status_line_t status_conflict()
http_status_line_t status_permanent_redirect()
http_status_line_t status_partial_content()
nonstd::string_view string_view_t
Definition: string_view.hpp:19
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)
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()
http_status_line_t status_ok()
http_field_t
C++ enum that repeats nodejs c-style enum.
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()
STL namespace.
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
void request_target(std::string t)
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
#define const
Definition: zconf.h:230