mirror of
https://github.com/boostorg/beast.git
synced 2025-08-02 14:24:31 +02:00
Doc work
This commit is contained in:
@@ -12,31 +12,20 @@
|
|||||||
While the parsers included in the library will handle a broad number of
|
While the parsers included in the library will handle a broad number of
|
||||||
use-cases, the __basic_parser__ interface can be subclassed to implement
|
use-cases, the __basic_parser__ interface can be subclassed to implement
|
||||||
custom strategies for storing parsed results: the basic parser processes
|
custom strategies for storing parsed results: the basic parser processes
|
||||||
the incoming octets into elements according to the HTTP/1 protocol
|
input buffers into elements according to the HTTP/1 protocol specification,
|
||||||
specification, while the derived class decides what to do with those
|
while the derived class decides what to do with those elements. Custom parsers
|
||||||
elements. In particular, users who create exotic containers for [*Fields]
|
will work with all of the HTTP stream read algorithms, as those algorithms use
|
||||||
may need to also create their own parser. Custom parsers will work with
|
only the basic parser interface. Some use cases for implementing custom
|
||||||
all of the stream read operations that work on parsers, as those algorithms
|
|
||||||
use only the basic parser interface. Some use cases for implementing custom
|
|
||||||
parsers are:
|
parsers are:
|
||||||
|
|
||||||
* Inspect incoming header fields and keep or discard them.
|
* Inspect incoming header fields and keep or discard them.
|
||||||
|
|
||||||
* Use a container provided by an external interface.
|
* Use a container provided by an external interface.
|
||||||
|
|
||||||
* Store header data in a user-defined __Fields__ type.
|
The basic parser uses virtual functions. To declare your user-defined parser,
|
||||||
|
derive from __basic_parser__ and implement all the required virtual functions.
|
||||||
|
A declaration for the derived class may look like this:
|
||||||
|
|
||||||
The basic parser uses the
|
[code_http_10_custom_parser]
|
||||||
[@https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern Curiously Recurring Template Pattern].
|
|
||||||
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
|
|
||||||
above or that the member functions are declared public (not recommended).
|
|
||||||
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.
|
|
||||||
|
|
||||||
[example_http_custom_parser]
|
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
@@ -131,6 +131,7 @@
|
|||||||
|
|
||||||
[import ../../test/doc/core_1_refresher.cpp]
|
[import ../../test/doc/core_1_refresher.cpp]
|
||||||
[import ../../test/doc/core_3_layers.cpp]
|
[import ../../test/doc/core_3_layers.cpp]
|
||||||
|
[import ../../test/doc/http_10_custom_parser.cpp]
|
||||||
[import ../../test/doc/websocket_3_handshake.cpp]
|
[import ../../test/doc/websocket_3_handshake.cpp]
|
||||||
|
|
||||||
[import ../../include/boost/beast/core/detect_ssl.hpp]
|
[import ../../include/boost/beast/core/detect_ssl.hpp]
|
||||||
|
@@ -61,17 +61,15 @@
|
|||||||
[link beast.ref.boost__beast__async_op_base `async_op_base`] and
|
[link beast.ref.boost__beast__async_op_base `async_op_base`] and
|
||||||
[link beast.ref.boost__beast__stable_async_op_base `stable_async_op_base`]
|
[link beast.ref.boost__beast__stable_async_op_base `stable_async_op_base`]
|
||||||
handle all composed operation boilerplate for you.
|
handle all composed operation boilerplate for you.
|
||||||
|
* [link beast.ref.boost__beast__ssl_stream `ssl_stream`] provides a
|
||||||
|
movable, assignable SSL stream with a flat write optimization.
|
||||||
* All asynchronous operations use Asio's
|
* All asynchronous operations use Asio's
|
||||||
[@boost:/doc/html/boost_asio/reference/async_initiate.html `async_initiate`]
|
[@boost:/doc/html/boost_asio/reference/async_initiate.html `async_initiate`]
|
||||||
for efficient integration with Coroutines TS.
|
for efficient integration with Coroutines TS.
|
||||||
* '''
|
* '''
|
||||||
⚡
|
⚡
|
||||||
'''
|
'''
|
||||||
[*['faster compilation]],
|
[*['faster compilation]], define `BOOST_BEAST_SPLIT_COMPILATION` and include
|
||||||
'''
|
|
||||||
⚡
|
|
||||||
'''
|
|
||||||
define `BOOST_BEAST_SPLIT_COMPILATION` and include
|
|
||||||
[@../../include/boost/beast/src.hpp src.hpp] in one of your .cpp files!
|
[@../../include/boost/beast/src.hpp src.hpp] in one of your .cpp files!
|
||||||
* See the full [link beast.release_notes [*Release Notes]] for a complete list
|
* See the full [link beast.release_notes [*Release Notes]] for a complete list
|
||||||
of changes.
|
of changes.
|
||||||
|
@@ -860,199 +860,6 @@ do_form_request(
|
|||||||
|
|
||||||
//]
|
//]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// Example: Custom Parser
|
|
||||||
//
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
//[example_http_custom_parser
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
class custom_parser : public basic_parser<isRequest>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
/// Called after receiving the request-line (isRequest == true).
|
|
||||||
void
|
|
||||||
on_request_impl(
|
|
||||||
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) override; // The error returned to the caller, if any
|
|
||||||
|
|
||||||
/// Called after receiving the start-line (isRequest == false).
|
|
||||||
void
|
|
||||||
on_response_impl(
|
|
||||||
int code, // The status-code
|
|
||||||
string_view reason, // The obsolete reason-phrase
|
|
||||||
int version, // The HTTP-version
|
|
||||||
error_code& ec) override; // The error returned to the caller, if any
|
|
||||||
|
|
||||||
/// Called after receiving a header field.
|
|
||||||
void
|
|
||||||
on_field_impl(
|
|
||||||
field f, // The known-field enumeration constant
|
|
||||||
string_view name, // The field name string.
|
|
||||||
string_view value, // The field value
|
|
||||||
error_code& ec) override; // The error returned to the caller, if any
|
|
||||||
|
|
||||||
/// Called after the complete header is received.
|
|
||||||
void
|
|
||||||
on_header_impl(
|
|
||||||
error_code& ec) override; // The error returned to the caller, if any
|
|
||||||
|
|
||||||
/// Called just before processing the body, if a body exists.
|
|
||||||
void
|
|
||||||
on_body_init_impl(
|
|
||||||
boost::optional<
|
|
||||||
std::uint64_t> const&
|
|
||||||
content_length, // Content length if known, else `boost::none`
|
|
||||||
error_code& ec) override; // The error returned to the caller, if any
|
|
||||||
|
|
||||||
/// Called for each piece of the body, if a body exists.
|
|
||||||
//!
|
|
||||||
//! This is used when there is no chunked transfer coding.
|
|
||||||
//!
|
|
||||||
//! The function returns the number of bytes consumed from the
|
|
||||||
//! input buffer. Any input octets not consumed will be will be
|
|
||||||
//! presented on subsequent calls.
|
|
||||||
//!
|
|
||||||
std::size_t
|
|
||||||
on_body_impl(
|
|
||||||
string_view s, // A portion of the body
|
|
||||||
error_code& ec) override; // The error returned to the caller, if any
|
|
||||||
|
|
||||||
/// Called for each chunk header.
|
|
||||||
void
|
|
||||||
on_chunk_header_impl(
|
|
||||||
std::uint64_t size, // The size of the upcoming chunk,
|
|
||||||
// or zero for the last chunk
|
|
||||||
string_view extension, // The chunk extensions (may be empty)
|
|
||||||
error_code& ec) override; // The error returned to the caller, if any
|
|
||||||
|
|
||||||
/// Called to deliver the chunk body.
|
|
||||||
//!
|
|
||||||
//! This is used when there is a chunked transfer coding. The
|
|
||||||
//! implementation will automatically remove the encoding before
|
|
||||||
//! calling this function.
|
|
||||||
//!
|
|
||||||
//! The function returns the number of bytes consumed from the
|
|
||||||
//! input buffer. Any input octets not consumed will be will be
|
|
||||||
//! presented on subsequent calls.
|
|
||||||
//!
|
|
||||||
std::size_t
|
|
||||||
on_chunk_body_impl(
|
|
||||||
std::uint64_t remain, // The number of bytes remaining in the chunk,
|
|
||||||
// including what is being passed here.
|
|
||||||
// or zero for the last chunk
|
|
||||||
string_view body, // The next piece of the chunk body
|
|
||||||
error_code& ec) override; // The error returned to the caller, if any
|
|
||||||
|
|
||||||
/// Called when the complete message is parsed.
|
|
||||||
void
|
|
||||||
on_finish_impl(
|
|
||||||
error_code& ec) override; // The error returned to the caller, if any
|
|
||||||
|
|
||||||
public:
|
|
||||||
custom_parser() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
//]
|
|
||||||
|
|
||||||
// Definitions are not part of the docs but necessary to link
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
void custom_parser<isRequest>::
|
|
||||||
on_request_impl(verb method, string_view method_str,
|
|
||||||
string_view path, int version, error_code& ec)
|
|
||||||
{
|
|
||||||
boost::ignore_unused(method, method_str, path, version);
|
|
||||||
ec = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
void custom_parser<isRequest>::
|
|
||||||
on_response_impl(
|
|
||||||
int status,
|
|
||||||
string_view reason,
|
|
||||||
int version,
|
|
||||||
error_code& ec)
|
|
||||||
{
|
|
||||||
boost::ignore_unused(status, reason, version);
|
|
||||||
ec = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
void custom_parser<isRequest>::
|
|
||||||
on_field_impl(
|
|
||||||
field f,
|
|
||||||
string_view name,
|
|
||||||
string_view value,
|
|
||||||
error_code& ec)
|
|
||||||
{
|
|
||||||
boost::ignore_unused(f, name, value);
|
|
||||||
ec = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
void custom_parser<isRequest>::
|
|
||||||
on_header_impl(error_code& ec)
|
|
||||||
{
|
|
||||||
ec = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
void custom_parser<isRequest>::
|
|
||||||
on_body_init_impl(
|
|
||||||
boost::optional<std::uint64_t> const& content_length,
|
|
||||||
error_code& ec)
|
|
||||||
{
|
|
||||||
boost::ignore_unused(content_length);
|
|
||||||
ec = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
std::size_t custom_parser<isRequest>::
|
|
||||||
on_body_impl(string_view body, error_code& ec)
|
|
||||||
{
|
|
||||||
boost::ignore_unused(body);
|
|
||||||
ec = {};
|
|
||||||
return body.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
void custom_parser<isRequest>::
|
|
||||||
on_chunk_header_impl(
|
|
||||||
std::uint64_t size,
|
|
||||||
string_view extension,
|
|
||||||
error_code& ec)
|
|
||||||
{
|
|
||||||
boost::ignore_unused(size, extension);
|
|
||||||
ec = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
std::size_t custom_parser<isRequest>::
|
|
||||||
on_chunk_body_impl(
|
|
||||||
std::uint64_t remain,
|
|
||||||
string_view body,
|
|
||||||
error_code& ec)
|
|
||||||
{
|
|
||||||
boost::ignore_unused(remain);
|
|
||||||
ec = {};
|
|
||||||
return body.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<bool isRequest>
|
|
||||||
void custom_parser<isRequest>::
|
|
||||||
on_finish_impl(error_code& ec)
|
|
||||||
{
|
|
||||||
ec = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Example: Incremental Read
|
// Example: Incremental Read
|
||||||
|
@@ -545,9 +545,7 @@ protected:
|
|||||||
std::size_t
|
std::size_t
|
||||||
on_body_impl(
|
on_body_impl(
|
||||||
string_view body,
|
string_view body,
|
||||||
error_code& ec)
|
error_code& ec) = 0;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called each time a new chunk header of a chunk encoded body is received.
|
/** Called each time a new chunk header of a chunk encoded body is received.
|
||||||
|
|
||||||
|
@@ -22,6 +22,7 @@ add_executable (tests-doc
|
|||||||
core_snippets.cpp
|
core_snippets.cpp
|
||||||
core_1_refresher.cpp
|
core_1_refresher.cpp
|
||||||
core_3_layers.cpp
|
core_3_layers.cpp
|
||||||
|
http_10_custom_parser.cpp
|
||||||
http_examples.cpp
|
http_examples.cpp
|
||||||
http_snippets.cpp
|
http_snippets.cpp
|
||||||
websocket_3_handshake.cpp
|
websocket_3_handshake.cpp
|
||||||
|
@@ -21,6 +21,7 @@ alias run-tests :
|
|||||||
[ compile websocket_snippets.cpp ]
|
[ compile websocket_snippets.cpp ]
|
||||||
[ run core_1_refresher.cpp $(TEST_MAIN) ]
|
[ run core_1_refresher.cpp $(TEST_MAIN) ]
|
||||||
[ run core_3_layers.cpp $(TEST_MAIN) ]
|
[ run core_3_layers.cpp $(TEST_MAIN) ]
|
||||||
|
[ run http_10_custom_parser.cpp $(TEST_MAIN) ]
|
||||||
[ run http_examples.cpp $(TEST_MAIN) ]
|
[ run http_examples.cpp $(TEST_MAIN) ]
|
||||||
[ run websocket_3_handshake.cpp $(TEST_MAIN) ]
|
[ run websocket_3_handshake.cpp $(TEST_MAIN) ]
|
||||||
;
|
;
|
||||||
@@ -29,6 +30,7 @@ exe fat-tests :
|
|||||||
$(TEST_MAIN)
|
$(TEST_MAIN)
|
||||||
core_1_refresher.cpp
|
core_1_refresher.cpp
|
||||||
core_3_layers.cpp
|
core_3_layers.cpp
|
||||||
|
http_10_custom_parser.cpp
|
||||||
http_examples.cpp
|
http_examples.cpp
|
||||||
websocket_3_handshake.cpp
|
websocket_3_handshake.cpp
|
||||||
;
|
;
|
||||||
|
311
test/doc/http_10_custom_parser.cpp
Normal file
311
test/doc/http_10_custom_parser.cpp
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2016-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)
|
||||||
|
//
|
||||||
|
// Official repository: https://github.com/boostorg/beast
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <boost/beast/http/basic_parser.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace beast {
|
||||||
|
namespace http {
|
||||||
|
|
||||||
|
//[code_http_10_custom_parser
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
class custom_parser : public basic_parser<isRequest>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
/** Called after receiving the request-line.
|
||||||
|
|
||||||
|
This virtual function is invoked after receiving a request-line
|
||||||
|
when parsing HTTP requests.
|
||||||
|
It can only be called when `isRequest == true`.
|
||||||
|
|
||||||
|
@param method The verb enumeration. If the method string is not
|
||||||
|
one of the predefined strings, this value will be @ref verb::unknown.
|
||||||
|
|
||||||
|
@param method_str The unmodified string representing the verb.
|
||||||
|
|
||||||
|
@param target The request-target.
|
||||||
|
|
||||||
|
@param version The HTTP-version. This will be 10 for HTTP/1.0,
|
||||||
|
and 11 for HTTP/1.1.
|
||||||
|
|
||||||
|
@param ec An output parameter which the function may set to indicate
|
||||||
|
an error. The error will be clear before this function is invoked.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
on_request_impl(
|
||||||
|
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) override; // The error returned to the caller, if any
|
||||||
|
|
||||||
|
/** Called after receiving the status-line.
|
||||||
|
|
||||||
|
This virtual function is invoked after receiving a status-line
|
||||||
|
when parsing HTTP responses.
|
||||||
|
It can only be called when `isRequest == false`.
|
||||||
|
|
||||||
|
@param code The numeric status code.
|
||||||
|
|
||||||
|
@param reason The reason-phrase. Note that this value is
|
||||||
|
now obsolete, and only provided for historical or diagnostic
|
||||||
|
purposes.
|
||||||
|
|
||||||
|
@param version The HTTP-version. This will be 10 for HTTP/1.0,
|
||||||
|
and 11 for HTTP/1.1.
|
||||||
|
|
||||||
|
@param ec An output parameter which the function may set to indicate
|
||||||
|
an error. The error will be clear before this function is invoked.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
on_response_impl(
|
||||||
|
int code, // The status-code
|
||||||
|
string_view reason, // The obsolete reason-phrase
|
||||||
|
int version, // The HTTP-version
|
||||||
|
error_code& ec) override; // The error returned to the caller, if any
|
||||||
|
|
||||||
|
/** Called once for each complete field in the HTTP header.
|
||||||
|
|
||||||
|
This virtual function is invoked for each field that is received
|
||||||
|
while parsing an HTTP message.
|
||||||
|
|
||||||
|
@param name The known field enum value. If the name of the field
|
||||||
|
is not recognized, this value will be @ref field::unknown.
|
||||||
|
|
||||||
|
@param name_string The exact name of the field as received from
|
||||||
|
the input, represented as a string.
|
||||||
|
|
||||||
|
@param value A string holding the value of the field.
|
||||||
|
|
||||||
|
@param ec An output parameter which the function may set to indicate
|
||||||
|
an error. The error will be clear before this function is invoked.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
on_field_impl(
|
||||||
|
field f, // The known-field enumeration constant
|
||||||
|
string_view name, // The field name string.
|
||||||
|
string_view value, // The field value
|
||||||
|
error_code& ec) override; // The error returned to the caller, if any
|
||||||
|
|
||||||
|
/** Called once after the complete HTTP header is received.
|
||||||
|
|
||||||
|
This virtual function is invoked once, after the complete HTTP
|
||||||
|
header is received while parsing a message.
|
||||||
|
|
||||||
|
@param ec An output parameter which the function may set to indicate
|
||||||
|
an error. The error will be clear before this function is invoked.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
on_header_impl(
|
||||||
|
error_code& ec) override; // The error returned to the caller, if any
|
||||||
|
|
||||||
|
/** Called once before the body is processed.
|
||||||
|
|
||||||
|
This virtual function is invoked once, before the content body is
|
||||||
|
processed (but after the complete header is received).
|
||||||
|
|
||||||
|
@param content_length A value representing the content length in
|
||||||
|
bytes if the length is known (this can include a zero length).
|
||||||
|
Otherwise, the value will be `boost::none`.
|
||||||
|
|
||||||
|
@param ec An output parameter which the function may set to indicate
|
||||||
|
an error. The error will be clear before this function is invoked.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
on_body_init_impl(
|
||||||
|
boost::optional<
|
||||||
|
std::uint64_t> const&
|
||||||
|
content_length, // Content length if known, else `boost::none`
|
||||||
|
error_code& ec) override; // The error returned to the caller, if any
|
||||||
|
|
||||||
|
/** Called each time additional data is received representing the content body.
|
||||||
|
|
||||||
|
This virtual function is invoked for each piece of the body which is
|
||||||
|
received while parsing of a message. This function is only used when
|
||||||
|
no chunked transfer encoding is present.
|
||||||
|
|
||||||
|
@param body A string holding the additional body contents. This may
|
||||||
|
contain nulls or unprintable characters.
|
||||||
|
|
||||||
|
@param ec An output parameter which the function may set to indicate
|
||||||
|
an error. The error will be clear before this function is invoked.
|
||||||
|
|
||||||
|
@see on_chunk_body_impl
|
||||||
|
*/
|
||||||
|
std::size_t
|
||||||
|
on_body_impl(
|
||||||
|
string_view s, // A portion of the body
|
||||||
|
error_code& ec) override; // The error returned to the caller, if any
|
||||||
|
|
||||||
|
/** Called each time a new chunk header of a chunk encoded body is received.
|
||||||
|
|
||||||
|
This function is invoked each time a new chunk header is received.
|
||||||
|
The function is only used when the chunked transfer encoding is present.
|
||||||
|
|
||||||
|
@param size The size of this chunk, in bytes.
|
||||||
|
|
||||||
|
@param extensions A string containing the entire chunk extensions.
|
||||||
|
This may be empty, indicating no extensions are present.
|
||||||
|
|
||||||
|
@param ec An output parameter which the function may set to indicate
|
||||||
|
an error. The error will be clear before this function is invoked.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
on_chunk_header_impl(
|
||||||
|
std::uint64_t size, // The size of the upcoming chunk,
|
||||||
|
// or zero for the last chunk
|
||||||
|
string_view extension, // The chunk extensions (may be empty)
|
||||||
|
error_code& ec) override; // The error returned to the caller, if any
|
||||||
|
|
||||||
|
/** Called each time additional data is received representing part of a body chunk.
|
||||||
|
|
||||||
|
This virtual function is invoked for each piece of the body which is
|
||||||
|
received while parsing of a message. This function is only used when
|
||||||
|
no chunked transfer encoding is present.
|
||||||
|
|
||||||
|
@param remain The number of bytes remaining in this chunk. This includes
|
||||||
|
the contents of passed `body`. If this value is zero, then this represents
|
||||||
|
the final chunk.
|
||||||
|
|
||||||
|
@param body A string holding the additional body contents. This may
|
||||||
|
contain nulls or unprintable characters.
|
||||||
|
|
||||||
|
@param ec An output parameter which the function may set to indicate
|
||||||
|
an error. The error will be clear before this function is invoked.
|
||||||
|
|
||||||
|
@return This function should return the number of bytes actually consumed
|
||||||
|
from the `body` value. Any bytes that are not consumed on this call
|
||||||
|
will be presented in a subsequent call.
|
||||||
|
|
||||||
|
@see on_body_impl
|
||||||
|
*/
|
||||||
|
std::size_t
|
||||||
|
on_chunk_body_impl(
|
||||||
|
std::uint64_t remain, // The number of bytes remaining in the chunk,
|
||||||
|
// including what is being passed here.
|
||||||
|
// or zero for the last chunk
|
||||||
|
string_view body, // The next piece of the chunk body
|
||||||
|
error_code& ec) override; // The error returned to the caller, if any
|
||||||
|
|
||||||
|
/** Called once when the complete message is received.
|
||||||
|
|
||||||
|
This virtual function is invoked once, after successfully parsing
|
||||||
|
a complete HTTP message.
|
||||||
|
|
||||||
|
@param ec An output parameter which the function may set to indicate
|
||||||
|
an error. The error will be clear before this function is invoked.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
on_finish_impl(
|
||||||
|
error_code& ec) override; // The error returned to the caller, if any
|
||||||
|
|
||||||
|
public:
|
||||||
|
custom_parser() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
//]
|
||||||
|
|
||||||
|
// Definitions are not part of the docs but necessary to link
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
void custom_parser<isRequest>::
|
||||||
|
on_request_impl(verb method, string_view method_str,
|
||||||
|
string_view path, int version, error_code& ec)
|
||||||
|
{
|
||||||
|
boost::ignore_unused(method, method_str, path, version);
|
||||||
|
ec = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
void custom_parser<isRequest>::
|
||||||
|
on_response_impl(
|
||||||
|
int status,
|
||||||
|
string_view reason,
|
||||||
|
int version,
|
||||||
|
error_code& ec)
|
||||||
|
{
|
||||||
|
boost::ignore_unused(status, reason, version);
|
||||||
|
ec = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
void custom_parser<isRequest>::
|
||||||
|
on_field_impl(
|
||||||
|
field f,
|
||||||
|
string_view name,
|
||||||
|
string_view value,
|
||||||
|
error_code& ec)
|
||||||
|
{
|
||||||
|
boost::ignore_unused(f, name, value);
|
||||||
|
ec = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
void custom_parser<isRequest>::
|
||||||
|
on_header_impl(error_code& ec)
|
||||||
|
{
|
||||||
|
ec = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
void custom_parser<isRequest>::
|
||||||
|
on_body_init_impl(
|
||||||
|
boost::optional<std::uint64_t> const& content_length,
|
||||||
|
error_code& ec)
|
||||||
|
{
|
||||||
|
boost::ignore_unused(content_length);
|
||||||
|
ec = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
std::size_t custom_parser<isRequest>::
|
||||||
|
on_body_impl(string_view body, error_code& ec)
|
||||||
|
{
|
||||||
|
boost::ignore_unused(body);
|
||||||
|
ec = {};
|
||||||
|
return body.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
void custom_parser<isRequest>::
|
||||||
|
on_chunk_header_impl(
|
||||||
|
std::uint64_t size,
|
||||||
|
string_view extension,
|
||||||
|
error_code& ec)
|
||||||
|
{
|
||||||
|
boost::ignore_unused(size, extension);
|
||||||
|
ec = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
std::size_t custom_parser<isRequest>::
|
||||||
|
on_chunk_body_impl(
|
||||||
|
std::uint64_t remain,
|
||||||
|
string_view body,
|
||||||
|
error_code& ec)
|
||||||
|
{
|
||||||
|
boost::ignore_unused(remain);
|
||||||
|
ec = {};
|
||||||
|
return body.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<bool isRequest>
|
||||||
|
void custom_parser<isRequest>::
|
||||||
|
on_finish_impl(error_code& ec)
|
||||||
|
{
|
||||||
|
ec = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
template class custom_parser<true>;
|
||||||
|
template class custom_parser<false>;
|
||||||
|
|
||||||
|
} // http
|
||||||
|
} // beast
|
||||||
|
} // boost
|
@@ -188,42 +188,6 @@ public:
|
|||||||
BEAST_EXPECT(to_string(req) == os.str());
|
BEAST_EXPECT(to_string(req) == os.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
doCustomParser()
|
|
||||||
{
|
|
||||||
{
|
|
||||||
string_view s{
|
|
||||||
"POST / HTTP/1.1\r\n"
|
|
||||||
"User-Agent: test\r\n"
|
|
||||||
"Content-Length: 13\r\n"
|
|
||||||
"\r\n"
|
|
||||||
"Hello, world!"
|
|
||||||
};
|
|
||||||
error_code ec;
|
|
||||||
custom_parser<true> p;
|
|
||||||
p.put(net::buffer(
|
|
||||||
s.data(), s.size()), ec);
|
|
||||||
BEAST_EXPECTS(! ec, ec.message());
|
|
||||||
}
|
|
||||||
{
|
|
||||||
string_view s{
|
|
||||||
"HTTP/1.1 200 OK\r\n"
|
|
||||||
"Server: test\r\n"
|
|
||||||
"Transfer-Encoding: chunked\r\n"
|
|
||||||
"\r\n"
|
|
||||||
"d\r\n"
|
|
||||||
"Hello, world!"
|
|
||||||
"\r\n"
|
|
||||||
"0\r\n\r\n"
|
|
||||||
};
|
|
||||||
error_code ec;
|
|
||||||
custom_parser<false> p;
|
|
||||||
p.put(net::buffer(
|
|
||||||
s.data(), s.size()), ec);
|
|
||||||
BEAST_EXPECTS(! ec, ec.message());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
doHEAD()
|
doHEAD()
|
||||||
{
|
{
|
||||||
@@ -428,7 +392,6 @@ public:
|
|||||||
doRelay();
|
doRelay();
|
||||||
doReadStdStream();
|
doReadStdStream();
|
||||||
doWriteStdStream();
|
doWriteStdStream();
|
||||||
doCustomParser();
|
|
||||||
doHEAD();
|
doHEAD();
|
||||||
doDeferredBody();
|
doDeferredBody();
|
||||||
doIncrementalRead();
|
doIncrementalRead();
|
||||||
|
Reference in New Issue
Block a user