13 #ifndef __DECODER_HPP__
14 #define __DECODER_HPP__
18 #define flags http_parser_flags
19 #include <http_parser.h>
22 #include <glog/logging.h>
37 #if !(HTTP_PARSER_VERSION_MAJOR >= 2)
38 #error HTTP Parser version >= 2 required.
50 : failure(false), request(nullptr)
52 http_parser_settings_init(&settings);
54 settings.on_message_begin = &DataDecoder::on_message_begin;
55 settings.on_url = &DataDecoder::on_url;
56 settings.on_header_field = &DataDecoder::on_header_field;
57 settings.on_header_value = &DataDecoder::on_header_value;
58 settings.on_headers_complete = &DataDecoder::on_headers_complete;
59 settings.on_body = &DataDecoder::on_body;
60 settings.on_message_complete = &DataDecoder::on_message_complete;
61 settings.on_chunk_complete = &DataDecoder::on_chunk_complete;
62 settings.on_chunk_header = &DataDecoder::on_chunk_header;
64 http_parser_init(&parser, HTTP_REQUEST);
78 std::deque<http::Request*>
decode(
const char* data,
size_t length)
80 size_t parsed = http_parser_execute(&parser, &settings, data, length);
82 if (parsed != length) {
87 if (!requests.empty()) {
88 std::deque<http::Request*> result = requests;
93 return std::deque<http::Request*>();
102 static int on_message_begin(http_parser* p)
106 CHECK(!decoder->failure);
108 decoder->header = HEADER_FIELD;
109 decoder->field.clear();
110 decoder->value.clear();
111 decoder->query.clear();
112 decoder->url.clear();
114 CHECK(decoder->request ==
nullptr);
121 static int on_chunk_complete(http_parser* p)
126 static int on_chunk_header(http_parser* p)
131 static int on_url(http_parser* p,
const char* data,
size_t length)
134 CHECK_NOTNULL(decoder->request);
140 decoder->url.append(data, length);
145 static int on_header_field(http_parser* p,
const char* data,
size_t length)
148 CHECK_NOTNULL(decoder->request);
150 if (decoder->header != HEADER_FIELD) {
151 decoder->request->headers[decoder->field] = decoder->value;
152 decoder->field.clear();
153 decoder->value.clear();
156 decoder->field.append(data, length);
157 decoder->header = HEADER_FIELD;
162 static int on_header_value(http_parser* p,
const char* data,
size_t length)
165 CHECK_NOTNULL(decoder->request);
166 decoder->value.append(data, length);
167 decoder->header = HEADER_VALUE;
171 static int on_headers_complete(http_parser* p)
175 CHECK_NOTNULL(decoder->request);
178 decoder->request->headers[decoder->field] = decoder->value;
179 decoder->field.clear();
180 decoder->value.clear();
182 decoder->request->method =
183 http_method_str((http_method) decoder->parser.method);
185 decoder->request->keepAlive = http_should_keep_alive(&decoder->parser) != 0;
190 static int on_body(http_parser* p,
const char* data,
size_t length)
193 CHECK_NOTNULL(decoder->request);
194 decoder->request->body.append(data, length);
198 static int on_message_complete(http_parser* p)
202 CHECK_NOTNULL(decoder->request);
207 http_parser_url_init(&url);
209 http_parser_parse_url(decoder->url.data(), decoder->url.size(), 0, &url);
211 if (parse_url != 0) {
212 decoder->failure =
true;
216 if (url.field_set & (1 << UF_PATH)) {
217 decoder->request->url.path = std::string(
218 decoder->url.data() + url.field_data[UF_PATH].off,
219 url.field_data[UF_PATH].len);
222 if (url.field_set & (1 << UF_FRAGMENT)) {
223 decoder->request->url.fragment = std::string(
224 decoder->url.data() + url.field_data[UF_FRAGMENT].off,
225 url.field_data[UF_FRAGMENT].len);
228 if (url.field_set & (1 << UF_QUERY)) {
229 decoder->query = std::string(
230 decoder->url.data() + url.field_data[UF_QUERY].off,
231 url.field_data[UF_QUERY].len);
239 decoder->failure =
true;
243 decoder->request->url.query = decoded.
get();
246 decoder->request->headers.
get(
"Content-Encoding");
248 if (encoding.
isSome() && encoding.
get() ==
"gzip") {
251 decoder->failure =
true;
254 decoder->request->body = decompressed.
get();
256 CHECK_LE(static_cast<long>(decoder->request->body.length()),
259 decoder->request->headers[
"Content-Length"] =
260 static_cast<char>(decoder->request->body.length());
263 decoder->requests.push_back(decoder->request);
264 decoder->request =
nullptr;
271 http_parser_settings settings;
284 http::Request* request;
286 std::deque<http::Request*> requests;
294 : failure(false), header(HEADER_FIELD), response(nullptr)
296 http_parser_settings_init(&settings);
298 settings.on_message_begin = &ResponseDecoder::on_message_begin;
299 settings.on_url = &ResponseDecoder::on_url;
300 settings.on_header_field = &ResponseDecoder::on_header_field;
301 settings.on_header_value = &ResponseDecoder::on_header_value;
302 settings.on_headers_complete = &ResponseDecoder::on_headers_complete;
303 settings.on_body = &ResponseDecoder::on_body;
304 settings.on_message_complete = &ResponseDecoder::on_message_complete;
305 settings.on_status = &ResponseDecoder::on_status;
306 settings.on_chunk_complete = &ResponseDecoder::on_chunk_complete;
307 settings.on_chunk_header = &ResponseDecoder::on_chunk_header;
309 http_parser_init(&parser, HTTP_RESPONSE);
323 std::deque<http::Response*>
decode(
const char* data,
size_t length)
325 size_t parsed = http_parser_execute(&parser, &settings, data, length);
327 if (parsed != length) {
332 if (!responses.empty()) {
333 std::deque<http::Response*> result = responses;
338 return std::deque<http::Response*>();
347 static int on_message_begin(http_parser* p)
351 CHECK(!decoder->failure);
353 decoder->header = HEADER_FIELD;
354 decoder->field.clear();
355 decoder->value.clear();
357 CHECK(decoder->response ==
nullptr);
360 decoder->response->
status.clear();
361 decoder->response->
headers.clear();
363 decoder->response->
body.clear();
364 decoder->response->
path.clear();
369 static int on_chunk_complete(http_parser* p)
374 static int on_chunk_header(http_parser* p)
379 static int on_url(http_parser* p,
const char* data,
size_t length)
384 static int on_header_field(http_parser* p,
const char* data,
size_t length)
387 CHECK_NOTNULL(decoder->response);
389 if (decoder->header != HEADER_FIELD) {
390 decoder->response->
headers[decoder->field] = decoder->value;
391 decoder->field.clear();
392 decoder->value.clear();
395 decoder->field.append(data, length);
396 decoder->header = HEADER_FIELD;
401 static int on_header_value(http_parser* p,
const char* data,
size_t length)
404 CHECK_NOTNULL(decoder->response);
405 decoder->value.append(data, length);
406 decoder->header = HEADER_VALUE;
410 static int on_headers_complete(http_parser* p)
414 CHECK_NOTNULL(decoder->response);
417 decoder->response->headers[decoder->field] = decoder->value;
418 decoder->field.clear();
419 decoder->value.clear();
424 static int on_body(http_parser* p,
const char* data,
size_t length)
427 CHECK_NOTNULL(decoder->response);
428 decoder->response->body.append(data, length);
432 static int on_message_complete(http_parser* p)
436 CHECK_NOTNULL(decoder->response);
439 decoder->response->code = decoder->parser.status_code;
441 decoder->response->status =
444 decoder->failure =
true;
450 decoder->response->headers.
get(
"Content-Encoding");
451 if (encoding.
isSome() && encoding.
get() ==
"gzip") {
454 decoder->failure =
true;
457 decoder->response->body = decompressed.
get();
459 CHECK_LE(static_cast<long>(decoder->response->body.length()),
462 decoder->response->headers[
"Content-Length"] =
463 static_cast<char>(decoder->response->body.length());
466 decoder->responses.push_back(decoder->response);
467 decoder->response =
nullptr;
471 static int on_status(http_parser* p,
const char* data,
size_t length)
479 http_parser_settings settings;
490 http::Response* response;
492 std::deque<http::Response*> responses;
507 : failure(false), header(HEADER_FIELD), response(nullptr)
509 http_parser_settings_init(&settings);
511 settings.on_message_begin =
512 &StreamingResponseDecoder::on_message_begin;
514 &StreamingResponseDecoder::on_url;
515 settings.on_header_field =
516 &StreamingResponseDecoder::on_header_field;
517 settings.on_header_value =
518 &StreamingResponseDecoder::on_header_value;
519 settings.on_headers_complete =
520 &StreamingResponseDecoder::on_headers_complete;
522 &StreamingResponseDecoder::on_body;
523 settings.on_message_complete =
524 &StreamingResponseDecoder::on_message_complete;
526 &StreamingResponseDecoder::on_status;
527 settings.on_chunk_complete =
528 &StreamingResponseDecoder::on_chunk_complete;
529 settings.on_chunk_header =
530 &StreamingResponseDecoder::on_chunk_header;
532 http_parser_init(&parser, HTTP_RESPONSE);
542 writer->fail(
"Decoder is being deleted");
550 std::deque<http::Response*>
decode(
const char* data,
size_t length)
552 size_t parsed = http_parser_execute(&parser, &settings, data, length);
554 if (parsed != length) {
561 writer_.
fail(
"failed to decode body");
566 if (!responses.empty()) {
567 std::deque<http::Response*> result = responses;
572 return std::deque<http::Response*>();
588 static int on_message_begin(http_parser* p)
592 CHECK(!decoder->failure);
594 decoder->header = HEADER_FIELD;
595 decoder->field.clear();
596 decoder->value.clear();
598 CHECK(decoder->response ==
nullptr);
603 decoder->writer =
None();
608 static int on_chunk_complete(http_parser* p)
613 static int on_chunk_header(http_parser* p)
618 static int on_status(http_parser* p,
const char* data,
size_t length)
623 static int on_url(http_parser* p,
const char* data,
size_t length)
628 static int on_header_field(http_parser* p,
const char* data,
size_t length)
632 CHECK_NOTNULL(decoder->response);
634 if (decoder->header != HEADER_FIELD) {
635 decoder->response->
headers[decoder->field] = decoder->value;
636 decoder->field.clear();
637 decoder->value.clear();
640 decoder->field.append(data, length);
641 decoder->header = HEADER_FIELD;
646 static int on_header_value(http_parser* p,
const char* data,
size_t length)
650 CHECK_NOTNULL(decoder->response);
652 decoder->value.append(data, length);
653 decoder->header = HEADER_VALUE;
657 static int on_headers_complete(http_parser* p)
661 CHECK_NOTNULL(decoder->response);
664 decoder->response->headers[decoder->field] = decoder->value;
665 decoder->field.clear();
666 decoder->value.clear();
669 decoder->response->code = decoder->parser.status_code;
671 decoder->response->status =
674 decoder->failure =
true;
680 decoder->response->headers.
get(
"Content-Encoding");
681 if (encoding.
isSome() && encoding.
get() ==
"gzip") {
682 decoder->failure =
true;
689 decoder->writer = pipe.writer();
690 decoder->response->reader = pipe.reader();
694 decoder->responses.push_back(decoder->response);
695 decoder->response =
nullptr;
700 static int on_body(http_parser* p,
const char* data,
size_t length)
706 http::Pipe::Writer writer = decoder->writer.
get();
707 writer.write(std::string(data, length));
712 static int on_message_complete(http_parser* p)
718 if (decoder->writer.isNone()) {
719 CHECK(decoder->failure);
723 http::Pipe::Writer writer = decoder->writer.get();
726 decoder->writer =
None();
734 http_parser_settings settings;
745 http::Response* response;
748 std::deque<http::Response*> responses;
760 : failure(false), header(HEADER_FIELD), request(nullptr)
762 http_parser_settings_init(&settings);
764 settings.on_message_begin =
765 &StreamingRequestDecoder::on_message_begin;
767 &StreamingRequestDecoder::on_url;
768 settings.on_header_field =
769 &StreamingRequestDecoder::on_header_field;
770 settings.on_header_value =
771 &StreamingRequestDecoder::on_header_value;
772 settings.on_headers_complete =
773 &StreamingRequestDecoder::on_headers_complete;
775 &StreamingRequestDecoder::on_body;
776 settings.on_message_complete =
777 &StreamingRequestDecoder::on_message_complete;
778 settings.on_chunk_complete =
779 &StreamingRequestDecoder::on_chunk_complete;
780 settings.on_chunk_header =
781 &StreamingRequestDecoder::on_chunk_header;
783 http_parser_init(&parser, HTTP_REQUEST);
792 if (writer.isSome()) {
793 writer->fail(
"Decoder is being deleted");
801 std::deque<http::Request*>
decode(
const char* data,
size_t length)
803 size_t parsed = http_parser_execute(&parser, &settings, data, length);
804 if (parsed != length) {
809 if (writer.isSome()) {
811 writer_.
fail(
"failed to decode body");
816 if (!requests.empty()) {
817 std::deque<http::Request*> result = requests;
822 return std::deque<http::Request*>();
831 static int on_message_begin(http_parser* p)
835 CHECK(!decoder->failure);
837 decoder->header = HEADER_FIELD;
838 decoder->field.clear();
839 decoder->value.clear();
840 decoder->query.clear();
841 decoder->url.clear();
843 CHECK(decoder->request ==
nullptr);
848 decoder->writer =
None();
849 decoder->decompressor.
reset();
854 static int on_chunk_complete(http_parser* p)
859 static int on_chunk_header(http_parser* p)
864 static int on_url(http_parser* p,
const char* data,
size_t length)
868 CHECK_NOTNULL(decoder->request);
874 decoder->url.append(data, length);
879 static int on_header_field(http_parser* p,
const char* data,
size_t length)
883 CHECK_NOTNULL(decoder->request);
885 if (decoder->header != HEADER_FIELD) {
886 decoder->request->headers[decoder->field] = decoder->value;
887 decoder->field.clear();
888 decoder->value.clear();
891 decoder->field.append(data, length);
892 decoder->header = HEADER_FIELD;
897 static int on_header_value(http_parser* p,
const char* data,
size_t length)
901 CHECK_NOTNULL(decoder->request);
903 decoder->value.append(data, length);
904 decoder->header = HEADER_VALUE;
908 static int on_headers_complete(http_parser* p)
912 CHECK_NOTNULL(decoder->request);
915 decoder->request->headers[decoder->field] = decoder->value;
916 decoder->field.clear();
917 decoder->value.clear();
919 decoder->request->method =
920 http_method_str((http_method) decoder->parser.method);
922 decoder->request->keepAlive = http_should_keep_alive(&decoder->parser) != 0;
927 http_parser_url_init(&url);
929 http_parser_parse_url(decoder->url.data(), decoder->url.size(), 0, &url);
931 if (parse_url != 0) {
932 decoder->failure =
true;
936 if (url.field_set & (1 << UF_PATH)) {
937 decoder->request->url.path = std::string(
938 decoder->url.data() + url.field_data[UF_PATH].off,
939 url.field_data[UF_PATH].len);
942 if (url.field_set & (1 << UF_FRAGMENT)) {
943 decoder->request->url.fragment = std::string(
944 decoder->url.data() + url.field_data[UF_FRAGMENT].off,
945 url.field_data[UF_FRAGMENT].len);
948 if (url.field_set & (1 << UF_QUERY)) {
949 decoder->query = std::string(
950 decoder->url.data() + url.field_data[UF_QUERY].off,
951 url.field_data[UF_QUERY].len);
959 decoder->failure =
true;
963 decoder->request->url.query = std::move(decoded.
get());
966 decoder->request->headers.
get(
"Content-Encoding");
968 if (encoding.isSome() && encoding.get() ==
"gzip") {
969 decoder->decompressor =
976 decoder->writer = pipe.writer();
977 decoder->request->reader = pipe.reader();
981 decoder->requests.push_back(decoder->request);
982 decoder->request =
nullptr;
987 static int on_body(http_parser* p,
const char* data,
size_t length)
993 http::Pipe::Writer writer = decoder->writer.get();
996 if (decoder->decompressor.get() !=
nullptr) {
998 decoder->decompressor->decompress(std::string(data, length));
1001 decoder->failure =
true;
1005 body = std::move(decompressed.
get());
1007 body = std::string(data, length);
1010 writer.write(std::move(body));
1015 static int on_message_complete(http_parser* p)
1021 if (decoder->writer.isNone()) {
1022 CHECK(decoder->failure);
1026 http::Pipe::Writer writer = decoder->writer.get();
1028 if (decoder->decompressor.get() !=
nullptr &&
1029 !decoder->decompressor->finished()) {
1030 writer.fail(
"Failed to decompress body");
1031 decoder->failure =
true;
1037 decoder->writer =
None();
1045 http_parser_settings settings;
1058 http::Request* request;
1060 Owned<gzip::Decompressor> decompressor;
1062 std::deque<http::Request*> requests;
1067 #endif // __DECODER_HPP__
~DataDecoder()
Definition: decoder.hpp:69
void reset()
Definition: owned.hpp:130
std::string status
Definition: http.hpp:621
enum process::http::Request::@3 type
#define CHECK_NONE(expression)
Definition: check.hpp:48
bool writingBody() const
Definition: decoder.hpp:582
StreamingRequestDecoder()
Definition: decoder.hpp:759
bool failed() const
Definition: decoder.hpp:341
bool failed() const
Definition: decoder.hpp:575
~StreamingResponseDecoder()
Definition: decoder.hpp:537
Try< hashmap< std::string, std::string > > decode(const std::string &query)
Decode a string that is Base64-encoded with the standard Base64 alphabet.
Definition: base64.hpp:172
bool isSome() const
Definition: option.hpp:115
std::deque< http::Request * > decode(const char *data, size_t length)
Definition: decoder.hpp:78
bool contains(const std::string &s, const std::string &substr)
Definition: strings.hpp:406
#define CHECK_SOME(expression)
Definition: check.hpp:44
std::string body
Definition: http.hpp:654
Definition: decoder.hpp:290
Option< T > max(const Option< T > &left, const Option< T > &right)
Definition: option.hpp:199
Try< std::string > decompress(const std::string &compressed)
Definition: gzip.hpp:243
~ResponseDecoder()
Definition: decoder.hpp:314
StreamingResponseDecoder()
Definition: decoder.hpp:506
bool fail(const std::string &message)
Try< std::array< int, 2 > > pipe()
Definition: pipe.hpp:26
const T & get() const &
Definition: option.hpp:118
Definition: decoder.hpp:503
bool failed() const
Definition: decoder.hpp:825
~StreamingRequestDecoder()
Definition: decoder.hpp:788
std::deque< http::Response * > decode(const char *data, size_t length)
Definition: decoder.hpp:323
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
DataDecoder()
Definition: decoder.hpp:49
Definition: decoder.hpp:756
bool isError() const
Definition: try.hpp:71
bool failed() const
Definition: decoder.hpp:96
std::string path
Definition: http.hpp:655
hashmap< uint16_t, std::string > * statuses
Definition: decoder.hpp:46
std::deque< http::Response * > decode(const char *data, size_t length)
Definition: decoder.hpp:550
static std::string string(uint16_t code)
Headers headers
Definition: http.hpp:623
enum process::http::Response::@4 type
std::deque< http::Request * > decode(const char *data, size_t length)
Definition: decoder.hpp:801
const T & get() const
Definition: try.hpp:73
ResponseDecoder()
Definition: decoder.hpp:293