Electroneum
parser.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <string>
4 #include <unordered_map>
5 #include <boost/algorithm/string.hpp>
6 #include <boost/tokenizer.hpp>
7 #include <algorithm>
8 
9 #include "http_parser_merged.h"
10 #include "http_request.h"
11 
12 namespace crow
13 {
14  template <typename Handler>
15  struct HTTPParser : public http_parser
16  {
17  static int on_message_begin(http_parser* self_)
18  {
19  HTTPParser* self = static_cast<HTTPParser*>(self_);
20  self->clear();
21  return 0;
22  }
23  static int on_url(http_parser* self_, const char* at, size_t length)
24  {
25  HTTPParser* self = static_cast<HTTPParser*>(self_);
26  self->raw_url.insert(self->raw_url.end(), at, at+length);
27  return 0;
28  }
29  static int on_header_field(http_parser* self_, const char* at, size_t length)
30  {
31  HTTPParser* self = static_cast<HTTPParser*>(self_);
32  switch (self->header_building_state)
33  {
34  case 0:
35  if (!self->header_value.empty())
36  {
37  self->headers.emplace(std::move(self->header_field), std::move(self->header_value));
38  }
39  self->header_field.assign(at, at+length);
40  self->header_building_state = 1;
41  break;
42  case 1:
43  self->header_field.insert(self->header_field.end(), at, at+length);
44  break;
45  }
46  return 0;
47  }
48  static int on_header_value(http_parser* self_, const char* at, size_t length)
49  {
50  HTTPParser* self = static_cast<HTTPParser*>(self_);
51  switch (self->header_building_state)
52  {
53  case 0:
54  self->header_value.insert(self->header_value.end(), at, at+length);
55  break;
56  case 1:
57  self->header_building_state = 0;
58  self->header_value.assign(at, at+length);
59  break;
60  }
61  return 0;
62  }
63  static int on_headers_complete(http_parser* self_)
64  {
65  HTTPParser* self = static_cast<HTTPParser*>(self_);
66  if (!self->header_field.empty())
67  {
68  self->headers.emplace(std::move(self->header_field), std::move(self->header_value));
69  }
70  self->process_header();
71  return 0;
72  }
73  static int on_body(http_parser* self_, const char* at, size_t length)
74  {
75  HTTPParser* self = static_cast<HTTPParser*>(self_);
76  self->body.insert(self->body.end(), at, at+length);
77  return 0;
78  }
79  static int on_message_complete(http_parser* self_)
80  {
81  HTTPParser* self = static_cast<HTTPParser*>(self_);
82 
83  // url params
84  self->url = self->raw_url.substr(0, self->raw_url.find("?"));
85  self->url_params = query_string(self->raw_url);
86 
87  self->process_message();
88  return 0;
89  }
90  HTTPParser(Handler* handler) :
91  handler_(handler)
92  {
94  }
95 
96  // return false on error
97  bool feed(const char* buffer, int length)
98  {
99  const static http_parser_settings settings_{
101  on_url,
102  nullptr,
106  on_body,
108  };
109 
110  int nparsed = http_parser_execute(this, &settings_, buffer, length);
111  return nparsed == length;
112  }
113 
114  bool done()
115  {
116  return feed(nullptr, 0);
117  }
118 
119  void clear()
120  {
121  url.clear();
122  raw_url.clear();
124  header_field.clear();
125  header_value.clear();
126  headers.clear();
127  url_params.clear();
128  body.clear();
129  }
130 
132  {
133  handler_->handle_header();
134  }
135 
137  {
138  handler_->handle();
139  }
140 
142  {
143  return request{(HTTPMethod)method, std::move(raw_url), std::move(url), std::move(url_params), std::move(headers), std::move(body)};
144  }
145 
146  bool is_upgrade() const
147  {
148  return upgrade;
149  }
150 
151  bool check_version(int major, int minor) const
152  {
153  return http_major == major && http_minor == minor;
154  }
155 
156  std::string raw_url;
157  std::string url;
158 
160  std::string header_field;
161  std::string header_value;
164  std::string body;
165 
166  Handler* handler_;
167  };
168 }
std::string raw_url
Definition: parser.h:156
Definition: http_parser_merged.h:204
std::string header_value
Definition: parser.h:161
unsigned int method
Definition: http_parser_merged.h:219
std::string header_field
Definition: parser.h:160
Definition: http_request.h:23
unsigned short http_minor
Definition: http_parser_merged.h:217
void clear()
Definition: query_string.h:294
HTTPParser(Handler *handler)
Definition: parser.h:90
static int on_url(http_parser *self_, const char *at, size_t length)
Definition: parser.h:23
int header_building_state
Definition: parser.h:159
static int on_message_begin(http_parser *self_)
Definition: parser.h:17
std::string url
Definition: parser.h:157
ci_map headers
Definition: parser.h:162
bool is_upgrade() const
Definition: parser.h:146
void process_header()
Definition: parser.h:131
void clear()
Definition: parser.h:119
Definition: http_parser_merged.h:234
request to_request() const
Definition: parser.h:141
bool check_version(int major, int minor) const
Definition: parser.h:151
bool done()
Definition: parser.h:114
static int on_body(http_parser *self_, const char *at, size_t length)
Definition: parser.h:73
Handler * handler_
Definition: parser.h:166
size_t http_parser_execute(http_parser *parser, const http_parser_settings *settings, const char *data, size_t len)
Definition: http_parser_merged.h:831
unsigned short http_major
Definition: http_parser_merged.h:216
Definition: http_parser_merged.h:132
static int on_header_field(http_parser *self_, const char *at, size_t length)
Definition: parser.h:29
static int on_headers_complete(http_parser *self_)
Definition: parser.h:63
static int on_header_value(http_parser *self_, const char *at, size_t length)
Definition: parser.h:48
std::string body
Definition: parser.h:164
std::unordered_multimap< std::string, std::string, ci_hash, ci_key_eq > ci_map
Definition: ci_map.h:33
bool feed(const char *buffer, int length)
Definition: parser.h:97
query_string url_params
Definition: parser.h:163
Definition: ci_map.h:7
void http_parser_init(http_parser *parser, enum http_parser_type type)
Definition: http_parser_merged.h:2299
unsigned int upgrade
Definition: http_parser_merged.h:227
void process_message()
Definition: parser.h:136
static int on_message_complete(http_parser *self_)
Definition: parser.h:79
HTTPMethod
Definition: common.h:11
Definition: parser.h:15
Definition: query_string.h:239