Remove message connection settings (API Change)

This commit is contained in:
Vinnie Falco
2017-06-07 04:49:20 -07:00
parent 80ca9a5961
commit 3340666ad3
11 changed files with 18 additions and 340 deletions

View File

@ -16,6 +16,7 @@ API Changes:
* Add verb to on_request for parsers
* Refactor prepare
* Protect basic_fields special members
* Remove message connection settings
--------------------------------------------------------------------------------

View File

@ -118,10 +118,7 @@ the __Body__ requirements:
The code examples below show how to create and fill in request and response
objects: Here is simple example of building an
[@https://tools.ietf.org/html/rfc7231#section-4.3.1 HTTP GET]
request. The function
[link beast.ref.http__message.prepare prepare]
allows for various connection options. The use of prepare is optional,
the Connection field may be set manually if desired.
request.
[table Create Request
[[Statements] [Serialized Result]]
@ -132,7 +129,6 @@ the Connection field may be set manually if desired.
GET /index.htm HTTP/1.1\r\n
Accept: text/html\r\n
User-Agent: Beast\r\n
Connection: close\r\n
\r\n
```
]]
@ -143,7 +139,7 @@ message has a body. The function
[link beast.ref.http__message.prepare prepare]
automatically sets the Content-Length or Transfer-Encoding field
depending on the body type. The use of prepare is optional, the
Content-Length and other fields may be set manually if desired.
fields may be set manually if desired.
[table Create Response
[[Statements] [Serialized Result]]

View File

@ -12,7 +12,6 @@
#include <beast/http/basic_parser.hpp>
#include <beast/http/buffer_body.hpp>
#include <beast/http/connection.hpp>
#include <beast/http/dynamic_body.hpp>
#include <beast/http/empty_body.hpp>
#include <beast/http/error.hpp>

View File

@ -1,88 +0,0 @@
//
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef BEAST_HTTP_CONNECTION_HPP
#define BEAST_HTTP_CONNECTION_HPP
#include <beast/config.hpp>
namespace beast {
namespace http {
/// The type of @ref connection::close
struct close_t {};
/// The type of @ref connection::upgrade
struct upgrade_t {};
/// The type of @ref connection::keep_alive
struct keep_alive_t {};
namespace detail {
template<class = void>
struct connection_impl
{
static close_t constexpr close{};
static keep_alive_t constexpr keep_alive{};
static upgrade_t constexpr upgrade{};
};
template<class _>
constexpr
close_t
connection_impl<_>::close;
template<class _>
constexpr
keep_alive_t
connection_impl<_>::keep_alive;
template<class _>
constexpr
upgrade_t
connection_impl<_>::upgrade;
} // detail
/** HTTP/1 Connection prepare options.
Each value is an individual settings, they can be combined.
@par Example
@code
request<empty_body> req;
req.version = 11;
req.method(verb::upgrade);
req.target("/");
req.insert(field::user_agent, "Beast");
req.prepare(connection::close, connection::upgrade);
@endcode
@note These values are used with @ref message::prepare.
*/
struct connection
#if ! BEAST_DOXYGEN
: detail::connection_impl<>
#endif
{
#if BEAST_DOXYGEN
/// Specify connection close semantics.
static close_t constexpr close;
/// Specify connection keep-alive semantics.
static keep_alive_t constexpr keep_alive;
/// Specify Connection: upgrade.
static upgrade_t constexpr upgrade;
#endif
};
} // http
} // beast
#endif

View File

@ -11,7 +11,6 @@
#include <beast/config.hpp>
#include <beast/core/string_view.hpp>
#include <beast/core/detail/ci_char_traits.hpp>
#include <beast/http/connection.hpp>
#include <beast/http/field.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/lexical_cast.hpp>
@ -396,24 +395,6 @@ protected:
*/
void content_length_impl(std::uint64_t n);
/** Add close to the Connection field.
@note This is called by the @ref header implementation.
*/
void connection_impl(close_t);
/** Add keep-alive to the Connection field.
@note This is called by the @ref header implementation.
*/
void connection_impl(keep_alive_t);
/** Add upgrade to the Connection field.
@note This is called by the @ref header implementation.
*/
void connection_impl(upgrade_t);
/** Add chunked to the Transfer-Encoding field.
@note This is called by the @ref header implementation.

View File

@ -662,48 +662,6 @@ content_length_impl(std::uint64_t n)
to_static_string(n));
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
connection_impl(close_t)
{
auto it = find("Connection");
if(it == end())
this->insert("Connection", "close");
else
this->replace("Connection",
it->value().to_string() + ", close");
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
connection_impl(keep_alive_t)
{
auto it = find("Connection");
if(it == end())
this->insert("Connection", "keep-alive");
else
this->replace("Connection",
it->value().to_string() + ", keep-alive");
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
connection_impl(upgrade_t)
{
auto it = find("Connection");
if(it == end())
this->insert("Connection", "upgrade");
else
this->replace("Connection",
it->value().to_string() + ", upgrade");
}
template<class Allocator>
inline
void

View File

@ -292,85 +292,19 @@ content_length(std::uint64_t n)
}
template<bool isRequest, class Body, class Fields>
template<class... Args>
void
message<isRequest, Body, Fields>::
prepare(Args const&... args)
prepare()
{
static_assert(is_body_reader<Body>::value,
"BodyReader requirements not met");
unsigned f = 0;
prepare_opt(f, args...);
if(f & 1)
{
if(this->version > 10)
this->connection_impl(connection::close);
}
if(f & 2)
{
if(this->version < 11)
this->connection_impl(connection::keep_alive);
}
if(f & 4)
{
if(this->version < 11)
BOOST_THROW_EXCEPTION(std::invalid_argument{
"invalid connection upgrade"});
this->connection_impl(connection::upgrade);
}
prepare_payload(typename header<
prepare(typename header<
isRequest, Fields>::is_request{});
}
template<bool isRequest, class Body, class Fields>
template<class Arg, class... Args>
inline
void
message<isRequest, Body, Fields>::
prepare_opt(unsigned& f,
Arg const& arg, Args const&... args)
{
prepare_opt(f, arg);
prepare_opt(f, args...);
}
template<bool isRequest, class Body, class Fields>
inline
void
message<isRequest, Body, Fields>::
prepare_opt(unsigned& f, close_t)
{
f |= 1;
}
template<bool isRequest, class Body, class Fields>
inline
void
message<isRequest, Body, Fields>::
prepare_opt(unsigned& f, keep_alive_t)
{
f |= 2;
}
template<bool isRequest, class Body, class Fields>
inline
void
message<isRequest, Body, Fields>::
prepare_opt(unsigned& f, upgrade_t)
{
f |= 4;
}
template<bool isRequest, class Body, class Fields>
inline
void
message<isRequest, Body, Fields>::
prepare_payload(std::true_type)
prepare(std::true_type)
{
auto const n = size();
if(this->method_ == verb::trace &&
@ -398,7 +332,7 @@ template<bool isRequest, class Body, class Fields>
inline
void
message<isRequest, Body, Fields>::
prepare_payload(std::false_type)
prepare(std::false_type)
{
auto const n = size();
if((status_class(this->result_) ==

View File

@ -9,7 +9,6 @@
#define BEAST_HTTP_MESSAGE_HPP
#include <beast/config.hpp>
#include <beast/http/connection.hpp>
#include <beast/http/fields.hpp>
#include <beast/http/verb.hpp>
#include <beast/http/status.hpp>
@ -500,34 +499,25 @@ struct message : header<isRequest, Fields>
void
content_length(std::uint64_t n);
/** Prepare some fields automatically.
/** Prepare the message payload fields for the body.
This function will adjust the Connection, Content-Length
and Transfer-Encoding, fields of the message based on the
properties of the body and the options passed in.
This function will adjust the Content-Length and
Transfer-Encoding field values based on the properties
of the body.
@par Example
@code
request<empty_body> req;
request<string_body> req;
req.version = 11;
req.method(verb::upgrade);
req.target("/");
req.insert(field::user_agent, "Beast");
req.prepare(connection::close, connection::upgrade);
req.body = "Hello, world!";
req.prepare();
@endcode
@param args An list of zero or more options to use.
@throw std::invalid_argument if the values of certain
fields detectably violate the semantic requirements of HTTP.
@note Undefined behavior if called more than once.
@see @ref connection
*/
template<class... Args>
void
prepare(Args const&... args);
prepare();
private:
static_assert(is_body<Body>::value,
@ -564,29 +554,11 @@ private:
return boost::none;
}
template<class Arg, class... Args>
void
prepare_opt(unsigned&, Arg const&, Args const&...);
prepare(std::true_type);
void
prepare_opt(unsigned&)
{
}
void
prepare_opt(unsigned&, close_t);
void
prepare_opt(unsigned&, keep_alive_t);
void
prepare_opt(unsigned&, upgrade_t);
void
prepare_payload(std::true_type);
void
prepare_payload(std::false_type);
prepare(std::false_type);
};
/// A typical HTTP request

View File

@ -38,7 +38,6 @@ void fxx() {
req.target("/index.htm");
req.insert(field::accept, "text/html");
req.insert(field::user_agent, "Beast");
req.prepare(connection::close);
//]
}

View File

@ -205,9 +205,8 @@ public:
m.insert("Upgrade", "test");
BEAST_EXPECT(! is_upgrade(m));
m.prepare(connection::upgrade);
m.insert(field::connection, "upgrade");
BEAST_EXPECT(is_upgrade(m));
BEAST_EXPECT(m["Connection"] == "upgrade");
m.version = 10;
BEAST_EXPECT(! is_upgrade(m));

View File

@ -510,42 +510,6 @@ public:
"*"
);
}
// keep-alive HTTP/1.0
{
message<true, string_body, fields> m;
m.method(verb::get);
m.target("/");
m.version = 10;
m.insert(field::user_agent, "test");
m.body = "*";
m.prepare(connection::keep_alive);
BEAST_EXPECT(str(m) ==
"GET / HTTP/1.0\r\n"
"User-Agent: test\r\n"
"Connection: keep-alive\r\n"
"Content-Length: 1\r\n"
"\r\n"
"*"
);
}
// upgrade HTTP/1.0
{
message<true, string_body, fields> m;
m.method(verb::get);
m.target("/");
m.version = 10;
m.insert(field::user_agent, "test");
m.body = "*";
try
{
m.prepare( connection::upgrade);
fail();
}
catch(std::exception const&)
{
pass();
}
}
// no content-length HTTP/1.0
{
message<true, unsized_body, fields> m;
@ -583,43 +547,6 @@ public:
"*"
);
}
// close HTTP/1.1
{
message<true, string_body, fields> m;
m.method(verb::get);
m.target("/");
m.version = 11;
m.insert(field::user_agent, "test");
m.body = "*";
m.prepare(connection::close);
test::string_ostream ss(ios_);
error_code ec;
write(ss, m, ec);
BEAST_EXPECT(ec == error::end_of_stream);
BEAST_EXPECT(ss.str ==
"GET / HTTP/1.1\r\n"
"User-Agent: test\r\n"
"Connection: close\r\n"
"Content-Length: 1\r\n"
"\r\n"
"*"
);
}
// upgrade HTTP/1.1
{
message<true, string_body, fields> m;
m.method(verb::get);
m.target("/");
m.version = 11;
m.insert(field::user_agent, "test");
m.prepare(connection::upgrade);
BEAST_EXPECT(str(m) ==
"GET / HTTP/1.1\r\n"
"User-Agent: test\r\n"
"Connection: upgrade\r\n"
"\r\n"
);
}
// no content-length HTTP/1.1
{
message<true, unsized_body, fields> m;