14#include <llhttp/llhttp.h>
25 LOG_TRACE_FMT(
"Received url to parse: {}", std::string_view(url));
27 const auto path_end = url.find(
'?');
28 const auto query_start =
29 path_end == std::string::npos ? url.size() : path_end + 1;
31 const auto query_end = url.find(
'#', query_start);
32 const auto fragment_start =
33 query_end == std::string::npos ? url.size() : query_end + 1;
35 return std::make_tuple(
36 url.substr(0, path_end),
37 url.substr(query_start, query_end - query_start),
38 url.substr(fragment_start));
41 static std::string url_decode(
const std::string_view& s_)
44 char const* src = s.c_str();
45 char const* end = s.c_str() + s.size();
50 char const c = *src++;
52 c ==
'%' && (src + 1) < end && (isxdigit(src[0]) != 0) &&
53 (isxdigit(src[1]) != 0))
55 const auto a = ccf::ds::hex_char_to_int(*src++);
56 const auto b = ccf::ds::hex_char_to_int(*src++);
57 *dst++ = (a << 4) | b;
69 s.resize(dst - s.data());
75 return status >= 200 && status < 300;
95 const std::string_view& url,
97 std::vector<uint8_t>&& body,
121 std::vector<uint8_t>&& body)
override
133 static int on_msg_begin(llhttp_t* parser);
134 static int on_url(llhttp_t* parser,
const char* at,
size_t length);
135 static int on_header_field(llhttp_t* parser,
const char* at,
size_t length);
136 static int on_header_value(llhttp_t* parser,
const char* at,
size_t length);
137 static int on_headers_complete(llhttp_t* parser);
138 static int on_body(llhttp_t* parser,
const char* at,
size_t length);
139 static int on_msg_end(llhttp_t* parser);
156 std::regex url_regex(
157 "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?");
160 if (!std::regex_match(url, match, url_regex))
162 throw std::invalid_argument(fmt::format(
"Unable to parse url: {}", url));
165 const auto host_port = match[4].str();
169 const auto closing_bracket = host_port.rfind(
']');
170 const auto port_delim_start =
171 closing_bracket == std::string::npos ? 0 : closing_bracket;
172 const auto port_delim = host_port.find(
':', port_delim_start);
175 u.
scheme = match[2].str();
176 u.
host = host_port.substr(0, port_delim);
177 if (port_delim != std::string::npos)
179 u.
port = host_port.substr(port_delim + 1);
181 u.
path = match[5].str();
182 u.
query = match[7].str();
220 settings.on_message_begin = on_msg_begin;
221 settings.on_header_field = on_header_field;
222 settings.on_header_value = on_header_value;
223 settings.on_headers_complete = on_headers_complete;
225 settings.on_message_complete = on_msg_end;
232 void execute(
const uint8_t* data,
size_t size)
235 const auto*
const data_char =
reinterpret_cast<const char*
>(data);
236 auto err_no = llhttp_execute(&
parser, data_char, size);
238 if (err_no == HPE_PAUSED_UPGRADE)
242 llhttp_resume_after_upgrade(&
parser);
244 else if (err_no != HPE_OK)
246 throw std::runtime_error(fmt::format(
247 "HTTP parsing failed ({}: {}) around byte {}",
248 llhttp_errno_name(err_no),
249 llhttp_get_error_reason(&
parser),
250 llhttp_get_error_pos(&
parser) - data_char));
259 std::copy(at, at + length, std::back_inserter(
body_buf));
262 ccf::http::default_max_body_size);
263 if (
body_buf.size() > max_body_size)
266 "HTTP request body is too large (max size allowed: {})",
272 throw std::runtime_error(
"Receiving content outside of message");
287 throw std::runtime_error(
288 "Entering new message when previous message isn't complete");
304 throw std::runtime_error(
"Ending message, but not in a message");
316 ccf::http::default_max_headers_count);
317 if (
headers.size() >= max_headers_count)
320 "Too many headers (max number allowed: {})", max_headers_count));
325 auto f = std::string(at, length);
326 ccf::nonstd::to_lower(f);
328 partial_header_key.append(f);
331 ccf::http::default_max_header_size);
332 if (partial_header_key.size() > max_header_size)
335 "Header key for '{}' is too large (max size allowed: {})",
344 partial_header_value.append(at, length);
346 ccf::http::default_max_header_size);
347 if (partial_header_value.size() > max_header_size)
350 "Header value for '{}' is too large (max size allowed: {})",
362 static int on_msg_begin(llhttp_t* parser)
364 auto* p =
reinterpret_cast<Parser*
>(parser->data);
369 static int on_header_field(llhttp_t* parser,
const char* at,
size_t length)
371 auto* p =
reinterpret_cast<Parser*
>(parser->data);
372 p->header_field(at, length);
376 static int on_header_value(llhttp_t* parser,
const char* at,
size_t length)
378 auto* p =
reinterpret_cast<Parser*
>(parser->data);
379 p->header_value(at, length);
383 static int on_headers_complete(llhttp_t* parser)
385 auto* p =
reinterpret_cast<Parser*
>(parser->data);
386 p->headers_complete();
390 static int on_body(llhttp_t* parser,
const char* at,
size_t length)
392 auto* p =
reinterpret_cast<Parser*
>(parser->data);
393 p->append_body(at, length);
397 static int on_msg_end(llhttp_t* parser)
399 auto* p =
reinterpret_cast<Parser*
>(parser->data);
419 Parser(HTTP_REQUEST, config),
427 url.append(at, length);
441 llhttp_method(
parser.method),
449 llhttp_method(
parser.method),
457 static int on_url(llhttp_t* parser,
const char* at,
size_t length)
459 auto* p =
reinterpret_cast<RequestParser*
>(parser->data);
460 p->append_url(at, length);
Definition http_parser.h:188
State state
Definition http_parser.h:196
virtual void handle_completed_message()=0
void append_body(const char *at, size_t length)
Definition http_parser.h:254
ccf::http::ParserConfiguration configuration
Definition http_parser.h:195
llhttp_t parser
Definition http_parser.h:193
void headers_complete()
Definition http_parser.h:356
virtual void new_message()
Definition http_parser.h:276
llhttp_settings_t settings
Definition http_parser.h:194
void execute(const uint8_t *data, size_t size)
Definition http_parser.h:232
std::vector< uint8_t > body_buf
Definition http_parser.h:198
void header_value(const char *at, size_t length)
Definition http_parser.h:341
Parser(llhttp_type_t type, ccf::http::ParserConfiguration config=ccf::http::ParserConfiguration{})
Definition http_parser.h:210
std::pair< std::string, std::string > partial_parsed_header
Definition http_parser.h:201
virtual ~Parser()=default
void complete_header()
Definition http_parser.h:203
void end_message()
Definition http_parser.h:294
void header_field(const char *at, size_t length)
Definition http_parser.h:308
ccf::http::HeaderMap headers
Definition http_parser.h:199
Definition http_parser.h:406
~RequestParser() override=default
RequestParser(RequestProcessor &proc_, const ccf::http::ParserConfiguration &config=ccf::http::ParserConfiguration{})
Definition http_parser.h:415
void handle_completed_message() override
Definition http_parser.h:436
void new_message() override
Definition http_parser.h:430
void append_url(const char *at, size_t length)
Definition http_parser.h:425
Definition http_proc.h:20
virtual void handle_request(llhttp_method method, const std::string_view &url, ccf::http::HeaderMap &&headers, std::vector< uint8_t > &&body, int32_t stream_id=http2::DEFAULT_STREAM_ID)=0
Definition http_parser.h:466
~ResponseParser() override=default
ResponseParser(ResponseProcessor &proc_)
Definition http_parser.h:473
void handle_completed_message() override
Definition http_parser.h:478
Definition http_proc.h:33
virtual void handle_response(ccf::http_status status, ccf::http::HeaderMap &&headers, std::vector< uint8_t > &&body)=0
#define LOG_TRACE_FMT
Definition internal_logger.h:13
std::map< std::string, std::string, std::less<> > HeaderMap
Definition http_header_map.h:10
Definition app_interface.h:14
llhttp_status http_status
Definition http_status.h:9
Definition error_reporter.h:6
auto split_url_path(const std::string_view &url)
Definition http_parser.h:23
bool status_success(ccf::http_status status)
Definition http_parser.h:73
State
Definition http_parser.h:128
@ DONE
Definition http_parser.h:129
@ IN_MESSAGE
Definition http_parser.h:130
URL parse_url_full(const std::string &url)
Definition http_parser.h:151
Definition http_configuration.h:24
std::optional< ccf::ds::SizeString > max_header_size
Definition http_configuration.h:26
std::optional< ccf::ds::SizeString > max_body_size
Definition http_configuration.h:25
std::optional< uint32_t > max_headers_count
Definition http_configuration.h:27
Definition http_parser.h:84
std::vector< uint8_t > body
Definition http_parser.h:88
std::string url
Definition http_parser.h:86
ccf::http::HeaderMap headers
Definition http_parser.h:87
llhttp_method method
Definition http_parser.h:85
Definition http_parser.h:79
~SimpleRequestProcessor() override=default
void handle_request(llhttp_method method, const std::string_view &url, ccf::http::HeaderMap &&headers, std::vector< uint8_t > &&body, int32_t) override
Definition http_parser.h:93
std::queue< Request > received
Definition http_parser.h:91
Definition http_parser.h:110
ccf::http::HeaderMap headers
Definition http_parser.h:112
ccf::http_status status
Definition http_parser.h:111
std::vector< uint8_t > body
Definition http_parser.h:113
Definition http_parser.h:105
void handle_response(ccf::http_status status, ccf::http::HeaderMap &&headers, std::vector< uint8_t > &&body) override
Definition http_parser.h:118
std::queue< Response > received
Definition http_parser.h:116
~SimpleResponseProcessor() override=default
Definition http_parser.h:142
std::string host
Definition http_parser.h:144
std::string query
Definition http_parser.h:147
std::string port
Definition http_parser.h:145
std::string path
Definition http_parser.h:146
std::string fragment
Definition http_parser.h:148
std::string scheme
Definition http_parser.h:143