diff --git a/CHANGELOG.md b/CHANGELOG.md index e4d74e56..9699ab47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ API Changes: * Tidy up chunk decorator * Rename to buffer_cat_view +* Consolidate parsers to parser.hpp -------------------------------------------------------------------------------- diff --git a/include/beast/http.hpp b/include/beast/http.hpp index 16eb2625..87c92258 100644 --- a/include/beast/http.hpp +++ b/include/beast/http.hpp @@ -16,9 +16,8 @@ #include #include #include -#include #include -#include +#include #include #include #include diff --git a/include/beast/http/header_parser.hpp b/include/beast/http/header_parser.hpp deleted file mode 100644 index efda061b..00000000 --- a/include/beast/http/header_parser.hpp +++ /dev/null @@ -1,206 +0,0 @@ -// -// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BEAST_HTTP_HEADER_PARSER_HPP -#define BEAST_HTTP_HEADER_PARSER_HPP - -#include -#include -#include -#include -#include -#include -#include - -namespace beast { -namespace http { - -/** A parser for producing HTTP/1 headers. - - This class uses the basic HTTP/1 wire format parser to convert - a series of octets into a @ref header. - - @note A new instance of the parser is required for each message. - - @tparam isRequest Indicates whether a request or response - will be parsed. - - @tparam Fields The type of container used to represent the fields. -*/ -template -class header_parser - : public basic_parser> -{ - header h_; - string_view body_; - -public: - /// The type of @ref header this object produces. - using value_type = header; - - /// Default constructor. - header_parser() = default; - - /// Copy constructor. - header_parser(header_parser const&) = default; - - /// Copy assignment. - header_parser& operator=(header_parser const&) = default; - - /** Move constructor. - - After the move, the only valid operation - on the moved-from object is destruction. - */ - header_parser(header_parser&&) = default; - - /** Move assignment - - After the move, the only valid operation - on the moved-from object is destruction. - */ - header_parser& operator=(header_parser&&) = default; - - /** Constructor - - @param args Optional arguments forwarded - forwarded to the @ref http::header constructor. - */ -#if BEAST_DOXYGEN - template - explicit - header_parser(Args&&... args); -#else - template::type, - header_parser>::value>> - explicit - header_parser(Arg0&& arg0, ArgN&&... argn); -#endif - - /** Returns parsed body octets. - - This function will return the most recent buffer - of octets corresponding to the parsed body. This - buffer will become invalidated on any subsequent - call to @ref put or @ref put_eof - */ - string_view - body() const - { - return body_; - } - - /** Returns the parsed header - - @note The return value is undefined unless - @ref is_header_done would return `true`. - */ - value_type const& - get() const - { - return h_; - } - - /** Returns the parsed header. - - @note The return value is undefined unless - @ref is_header_done would return `true`. - */ - value_type& - get() - { - return h_; - } - - /** Returns ownership of the parsed header. - - Ownership is transferred to the caller. - - @note The return value is undefined unless - @ref is_header_done would return `true`. - - Requires: - @ref value_type is @b MoveConstructible - */ - value_type - release() - { - static_assert( - std::is_move_constructible::value, - "MoveConstructible requirements not met"); - return std::move(h_); - } - -private: - friend class basic_parser; - - void - on_request(string_view method, - string_view path, int version, error_code&) - { - h_.target(path); - h_.method(method); - h_.version = version; - } - - void - on_response(int status, string_view reason, - int version, error_code&) - { - h_.status = status; - h_.version = version; - h_.reason(reason); - } - - void - on_field(string_view name, - string_view value, error_code&) - { - h_.fields.insert(name, value); - } - - void - on_header(error_code&) - { - } - - void - on_body(boost::optional const&, error_code&) - { - } - - void - on_data(string_view s, error_code&) - { - body_ = s; - } - - void - on_chunk(std::uint64_t, - string_view const&, error_code&) - { - body_ = {}; - } - - void - on_complete(error_code&) - { - body_ = {}; - } -}; - -} // http -} // beast - -#include - -#endif diff --git a/include/beast/http/impl/header_parser.ipp b/include/beast/http/impl/header_parser.ipp deleted file mode 100644 index 9ffb8151..00000000 --- a/include/beast/http/impl/header_parser.ipp +++ /dev/null @@ -1,26 +0,0 @@ -// -// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef BEAST_HTTP_IMPL_HEADER_PARSER_IPP -#define BEAST_HTTP_IMPL_HEADER_PARSER_IPP - -namespace beast { -namespace http { - -template -template -header_parser:: -header_parser(Arg0&& arg0, ArgN&&... argn) - : h_(std::forward(arg0), - std::forward(argn)...) -{ -} - -} // http -} // beast - -#endif diff --git a/include/beast/http/impl/message_parser.ipp b/include/beast/http/impl/parser.ipp similarity index 75% rename from include/beast/http/impl/message_parser.ipp rename to include/beast/http/impl/parser.ipp index b387755d..f00b6dbc 100644 --- a/include/beast/http/impl/message_parser.ipp +++ b/include/beast/http/impl/parser.ipp @@ -5,12 +5,21 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BEAST_HTTP_IMPL_MESSAGE_PARSER_IPP -#define BEAST_HTTP_IMPL_MESSAGE_PARSER_IPP +#ifndef BEAST_HTTP_IMPL_PARSER_IPP +#define BEAST_HTTP_IMPL_PARSER_IPP namespace beast { namespace http { +template +template +header_parser:: +header_parser(Arg0&& arg0, ArgN&&... argn) + : h_(std::forward(arg0), + std::forward(argn)...) +{ +} + template template message_parser:: diff --git a/include/beast/http/impl/read.ipp b/include/beast/http/impl/read.ipp index bfcb864e..4dcb58d9 100644 --- a/include/beast/http/impl/read.ipp +++ b/include/beast/http/impl/read.ipp @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/beast/http/message_parser.hpp b/include/beast/http/parser.hpp similarity index 57% rename from include/beast/http/message_parser.hpp rename to include/beast/http/parser.hpp index de9a6d4b..31aab2b5 100644 --- a/include/beast/http/message_parser.hpp +++ b/include/beast/http/parser.hpp @@ -5,21 +5,200 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // -#ifndef BEAST_HTTP_MESSAGE_PARSER_HPP -#define BEAST_HTTP_MESSAGE_PARSER_HPP +#ifndef BEAST_HTTP_PARSER_HPP +#define BEAST_HTTP_PARSER_HPP #include +#include #include -#include -#include +#include #include -#include +#include #include #include namespace beast { namespace http { +/** A parser for producing HTTP/1 headers. + + This class uses the basic HTTP/1 wire format parser to convert + a series of octets into a @ref header. + + @note A new instance of the parser is required for each message. + + @tparam isRequest Indicates whether a request or response + will be parsed. + + @tparam Fields The type of container used to represent the fields. +*/ +template +class header_parser + : public basic_parser> +{ + header h_; + string_view body_; + +public: + /// The type of @ref header this object produces. + using value_type = header; + + /// Default constructor. + header_parser() = default; + + /// Copy constructor. + header_parser(header_parser const&) = default; + + /// Copy assignment. + header_parser& operator=(header_parser const&) = default; + + /** Move constructor. + + After the move, the only valid operation + on the moved-from object is destruction. + */ + header_parser(header_parser&&) = default; + + /** Move assignment + + After the move, the only valid operation + on the moved-from object is destruction. + */ + header_parser& operator=(header_parser&&) = default; + + /** Constructor + + @param args Optional arguments forwarded + forwarded to the @ref http::header constructor. + */ +#if BEAST_DOXYGEN + template + explicit + header_parser(Args&&... args); +#else + template::type, + header_parser>::value>> + explicit + header_parser(Arg0&& arg0, ArgN&&... argn); +#endif + + /** Returns parsed body octets. + + This function will return the most recent buffer + of octets corresponding to the parsed body. This + buffer will become invalidated on any subsequent + call to @ref put or @ref put_eof + */ + string_view + body() const + { + return body_; + } + + /** Returns the parsed header + + @note The return value is undefined unless + @ref is_header_done would return `true`. + */ + value_type const& + get() const + { + return h_; + } + + /** Returns the parsed header. + + @note The return value is undefined unless + @ref is_header_done would return `true`. + */ + value_type& + get() + { + return h_; + } + + /** Returns ownership of the parsed header. + + Ownership is transferred to the caller. + + @note The return value is undefined unless + @ref is_header_done would return `true`. + + Requires: + @ref value_type is @b MoveConstructible + */ + value_type + release() + { + static_assert( + std::is_move_constructible::value, + "MoveConstructible requirements not met"); + return std::move(h_); + } + +private: + friend class basic_parser; + + void + on_request(string_view method, + string_view path, int version, error_code&) + { + h_.target(path); + h_.method(method); + h_.version = version; + } + + void + on_response(int status, string_view reason, + int version, error_code&) + { + h_.status = status; + h_.version = version; + h_.reason(reason); + } + + void + on_field(string_view name, + string_view value, error_code&) + { + h_.fields.insert(name, value); + } + + void + on_header(error_code&) + { + } + + void + on_body(boost::optional const&, error_code&) + { + } + + void + on_data(string_view s, error_code&) + { + body_ = s; + } + + void + on_chunk(std::uint64_t, + string_view const&, error_code&) + { + body_ = {}; + } + + void + on_complete(error_code&) + { + body_ = {}; + } +}; + /** A parser for producing HTTP/1 messages. This class uses the basic HTTP/1 wire format parser to convert @@ -230,6 +409,6 @@ using response_parser = message_parser; } // http } // beast -#include +#include #endif diff --git a/include/beast/websocket/impl/accept.ipp b/include/beast/websocket/impl/accept.ipp index 1b4a1c34..c9c761fb 100644 --- a/include/beast/websocket/impl/accept.ipp +++ b/include/beast/websocket/impl/accept.ipp @@ -10,8 +10,7 @@ #include #include -#include -#include +#include #include #include #include diff --git a/test/Jamfile b/test/Jamfile index 902fd5dc..e9a0798a 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -47,9 +47,8 @@ unit-test http-tests : http/dynamic_body.cpp http/error.cpp http/fields.cpp - http/header_parser.cpp http/message.cpp - http/message_parser.cpp + http/parser.cpp http/read.cpp http/rfc7230.cpp http/serializer.cpp diff --git a/test/http/CMakeLists.txt b/test/http/CMakeLists.txt index a141e479..73508b72 100644 --- a/test/http/CMakeLists.txt +++ b/test/http/CMakeLists.txt @@ -17,9 +17,8 @@ add_executable (http-tests empty_body.cpp error.cpp fields.cpp - header_parser.cpp message.cpp - message_parser.cpp + parser.cpp read.cpp rfc7230.cpp serializer.cpp diff --git a/test/http/dynamic_body.cpp b/test/http/dynamic_body.cpp index 9a455ec1..7818e327 100644 --- a/test/http/dynamic_body.cpp +++ b/test/http/dynamic_body.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include #include diff --git a/test/http/header_parser.cpp b/test/http/header_parser.cpp deleted file mode 100644 index 12689d71..00000000 --- a/test/http/header_parser.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -// Test that header file is self-contained. -#include - -#include -#include -#include -#include -#include - -namespace beast { -namespace http { - -class header_parser_test - : public beast::unit_test::suite - , public test::enable_yield_to -{ -public: - static - boost::asio::const_buffers_1 - buf(string_view s) - { - return {s.data(), s.size()}; - } - - void - testParse() - { - { - test::string_istream is{ios_, - "GET / HTTP/1.1\r\n" - "User-Agent: test\r\n" - "\r\n" - }; - flat_buffer db{1024}; - header_parser p; - read_some(is, db, p); - BEAST_EXPECT(p.is_header_done()); - } - { - test::string_istream is{ios_, - "POST / HTTP/1.1\r\n" - "User-Agent: test\r\n" - "Content-Length: 1\r\n" - "\r\n" - "*" - }; - flat_buffer db{1024}; - header_parser p; - read_some(is, db, p); - BEAST_EXPECT(p.is_header_done()); - BEAST_EXPECT(! p.is_done()); - } - } - - void - run() override - { - testParse(); - } -}; - -BEAST_DEFINE_TESTSUITE(header_parser,http,beast); - -} // http -} // beast - diff --git a/test/http/message_parser.cpp b/test/http/parser.cpp similarity index 89% rename from test/http/message_parser.cpp rename to test/http/parser.cpp index 43ab78e8..aa9d7ca1 100644 --- a/test/http/message_parser.cpp +++ b/test/http/parser.cpp @@ -6,7 +6,7 @@ // // Test that header file is self-contained. -#include +#include #include "test_parser.hpp" @@ -25,7 +25,58 @@ namespace beast { namespace http { -class message_parser_test +class header_parser_test + : public beast::unit_test::suite + , public test::enable_yield_to +{ +public: + static + boost::asio::const_buffers_1 + buf(string_view s) + { + return {s.data(), s.size()}; + } + + void + testParse() + { + { + test::string_istream is{ios_, + "GET / HTTP/1.1\r\n" + "User-Agent: test\r\n" + "\r\n" + }; + flat_buffer db{1024}; + header_parser p; + read_some(is, db, p); + BEAST_EXPECT(p.is_header_done()); + } + { + test::string_istream is{ios_, + "POST / HTTP/1.1\r\n" + "User-Agent: test\r\n" + "Content-Length: 1\r\n" + "\r\n" + "*" + }; + flat_buffer db{1024}; + header_parser p; + read_some(is, db, p); + BEAST_EXPECT(p.is_header_done()); + BEAST_EXPECT(! p.is_done()); + } + } + + void + run() override + { + testParse(); + } +}; + +BEAST_DEFINE_TESTSUITE(header_parser,http,beast); + +class parser_test : public beast::unit_test::suite , public beast::test::enable_yield_to { @@ -363,7 +414,7 @@ public: } }; -BEAST_DEFINE_TESTSUITE(message_parser,http,beast); +BEAST_DEFINE_TESTSUITE(parser,http,beast); } // http } // beast diff --git a/test/http/read.cpp b/test/http/read.cpp index a972bc42..7428b4d1 100644 --- a/test/http/read.cpp +++ b/test/http/read.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include