RESTinio
parser_callbacks.ipp
Go to the documentation of this file.
1 /*
2  restinio
3 */
4 
5 /*!
6  Callbacks used with http parser.
7 */
8 
9 inline int
10 restinio_url_cb( http_parser * parser, const char * at, size_t length )
11 {
12  try
13  {
14  auto * ctx =
15  reinterpret_cast< restinio::impl::http_parser_ctx_t * >(
16  parser->data );
17 
18  ctx->m_header.append_request_target( at, length );
19  }
20  catch( const std::exception & )
21  {
22  return 1;
23  }
24 
25  return 0;
26 }
27 
28 inline int
29 restinio_header_field_cb( http_parser * parser, const char *at, size_t length )
30 {
31  try
32  {
33  auto * ctx =
34  reinterpret_cast< restinio::impl::http_parser_ctx_t * >(
35  parser->data );
36 
37  if( ctx->m_last_was_value )
38  {
39  ctx->m_current_field_name.assign( at, length );
40  ctx->m_last_was_value = false;
41  }
42  else
43  {
44  ctx->m_current_field_name.append( at, length );
45  }
46  }
47  catch( const std::exception & )
48  {
49  return 1;
50  }
51 
52  return 0;
53 }
54 
55 inline void
56 append_last_field_accessor( http_header_fields_t & fields, string_view_t value )
57 {
58  fields.append_last_field( value );
59 }
60 
61 inline int
62 restinio_header_value_cb( http_parser * parser, const char *at, size_t length )
63 {
64  try
65  {
66  auto * ctx =
67  reinterpret_cast< restinio::impl::http_parser_ctx_t * >( parser->data );
68 
69  if( !ctx->m_last_was_value )
70  {
71  ctx->m_header.set_field(
72  std::move( ctx->m_current_field_name ),
73  std::string{ at, length } );
74 
75  ctx->m_last_was_value = true;
76  }
77  else
78  {
79  append_last_field_accessor( ctx->m_header, std::string{ at, length } );
80  }
81  }
82  catch( const std::exception & )
83  {
84  return 1;
85  }
86 
87  return 0;
88 }
89 
90 inline int
91 restinio_headers_complete_cb( http_parser * parser )
92 {
93  if( ULLONG_MAX != parser->content_length &&
94  0 < parser->content_length )
95  {
96  try
97  {
98  auto * ctx =
99  reinterpret_cast< restinio::impl::http_parser_ctx_t * >(
100  parser->data );
101 
102  ctx->m_body.reserve(
103  ::restinio::utils::impl::uint64_to_size_t(
104  parser->content_length) );
105  }
106  catch( const std::exception & )
107  {
108  return 1;
109  }
110  }
111 
112  return 0;
113 }
114 
115 
116 inline int
117 restinio_body_cb( http_parser * parser, const char *at, size_t length )
118 {
119  try
120  {
121  auto * ctx =
122  reinterpret_cast< restinio::impl::http_parser_ctx_t * >(
123  parser->data );
124 
125  ctx->m_body.append( at, length );
126  }
127  catch( const std::exception & )
128  {
129  return 1;
130  }
131 
132  return 0;
133 }
134 
135 template< typename Http_Methods >
136 int
137 restinio_message_complete_cb( http_parser * parser )
138 {
139  // If entire http-message consumed, we need to stop parser.
140  http_parser_pause( parser, 1 );
141 
142  auto * ctx =
143  reinterpret_cast< restinio::impl::http_parser_ctx_t * >(
144  parser->data );
145 
146  ctx->m_message_complete = true;
147  ctx->m_header.method( Http_Methods::from_nodejs( parser->method ) );
148 
149  if( 0 == parser->upgrade )
150  ctx->m_header.should_keep_alive( 0 != http_should_keep_alive( parser ) );
151  else
152  ctx->m_header.connection( http_connection_header_t::upgrade );
153 
154  return 0;
155 }
int restinio_url_cb(http_parser *parser, const char *at, size_t length)
void append_last_field_accessor(http_header_fields_t &fields, string_view_t value)
int restinio_body_cb(http_parser *parser, const char *at, size_t length)
int restinio_headers_complete_cb(http_parser *parser)
int restinio_header_value_cb(http_parser *parser, const char *at, size_t length)
int restinio_header_field_cb(http_parser *parser, const char *at, size_t length)
int restinio_message_complete_cb(http_parser *parser)