mirror of
https://github.com/boostorg/beast.git
synced 2025-07-29 20:37:31 +02:00
Distinguish HTTP/1 messages from general HTTP messages:
The version field is moved into message_v1, all public interfaces are reworked to identify HTTP/1 wire format operations (suffix "_v1") versus general HTTP.
This commit is contained in:
@ -122,12 +122,14 @@ INPUT = \
|
||||
../include/beast/write_streambuf.hpp \
|
||||
../include/beast/http/basic_headers.hpp \
|
||||
../include/beast/http/basic_parser.hpp \
|
||||
../include/beast/http/body_writer.hpp \
|
||||
../include/beast/http/chunk_encode.hpp \
|
||||
../include/beast/http/empty_body.hpp \
|
||||
../include/beast/http/error.hpp \
|
||||
../include/beast/http/fields.hpp \
|
||||
../include/beast/http/headers.hpp \
|
||||
../include/beast/http/message.hpp \
|
||||
../include/beast/http/message_v1.hpp \
|
||||
../include/beast/http/method.hpp \
|
||||
../include/beast/http/parse_error.hpp \
|
||||
../include/beast/http/parser.hpp \
|
||||
|
@ -20,8 +20,7 @@
|
||||
#ifndef BEAST_EXAMPLE_FILE_BODY_H_INCLUDED
|
||||
#define BEAST_EXAMPLE_FILE_BODY_H_INCLUDED
|
||||
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/resume_context.hpp>
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <cstdio>
|
||||
@ -44,7 +43,8 @@ struct file_body
|
||||
std::size_t buf_len_;
|
||||
|
||||
public:
|
||||
static bool constexpr is_single_pass = false;
|
||||
writer(writer const&) = delete;
|
||||
writer& operator=(writer const&) = delete;
|
||||
|
||||
template<bool isRequest, class Headers>
|
||||
writer(message<isRequest, file_body, Headers> const& m) noexcept
|
||||
|
@ -41,8 +41,8 @@ class http_async_server
|
||||
using address_type = boost::asio::ip::address;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
|
||||
using req_type = request<string_body>;
|
||||
using resp_type = response<file_body>;
|
||||
using req_type = request_v1<string_body>;
|
||||
using resp_type = response_v1<file_body>;
|
||||
|
||||
boost::asio::io_service ios_;
|
||||
socket_type sock_;
|
||||
@ -127,7 +127,7 @@ private:
|
||||
path = root_ + path;
|
||||
if(! boost::filesystem::exists(path))
|
||||
{
|
||||
response<string_body> resp(
|
||||
response_v1<string_body> resp(
|
||||
{404, "Not Found", req_.version});
|
||||
resp.headers.replace("Server", "http_async_server");
|
||||
resp.body = "The file '" + path + "' was not found";
|
||||
@ -137,7 +137,7 @@ private:
|
||||
asio::placeholders::error));
|
||||
return;
|
||||
}
|
||||
response<file_body> resp(
|
||||
resp_type resp(
|
||||
{200, "OK", req_.version});
|
||||
resp.headers.replace("Server", "http_async_server");
|
||||
resp.headers.replace("Content-Type", "text/html");
|
||||
|
@ -46,13 +46,13 @@ int main(int, char const*[])
|
||||
stream<ip::tcp::socket> hs(ios);
|
||||
connect(hs.lowest_layer(), it);
|
||||
auto ep = hs.lowest_layer().remote_endpoint();
|
||||
request<empty_body> req({"GET", "/", 11});
|
||||
request_v1<empty_body> req({"GET", "/", 11});
|
||||
req.headers.insert("Host", host +
|
||||
std::string(":") + std::to_string(ep.port()));
|
||||
req.headers.insert("User-Agent", "beast/http");
|
||||
prepare(req);
|
||||
hs.write(req);
|
||||
response<string_body> resp;
|
||||
response_v1<string_body> resp;
|
||||
hs.read(resp);
|
||||
std::cout << resp;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ int main()
|
||||
using namespace beast::http;
|
||||
|
||||
// Send HTTP request using beast
|
||||
request<empty_body> req({"GET", "/", 11});
|
||||
request_v1<empty_body> req({"GET", "/", 11});
|
||||
req.headers.replace("Host", host + ":" + std::to_string(sock.remote_endpoint().port()));
|
||||
req.headers.replace("User-Agent", "Beast");
|
||||
prepare(req);
|
||||
@ -31,7 +31,7 @@ int main()
|
||||
|
||||
// Receive and print HTTP response using beast
|
||||
beast::streambuf sb;
|
||||
response<streambuf_body> resp;
|
||||
response_v1<streambuf_body> resp;
|
||||
read(sock, sb, resp);
|
||||
std::cout << resp;
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ public:
|
||||
*/
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(message<isRequest, Body, Headers>& msg)
|
||||
read(message_v1<isRequest, Body, Headers>& msg)
|
||||
{
|
||||
error_code ec;
|
||||
read(msg, ec);
|
||||
@ -295,7 +295,7 @@ public:
|
||||
*/
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(message<isRequest, Body, Headers>& msg,
|
||||
read(message_v1<isRequest, Body, Headers>& msg,
|
||||
error_code& ec);
|
||||
|
||||
/** Start reading a HTTP message from the stream asynchronously.
|
||||
@ -339,7 +339,7 @@ public:
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_read(message<isRequest, Body, Headers>& msg,
|
||||
async_read(message_v1<isRequest, Body, Headers>& msg,
|
||||
ReadHandler&& handler);
|
||||
|
||||
/** Write a HTTP message to the stream.
|
||||
@ -365,7 +365,7 @@ public:
|
||||
*/
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
write(message<isRequest, Body, Headers> const& msg)
|
||||
write(message_v1<isRequest, Body, Headers> const& msg)
|
||||
{
|
||||
error_code ec;
|
||||
write(msg, ec);
|
||||
@ -396,7 +396,7 @@ public:
|
||||
*/
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
write(message<isRequest, Body, Headers> const& msg,
|
||||
write(message_v1<isRequest, Body, Headers> const& msg,
|
||||
error_code& ec);
|
||||
|
||||
/** Start pipelining a HTTP message to the stream asynchronously.
|
||||
@ -434,7 +434,7 @@ public:
|
||||
typename async_completion<
|
||||
WriteHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_write(message<isRequest, Body, Headers> const& msg,
|
||||
async_write(message_v1<isRequest, Body, Headers> const& msg,
|
||||
WriteHandler&& handler);
|
||||
|
||||
/** Start pipelining a HTTP message to the stream asynchronously.
|
||||
@ -473,7 +473,7 @@ public:
|
||||
typename async_completion<
|
||||
WriteHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_write(message<isRequest, Body, Headers>&& msg,
|
||||
async_write(message_v1<isRequest, Body, Headers>&& msg,
|
||||
WriteHandler&& handler);
|
||||
|
||||
private:
|
||||
|
@ -20,10 +20,11 @@
|
||||
#ifndef BEAST_HTTP_STREAM_IPP_INCLUDED
|
||||
#define BEAST_HTTP_STREAM_IPP_INCLUDED
|
||||
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/read.hpp>
|
||||
#include <beast/http/write.hpp>
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <cassert>
|
||||
|
||||
namespace beast {
|
||||
@ -40,14 +41,14 @@ class stream<NextLayer, Allocator>::read_op
|
||||
struct data
|
||||
{
|
||||
stream<NextLayer>& s;
|
||||
message<isRequest, Body, Headers>& m;
|
||||
message_v1<isRequest, Body, Headers>& m;
|
||||
Handler h;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& s_,
|
||||
message<isRequest, Body, Headers>& m_)
|
||||
message_v1<isRequest, Body, Headers>& m_)
|
||||
: s(s_)
|
||||
, m(m_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
@ -142,14 +143,14 @@ class stream<NextLayer, Allocator>::write_op : public op
|
||||
struct data
|
||||
{
|
||||
stream<NextLayer>& s;
|
||||
message<isRequest, Body, Headers> m;
|
||||
message_v1<isRequest, Body, Headers> m;
|
||||
Handler h;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& s_,
|
||||
message<isRequest, Body, Headers> const& m_,
|
||||
message_v1<isRequest, Body, Headers> const& m_,
|
||||
bool cont_)
|
||||
: s(s_)
|
||||
, m(m_)
|
||||
@ -160,7 +161,7 @@ class stream<NextLayer, Allocator>::write_op : public op
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& s_,
|
||||
message<isRequest, Body, Headers>&& m_,
|
||||
message_v1<isRequest, Body, Headers>&& m_,
|
||||
bool cont_)
|
||||
: s(s_)
|
||||
, m(std::move(m_))
|
||||
@ -305,7 +306,7 @@ template<class NextLayer, class Allocator>
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
stream<NextLayer, Allocator>::
|
||||
read(message<isRequest, Body, Headers>& msg,
|
||||
read(message_v1<isRequest, Body, Headers>& msg,
|
||||
error_code& ec)
|
||||
{
|
||||
beast::http::read(next_layer_, rd_buf_, msg, ec);
|
||||
@ -316,7 +317,7 @@ template<bool isRequest, class Body, class Headers,
|
||||
class ReadHandler>
|
||||
auto
|
||||
stream<NextLayer, Allocator>::
|
||||
async_read(message<isRequest, Body, Headers>& msg,
|
||||
async_read(message_v1<isRequest, Body, Headers>& msg,
|
||||
ReadHandler&& handler) ->
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
@ -334,7 +335,7 @@ template<class NextLayer, class Allocator>
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
stream<NextLayer, Allocator>::
|
||||
write(message<isRequest, Body, Headers> const& msg,
|
||||
write(message_v1<isRequest, Body, Headers> const& msg,
|
||||
error_code& ec)
|
||||
{
|
||||
beast::http::write(next_layer_, msg, ec);
|
||||
@ -345,7 +346,7 @@ template<bool isRequest, class Body, class Headers,
|
||||
class WriteHandler>
|
||||
auto
|
||||
stream<NextLayer, Allocator>::
|
||||
async_write(message<isRequest, Body, Headers> const& msg,
|
||||
async_write(message_v1<isRequest, Body, Headers> const& msg,
|
||||
WriteHandler&& handler) ->
|
||||
typename async_completion<
|
||||
WriteHandler, void(error_code)>::result_type
|
||||
@ -376,7 +377,7 @@ template<bool isRequest, class Body, class Headers,
|
||||
class WriteHandler>
|
||||
auto
|
||||
stream<NextLayer, Allocator>::
|
||||
async_write(message<isRequest, Body, Headers>&& msg,
|
||||
async_write(message_v1<isRequest, Body, Headers>&& msg,
|
||||
WriteHandler&& handler) ->
|
||||
typename async_completion<
|
||||
WriteHandler, void(error_code)>::result_type
|
||||
|
@ -43,8 +43,8 @@ class http_sync_server
|
||||
using address_type = boost::asio::ip::address;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
|
||||
using req_type = request<string_body>;
|
||||
using resp_type = response<file_body>;
|
||||
using req_type = request_v1<string_body>;
|
||||
using resp_type = response_v1<file_body>;
|
||||
|
||||
boost::asio::io_service ios_;
|
||||
socket_type sock_;
|
||||
@ -155,7 +155,7 @@ public:
|
||||
path = root_ + path;
|
||||
if(! boost::filesystem::exists(path))
|
||||
{
|
||||
response<string_body> resp(
|
||||
response_v1<string_body> resp(
|
||||
{404, "Not Found", req.version});
|
||||
resp.headers.replace("Server", "http_sync_server");
|
||||
resp.body = "The file '" + path + "' was not found";
|
||||
@ -164,7 +164,7 @@ public:
|
||||
if(ec)
|
||||
break;
|
||||
}
|
||||
response<file_body> resp(
|
||||
resp_type resp(
|
||||
{200, "OK", req.version});
|
||||
resp.headers.replace("Server", "http_sync_server");
|
||||
resp.headers.replace("Content-Type", "text/html");
|
||||
|
@ -9,13 +9,15 @@
|
||||
#define BEAST_HTTP_HPP_INCLUDED
|
||||
|
||||
#include <beast/http/basic_headers.hpp>
|
||||
#include <beast/http/basic_parser.hpp>
|
||||
#include <beast/http/basic_parser_v1.hpp>
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <beast/http/empty_body.hpp>
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/headers.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/parse_error.hpp>
|
||||
#include <beast/http/parser.hpp>
|
||||
#include <beast/http/parser_v1.hpp>
|
||||
#include <beast/http/read.hpp>
|
||||
#include <beast/http/reason.hpp>
|
||||
#include <beast/http/resume_context.hpp>
|
||||
|
@ -5,13 +5,13 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_BASIC_PARSER_HPP
|
||||
#define BEAST_HTTP_BASIC_PARSER_HPP
|
||||
#ifndef BEAST_HTTP_BASIC_PARSER_v1_HPP
|
||||
#define BEAST_HTTP_BASIC_PARSER_v1_HPP
|
||||
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/parse_error.hpp>
|
||||
#include <beast/http/rfc7230.hpp>
|
||||
#include <beast/http/detail/basic_parser.hpp>
|
||||
#include <beast/http/detail/basic_parser_v1.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <array>
|
||||
@ -37,7 +37,7 @@ enum values
|
||||
};
|
||||
} // parse_flag
|
||||
|
||||
/** Parser for producing HTTP requests and responses.
|
||||
/** Base class for parsing HTTP/1 requests and responses.
|
||||
|
||||
During parsing, callbacks will be made to the derived class
|
||||
if those members are present (detected through SFINAE). The
|
||||
@ -84,7 +84,7 @@ enum values
|
||||
@li `void on_complete(error_code& ec)`
|
||||
|
||||
Called when the entire message has been parsed successfully.
|
||||
At this point, basic_parser::complete() returns `true`, and
|
||||
At this point, basic_parser_v1::complete() returns `true`, and
|
||||
the parser is ready to parse another message if keep_alive()
|
||||
would return `true`.
|
||||
|
||||
@ -109,10 +109,10 @@ enum values
|
||||
and the error is returned to the caller.
|
||||
*/
|
||||
template<bool isRequest, class Derived>
|
||||
class basic_parser
|
||||
class basic_parser_v1
|
||||
{
|
||||
private:
|
||||
using self = basic_parser;
|
||||
using self = basic_parser_v1;
|
||||
typedef void(self::*pmf_t)(error_code&, boost::string_ref const&);
|
||||
|
||||
static std::uint64_t constexpr no_content_length =
|
||||
@ -237,13 +237,13 @@ private:
|
||||
|
||||
public:
|
||||
/// Copy constructor.
|
||||
basic_parser(basic_parser const&) = default;
|
||||
basic_parser_v1(basic_parser_v1 const&) = default;
|
||||
|
||||
/// Copy assignment.
|
||||
basic_parser& operator=(basic_parser const&) = default;
|
||||
basic_parser_v1& operator=(basic_parser_v1 const&) = default;
|
||||
|
||||
/// Constructor
|
||||
basic_parser()
|
||||
basic_parser_v1()
|
||||
{
|
||||
init(std::integral_constant<bool, isRequest>{});
|
||||
}
|
||||
@ -759,6 +759,6 @@ private:
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#include <beast/http/impl/basic_parser.ipp>
|
||||
#include <beast/http/impl/basic_parser_v1.ipp>
|
||||
|
||||
#endif
|
19
include/beast/http/body_writer.hpp
Normal file
19
include/beast/http/body_writer.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_BODY_WRITER_HPP
|
||||
#define BEAST_HTTP_BODY_WRITER_HPP
|
||||
|
||||
// Convenience header to include everything necessary for
|
||||
// declaring an object meeting the BodyWriter requirements.
|
||||
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/resume_context.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
|
||||
#endif
|
@ -5,8 +5,8 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_DETAIL_BASIC_PARSER_HPP
|
||||
#define BEAST_HTTP_DETAIL_BASIC_PARSER_HPP
|
||||
#ifndef BEAST_HTTP_DETAIL_BASIC_PARSER_V1_HPP
|
||||
#define BEAST_HTTP_DETAIL_BASIC_PARSER_V1_HPP
|
||||
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
43
include/beast/http/detail/has_content_length.hpp
Normal file
43
include/beast/http/detail/has_content_length.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_DETAIL_HAS_CONTENT_LENGTH_HPP
|
||||
#define BEAST_HTTP_DETAIL_HAS_CONTENT_LENGTH_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
class has_content_length_value
|
||||
{
|
||||
template<class U, class R = typename std::is_convertible<
|
||||
decltype(std::declval<U>().content_length()),
|
||||
std::uint64_t>>
|
||||
static R check(int);
|
||||
template <class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<T>(0));
|
||||
public:
|
||||
// `true` if `T` meets the requirements.
|
||||
static bool const value = type::value;
|
||||
};
|
||||
|
||||
// Determines if the writer can provide the content length
|
||||
template<class T>
|
||||
using has_content_length =
|
||||
std::integral_constant<bool,
|
||||
has_content_length_value<T>::value>;
|
||||
|
||||
} // detail
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#endif
|
@ -1,83 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_DETAIL_WRITE_PREPARATION_HPP
|
||||
#define BEAST_HTTP_DETAIL_WRITE_PREPARATION_HPP
|
||||
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/rfc2616.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/write_streambuf.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
namespace detail {
|
||||
|
||||
template<class T>
|
||||
class has_content_length_value
|
||||
{
|
||||
template<class U, class R = typename std::is_convertible<
|
||||
decltype(std::declval<U>().content_length()),
|
||||
std::size_t>>
|
||||
static R check(int);
|
||||
template <class>
|
||||
static std::false_type check(...);
|
||||
using type = decltype(check<T>(0));
|
||||
public:
|
||||
// `true` if `T` meets the requirements.
|
||||
static bool const value = type::value;
|
||||
};
|
||||
|
||||
// Determines if the writer can provide the content length
|
||||
template<class T>
|
||||
using has_content_length =
|
||||
std::integral_constant<bool,
|
||||
has_content_length_value<T>::value>;
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
struct write_preparation
|
||||
{
|
||||
using headers_type =
|
||||
basic_headers<std::allocator<char>>;
|
||||
|
||||
message<isRequest, Body, Headers> const& msg;
|
||||
typename Body::writer w;
|
||||
streambuf sb;
|
||||
bool chunked;
|
||||
bool close;
|
||||
|
||||
explicit
|
||||
write_preparation(
|
||||
message<isRequest, Body, Headers> const& msg_)
|
||||
: msg(msg_)
|
||||
, w(msg)
|
||||
, chunked(rfc2616::token_in_list(
|
||||
msg.headers["Transfer-Encoding"], "chunked"))
|
||||
, close(rfc2616::token_in_list(
|
||||
msg.headers["Connection"], "close") ||
|
||||
(msg.version < 11 && ! msg.headers.exists(
|
||||
"Content-Length")))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
init(error_code& ec)
|
||||
{
|
||||
w.init(ec);
|
||||
if(ec)
|
||||
return;
|
||||
msg.write_firstline(sb);
|
||||
write_fields(sb, msg.headers);
|
||||
beast::write(sb, "\r\n");
|
||||
}
|
||||
};
|
||||
|
||||
} // detail
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#endif
|
@ -8,8 +8,7 @@
|
||||
#ifndef BEAST_HTTP_EMPTY_BODY_HPP
|
||||
#define BEAST_HTTP_EMPTY_BODY_HPP
|
||||
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <memory>
|
||||
@ -35,9 +34,9 @@ private:
|
||||
|
||||
struct reader
|
||||
{
|
||||
template<bool isRequest, class Allocator>
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
reader(message<isRequest, empty_body, Allocator>&)
|
||||
reader(message<isRequest, empty_body, Headers>&)
|
||||
{
|
||||
}
|
||||
|
||||
@ -49,9 +48,12 @@ private:
|
||||
|
||||
struct writer
|
||||
{
|
||||
template<bool isRequest, class Allocator>
|
||||
writer(writer const&) = delete;
|
||||
writer& operator=(writer const&) = delete;
|
||||
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
writer(message<isRequest, empty_body, Allocator> const& m)
|
||||
writer(message<isRequest, empty_body, Headers> const& m)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -5,15 +5,15 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_IMPL_BASIC_PARSER_IPP
|
||||
#define BEAST_HTTP_IMPL_BASIC_PARSER_IPP
|
||||
#ifndef BEAST_HTTP_IMPL_BASIC_PARSER_V1_IPP
|
||||
#define BEAST_HTTP_IMPL_BASIC_PARSER_V1_IPP
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
template<bool isRequest, class Derived>
|
||||
bool
|
||||
basic_parser<isRequest, Derived>::
|
||||
basic_parser_v1<isRequest, Derived>::
|
||||
keep_alive() const
|
||||
{
|
||||
if(http_major_ > 0 && http_minor_ > 0)
|
||||
@ -34,7 +34,7 @@ keep_alive() const
|
||||
template<bool isRequest, class Derived>
|
||||
template<class ConstBufferSequence, class>
|
||||
std::size_t
|
||||
basic_parser<isRequest, Derived>::
|
||||
basic_parser_v1<isRequest, Derived>::
|
||||
write(ConstBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
static_assert(is_ConstBufferSequence<ConstBufferSequence>::value,
|
||||
@ -51,7 +51,7 @@ write(ConstBufferSequence const& buffers, error_code& ec)
|
||||
|
||||
template<bool isRequest, class Derived>
|
||||
std::size_t
|
||||
basic_parser<isRequest, Derived>::
|
||||
basic_parser_v1<isRequest, Derived>::
|
||||
write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
{
|
||||
using beast::http::detail::is_digit;
|
||||
@ -1022,7 +1022,7 @@ write(boost::asio::const_buffer const& buffer, error_code& ec)
|
||||
|
||||
template<bool isRequest, class Derived>
|
||||
void
|
||||
basic_parser<isRequest, Derived>::
|
||||
basic_parser_v1<isRequest, Derived>::
|
||||
write_eof(error_code& ec)
|
||||
{
|
||||
switch(s_)
|
||||
@ -1042,7 +1042,7 @@ write_eof(error_code& ec)
|
||||
|
||||
template<bool isRequest, class Derived>
|
||||
bool
|
||||
basic_parser<isRequest, Derived>::
|
||||
basic_parser_v1<isRequest, Derived>::
|
||||
needs_eof(std::true_type) const
|
||||
{
|
||||
return false;
|
||||
@ -1050,7 +1050,7 @@ needs_eof(std::true_type) const
|
||||
|
||||
template<bool isRequest, class Derived>
|
||||
bool
|
||||
basic_parser<isRequest, Derived>::
|
||||
basic_parser_v1<isRequest, Derived>::
|
||||
needs_eof(std::false_type) const
|
||||
{
|
||||
// See RFC 2616 section 4.4
|
@ -5,33 +5,21 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_IMPL_MESSAGE_IPP
|
||||
#define BEAST_HTTP_IMPL_MESSAGE_IPP
|
||||
#ifndef BEAST_HTTP_IMPL_MESSAGE_V1_IPP
|
||||
#define BEAST_HTTP_IMPL_MESSAGE_V1_IPP
|
||||
|
||||
#include <beast/http/resume_context.hpp>
|
||||
#include <beast/http/rfc2616.hpp>
|
||||
#include <beast/write_streambuf.hpp>
|
||||
#include <beast/http/detail/has_content_length.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/http/detail/write_preparation.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
message<isRequest, Body, Headers>::
|
||||
message()
|
||||
{
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
message<isRequest, Body, Headers>::
|
||||
message(request_params params)
|
||||
message_v1<isRequest, Body, Headers>::
|
||||
message_v1(request_params params)
|
||||
{
|
||||
static_assert(isRequest, "message is not a request");
|
||||
this->method = params.method;
|
||||
@ -40,8 +28,8 @@ message(request_params params)
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
message<isRequest, Body, Headers>::
|
||||
message(response_params params)
|
||||
message_v1<isRequest, Body, Headers>::
|
||||
message_v1(response_params params)
|
||||
{
|
||||
static_assert(! isRequest, "message is not a response");
|
||||
this->status = params.status;
|
||||
@ -49,126 +37,11 @@ message(response_params params)
|
||||
version = params.version;
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
template<class Streambuf>
|
||||
void
|
||||
message<isRequest, Body, Headers>::
|
||||
write_firstline(Streambuf& streambuf,
|
||||
std::true_type) const
|
||||
{
|
||||
write(streambuf, this->method);
|
||||
write(streambuf, " ");
|
||||
write(streambuf, this->url);
|
||||
switch(version)
|
||||
{
|
||||
case 10:
|
||||
write(streambuf, " HTTP/1.0\r\n");
|
||||
break;
|
||||
case 11:
|
||||
write(streambuf, " HTTP/1.1\r\n");
|
||||
break;
|
||||
default:
|
||||
write(streambuf, " HTTP/");
|
||||
write(streambuf, version / 10);
|
||||
write(streambuf, ".");
|
||||
write(streambuf, version % 10);
|
||||
write(streambuf, "\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
template<class Streambuf>
|
||||
void
|
||||
message<isRequest, Body, Headers>::
|
||||
write_firstline(Streambuf& streambuf,
|
||||
std::false_type) const
|
||||
{
|
||||
switch(version)
|
||||
{
|
||||
case 10:
|
||||
write(streambuf, "HTTP/1.0 ");
|
||||
break;
|
||||
case 11:
|
||||
write(streambuf, "HTTP/1.1 ");
|
||||
break;
|
||||
default:
|
||||
write(streambuf, " HTTP/");
|
||||
write(streambuf, version / 10);
|
||||
write(streambuf, ".");
|
||||
write(streambuf, version % 10);
|
||||
write(streambuf, " ");
|
||||
break;
|
||||
}
|
||||
write(streambuf, this->status);
|
||||
write(streambuf, " ");
|
||||
write(streambuf, this->reason);
|
||||
write(streambuf, "\r\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
set_connection(bool keep_alive,
|
||||
message<isRequest, Body, Headers>& req)
|
||||
{
|
||||
if(req.version >= 11)
|
||||
{
|
||||
if(! keep_alive)
|
||||
req.headers.replace("Connection", "close");
|
||||
else
|
||||
req.headers.erase("Connection");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(keep_alive)
|
||||
req.headers.replace("Connection", "keep-alive");
|
||||
else
|
||||
req.headers.erase("Connection");
|
||||
}
|
||||
}
|
||||
|
||||
template<class Body, class Headers,
|
||||
class OtherBody, class OtherAllocator>
|
||||
void
|
||||
set_connection(bool keep_alive,
|
||||
message<false, Body, Headers>& resp,
|
||||
message<true, OtherBody, OtherAllocator> const& req)
|
||||
{
|
||||
if(req.version >= 11)
|
||||
{
|
||||
if(rfc2616::token_in_list(req["Connection"], "close"))
|
||||
keep_alive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(! rfc2616::token_in_list(req["Connection"], "keep-alive"))
|
||||
keep_alive = false;
|
||||
}
|
||||
set_connection(keep_alive, resp);
|
||||
}
|
||||
|
||||
template<class Streambuf, class FieldSequence>
|
||||
void
|
||||
write_fields(Streambuf& streambuf, FieldSequence const& fields)
|
||||
{
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
//static_assert(is_FieldSequence<FieldSequence>::value,
|
||||
// "FieldSequence requirements not met");
|
||||
for(auto const& field : fields)
|
||||
{
|
||||
write(streambuf, field.name());
|
||||
write(streambuf, ": ");
|
||||
write(streambuf, field.value());
|
||||
write(streambuf, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
bool
|
||||
is_keep_alive(message<isRequest, Body, Headers> const& msg)
|
||||
is_keep_alive(message_v1<isRequest, Body, Headers> const& msg)
|
||||
{
|
||||
if(msg.version >= 11)
|
||||
{
|
||||
@ -185,7 +58,7 @@ is_keep_alive(message<isRequest, Body, Headers> const& msg)
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
bool
|
||||
is_upgrade(message<isRequest, Body, Headers> const& msg)
|
||||
is_upgrade(message_v1<isRequest, Body, Headers> const& msg)
|
||||
{
|
||||
if(msg.version < 11)
|
||||
return false;
|
||||
@ -207,14 +80,14 @@ template<bool isRequest, class Body, class Headers>
|
||||
inline
|
||||
void
|
||||
prepare_options(prepare_info& pi,
|
||||
message<isRequest, Body, Headers>& msg)
|
||||
message_v1<isRequest, Body, Headers>& msg)
|
||||
{
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
prepare_option(prepare_info& pi,
|
||||
message<isRequest, Body, Headers>& msg,
|
||||
message_v1<isRequest, Body, Headers>& msg,
|
||||
connection value)
|
||||
{
|
||||
pi.connection_value = value;
|
||||
@ -225,7 +98,7 @@ template<
|
||||
class Opt, class... Opts>
|
||||
void
|
||||
prepare_options(prepare_info& pi,
|
||||
message<isRequest, Body, Headers>& msg,
|
||||
message_v1<isRequest, Body, Headers>& msg,
|
||||
Opt&& opt, Opts&&... opts)
|
||||
{
|
||||
prepare_option(pi, msg, opt);
|
||||
@ -236,7 +109,7 @@ prepare_options(prepare_info& pi,
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
prepare_content_length(prepare_info& pi,
|
||||
message<isRequest, Body, Headers> const& msg,
|
||||
message_v1<isRequest, Body, Headers> const& msg,
|
||||
std::true_type)
|
||||
{
|
||||
typename Body::writer w(msg);
|
||||
@ -247,7 +120,7 @@ prepare_content_length(prepare_info& pi,
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
prepare_content_length(prepare_info& pi,
|
||||
message<isRequest, Body, Headers> const& msg,
|
||||
message_v1<isRequest, Body, Headers> const& msg,
|
||||
std::false_type)
|
||||
{
|
||||
pi.content_length = boost::none;
|
||||
@ -258,7 +131,7 @@ prepare_content_length(prepare_info& pi,
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
void
|
||||
prepare_connection(
|
||||
message<isRequest, Body, Headers>& msg)
|
||||
message_v1<isRequest, Body, Headers>& msg)
|
||||
{
|
||||
if(msg.version >= 11)
|
||||
{
|
||||
@ -286,7 +159,7 @@ template<
|
||||
bool isRequest, class Body, class Headers,
|
||||
class... Options>
|
||||
void
|
||||
prepare(message<isRequest, Body, Headers>& msg,
|
||||
prepare(message_v1<isRequest, Body, Headers>& msg,
|
||||
Options&&... options)
|
||||
{
|
||||
// VFALCO TODO
|
@ -8,6 +8,7 @@
|
||||
#ifndef BEAST_HTTP_IMPL_READ_IPP_HPP
|
||||
#define BEAST_HTTP_IMPL_READ_IPP_HPP
|
||||
|
||||
#include <beast/http/parser_v1.hpp>
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <cassert>
|
||||
@ -26,10 +27,10 @@ class read_op
|
||||
handler_alloc<char, Handler>;
|
||||
|
||||
using parser_type =
|
||||
parser<isRequest, Body, Headers>;
|
||||
parser_v1<isRequest, Body, Headers>;
|
||||
|
||||
using message_type =
|
||||
message<isRequest, Body, Headers>;
|
||||
message_v1<isRequest, Body, Headers>;
|
||||
|
||||
struct data
|
||||
{
|
||||
@ -214,14 +215,14 @@ template<class SyncReadStream, class Streambuf,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
message<isRequest, Body, Headers>& m,
|
||||
message_v1<isRequest, Body, Headers>& m,
|
||||
error_code& ec)
|
||||
{
|
||||
static_assert(is_SyncReadStream<SyncReadStream>::value,
|
||||
"SyncReadStream requirements not met");
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
parser<isRequest, Body, Headers> p;
|
||||
parser_v1<isRequest, Body, Headers> p;
|
||||
bool started = false;
|
||||
for(;;)
|
||||
{
|
||||
@ -264,7 +265,7 @@ template<class AsyncReadStream, class Streambuf,
|
||||
typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
async_read(AsyncReadStream& stream, Streambuf& streambuf,
|
||||
message<isRequest, Body, Headers>& m,
|
||||
message_v1<isRequest, Body, Headers>& m,
|
||||
ReadHandler&& handler)
|
||||
{
|
||||
static_assert(is_AsyncReadStream<AsyncReadStream>::value,
|
||||
|
@ -10,12 +10,13 @@
|
||||
|
||||
#include <beast/http/resume_context.hpp>
|
||||
#include <beast/http/detail/chunk_encode.hpp>
|
||||
#include <beast/http/detail/write_preparation.hpp>
|
||||
#include <beast/http/detail/has_content_length.hpp>
|
||||
#include <beast/buffer_cat.hpp>
|
||||
#include <beast/bind_handler.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <beast/write_streambuf.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <boost/logic/tribool.hpp>
|
||||
#include <condition_variable>
|
||||
@ -29,6 +30,114 @@ namespace http {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<class Streambuf, class Body, class Headers>
|
||||
void
|
||||
write_firstline(Streambuf& streambuf,
|
||||
message_v1<true, Body, Headers> const& msg)
|
||||
{
|
||||
write(streambuf, msg.method);
|
||||
write(streambuf, " ");
|
||||
write(streambuf, msg.url);
|
||||
switch(msg.version)
|
||||
{
|
||||
case 10:
|
||||
write(streambuf, " HTTP/1.0\r\n");
|
||||
break;
|
||||
case 11:
|
||||
write(streambuf, " HTTP/1.1\r\n");
|
||||
break;
|
||||
default:
|
||||
write(streambuf, " HTTP/");
|
||||
write(streambuf, msg.version / 10);
|
||||
write(streambuf, ".");
|
||||
write(streambuf, msg.version % 10);
|
||||
write(streambuf, "\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<class Streambuf, class Body, class Headers>
|
||||
void
|
||||
write_firstline(Streambuf& streambuf,
|
||||
message_v1<false, Body, Headers> const& msg)
|
||||
{
|
||||
switch(msg.version)
|
||||
{
|
||||
case 10:
|
||||
write(streambuf, "HTTP/1.0 ");
|
||||
break;
|
||||
case 11:
|
||||
write(streambuf, "HTTP/1.1 ");
|
||||
break;
|
||||
default:
|
||||
write(streambuf, " HTTP/");
|
||||
write(streambuf, msg.version / 10);
|
||||
write(streambuf, ".");
|
||||
write(streambuf, msg.version % 10);
|
||||
write(streambuf, " ");
|
||||
break;
|
||||
}
|
||||
write(streambuf, msg.status);
|
||||
write(streambuf, " ");
|
||||
write(streambuf, msg.reason);
|
||||
write(streambuf, "\r\n");
|
||||
}
|
||||
|
||||
template<class Streambuf, class FieldSequence>
|
||||
void
|
||||
write_fields(Streambuf& streambuf, FieldSequence const& fields)
|
||||
{
|
||||
static_assert(is_Streambuf<Streambuf>::value,
|
||||
"Streambuf requirements not met");
|
||||
//static_assert(is_FieldSequence<FieldSequence>::value,
|
||||
// "FieldSequence requirements not met");
|
||||
for(auto const& field : fields)
|
||||
{
|
||||
write(streambuf, field.name());
|
||||
write(streambuf, ": ");
|
||||
write(streambuf, field.value());
|
||||
write(streambuf, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
struct write_preparation
|
||||
{
|
||||
using headers_type =
|
||||
basic_headers<std::allocator<char>>;
|
||||
|
||||
message_v1<isRequest, Body, Headers> const& msg;
|
||||
typename Body::writer w;
|
||||
streambuf sb;
|
||||
bool chunked;
|
||||
bool close;
|
||||
|
||||
explicit
|
||||
write_preparation(
|
||||
message_v1<isRequest, Body, Headers> const& msg_)
|
||||
: msg(msg_)
|
||||
, w(msg)
|
||||
, chunked(rfc2616::token_in_list(
|
||||
msg.headers["Transfer-Encoding"], "chunked"))
|
||||
, close(rfc2616::token_in_list(
|
||||
msg.headers["Connection"], "close") ||
|
||||
(msg.version < 11 && ! msg.headers.exists(
|
||||
"Content-Length")))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
init(error_code& ec)
|
||||
{
|
||||
w.init(ec);
|
||||
if(ec)
|
||||
return;
|
||||
write_firstline(sb, msg);
|
||||
write_fields(sb, msg.headers);
|
||||
beast::write(sb, "\r\n");
|
||||
}
|
||||
};
|
||||
|
||||
template<class Stream, class Handler,
|
||||
bool isRequest, class Body, class Headers>
|
||||
class write_op
|
||||
@ -50,7 +159,7 @@ class write_op
|
||||
|
||||
template<class DeducedHandler>
|
||||
data(DeducedHandler&& h_, Stream& s_,
|
||||
message<isRequest, Body, Headers> const& m_)
|
||||
message_v1<isRequest, Body, Headers> const& m_)
|
||||
: s(s_)
|
||||
, wp(m_)
|
||||
, h(std::forward<DeducedHandler>(h_))
|
||||
@ -356,7 +465,21 @@ template<class SyncWriteStream,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
write(SyncWriteStream& stream,
|
||||
message<isRequest, Body, Headers> const& msg,
|
||||
message_v1<isRequest, Body, Headers> const& msg)
|
||||
{
|
||||
static_assert(is_SyncWriteStream<SyncWriteStream>::value,
|
||||
"SyncWriteStream requirements not met");
|
||||
error_code ec;
|
||||
write(stream, msg, ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
}
|
||||
|
||||
template<class SyncWriteStream,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
write(SyncWriteStream& stream,
|
||||
message_v1<isRequest, Body, Headers> const& msg,
|
||||
boost::system::error_code& ec)
|
||||
{
|
||||
static_assert(is_SyncWriteStream<SyncWriteStream>::value,
|
||||
@ -441,7 +564,7 @@ template<class AsyncWriteStream,
|
||||
typename async_completion<
|
||||
WriteHandler, void(error_code)>::result_type
|
||||
async_write(AsyncWriteStream& stream,
|
||||
message<isRequest, Body, Headers> const& msg,
|
||||
message_v1<isRequest, Body, Headers> const& msg,
|
||||
WriteHandler&& handler)
|
||||
{
|
||||
static_assert(
|
||||
@ -506,7 +629,7 @@ public:
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os,
|
||||
message<isRequest, Body, Headers> const& msg)
|
||||
message_v1<isRequest, Body, Headers> const& msg)
|
||||
{
|
||||
detail::ostream_SyncStream oss(os);
|
||||
error_code ec;
|
||||
|
@ -32,24 +32,6 @@ struct response_fields
|
||||
|
||||
} // detail
|
||||
|
||||
#if ! GENERATING_DOCS
|
||||
|
||||
struct request_params
|
||||
{
|
||||
std::string method;
|
||||
std::string url;
|
||||
int version;
|
||||
};
|
||||
|
||||
struct response_params
|
||||
{
|
||||
int status;
|
||||
std::string reason;
|
||||
int version;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/** A HTTP message.
|
||||
|
||||
A message can be a request or response, depending on the `isRequest`
|
||||
@ -70,62 +52,24 @@ struct message
|
||||
: std::conditional<isRequest,
|
||||
detail::request_fields, detail::response_fields>::type
|
||||
{
|
||||
/** The trait type characterizing the body.
|
||||
/** The type controlling the body traits.
|
||||
|
||||
The body member will be of type body_type::value_type.
|
||||
The body member will be of type `body_type::value_type`.
|
||||
*/
|
||||
using body_type = Body;
|
||||
|
||||
/// The type representing the headers.
|
||||
using headers_type = Headers;
|
||||
|
||||
/// Indicates if the message is a request.
|
||||
using is_request =
|
||||
std::integral_constant<bool, isRequest>;
|
||||
|
||||
int version; // 10 or 11
|
||||
/// The container holding the headers.
|
||||
headers_type headers;
|
||||
|
||||
/// A container representing the body.
|
||||
typename Body::value_type body;
|
||||
|
||||
message();
|
||||
message(message&&) = default;
|
||||
message(message const&) = default;
|
||||
message& operator=(message&&) = default;
|
||||
message& operator=(message const&) = default;
|
||||
|
||||
/** Construct a HTTP request.
|
||||
*/
|
||||
explicit
|
||||
message(request_params params);
|
||||
|
||||
/** Construct a HTTP response.
|
||||
*/
|
||||
explicit
|
||||
message(response_params params);
|
||||
|
||||
/// Serialize the request or response line to a Streambuf.
|
||||
template<class Streambuf>
|
||||
void
|
||||
write_firstline(Streambuf& streambuf) const
|
||||
{
|
||||
write_firstline(streambuf,
|
||||
std::integral_constant<bool, isRequest>{});
|
||||
}
|
||||
|
||||
/// Diagnostics only
|
||||
template<bool, class, class>
|
||||
friend
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os,
|
||||
message const& m);
|
||||
|
||||
private:
|
||||
template<class Streambuf>
|
||||
void
|
||||
write_firstline(Streambuf& streambuf,
|
||||
std::true_type) const;
|
||||
|
||||
template<class Streambuf>
|
||||
void
|
||||
write_firstline(Streambuf& streambuf,
|
||||
std::false_type) const;
|
||||
};
|
||||
|
||||
#if ! GENERATING_DOCS
|
||||
@ -142,53 +86,7 @@ using response = message<false, Body, Headers>;
|
||||
|
||||
#endif
|
||||
|
||||
/// Write a FieldSequence to a Streambuf.
|
||||
template<class Streambuf, class FieldSequence>
|
||||
void
|
||||
write_fields(Streambuf& streambuf, FieldSequence const& fields);
|
||||
|
||||
/// Returns `true` if a message indicates a keep alive
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
bool
|
||||
is_keep_alive(message<isRequest, Body, Headers> const& msg);
|
||||
|
||||
/// Returns `true` if a message indicates a HTTP Upgrade request or response
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
bool
|
||||
is_upgrade(message<isRequest, Body, Headers> const& msg);
|
||||
|
||||
/** Connection prepare options.
|
||||
|
||||
These values are used with prepare().
|
||||
*/
|
||||
enum class connection
|
||||
{
|
||||
/// Indicates the message should specify Connection: close semantics
|
||||
close,
|
||||
|
||||
/// Indicates the message should specify Connection: keep-alive semantics if possible
|
||||
keep_alive,
|
||||
|
||||
/// Indicates the message should specify a Connection: upgrade
|
||||
upgrade
|
||||
};
|
||||
|
||||
/** Prepare a message.
|
||||
|
||||
This function will adjust the Content-Length, Transfer-Encoding,
|
||||
and Connection headers of the message based on the properties of
|
||||
the body and the options passed in.
|
||||
*/
|
||||
template<
|
||||
bool isRequest, class Body, class Headers,
|
||||
class... Options>
|
||||
void
|
||||
prepare(message<isRequest, Body, Headers>& msg,
|
||||
Options&&... options);
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#include <beast/http/impl/message.ipp>
|
||||
|
||||
#endif
|
||||
|
131
include/beast/http/message_v1.hpp
Normal file
131
include/beast/http/message_v1.hpp
Normal file
@ -0,0 +1,131 @@
|
||||
//
|
||||
// Copyright (c) 2013-2016 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_MESSAGE_V1_HPP
|
||||
#define BEAST_HTTP_MESSAGE_V1_HPP
|
||||
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
#if ! GENERATING_DOCS
|
||||
|
||||
struct request_params
|
||||
{
|
||||
std::string method;
|
||||
std::string url;
|
||||
int version;
|
||||
};
|
||||
|
||||
struct response_params
|
||||
{
|
||||
int status;
|
||||
std::string reason;
|
||||
int version;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/** A HTTP/1 message.
|
||||
|
||||
A message can be a request or response, depending on the `isRequest`
|
||||
template argument value. Requests and responses have different types,
|
||||
so functions may be overloaded on them if desired.
|
||||
|
||||
The `Body` template argument type determines the model used
|
||||
to read or write the content body of the message.
|
||||
|
||||
@tparam isRequest `true` if this is a request.
|
||||
|
||||
@tparam Body A type meeting the requirements of Body.
|
||||
|
||||
@tparam Headers A type meeting the requirements of Headers.
|
||||
*/
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
struct message_v1 : message<isRequest, Body, Headers>
|
||||
{
|
||||
/// HTTP/1 version (10 or 11)
|
||||
int version;
|
||||
|
||||
message_v1() = default;
|
||||
|
||||
/// Construct a HTTP/1 request.
|
||||
explicit
|
||||
message_v1(request_params params);
|
||||
|
||||
/// Construct a HTTP/1 response.
|
||||
explicit
|
||||
message_v1(response_params params);
|
||||
};
|
||||
|
||||
#if ! GENERATING_DOCS
|
||||
|
||||
/// A typical HTTP/1 request
|
||||
template<class Body,
|
||||
class Headers = basic_headers<std::allocator<char>>>
|
||||
using request_v1 = message_v1<true, Body, Headers>;
|
||||
|
||||
/// A typical HTTP/1 response
|
||||
template<class Body,
|
||||
class Headers = basic_headers<std::allocator<char>>>
|
||||
using response_v1 = message_v1<false, Body, Headers>;
|
||||
|
||||
#endif
|
||||
|
||||
/// Returns `true` if a HTTP/1 message indicates a keep alive
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
bool
|
||||
is_keep_alive(message_v1<isRequest, Body, Headers> const& msg);
|
||||
|
||||
/// Returns `true` if a HTTP/1 message indicates an Upgrade request or response
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
bool
|
||||
is_upgrade(message_v1<isRequest, Body, Headers> const& msg);
|
||||
|
||||
/** HTTP/1 connection prepare options.
|
||||
|
||||
@note These values are used with `prepare`.
|
||||
*/
|
||||
enum class connection
|
||||
{
|
||||
/// Specify Connection: close.
|
||||
close,
|
||||
|
||||
/// Specify Connection: keep-alive where possible.
|
||||
keep_alive,
|
||||
|
||||
/// Specify Connection: upgrade.
|
||||
upgrade
|
||||
};
|
||||
|
||||
/** Prepare a HTTP/1 message.
|
||||
|
||||
This function will adjust the Content-Length, Transfer-Encoding,
|
||||
and Connection headers of the message based on the properties of
|
||||
the body and the options passed in.
|
||||
|
||||
@param msg The message to prepare. The headers may be modified.
|
||||
|
||||
@param options A list of prepare options.
|
||||
*/
|
||||
template<
|
||||
bool isRequest, class Body, class Headers,
|
||||
class... Options>
|
||||
void
|
||||
prepare(message_v1<isRequest, Body, Headers>& msg,
|
||||
Options&&... options);
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#include <beast/http/impl/message_v1.ipp>
|
||||
|
||||
#endif
|
@ -5,12 +5,12 @@
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
|
||||
#ifndef BEAST_HTTP_PARSER_HPP
|
||||
#define BEAST_HTTP_PARSER_HPP
|
||||
#ifndef BEAST_HTTP_PARSER_V1_HPP
|
||||
#define BEAST_HTTP_PARSER_V1_HPP
|
||||
|
||||
#include <beast/http/basic_parser.hpp>
|
||||
#include <beast/http/basic_parser_v1.hpp>
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <functional>
|
||||
#include <string>
|
||||
@ -35,15 +35,20 @@ struct parser_response
|
||||
|
||||
} // detail
|
||||
|
||||
/** A parser for producing HTTP/1 messages.
|
||||
|
||||
This class uses the basic HTTP/1 wire format parser to convert
|
||||
a series of octets into a `message_v1`.
|
||||
*/
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
class parser
|
||||
: public basic_parser<isRequest,
|
||||
parser<isRequest, Body, Headers>>
|
||||
class parser_v1
|
||||
: public basic_parser_v1<isRequest,
|
||||
parser_v1<isRequest, Body, Headers>>
|
||||
, private std::conditional<isRequest,
|
||||
detail::parser_request, detail::parser_response>::type
|
||||
{
|
||||
using message_type =
|
||||
message<isRequest, Body, Headers>;
|
||||
message_v1<isRequest, Body, Headers>;
|
||||
|
||||
std::string field_;
|
||||
std::string value_;
|
||||
@ -51,9 +56,9 @@ class parser
|
||||
typename message_type::body_type::reader r_;
|
||||
|
||||
public:
|
||||
parser(parser&&) = default;
|
||||
parser_v1(parser_v1&&) = default;
|
||||
|
||||
parser()
|
||||
parser_v1()
|
||||
: r_(m_)
|
||||
{
|
||||
}
|
||||
@ -65,7 +70,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
friend class basic_parser<isRequest, parser>;
|
||||
friend class basic_parser_v1<isRequest, parser_v1>;
|
||||
|
||||
void flush()
|
||||
{
|
@ -8,16 +8,16 @@
|
||||
#ifndef BEAST_HTTP_READ_HPP
|
||||
#define BEAST_HTTP_READ_HPP
|
||||
|
||||
#include <beast/async_completion.hpp>
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/parser.hpp>
|
||||
#include <beast/http/parser_v1.hpp>
|
||||
#include <beast/async_completion.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** Read a HTTP message from a stream.
|
||||
/** Read a HTTP/1 message from a stream.
|
||||
|
||||
@param stream The stream to read the message from.
|
||||
|
||||
@ -35,7 +35,7 @@ template<class SyncReadStream, class Streambuf,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
message<isRequest, Body, Headers>& msg)
|
||||
message_v1<isRequest, Body, Headers>& msg)
|
||||
{
|
||||
error_code ec;
|
||||
read(stream, streambuf, msg, ec);
|
||||
@ -61,7 +61,7 @@ template<class SyncReadStream, class Streambuf,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
read(SyncReadStream& stream, Streambuf& streambuf,
|
||||
message<isRequest, Body, Headers>& msg,
|
||||
message_v1<isRequest, Body, Headers>& msg,
|
||||
error_code& ec);
|
||||
|
||||
/** Start reading a HTTP message from a stream asynchronously.
|
||||
@ -97,7 +97,7 @@ typename async_completion<
|
||||
ReadHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_read(AsyncReadStream& stream, Streambuf& streambuf,
|
||||
message<isRequest, Body, Headers>& msg,
|
||||
message_v1<isRequest, Body, Headers>& msg,
|
||||
ReadHandler&& handler);
|
||||
|
||||
} // http
|
||||
|
@ -8,8 +8,7 @@
|
||||
#ifndef BEAST_HTTP_STREAMBUF_BODY_HPP
|
||||
#define BEAST_HTTP_STREAMBUF_BODY_HPP
|
||||
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <beast/buffer_cat.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <memory>
|
||||
@ -59,10 +58,13 @@ private:
|
||||
Streambuf const& body_;
|
||||
|
||||
public:
|
||||
template<bool isRequest, class Allocator>
|
||||
writer(writer const&) = delete;
|
||||
writer& operator=(writer const&) = delete;
|
||||
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
writer(message<isRequest, basic_streambuf_body,
|
||||
Allocator> const& m)
|
||||
writer(message<
|
||||
isRequest, basic_streambuf_body, Headers> const& m)
|
||||
: body_(m.body)
|
||||
{
|
||||
}
|
||||
|
@ -8,9 +8,7 @@
|
||||
#ifndef BEAST_HTTP_STRING_BODY_HPP
|
||||
#define BEAST_HTTP_STRING_BODY_HPP
|
||||
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/resume_context.hpp>
|
||||
#include <beast/http/body_writer.hpp>
|
||||
#include <beast/buffer_cat.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <memory>
|
||||
@ -58,9 +56,13 @@ private:
|
||||
value_type const& body_;
|
||||
|
||||
public:
|
||||
template<bool isRequest, class Allocator>
|
||||
writer(writer const&) = delete;
|
||||
writer& operator=(writer const&) = delete;
|
||||
|
||||
template<bool isRequest, class Headers>
|
||||
explicit
|
||||
writer(message<isRequest, string_body, Allocator> const& msg)
|
||||
writer(message<
|
||||
isRequest, string_body, Headers> const& msg)
|
||||
: body_(msg.body)
|
||||
{
|
||||
}
|
||||
|
@ -9,9 +9,8 @@
|
||||
#define BEAST_HTTP_WRITE_HPP
|
||||
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/async_completion.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <boost/system/error_code.hpp>
|
||||
#include <ostream>
|
||||
#include <type_traits>
|
||||
@ -19,7 +18,7 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** Write a HTTP message to a stream.
|
||||
/** Write a HTTP/1 message to a stream.
|
||||
|
||||
@param stream The stream to send the message on.
|
||||
|
||||
@ -31,15 +30,9 @@ template<class SyncWriteStream,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
write(SyncWriteStream& stream,
|
||||
message<isRequest, Body, Headers> const& msg)
|
||||
{
|
||||
error_code ec;
|
||||
write(stream, msg, ec);
|
||||
if(ec)
|
||||
throw boost::system::system_error{ec};
|
||||
}
|
||||
message_v1<isRequest, Body, Headers> const& msg);
|
||||
|
||||
/** Write a HTTP message to a stream.
|
||||
/** Write a HTTP/1 message to a stream.
|
||||
|
||||
@param stream The stream to send the message on.
|
||||
|
||||
@ -51,10 +44,10 @@ template<class SyncWriteStream,
|
||||
bool isRequest, class Body, class Headers>
|
||||
void
|
||||
write(SyncWriteStream& stream,
|
||||
message<isRequest, Body, Headers> const& msg,
|
||||
message_v1<isRequest, Body, Headers> const& msg,
|
||||
error_code& ec);
|
||||
|
||||
/** Start writing a HTTP message to a stream asynchronously.
|
||||
/** Start writing a HTTP/1 message to a stream asynchronously.
|
||||
|
||||
@param stream The stream to send the message on.
|
||||
|
||||
@ -84,12 +77,12 @@ typename async_completion<
|
||||
WriteHandler, void(error_code)>::result_type
|
||||
#endif
|
||||
async_write(AsyncWriteStream& stream,
|
||||
message<isRequest, Body, Headers> const& msg,
|
||||
message_v1<isRequest, Body, Headers> const& msg,
|
||||
WriteHandler&& handler);
|
||||
|
||||
/** Serialize a message to an ostream.
|
||||
/** Serialize a HTTP/1 message to an ostream.
|
||||
|
||||
The function converts the message to its HTTP/1.* serialized
|
||||
The function converts the message to its HTTP/1 serialized
|
||||
representation and stores the result in the output stream.
|
||||
|
||||
@param os The ostream to write to.
|
||||
@ -99,7 +92,7 @@ async_write(AsyncWriteStream& stream,
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os,
|
||||
message<isRequest, Body, Headers> const& msg);
|
||||
message_v1<isRequest, Body, Headers> const& msg);
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
@ -9,10 +9,11 @@
|
||||
#define BEAST_WEBSOCKET_IMPL_ACCEPT_OP_HPP
|
||||
|
||||
#include <beast/websocket/impl/response_op.ipp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/parser_v1.hpp>
|
||||
#include <beast/http/read.hpp>
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/prepare_buffers.hpp>
|
||||
#include <beast/http/parser.hpp>
|
||||
#include <beast/http/read.hpp>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
@ -32,7 +33,7 @@ class stream<NextLayer>::accept_op
|
||||
struct data
|
||||
{
|
||||
stream<NextLayer>& ws;
|
||||
http::request<http::empty_body> req;
|
||||
http::request_v1<http::empty_body> req;
|
||||
Handler h;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/http/empty_body.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/read.hpp>
|
||||
#include <beast/http/write.hpp>
|
||||
#include <cassert>
|
||||
@ -33,8 +33,8 @@ class stream<NextLayer>::handshake_op
|
||||
stream<NextLayer>& ws;
|
||||
Handler h;
|
||||
std::string key;
|
||||
http::request<http::empty_body> req;
|
||||
http::response<http::string_body> resp;
|
||||
http::request_v1<http::empty_body> req;
|
||||
http::response_v1<http::string_body> resp;
|
||||
bool cont;
|
||||
int state = 0;
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define BEAST_WEBSOCKET_IMPL_RESPONSE_OP_HPP
|
||||
|
||||
#include <beast/handler_alloc.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/string_body.hpp>
|
||||
#include <beast/http/write.hpp>
|
||||
#include <memory>
|
||||
@ -27,7 +28,7 @@ class stream<NextLayer>::response_op
|
||||
struct data
|
||||
{
|
||||
stream<NextLayer>& ws;
|
||||
http::response<http::string_body> resp;
|
||||
http::response_v1<http::string_body> resp;
|
||||
Handler h;
|
||||
error_code final_ec;
|
||||
bool cont;
|
||||
@ -36,7 +37,7 @@ class stream<NextLayer>::response_op
|
||||
template<class DeducedHandler,
|
||||
class Body, class Headers>
|
||||
data(DeducedHandler&& h_, stream<NextLayer>& ws_,
|
||||
http::message<true, Body, Headers> const& req,
|
||||
http::request_v1<Body, Headers> const& req,
|
||||
bool cont_)
|
||||
: ws(ws_)
|
||||
, resp(ws_.build_response(req))
|
||||
|
@ -241,7 +241,7 @@ accept(ConstBufferSequence const& buffers, error_code& ec)
|
||||
stream_.buffer().commit(buffer_copy(
|
||||
stream_.buffer().prepare(
|
||||
buffer_size(buffers)), buffers));
|
||||
http::request<http::empty_body> m;
|
||||
http::request_v1<http::empty_body> m;
|
||||
http::read(next_layer(), stream_.buffer(), m, ec);
|
||||
if(ec)
|
||||
return;
|
||||
@ -272,7 +272,7 @@ template<class NextLayer>
|
||||
template<class Body, class Headers>
|
||||
void
|
||||
stream<NextLayer>::
|
||||
accept(http::message<true, Body, Headers> const& request)
|
||||
accept(http::request_v1<Body, Headers> const& request)
|
||||
{
|
||||
static_assert(is_SyncStream<next_layer_type>::value,
|
||||
"SyncStream requirements not met");
|
||||
@ -285,12 +285,12 @@ template<class NextLayer>
|
||||
template<class Body, class Headers>
|
||||
void
|
||||
stream<NextLayer>::
|
||||
accept(http::message<true, Body, Headers> const& req,
|
||||
accept(http::request_v1<Body, Headers> const& req,
|
||||
error_code& ec)
|
||||
{
|
||||
static_assert(is_SyncStream<next_layer_type>::value,
|
||||
"SyncStream requirements not met");
|
||||
auto resp = build_response(req);
|
||||
auto const resp = build_response(req);
|
||||
http::write(stream_, resp, ec);
|
||||
if(resp.status != 101)
|
||||
{
|
||||
@ -307,7 +307,7 @@ template<class Body, class Headers, class AcceptHandler>
|
||||
typename async_completion<
|
||||
AcceptHandler, void(error_code)>::result_type
|
||||
stream<NextLayer>::
|
||||
async_accept(http::message<true, Body, Headers> const& req,
|
||||
async_accept(http::request_v1<Body, Headers> const& req,
|
||||
AcceptHandler&& handler)
|
||||
{
|
||||
static_assert(is_AsyncStream<next_layer_type>::value,
|
||||
@ -348,7 +348,7 @@ handshake(boost::string_ref const& host,
|
||||
build_request(host, resource, key), ec);
|
||||
if(ec)
|
||||
return;
|
||||
http::response<http::string_body> resp;
|
||||
http::response_v1<http::string_body> resp;
|
||||
http::read(next_layer(), stream_.buffer(), resp, ec);
|
||||
if(ec)
|
||||
return;
|
||||
@ -826,12 +826,12 @@ async_write_frame(bool fin,
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template<class NextLayer>
|
||||
http::request<http::empty_body>
|
||||
http::request_v1<http::empty_body>
|
||||
stream<NextLayer>::
|
||||
build_request(boost::string_ref const& host,
|
||||
boost::string_ref const& resource, std::string& key)
|
||||
{
|
||||
http::request<http::empty_body> req;
|
||||
http::request_v1<http::empty_body> req;
|
||||
req.url = "/";
|
||||
req.version = 11;
|
||||
req.method = "GET";
|
||||
@ -847,14 +847,14 @@ build_request(boost::string_ref const& host,
|
||||
|
||||
template<class NextLayer>
|
||||
template<class Body, class Headers>
|
||||
http::response<http::string_body>
|
||||
http::response_v1<http::string_body>
|
||||
stream<NextLayer>::
|
||||
build_response(http::message<true, Body, Headers> const& req)
|
||||
build_response(http::request_v1<Body, Headers> const& req)
|
||||
{
|
||||
auto err =
|
||||
[&](std::string const& text)
|
||||
{
|
||||
http::response<http::string_body> resp(
|
||||
http::response_v1<http::string_body> resp(
|
||||
{400, http::reason_string(400), req.version});
|
||||
resp.body = text;
|
||||
// VFALCO TODO respect keep-alive here
|
||||
@ -881,7 +881,7 @@ build_response(http::message<true, Body, Headers> const& req)
|
||||
if(! rfc2616::token_in_list(
|
||||
req.headers["Upgrade"], "websocket"))
|
||||
return err("Missing websocket Upgrade token");
|
||||
http::response<http::string_body> resp(
|
||||
http::response_v1<http::string_body> resp(
|
||||
{101, http::reason_string(101), req.version});
|
||||
resp.headers.insert("Upgrade", "websocket");
|
||||
{
|
||||
@ -901,7 +901,7 @@ template<class NextLayer>
|
||||
template<class Body, class Headers>
|
||||
void
|
||||
stream<NextLayer>::
|
||||
do_response(http::message<false, Body, Headers> const& resp,
|
||||
do_response(http::response_v1<Body, Headers> const& resp,
|
||||
boost::string_ref const& key, error_code& ec)
|
||||
{
|
||||
// VFALCO Review these error codes
|
||||
|
@ -10,11 +10,11 @@
|
||||
|
||||
#include <beast/websocket/option.hpp>
|
||||
#include <beast/websocket/detail/stream_base.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/string_body.hpp>
|
||||
#include <beast/streambuf_readstream.hpp>
|
||||
#include <beast/async_completion.hpp>
|
||||
#include <beast/detail/get_lowest_layer.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <beast/http/string_body.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <algorithm>
|
||||
@ -495,8 +495,7 @@ public:
|
||||
// VFALCO TODO This should also take a streambuf with any leftover bytes.
|
||||
template<class Body, class Headers>
|
||||
void
|
||||
accept(http::message<true,
|
||||
Body, Headers> const& request);
|
||||
accept(http::request_v1<Body, Headers> const& request);
|
||||
|
||||
/** Respond to a WebSocket HTTP Upgrade request
|
||||
|
||||
@ -525,8 +524,8 @@ public:
|
||||
*/
|
||||
template<class Body, class Headers>
|
||||
void
|
||||
accept(http::message<true,
|
||||
Body, Headers> const& request, error_code& ec);
|
||||
accept(http::request_v1<Body, Headers> const& request,
|
||||
error_code& ec);
|
||||
|
||||
/** Start reading and responding to a WebSocket HTTP Upgrade request.
|
||||
|
||||
@ -560,8 +559,8 @@ public:
|
||||
template<class Body, class Headers, class AcceptHandler>
|
||||
typename async_completion<
|
||||
AcceptHandler, void(error_code)>::result_type
|
||||
async_accept(http::message<true,
|
||||
Body, Headers> const& request, AcceptHandler&& handler);
|
||||
async_accept(http::request_v1<Body, Headers> const& request,
|
||||
AcceptHandler&& handler);
|
||||
|
||||
/** Send a WebSocket Upgrade request.
|
||||
|
||||
@ -1129,18 +1128,18 @@ private:
|
||||
template<class Buffers, class Handler> class write_op;
|
||||
template<class Buffers, class Handler> class write_frame_op;
|
||||
|
||||
http::request<http::empty_body>
|
||||
http::request_v1<http::empty_body>
|
||||
build_request(boost::string_ref const& host,
|
||||
boost::string_ref const& resource,
|
||||
std::string& key);
|
||||
|
||||
template<class Body, class Headers>
|
||||
http::response<http::string_body>
|
||||
build_response(http::message<true, Body, Headers> const& req);
|
||||
http::response_v1<http::string_body>
|
||||
build_response(http::request_v1<Body, Headers> const& req);
|
||||
|
||||
template<class Body, class Headers>
|
||||
void
|
||||
do_response(http::message<false, Body, Headers> const& resp,
|
||||
do_response(http::response_v1<Body, Headers> const& resp,
|
||||
boost::string_ref const& key, error_code& ec);
|
||||
|
||||
void
|
||||
|
@ -33,11 +33,12 @@ add_executable (http-tests
|
||||
${BEAST_INCLUDES}
|
||||
main.cpp
|
||||
http/basic_headers.cpp
|
||||
http/basic_parser.cpp
|
||||
http/basic_parser_v1.cpp
|
||||
http/empty_body.cpp
|
||||
http/error.cpp
|
||||
http/headers.cpp
|
||||
http/message.cpp
|
||||
http/message_v1.cpp
|
||||
http/parse_error.cpp
|
||||
http/parser.cpp
|
||||
http/read.cpp
|
||||
|
@ -31,11 +31,12 @@ unit-test core-tests :
|
||||
unit-test http-tests :
|
||||
main.cpp
|
||||
http/basic_headers.cpp
|
||||
http/basic_parser.cpp
|
||||
http/basic_parser_v1.cpp
|
||||
http/empty_body.cpp
|
||||
http/error.cpp
|
||||
http/headers.cpp
|
||||
http/message.cpp
|
||||
http/message_v1.cpp
|
||||
http/parse_error.cpp
|
||||
http/parser.cpp
|
||||
http/read.cpp
|
||||
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/http/basic_parser.hpp>
|
||||
#include <beast/http/basic_parser_v1.hpp>
|
||||
|
||||
#include "message_fuzz.hpp"
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
class basic_parser_test : public beast::detail::unit_test::suite
|
||||
class basic_parser_v1_test : public beast::detail::unit_test::suite
|
||||
{
|
||||
std::mt19937 rng_;
|
||||
|
||||
@ -47,9 +47,9 @@ public:
|
||||
|
||||
template<bool isRequest>
|
||||
struct cb_checker
|
||||
: public basic_parser<isRequest, cb_checker<isRequest>>
|
||||
: public basic_parser_v1<isRequest, cb_checker<isRequest>>
|
||||
, std::conditional<isRequest,
|
||||
cb_req_checker, cb_res_checker>::type
|
||||
cb_req_checker, cb_res_checker>::type
|
||||
|
||||
{
|
||||
bool field = false;
|
||||
@ -59,7 +59,7 @@ public:
|
||||
bool complete = false;
|
||||
|
||||
private:
|
||||
friend class basic_parser<isRequest, cb_checker<isRequest>>;
|
||||
friend class basic_parser_v1<isRequest, cb_checker<isRequest>>;
|
||||
|
||||
void on_method(boost::string_ref const&, error_code&)
|
||||
{
|
||||
@ -129,13 +129,13 @@ public:
|
||||
}
|
||||
|
||||
template<bool isRequest>
|
||||
struct null_parser : basic_parser<isRequest, null_parser<isRequest>>
|
||||
struct null_parser : basic_parser_v1<isRequest, null_parser<isRequest>>
|
||||
{
|
||||
};
|
||||
|
||||
template<bool isRequest>
|
||||
class test_parser :
|
||||
public basic_parser<isRequest, test_parser<isRequest>>
|
||||
public basic_parser_v1<isRequest, test_parser<isRequest>>
|
||||
{
|
||||
std::string field_;
|
||||
std::string value_;
|
||||
@ -635,7 +635,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(basic_parser,http,beast);
|
||||
BEAST_DEFINE_TESTSUITE(basic_parser_v1,http,beast);
|
||||
|
||||
} // http
|
||||
} // beast
|
@ -19,168 +19,3 @@
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/http/message.hpp>
|
||||
|
||||
#include <beast/detail/unit_test/suite.hpp>
|
||||
#include <beast/detail/unit_test/thread.hpp>
|
||||
#include <beast/placeholders.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/http.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
namespace test {
|
||||
|
||||
class sync_echo_http_server
|
||||
{
|
||||
public:
|
||||
using error_code = boost::system::error_code;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using address_type = boost::asio::ip::address;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
|
||||
private:
|
||||
beast::detail::unit_test::suite& suite_;
|
||||
boost::asio::io_service ios_;
|
||||
socket_type sock_;
|
||||
boost::asio::ip::tcp::acceptor acceptor_;
|
||||
beast::detail::unit_test::thread thread_;
|
||||
|
||||
public:
|
||||
sync_echo_http_server(
|
||||
endpoint_type ep, beast::detail::unit_test::suite& suite)
|
||||
: suite_(suite)
|
||||
, sock_(ios_)
|
||||
, acceptor_(ios_)
|
||||
{
|
||||
error_code ec;
|
||||
acceptor_.open(ep.protocol(), ec);
|
||||
maybe_throw(ec, "open");
|
||||
acceptor_.bind(ep, ec);
|
||||
maybe_throw(ec, "bind");
|
||||
acceptor_.listen(
|
||||
boost::asio::socket_base::max_connections, ec);
|
||||
maybe_throw(ec, "listen");
|
||||
acceptor_.async_accept(sock_,
|
||||
std::bind(&sync_echo_http_server::on_accept, this,
|
||||
beast::asio::placeholders::error));
|
||||
thread_ = beast::detail::unit_test::thread(suite_,
|
||||
[&]
|
||||
{
|
||||
ios_.run();
|
||||
});
|
||||
}
|
||||
|
||||
~sync_echo_http_server()
|
||||
{
|
||||
error_code ec;
|
||||
ios_.dispatch(
|
||||
[&]{ acceptor_.close(ec); });
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
fail(error_code ec, std::string what)
|
||||
{
|
||||
suite_.log <<
|
||||
what << ": " << ec.message();
|
||||
}
|
||||
|
||||
void
|
||||
maybe_throw(error_code ec, std::string what)
|
||||
{
|
||||
if(ec &&
|
||||
ec != boost::asio::error::operation_aborted)
|
||||
{
|
||||
fail(ec, what);
|
||||
throw ec;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
on_accept(error_code ec)
|
||||
{
|
||||
if(ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
maybe_throw(ec, "accept");
|
||||
std::thread{&sync_echo_http_server::do_client, this,
|
||||
std::move(sock_), boost::asio::io_service::work{
|
||||
sock_.get_io_service()}}.detach();
|
||||
acceptor_.async_accept(sock_,
|
||||
std::bind(&sync_echo_http_server::on_accept, this,
|
||||
beast::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void
|
||||
do_client(socket_type sock, boost::asio::io_service::work)
|
||||
{
|
||||
error_code ec;
|
||||
streambuf rb;
|
||||
for(;;)
|
||||
{
|
||||
request<string_body> req;
|
||||
read(sock, rb, req, ec);
|
||||
if(ec)
|
||||
break;
|
||||
response<string_body> resp(
|
||||
{100, "OK", req.version});
|
||||
resp.body = "Completed successfully.";
|
||||
write(sock, resp, ec);
|
||||
if(ec)
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class message_test : public beast::detail::unit_test::suite
|
||||
{
|
||||
public:
|
||||
using error_code = boost::system::error_code;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using address_type = boost::asio::ip::address;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
|
||||
void
|
||||
syncEcho(endpoint_type ep)
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
socket_type sock(ios);
|
||||
sock.connect(ep);
|
||||
|
||||
streambuf rb;
|
||||
{
|
||||
request<string_body> req({"GET", "/", 11});
|
||||
req.body = "Beast.HTTP";
|
||||
req.headers.replace("Host",
|
||||
ep.address().to_string() + ":" +
|
||||
std::to_string(ep.port()));
|
||||
write(sock, req);
|
||||
}
|
||||
{
|
||||
response<string_body> m;
|
||||
read(sock, rb, m);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testAsio()
|
||||
{
|
||||
endpoint_type ep{
|
||||
address_type::from_string("127.0.0.1"), 6000};
|
||||
sync_echo_http_server s(ep, *this);
|
||||
syncEcho(ep);
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testAsio();
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(message,http,beast);
|
||||
|
||||
} // test
|
||||
} // http
|
||||
} // beast
|
||||
|
@ -8,7 +8,7 @@
|
||||
#ifndef BEAST_HTTP_TEST_MESSAGE_FUZZ_HPP
|
||||
#define BEAST_HTTP_TEST_MESSAGE_FUZZ_HPP
|
||||
|
||||
#include <beast/http/detail/basic_parser.hpp>
|
||||
#include <beast/http/detail/basic_parser_v1.hpp>
|
||||
#include <beast/write_streambuf.hpp>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
|
186
test/http/message_v1.cpp
Normal file
186
test/http/message_v1.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/http/message_v1.hpp>
|
||||
|
||||
#include <beast/detail/unit_test/suite.hpp>
|
||||
#include <beast/detail/unit_test/thread.hpp>
|
||||
#include <beast/placeholders.hpp>
|
||||
#include <beast/streambuf.hpp>
|
||||
#include <beast/http.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
namespace test {
|
||||
|
||||
class sync_echo_http_server
|
||||
{
|
||||
public:
|
||||
using error_code = boost::system::error_code;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using address_type = boost::asio::ip::address;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
|
||||
private:
|
||||
beast::detail::unit_test::suite& suite_;
|
||||
boost::asio::io_service ios_;
|
||||
socket_type sock_;
|
||||
boost::asio::ip::tcp::acceptor acceptor_;
|
||||
beast::detail::unit_test::thread thread_;
|
||||
|
||||
public:
|
||||
sync_echo_http_server(
|
||||
endpoint_type ep, beast::detail::unit_test::suite& suite)
|
||||
: suite_(suite)
|
||||
, sock_(ios_)
|
||||
, acceptor_(ios_)
|
||||
{
|
||||
error_code ec;
|
||||
acceptor_.open(ep.protocol(), ec);
|
||||
maybe_throw(ec, "open");
|
||||
acceptor_.bind(ep, ec);
|
||||
maybe_throw(ec, "bind");
|
||||
acceptor_.listen(
|
||||
boost::asio::socket_base::max_connections, ec);
|
||||
maybe_throw(ec, "listen");
|
||||
acceptor_.async_accept(sock_,
|
||||
std::bind(&sync_echo_http_server::on_accept, this,
|
||||
beast::asio::placeholders::error));
|
||||
thread_ = beast::detail::unit_test::thread(suite_,
|
||||
[&]
|
||||
{
|
||||
ios_.run();
|
||||
});
|
||||
}
|
||||
|
||||
~sync_echo_http_server()
|
||||
{
|
||||
error_code ec;
|
||||
ios_.dispatch(
|
||||
[&]{ acceptor_.close(ec); });
|
||||
thread_.join();
|
||||
}
|
||||
|
||||
private:
|
||||
void
|
||||
fail(error_code ec, std::string what)
|
||||
{
|
||||
suite_.log <<
|
||||
what << ": " << ec.message();
|
||||
}
|
||||
|
||||
void
|
||||
maybe_throw(error_code ec, std::string what)
|
||||
{
|
||||
if(ec &&
|
||||
ec != boost::asio::error::operation_aborted)
|
||||
{
|
||||
fail(ec, what);
|
||||
throw ec;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
on_accept(error_code ec)
|
||||
{
|
||||
if(ec == boost::asio::error::operation_aborted)
|
||||
return;
|
||||
maybe_throw(ec, "accept");
|
||||
std::thread{&sync_echo_http_server::do_client, this,
|
||||
std::move(sock_), boost::asio::io_service::work{
|
||||
sock_.get_io_service()}}.detach();
|
||||
acceptor_.async_accept(sock_,
|
||||
std::bind(&sync_echo_http_server::on_accept, this,
|
||||
beast::asio::placeholders::error));
|
||||
}
|
||||
|
||||
void
|
||||
do_client(socket_type sock, boost::asio::io_service::work)
|
||||
{
|
||||
error_code ec;
|
||||
streambuf rb;
|
||||
for(;;)
|
||||
{
|
||||
request_v1<string_body> req;
|
||||
read(sock, rb, req, ec);
|
||||
if(ec)
|
||||
break;
|
||||
response_v1<string_body> resp(
|
||||
{100, "OK", req.version});
|
||||
resp.body = "Completed successfully.";
|
||||
write(sock, resp, ec);
|
||||
if(ec)
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class message_test : public beast::detail::unit_test::suite
|
||||
{
|
||||
public:
|
||||
using error_code = boost::system::error_code;
|
||||
using endpoint_type = boost::asio::ip::tcp::endpoint;
|
||||
using address_type = boost::asio::ip::address;
|
||||
using socket_type = boost::asio::ip::tcp::socket;
|
||||
|
||||
void
|
||||
syncEcho(endpoint_type ep)
|
||||
{
|
||||
boost::asio::io_service ios;
|
||||
socket_type sock(ios);
|
||||
sock.connect(ep);
|
||||
|
||||
streambuf rb;
|
||||
{
|
||||
request_v1<string_body> req({"GET", "/", 11});
|
||||
req.body = "Beast.HTTP";
|
||||
req.headers.replace("Host",
|
||||
ep.address().to_string() + ":" +
|
||||
std::to_string(ep.port()));
|
||||
write(sock, req);
|
||||
}
|
||||
{
|
||||
response_v1<string_body> m;
|
||||
read(sock, rb, m);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testAsio()
|
||||
{
|
||||
endpoint_type ep{
|
||||
address_type::from_string("127.0.0.1"), 6000};
|
||||
sync_echo_http_server s(ep, *this);
|
||||
syncEcho(ep);
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
testAsio();
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(message,http,beast);
|
||||
|
||||
} // test
|
||||
} // http
|
||||
} // beast
|
@ -10,7 +10,8 @@
|
||||
|
||||
#include "nodejs-parser/http_parser.h"
|
||||
|
||||
#include <beast/http/basic_parser.hpp>
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message_v1.hpp>
|
||||
#include <beast/http/rfc2616.hpp>
|
||||
#include <beast/type_check.hpp>
|
||||
#include <boost/asio/buffer.hpp>
|
||||
@ -18,6 +19,7 @@
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
@ -730,19 +732,6 @@ nodejs_basic_parser<Derived>::cb_chunk_complete(http_parser*)
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // http
|
||||
} // beast
|
||||
|
||||
#include <beast/http/error.hpp>
|
||||
#include <beast/http/message.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace beast {
|
||||
namespace http {
|
||||
|
||||
/** A HTTP parser.
|
||||
|
||||
The parser may only be used once.
|
||||
@ -752,7 +741,7 @@ class nodejs_parser
|
||||
: public nodejs_basic_parser<nodejs_parser<isRequest, Body, Headers>>
|
||||
{
|
||||
using message_type =
|
||||
message<isRequest, Body, Headers>;
|
||||
message_v1<isRequest, Body, Headers>;
|
||||
|
||||
message_type m_;
|
||||
typename message_type::body_type::reader r_;
|
||||
|
@ -6,7 +6,7 @@
|
||||
//
|
||||
|
||||
// Test that header file is self-contained.
|
||||
#include <beast/http/parser.hpp>
|
||||
#include <beast/http/parser_v1.hpp>
|
||||
|
||||
#include <beast/http/headers.hpp>
|
||||
#include <beast/http/string_body.hpp>
|
||||
@ -23,7 +23,7 @@ public:
|
||||
using boost::asio::buffer;
|
||||
{
|
||||
error_code ec;
|
||||
parser<true, string_body,
|
||||
parser_v1<true, string_body,
|
||||
basic_headers<std::allocator<char>>> p;
|
||||
std::string const s =
|
||||
"GET / HTTP/1.1\r\n"
|
||||
@ -43,7 +43,7 @@ public:
|
||||
}
|
||||
{
|
||||
error_code ec;
|
||||
parser<false, string_body,
|
||||
parser_v1<false, string_body,
|
||||
basic_headers<std::allocator<char>>> p;
|
||||
std::string const s =
|
||||
"HTTP/1.1 200 OK\r\n"
|
||||
|
@ -97,7 +97,7 @@ public:
|
||||
}
|
||||
|
||||
template<bool isRequest>
|
||||
struct null_parser : basic_parser<isRequest, null_parser<isRequest>>
|
||||
struct null_parser : basic_parser_v1<isRequest, null_parser<isRequest>>
|
||||
{
|
||||
};
|
||||
|
||||
@ -108,10 +108,10 @@ public:
|
||||
static std::size_t constexpr Repeat = 50;
|
||||
|
||||
log << "sizeof(request parser) == " <<
|
||||
sizeof(basic_parser<true, null_parser<true>>);
|
||||
sizeof(basic_parser_v1<true, null_parser<true>>);
|
||||
|
||||
log << "sizeof(response parser) == " <<
|
||||
sizeof(basic_parser<false, null_parser<true>>);
|
||||
sizeof(basic_parser_v1<false, null_parser<true>>);
|
||||
|
||||
testcase << "Parser speed test, " <<
|
||||
((Repeat * size_ + 512) / 1024) << "KB in " <<
|
||||
@ -127,13 +127,13 @@ public:
|
||||
false, streambuf_body, headers>>(
|
||||
Repeat, cres_);
|
||||
});
|
||||
timedTest(Trials, "http::basic_parser",
|
||||
timedTest(Trials, "http::basic_parser_v1",
|
||||
[&]
|
||||
{
|
||||
testParser<parser<
|
||||
testParser<parser_v1<
|
||||
true, streambuf_body, headers>>(
|
||||
Repeat, creq_);
|
||||
testParser<parser<
|
||||
testParser<parser_v1<
|
||||
false, streambuf_body, headers>>(
|
||||
Repeat, cres_);
|
||||
});
|
||||
|
@ -89,7 +89,7 @@ public:
|
||||
|
||||
template<bool isRequest, class Body, class Headers>
|
||||
std::string
|
||||
str(message<isRequest, Body, Headers> const& m)
|
||||
str(message_v1<isRequest, Body, Headers> const& m)
|
||||
{
|
||||
string_SyncStream ss;
|
||||
write(ss, m);
|
||||
@ -101,7 +101,7 @@ public:
|
||||
{
|
||||
// auto content-length HTTP/1.0
|
||||
{
|
||||
message<true, string_body, headers> m{{
|
||||
message_v1<true, string_body, headers> m{{
|
||||
"GET", "/", 10}};
|
||||
m.headers.insert("User-Agent", "test");
|
||||
m.body = "*";
|
||||
@ -116,7 +116,7 @@ public:
|
||||
}
|
||||
// keep-alive HTTP/1.0
|
||||
{
|
||||
message<true, string_body, headers> m{{
|
||||
message_v1<true, string_body, headers> m{{
|
||||
"GET", "/", 10}};
|
||||
m.headers.insert("User-Agent", "test");
|
||||
m.body = "*";
|
||||
@ -132,7 +132,7 @@ public:
|
||||
}
|
||||
// upgrade HTTP/1.0
|
||||
{
|
||||
message<true, string_body, headers> m{{
|
||||
message_v1<true, string_body, headers> m{{
|
||||
"GET", "/", 10}};
|
||||
m.headers.insert("User-Agent", "test");
|
||||
m.body = "*";
|
||||
@ -148,7 +148,7 @@ public:
|
||||
}
|
||||
// no content-length HTTP/1.0
|
||||
{
|
||||
message<true, test_Body, headers> m{{
|
||||
message_v1<true, test_Body, headers> m{{
|
||||
"GET", "/", 10}};
|
||||
m.headers.insert("User-Agent", "test");
|
||||
m.body = "*";
|
||||
@ -166,7 +166,7 @@ public:
|
||||
}
|
||||
// auto content-length HTTP/1.1
|
||||
{
|
||||
message<true, string_body, headers> m{{
|
||||
message_v1<true, string_body, headers> m{{
|
||||
"GET", "/", 11}};
|
||||
m.headers.insert("User-Agent", "test");
|
||||
m.body = "*";
|
||||
@ -181,7 +181,7 @@ public:
|
||||
}
|
||||
// close HTTP/1.1
|
||||
{
|
||||
message<true, string_body, headers> m{{
|
||||
message_v1<true, string_body, headers> m{{
|
||||
"GET", "/", 11}};
|
||||
m.headers.insert("User-Agent", "test");
|
||||
m.body = "*";
|
||||
@ -201,7 +201,7 @@ public:
|
||||
}
|
||||
// upgrade HTTP/1.1
|
||||
{
|
||||
message<true, empty_body, headers> m{{
|
||||
message_v1<true, empty_body, headers> m{{
|
||||
"GET", "/", 11}};
|
||||
m.headers.insert("User-Agent", "test");
|
||||
prepare(m, connection::upgrade);
|
||||
@ -214,7 +214,7 @@ public:
|
||||
}
|
||||
// no content-length HTTP/1.1
|
||||
{
|
||||
message<true, test_Body, headers> m{{
|
||||
message_v1<true, test_Body, headers> m{{
|
||||
"GET", "/", 11}};
|
||||
m.headers.insert("User-Agent", "test");
|
||||
m.body = "*";
|
||||
@ -236,7 +236,7 @@ public:
|
||||
|
||||
void testConvert()
|
||||
{
|
||||
message<true, string_body, headers> m{{
|
||||
message_v1<true, string_body, headers> m{{
|
||||
"GET", "/", 11}};
|
||||
m.headers.insert("User-Agent", "test");
|
||||
m.body = "*";
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include <beast/http/parser.hpp>
|
||||
#include <beast/http/parser_v1.hpp>
|
||||
|
||||
namespace beast {
|
||||
namespace websocket {
|
||||
|
Reference in New Issue
Block a user