From ff216a89a86969389bdbb8b23eac1885431eb967 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Mon, 5 Jun 2017 15:44:47 -0700 Subject: [PATCH] Add verb to on_request for parsers (API Change) --- CHANGELOG.md | 1 + doc/4_08_custom_parsers.qbk | 80 +----------------------- examples/doc_http_samples.hpp | 20 ++++-- include/beast/http/basic_parser.hpp | 71 +-------------------- include/beast/http/impl/basic_parser.ipp | 2 +- include/beast/http/parser.hpp | 11 ++-- test/http/parser_bench.cpp | 5 +- test/http/test_parser.hpp | 7 +-- 8 files changed, 30 insertions(+), 167 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe6ee02c..faa735c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Version 50 API Changes: * Remove header_parser +* Add verb to on_request for parsers -------------------------------------------------------------------------------- diff --git a/doc/4_08_custom_parsers.qbk b/doc/4_08_custom_parsers.qbk index 75a9a9af..7fbc2047 100644 --- a/doc/4_08_custom_parsers.qbk +++ b/doc/4_08_custom_parsers.qbk @@ -19,16 +19,7 @@ that work on parsers, as those algorithms use only the basic parser interface. The basic parser uses the Curiously Recurring Template Pattern ([@https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern CRTP]). -To declare your user defined parser, first derive it from __basic_parser__: -``` -template -class custom_parser - : public basic_parser> -{ - friend class basic_parser; - ... -``` - +To declare your user defined parser, derive it from __basic_parser__. The interface to the parser is event-driven. Member functions of the derived class (termed "callbacks" in this context) are invoked with parsed elements as they become available, requiring either the `friend` declaration as shown @@ -37,73 +28,6 @@ Buffers provided by the parser are non-owning references, it is the responsibility of the derived class to copy any information it needs before returning from the callback. - -``` -template -class custom_parser - : public basic_parser> -{ - friend class basic_parser; - - /// Called after receiving the request-line (isRequest == true). - void - on_request( - string_view method, // The method - string_view target, // The request-target - int version, // The HTTP-version - error_code& ec); // The error returned to the caller, if any - - /// Called after receiving the start-line (isRequest == false). - void - on_response( - int code, // The status-code - string_view reason, // The obsolete reason-phrase - int version, // The HTTP-version - error_code& ec); // The error returned to the caller, if any - - /// Called after receiving a header field. - void - on_field( - string_view name, // The field name - string_view value, // The field value - error_code& ec); // The error returned to the caller, if any - - /// Called after the complete header is received. - void - on_header( - error_code& ec); // The error returned to the caller, if any - - /// Called just before processing the body, if a body exists. - void - on_body(boost::optional< - std::uint64_t> const& - content_length, // Content length if known, else `boost::none` - error_code& ec); // The error returned to the caller, if any - - /// Called for each piece of the body, if a body exists. - // - // If present, the chunked Transfer-Encoding will be removed - // before this callback is invoked. - // - void - on_data( - string_view s, // A portion of the body - error_code& ec); // The error returned to the caller, if any - - /// Called for each chunk header. - void - on_chunk( - std::uint64_t size, // The size of the upcoming chunk - string_view extension, // The chunk-extension (may be empty) - error_code& ec); // The error returned to the caller, if any - - /// Called when the complete message is parsed. - void - on_complete(error_code& ec); - -public: - custom_parser() = default; -}; -``` +[http_sample_custom_parser] [endsect] diff --git a/examples/doc_http_samples.hpp b/examples/doc_http_samples.hpp index 4e31dcef..95b7dfe0 100644 --- a/examples/doc_http_samples.hpp +++ b/examples/doc_http_samples.hpp @@ -866,12 +866,15 @@ template class custom_parser : public basic_parser> { + // The friend declaration is needed, + // otherwise the callbacks must be made public. friend class basic_parser; /// Called after receiving the request-line (isRequest == true). void on_request( - string_view method, // The method + verb method, // The method verb, verb::unknown if no match + string_view method_str, // The method as a string string_view target, // The request-target int version, // The HTTP-version error_code& ec); // The error returned to the caller, if any @@ -934,19 +937,22 @@ public: template void custom_parser:: -on_request(string_view method, string_view path, int version, error_code& ec) +on_request(verb method, string_view method_str, + string_view path, int version, error_code& ec) { } template void custom_parser:: -on_response(int status, string_view reason, int version, error_code& ec) +on_response(int status, string_view reason, + int version, error_code& ec) { } template void custom_parser:: -on_field(string_view name, string_view value, error_code& ec) +on_field(string_view name, + string_view value, error_code& ec) { } @@ -958,7 +964,8 @@ on_header(error_code& ec) template void custom_parser:: -on_body(boost::optional const& content_length, error_code& ec) +on_body(boost::optional const& content_length, + error_code& ec) { } @@ -970,7 +977,8 @@ on_data(string_view s, error_code& ec) template void custom_parser:: -on_chunk(std::uint64_t size, string_view extension, error_code& ec) +on_chunk(std::uint64_t size, + string_view extension, error_code& ec) { } diff --git a/include/beast/http/basic_parser.hpp b/include/beast/http/basic_parser.hpp index f1079d54..7941986b 100644 --- a/include/beast/http/basic_parser.hpp +++ b/include/beast/http/basic_parser.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -53,76 +54,6 @@ namespace http { the derived class. If a callback sets the error code, the error will be propagated to the caller of the parser. - @par Example - - @code - template - class custom_parser - : public basic_parser> - { - friend class basic_parser; - - /// Called after receiving the request-line (isRequest == true). - void - on_request( - string_view method, // The method - string_view target, // The request-target - int version, // The HTTP-version - error_code& ec); // The error returned to the caller, if any - - /// Called after receiving the start-line (isRequest == false). - void - on_response( - int status, // The status-code - string_view reason, // The obsolete reason-phrase - int version, // The HTTP-version - error_code& ec); // The error returned to the caller, if any - - /// Called after receiving a header field. - void - on_field( - string_view name, // The field name - string_view value, // The field value - error_code& ec); // The error returned to the caller, if any - - /// Called after the complete header is received. - void - on_header( - error_code& ec); // The error returned to the caller, if any - - /// Called just before processing the body, if a body exists. - void - on_body(boost::optional< - std::uint64_t> const& - content_length, // Content length if known, else `boost::none` - error_code& ec); // The error returned to the caller, if any - - /// Called for each piece of the body, if a body exists. - // - // If present, the chunked Transfer-Encoding will be removed - // before this callback is invoked. - // - void - on_data( - string_view s, // A portion of the body - error_code& ec); // The error returned to the caller, if any - - /// Called for each chunk header. - void - on_chunk( - std::uint64_t size, // The size of the upcoming chunk - string_view extension, // The chunk-extension (may be empty) - error_code& ec); // The error returned to the caller, if any - - /// Called when the complete message is parsed. - void - on_complete(error_code& ec); - - public: - custom_parser() = default; - }; - @endcode - @tparam isRequest A `bool` indicating whether the parser will be presented with request or response message. diff --git a/include/beast/http/impl/basic_parser.ipp b/include/beast/http/impl/basic_parser.ipp index 51a94866..ba7b010a 100644 --- a/include/beast/http/impl/basic_parser.ipp +++ b/include/beast/http/impl/basic_parser.ipp @@ -325,7 +325,7 @@ parse_header(char const*& p, char const* term, if(version >= 11) f_ |= flagHTTP11; - impl().on_request( + impl().on_request(string_to_verb(method), method, target, version, ec); if(ec) return; diff --git a/include/beast/http/parser.hpp b/include/beast/http/parser.hpp index 0271eff8..b1118793 100644 --- a/include/beast/http/parser.hpp +++ b/include/beast/http/parser.hpp @@ -182,13 +182,14 @@ private: friend class basic_parser; void - on_request( - string_view method, - string_view target, - int version, error_code&) + on_request(verb method, string_view method_str, + string_view target, int version, error_code&) { m_.target(target); - m_.method(method); + if(method != verb::unknown) + m_.method(method); + else + m_.method(method_str); m_.version = version; } diff --git a/test/http/parser_bench.cpp b/test/http/parser_bench.cpp index dd4daa31..eae2a603 100644 --- a/test/http/parser_bench.cpp +++ b/test/http/parser_bench.cpp @@ -165,9 +165,8 @@ public: boost::asio::mutable_buffers_1; void - on_request(string_view, - string_view, - int, error_code&) + on_request(verb, string_view, + string_view, int, error_code&) { } diff --git a/test/http/test_parser.hpp b/test/http/test_parser.hpp index f0de6e05..15a1e967 100644 --- a/test/http/test_parser.hpp +++ b/test/http/test_parser.hpp @@ -47,12 +47,11 @@ public: } void - on_request(string_view method_, - string_view path_, - int version_, error_code& ec) + on_request(verb, string_view method_str_, + string_view path_, int version_, error_code& ec) { method = std::string( - method_.data(), method_.size()); + method_str_.data(), method_str_.size()); path = std::string( path_.data(), path_.size()); version = version_;