mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00: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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user