26 #ifndef STATICLIB_PION_HTTP_PARSER_HPP
27 #define STATICLIB_PION_HTTP_PARSER_HPP
34 #include "staticlib/config.hpp"
35 #include "staticlib/support.hpp"
62 using payload_handler_type = std::function<void(const char *, size_t)>;
98 const char *
name() const STATICLIB_NOEXCEPT {
108 std::string
message(
int ev)
const;
177 enum message_parse_state_type {
182 PARSE_CONTENT_NO_LENGTH,
183 PARSE_CHUNKS, PARSE_END
190 enum header_parse_state_type {
195 PARSE_HTTP_VERSION_H,
196 PARSE_HTTP_VERSION_T_1,
197 PARSE_HTTP_VERSION_T_2,
198 PARSE_HTTP_VERSION_P,
199 PARSE_HTTP_VERSION_SLASH,
200 PARSE_HTTP_VERSION_MAJOR_START,
201 PARSE_HTTP_VERSION_MAJOR,
202 PARSE_HTTP_VERSION_MINOR_START,
203 PARSE_HTTP_VERSION_MINOR,
204 PARSE_STATUS_CODE_START,
206 PARSE_STATUS_MESSAGE,
207 PARSE_EXPECTING_NEWLINE,
209 PARSE_HEADER_WHITESPACE,
212 PARSE_SPACE_BEFORE_HEADER_VALUE,
214 PARSE_EXPECTING_FINAL_NEWLINE,
215 PARSE_EXPECTING_FINAL_CR
222 enum chunk_parse_state_type {
223 PARSE_CHUNK_SIZE_START,
225 PARSE_EXPECTING_IGNORED_TEXT_AFTER_CHUNK_SIZE,
226 PARSE_EXPECTING_CR_AFTER_CHUNK_SIZE,
227 PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE,
229 PARSE_EXPECTING_CR_AFTER_CHUNK,
230 PARSE_EXPECTING_LF_AFTER_CHUNK,
231 PARSE_EXPECTING_FINAL_CR_OR_FOOTERS_AFTER_LAST_CHUNK,
232 PARSE_EXPECTING_FINAL_LF_AFTER_LAST_CHUNK
238 message_parse_state_type m_message_parse_state;
243 header_parse_state_type m_headers_parse_state;
248 chunk_parse_state_type m_chunked_content_parse_state;
253 payload_handler_type* m_payload_handler =
nullptr;
258 uint16_t m_status_code;
263 std::string m_status_message;
268 std::string m_method;
273 std::string m_resource;
278 std::string m_query_string;
283 std::string m_raw_headers;
288 std::string m_header_name;
293 std::string m_header_value;
298 std::string m_chunk_size_str;
303 size_t m_size_of_current_chunk;
308 size_t m_bytes_read_in_current_chunk;
313 size_t m_bytes_content_remaining;
318 size_t m_bytes_content_read;
323 size_t m_bytes_last_read;
328 size_t m_bytes_total_read;
333 size_t m_max_content_length;
338 bool m_parse_headers_only;
343 bool m_save_raw_headers;
348 static error_category_t * m_error_category_ptr;
353 static std::once_flag m_instance_flag;
365 m_message_parse_state(PARSE_START),
366 m_headers_parse_state(PARSE_METHOD_START),
367 m_chunked_content_parse_state(PARSE_CHUNK_SIZE_START),
369 m_bytes_content_remaining(0),
370 m_bytes_content_read(0),
371 m_bytes_last_read(0),
372 m_bytes_total_read(0),
373 m_max_content_length(max_content_length),
374 m_parse_headers_only(false),
375 m_save_raw_headers(false) { }
429 void load_read_pos(
const char *&read_ptr,
const char *&read_end_ptr)
const {
443 if (m_message_parse_state != PARSE_CONTENT_NO_LENGTH) {
446 m_message_parse_state = PARSE_END;
458 m_parse_headers_only = b;
475 m_message_parse_state = PARSE_START;
476 m_headers_parse_state = PARSE_METHOD_START;
477 m_chunked_content_parse_state = PARSE_CHUNK_SIZE_START;
479 m_status_message.erase();
482 m_query_string.erase();
483 m_raw_headers.erase();
484 m_bytes_content_read = m_bytes_last_read = m_bytes_total_read = 0;
511 return m_bytes_last_read;
520 return m_bytes_total_read;
529 return m_bytes_content_read;
538 return m_max_content_length;
547 return m_raw_headers;
554 return m_save_raw_headers;
563 return m_parse_headers_only;
586 m_payload_handler = &h;
595 m_max_content_length = n;
611 m_save_raw_headers = b;
626 static bool parse_uri(
const std::string& uri, std::string& proto, std::string& host,
627 uint16_t& port, std::string& path, std::string& query);
639 static bool parse_url_encoded(std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to>& dict,
640 const char *ptr,
const size_t len);
653 static bool parse_multipart_form_data(std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to>& dict,
654 const std::string& content_type,
const char *ptr,
const size_t len);
667 static bool parse_cookie_header(std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to>& dict,
668 const char *ptr,
const size_t len,
bool set_cookie_header);
680 static bool parse_cookie_header(std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to>& dict,
681 const std::string& cookie_header,
bool set_cookie_header);
692 static bool parse_url_encoded(std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to>& dict,
693 const std::string& query);
705 static bool parse_multipart_form_data(std::unordered_multimap<std::string, std::string, algorithm::ihash, algorithm::iequal_to>& dict,
706 const std::string& content_type,
const std::string& form_data);
729 return *m_error_category_ptr;
776 sl::support::tribool
parse_chunks(std::vector<char>& chunk_buffers, std::error_code& ec);
822 m_error_category_ptr = &UNIQUE_ERROR_CATEGORY;
828 return (c >=
'0' && c <=
'9');
832 return ((c >=
'0' && c <=
'9') || (c >=
'a' && c <=
'f') || (c >=
'A' && c <=
'F'));
842 #endif // STATICLIB_PION_HTTP_PARSER_HPP