Derive header from Fields (API Change)

This commit is contained in:
Vinnie Falco
2017-06-05 19:28:17 -07:00
parent 5f2e7560b6
commit 2af19481a9
35 changed files with 304 additions and 298 deletions

View File

@@ -51,7 +51,7 @@ This diagram shows the inheritance relationship between header and message,
along with the fields from the different partial specializations for each
possible value of `isRequest`:
[$images/message.png [width 711px] [height 424px]]
[$images/message.png [width 730px] [height 410px]]
For notational convenience, the template type aliases
[link beast.ref.http__request `request`] and
@@ -126,9 +126,9 @@ objects:
req.version = 11; // HTTP/1.1
req.method(verb::get);
req.target("/index.htm");
req.fields.insert("Accept", "text/html");
req.fields.insert("Connection", "keep-alive");
req.fields.insert("User-Agent", "Beast");
req.insert("Accept", "text/html");
req.insert("Connection", "keep-alive");
req.insert("User-Agent", "Beast");
```
][
```
@@ -149,8 +149,8 @@ objects:
res.version = 11; // HTTP/1.1
res.result(status::ok);
res.body = "Hello, world!";
res.fields.insert("Server", "Beast");
res.fields.insert("Content-Length", res.body.size());
res.insert("Server", "Beast");
res.insert("Content-Length", res.body.size());
```
][
```

View File

@@ -129,7 +129,7 @@ the number of octets received prior to the server closing the connection:
response<string_body> res;
res.version = 11;
res.result(status::ok);
res.fields.insert("Server", "Beast");
res.insert("Server", "Beast");
res.body = "Hello, world!";
error_code ec;

View File

@@ -61,7 +61,7 @@ on the request:
```
void decorate(websocket::request_type& req)
{
req.fields.insert("Sec-WebSocket-Protocol", "xmpp;ws-chat");
req.insert("Sec-WebSocket-Protocol", "xmpp;ws-chat");
}
...
ws.handshake_ex("localhost", "/", &decorate);
@@ -102,7 +102,7 @@ as follows:
```
websocket::response_type res;
ws.handshake(res, "localhost", "/");
if(! res.fields.exists("Sec-WebSocket-Protocol"))
if(! res.exists("Sec-WebSocket-Protocol"))
throw std::invalid_argument("missing subprotocols");
```

View File

@@ -53,7 +53,7 @@ field on the response:
ws.accept_ex(
[](websocket::response_type& res)
{
res.fields.insert("Server", "AcmeServer");
res.insert("Server", "AcmeServer");
});
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -61,7 +61,7 @@ send_expect_100_continue(
"DynamicBuffer requirements not met");
// Insert or replace the Expect field
req.fields.replace("Expect", "100-continue");
req.replace("Expect", "100-continue");
// Create the serializer
auto sr = make_serializer(req);
@@ -130,13 +130,13 @@ receive_expect_100_continue(
return;
// Check for the Expect field value
if(parser.get().fields["Expect"] == "100-continue")
if(parser.get()["Expect"] == "100-continue")
{
// send 100 response
response<empty_body> res;
res.version = 11;
res.result(status::continue_);
res.fields.insert("Server", "test");
res.insert("Server", "test");
write(stream, res, ec);
if(ec)
return;
@@ -198,8 +198,8 @@ send_cgi_response(
res.result(status::ok);
res.version = 11;
res.fields.insert("Server", "Beast");
res.fields.insert("Transfer-Encoding", "chunked");
res.insert("Server", "Beast");
res.insert("Transfer-Encoding", "chunked");
// No data yet, but we set more = true to indicate
// that it might be coming later. Otherwise the
@@ -307,7 +307,7 @@ void do_server_head(
// Set up the response, starting with the common fields
response<string_body> res;
res.version = 11;
res.fields.insert("Server", "test");
res.insert("Server", "test");
// Now handle request-specific fields
switch(req.method())
@@ -319,7 +319,7 @@ void do_server_head(
// set of headers that would be sent for a GET request,
// including the Content-Length, except for the body.
res.result(status::ok);
res.fields.insert("Content-Length", payload.size());
res.insert("Content-Length", payload.size());
// For GET requests, we include the body
if(req.method() == verb::get)
@@ -337,7 +337,7 @@ void do_server_head(
// We return responses indicating an error if
// we do not recognize the request method.
res.result(status::bad_request);
res.fields.insert("Content-Type", "text/plain");
res.insert("Content-Type", "text/plain");
res.body = "Invalid request-method '" + req.method_string().to_string() + "'";
break;
}
@@ -397,11 +397,11 @@ do_head_request(
req.version = 11;
req.method(verb::head);
req.target(target);
req.fields.insert("User-Agent", "test");
req.insert("User-Agent", "test");
// A client MUST send a Host header field in all HTTP/1.1 request messages.
// https://tools.ietf.org/html/rfc7230#section-5.4
req.fields.insert("Host", "localhost");
req.insert("Host", "localhost");
// Now send it
write(stream, req, ec);
@@ -813,8 +813,8 @@ do_form_request(
case verb::post:
{
// If this is not a form upload then use a string_body
if( req0.get().fields["Content-Type"] != "application/x-www-form-urlencoded" &&
req0.get().fields["Content-Type"] != "multipart/form-data")
if( req0.get()["Content-Type"] != "application/x-www-form-urlencoded" &&
req0.get()["Content-Type"] != "multipart/form-data")
goto do_string_body;
// Commit to string_body as the body type.

View File

@@ -236,8 +236,8 @@ private:
response<string_body> res;
res.result(status::not_found);
res.version = req_.version;
res.fields.insert("Server", "http_async_server");
res.fields.insert("Content-Type", "text/html");
res.insert("Server", "http_async_server");
res.insert("Content-Type", "text/html");
res.body = "The file '" + path + "' was not found";
prepare(res);
async_write(sock_, std::move(res),
@@ -250,8 +250,8 @@ private:
resp_type res;
res.result(status::ok);
res.version = req_.version;
res.fields.insert("Server", "http_async_server");
res.fields.insert("Content-Type", mime_type(path));
res.insert("Server", "http_async_server");
res.insert("Content-Type", mime_type(path));
res.body = path;
prepare(res);
async_write(sock_, std::move(res),
@@ -263,8 +263,8 @@ private:
response<string_body> res;
res.result(status::internal_server_error);
res.version = req_.version;
res.fields.insert("Server", "http_async_server");
res.fields.insert("Content-Type", "text/html");
res.insert("Server", "http_async_server");
res.insert("Content-Type", "text/html");
res.body =
std::string{"An internal error occurred"} + e.what();
prepare(res);

View File

@@ -40,9 +40,9 @@ int main(int, char const*[])
req.method(verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", host + std::string(":") +
req.insert("Host", host + std::string(":") +
boost::lexical_cast<std::string>(ep.port()));
req.fields.insert("User-Agent", "beast/http");
req.insert("User-Agent", "beast/http");
prepare(req);
write(sock, req);
response<string_body> res;

View File

@@ -29,9 +29,9 @@ int main()
req.method(beast::http::verb::get);
req.target("/");
req.version = 11;
req.fields.replace("Host", host + ":" +
req.replace("Host", host + ":" +
boost::lexical_cast<std::string>(sock.remote_endpoint().port()));
req.fields.replace("User-Agent", "Beast");
req.replace("User-Agent", "Beast");
beast::http::prepare(req);
beast::http::write(sock, req);

View File

@@ -166,8 +166,8 @@ private:
response<string_body> res;
res.result(status::not_found);
res.version = req.version;
res.fields.insert("Server", "http_sync_server");
res.fields.insert("Content-Type", "text/html");
res.insert("Server", "http_sync_server");
res.insert("Content-Type", "text/html");
res.body = "The file '" + path + "' was not found";
prepare(res);
write(sock, res, ec);
@@ -181,8 +181,8 @@ private:
res.result(status::ok);
res.reason("OK");
res.version = req.version;
res.fields.insert("Server", "http_sync_server");
res.fields.insert("Content-Type", mime_type(path));
res.insert("Server", "http_sync_server");
res.insert("Content-Type", mime_type(path));
res.body = path;
prepare(res);
write(sock, res, ec);
@@ -195,8 +195,8 @@ private:
res.result(status::internal_server_error);
res.reason("Internal Error");
res.version = req.version;
res.fields.insert("Server", "http_sync_server");
res.fields.insert("Content-Type", "text/html");
res.insert("Server", "http_sync_server");
res.insert("Content-Type", "text/html");
res.body =
std::string{"An internal error occurred: "} + e.what();
prepare(res);

View File

@@ -38,9 +38,9 @@ int main()
req.method(beast::http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", host + ":" +
req.insert("Host", host + ":" +
boost::lexical_cast<std::string>(sock.remote_endpoint().port()));
req.fields.insert("User-Agent", "Beast");
req.insert("User-Agent", "Beast");
beast::http::prepare(req);
beast::http::write(stream, req);

View File

@@ -263,7 +263,7 @@ private:
d.ws.async_accept_ex(
[](beast::websocket::response_type& res)
{
res.fields.insert(
res.insert(
"Server", "async_echo_server");
},
std::move(*this));

View File

@@ -274,7 +274,7 @@ private:
ws.accept_ex(
[](beast::websocket::response_type& res)
{
res.fields.insert(
res.insert(
"Server", "sync_echo_server");
},
ec);

View File

@@ -268,54 +268,14 @@ public:
boost::lexical_cast<std::string>(value));
}
#if BEAST_DOXYGEN
private:
#endif
string_view
method_impl() const
{
return (*this)[":method"];
}
void
method_impl(string_view s)
{
if(s.empty())
this->erase(":method");
else
this->replace(":method", s);
}
string_view
target_impl() const
{
return (*this)[":target"];
}
void
target_impl(string_view s)
{
if(s.empty())
this->erase(":target");
else
return this->replace(":target", s);
}
string_view
reason_impl() const
{
return (*this)[":reason"];
}
void
reason_impl(string_view s)
{
if(s.empty())
this->erase(":reason");
else
this->replace(":reason", s);
}
protected:
// for header
string_view method_impl() const;
string_view target_impl() const;
string_view reason_impl() const;
void method_impl(string_view s);
void target_impl(string_view s);
void reason_impl(string_view s);
private:
struct element

View File

@@ -26,6 +26,71 @@ basic_fields<Allocator>::
//------------------------------------------------------------------------------
template<class Allocator>
inline
string_view
basic_fields<Allocator>::
method_impl() const
{
return (*this)[":method"];
}
template<class Allocator>
inline
string_view
basic_fields<Allocator>::
target_impl() const
{
return (*this)[":target"];
}
template<class Allocator>
inline
string_view
basic_fields<Allocator>::
reason_impl() const
{
return (*this)[":reason"];
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
method_impl(string_view s)
{
if(s.empty())
this->erase(":method");
else
this->replace(":method", s);
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
target_impl(string_view s)
{
if(s.empty())
this->erase(":target");
else
return this->replace(":target", s);
}
template<class Allocator>
inline
void
basic_fields<Allocator>::
reason_impl(string_view s)
{
if(s.empty())
this->erase(":reason");
else
this->replace(":reason", s);
}
//------------------------------------------------------------------------------
template<class Allocator>
class basic_fields<Allocator>::
const_iterator

View File

@@ -30,7 +30,7 @@ get_method_string() const
{
if(method_ != verb::unknown)
return to_string(method_);
return fields.method_impl();
return this->method_impl();
}
template<class Fields>
@@ -43,7 +43,7 @@ set_method(verb v)
BOOST_THROW_EXCEPTION(
std::invalid_argument{"unknown verb"});
method_ = v;
fields.method_impl({});
this->method_impl({});
}
template<class Fields>
@@ -54,9 +54,9 @@ set_method(string_view s)
{
method_ = string_to_verb(s);
if(method_ != verb::unknown)
fields.method_impl({});
this->method_impl({});
else
fields.method_impl(s);
this->method_impl(s);
}
template<class Fields>
@@ -65,7 +65,7 @@ string_view
header<false, Fields>::
get_reason() const
{
auto const s = fields.reason_impl();
auto const s = this->reason_impl();
if(! s.empty())
return s;
return obsolete_reason(result_);
@@ -74,25 +74,29 @@ get_reason() const
template<class Fields>
void
swap(
header<true, Fields>& m1,
header<true, Fields>& m2)
header<true, Fields>& h1,
header<true, Fields>& h2)
{
using std::swap;
swap(m1.version, m2.version);
swap(m1.fields, m2.fields);
swap(m1.method_, m2.method_);
swap(
static_cast<Fields&>(h1),
static_cast<Fields&>(h2));
swap(h1.version, h2.version);
swap(h1.method_, h2.method_);
}
template<class Fields>
void
swap(
header<false, Fields>& a,
header<false, Fields>& b)
header<false, Fields>& h1,
header<false, Fields>& h2)
{
using std::swap;
swap(a.version, b.version);
swap(a.fields, b.fields);
swap(a.result_, b.result_);
swap(
static_cast<Fields&>(h1),
static_cast<Fields&>(h2));
swap(h1.version, h2.version);
swap(h1.result_, h2.result_);
}
template<bool isRequest, class Body, class Fields>
@@ -113,11 +117,11 @@ is_keep_alive(header<isRequest, Fields> const& msg)
BOOST_ASSERT(msg.version == 10 || msg.version == 11);
if(msg.version == 11)
{
if(token_list{msg.fields["Connection"]}.exists("close"))
if(token_list{msg["Connection"]}.exists("close"))
return false;
return true;
}
if(token_list{msg.fields["Connection"]}.exists("keep-alive"))
if(token_list{msg["Connection"]}.exists("keep-alive"))
return true;
return false;
}
@@ -129,7 +133,7 @@ is_upgrade(header<isRequest, Fields> const& msg)
BOOST_ASSERT(msg.version == 10 || msg.version == 11);
if(msg.version == 10)
return false;
if(token_list{msg.fields["Connection"]}.exists("upgrade"))
if(token_list{msg["Connection"]}.exists("upgrade"))
return true;
return false;
}
@@ -219,15 +223,15 @@ prepare(message<isRequest, Body, Fields>& msg,
detail::prepare_options(pi, msg,
std::forward<Options>(options)...);
if(msg.fields.exists("Connection"))
if(msg.exists("Connection"))
BOOST_THROW_EXCEPTION(std::invalid_argument{
"prepare called with Connection field set"});
if(msg.fields.exists("Content-Length"))
if(msg.exists("Content-Length"))
BOOST_THROW_EXCEPTION(std::invalid_argument{
"prepare called with Content-Length field set"});
if(token_list{msg.fields["Transfer-Encoding"]}.exists("chunked"))
if(token_list{msg["Transfer-Encoding"]}.exists("chunked"))
BOOST_THROW_EXCEPTION(std::invalid_argument{
"prepare called with Transfer-Encoding: chunked set"});
@@ -245,7 +249,7 @@ prepare(message<isRequest, Body, Fields>& msg,
if(*pi.content_length > 0 ||
msg.method() == verb::post)
{
msg.fields.insert(
msg.insert(
"Content-Length", *pi.content_length);
}
}
@@ -258,7 +262,7 @@ prepare(message<isRequest, Body, Fields>& msg,
msg.result() != status::no_content &&
msg.result() != status::not_modified)
{
msg.fields.insert(
msg.insert(
"Content-Length", *pi.content_length);
}
}
@@ -267,39 +271,39 @@ prepare(message<isRequest, Body, Fields>& msg,
}
else if(msg.version >= 11)
{
msg.fields.insert("Transfer-Encoding", "chunked");
msg.insert("Transfer-Encoding", "chunked");
}
}
auto const content_length =
msg.fields.exists("Content-Length");
msg.exists("Content-Length");
if(pi.connection_value)
{
switch(*pi.connection_value)
{
case connection::upgrade:
msg.fields.insert("Connection", "upgrade");
msg.insert("Connection", "upgrade");
break;
case connection::keep_alive:
if(msg.version < 11)
{
if(content_length)
msg.fields.insert("Connection", "keep-alive");
msg.insert("Connection", "keep-alive");
}
break;
case connection::close:
if(msg.version >= 11)
msg.fields.insert("Connection", "close");
msg.insert("Connection", "close");
break;
}
}
// rfc7230 6.7.
if(msg.version < 11 && token_list{
msg.fields["Connection"]}.exists("upgrade"))
msg["Connection"]}.exists("upgrade"))
BOOST_THROW_EXCEPTION(std::invalid_argument{
"invalid version for Connection: upgrade"});
}

View File

@@ -94,12 +94,12 @@ get(error_code& ec, Visit&& visit)
case do_construct:
{
chunked_ = token_list{
m_.fields["Transfer-Encoding"]}.exists("chunked");
close_ = token_list{m_.fields["Connection"]}.exists("close") ||
(m_.version < 11 && ! m_.fields.exists("Content-Length"));
m_["Transfer-Encoding"]}.exists("chunked");
close_ = token_list{m_["Connection"]}.exists("close") ||
(m_.version < 11 && ! m_.exists("Content-Length"));
auto os = ostream(b_);
detail::write_start_line(os, m_);
detail::write_fields(os, m_.fields);
detail::write_fields(os, m_);
os << "\r\n";
if(chunked_)
goto go_init_c;

View File

@@ -828,7 +828,7 @@ operator<<(std::ostream& os,
header<isRequest, Fields> const& msg)
{
detail::write_start_line(os, msg);
detail::write_fields(os, msg.fields);
detail::write_fields(os, msg);
os << "\r\n";
return os;
}

View File

@@ -45,7 +45,7 @@ template<bool isRequest, class Fields = fields>
struct header;
template<class Fields>
struct header<true, Fields>
struct header<true, Fields> : Fields
#endif
{
/// Indicates if the header is a request or response.
@@ -59,6 +59,17 @@ struct header<true, Fields>
/// The type representing the fields.
using fields_type = Fields;
/** The HTTP-version.
This holds both the major and minor version numbers,
using these formulas:
@code
int major = version / 10;
int minor = version % 10;
@endcode
*/
int version;
/// Default constructor
header() = default;
@@ -96,25 +107,11 @@ struct header<true, Fields>
header>::value>::type>
explicit
header(Arg1&& arg1, ArgN&&... argn)
: fields(std::forward<Arg1>(arg1),
: Fields(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
}
/** The HTTP-version.
This holds both the major and minor version numbers,
using these formulas:
@code
int major = version / 10;
int minor = version % 10;
@endcode
*/
int version;
/// The HTTP field values.
fields_type fields;
/** Return the request-method verb.
If the request-method is not one of the recognized verbs,
@@ -181,7 +178,7 @@ struct header<true, Fields>
string_view
target() const
{
return fields.target_impl();
return this->target_impl();
}
/** Set the request-target string.
@@ -193,7 +190,7 @@ struct header<true, Fields>
void
target(string_view s)
{
fields.target_impl(s);
this->target_impl(s);
}
private:
@@ -230,7 +227,7 @@ private:
@li Invoke algorithms which operate on the header only.
*/
template<class Fields>
struct header<false, Fields>
struct header<false, Fields> : Fields
{
/// Indicates if the header is a request or response.
static bool constexpr is_request = false;
@@ -249,9 +246,6 @@ struct header<false, Fields>
*/
int version;
/// The HTTP field values.
fields_type fields;
/// Default constructor.
header() = default;
@@ -283,7 +277,7 @@ struct header<false, Fields>
header>::value>::type>
explicit
header(Arg1&& arg1, ArgN&&... argn)
: fields(std::forward<Arg1>(arg1),
: Fields(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
}
@@ -379,7 +373,7 @@ struct header<false, Fields>
void
reason(string_view s)
{
fields.reason_impl(s);
this->reason_impl(s);
}
private:

View File

@@ -208,7 +208,7 @@ private:
string_view value,
error_code&)
{
m_.fields.insert(name, value);
m_.insert(name, value);
}
void

View File

@@ -153,8 +153,7 @@ operator()(error_code ec, bool again)
ec = error::handshake_failed;
if(! ec)
{
pmd_read(
d.ws.pmd_config_, d.res.fields);
pmd_read(d.ws.pmd_config_, d.res);
d.ws.open(detail::role_type::server);
}
break;

View File

@@ -132,8 +132,7 @@ operator()(error_code ec, bool again)
// VFALCO Do we need the ability to move
// a message on the async_write?
//
pmd_read(
d.ws.pmd_config_, d.req.fields);
pmd_read(d.ws.pmd_config_, d.req);
http::async_write(d.ws.stream_,
d.req, std::move(*this));
// TODO We don't need d.req now. Figure

View File

@@ -23,9 +23,9 @@ is_upgrade(http::header<true, Fields> const& req)
return false;
if(! http::is_upgrade(req))
return false;
if(! http::token_list{req.fields["Upgrade"]}.exists("websocket"))
if(! http::token_list{req["Upgrade"]}.exists("websocket"))
return false;
if(! req.fields.exists("Sec-WebSocket-Version"))
if(! req.exists("Sec-WebSocket-Version"))
return false;
return true;
}

View File

@@ -117,7 +117,7 @@ do_accept(http::header<true, Fields> const& req,
// teardown if Connection: close.
return;
}
pmd_read(pmd_config_, req.fields);
pmd_read(pmd_config_, req);
open(detail::role_type::server);
}
@@ -137,7 +137,7 @@ do_handshake(response_type* res_p,
{
auto const req = build_request(
key, host, target, decorator);
pmd_read(pmd_config_, req.fields);
pmd_read(pmd_config_, req);
http::write(stream_, req, ec);
}
if(ec)
@@ -163,12 +163,12 @@ build_request(detail::sec_ws_key_type& key,
req.target(target);
req.version = 11;
req.method(http::verb::get);
req.fields.insert("Host", host);
req.fields.insert("Upgrade", "websocket");
req.fields.insert("Connection", "upgrade");
req.insert("Host", host);
req.insert("Upgrade", "websocket");
req.insert("Connection", "upgrade");
detail::make_sec_ws_key(key, maskgen_);
req.fields.insert("Sec-WebSocket-Key", key);
req.fields.insert("Sec-WebSocket-Version", "13");
req.insert("Sec-WebSocket-Key", key);
req.insert("Sec-WebSocket-Version", "13");
if(pmd_opts_.client_enable)
{
detail::pmd_offer config;
@@ -181,14 +181,13 @@ build_request(detail::sec_ws_key_type& key,
pmd_opts_.server_no_context_takeover;
config.client_no_context_takeover =
pmd_opts_.client_no_context_takeover;
detail::pmd_write(
req.fields, config);
detail::pmd_write(req, config);
}
decorator(req);
if(! req.fields.exists("User-Agent"))
if(! req.exists("User-Agent"))
{
static_string<20> s(BEAST_VERSION_STRING);
req.fields.insert("User-Agent", s);
req.insert("User-Agent", s);
}
return req;
}
@@ -204,10 +203,10 @@ build_response(http::header<true, Fields> const& req,
[&decorator](response_type& res)
{
decorator(res);
if(! res.fields.exists("Server"))
if(! res.exists("Server"))
{
static_string<20> s(BEAST_VERSION_STRING);
res.fields.insert("Server", s);
res.insert("Server", s);
}
};
auto err =
@@ -227,18 +226,18 @@ build_response(http::header<true, Fields> const& req,
return err("Wrong method");
if(! is_upgrade(req))
return err("Expected Upgrade request");
if(! req.fields.exists("Host"))
if(! req.exists("Host"))
return err("Missing Host");
if(! req.fields.exists("Sec-WebSocket-Key"))
if(! req.exists("Sec-WebSocket-Key"))
return err("Missing Sec-WebSocket-Key");
if(! http::token_list{req.fields["Upgrade"]}.exists("websocket"))
if(! http::token_list{req["Upgrade"]}.exists("websocket"))
return err("Missing websocket Upgrade token");
auto const key = req.fields["Sec-WebSocket-Key"];
auto const key = req["Sec-WebSocket-Key"];
if(key.size() > detail::sec_ws_key_type::max_size_n)
return err("Invalid Sec-WebSocket-Key");
{
auto const version =
req.fields["Sec-WebSocket-Version"];
req["Sec-WebSocket-Version"];
if(version.empty())
return err("Missing Sec-WebSocket-Version");
if(version != "13")
@@ -246,7 +245,7 @@ build_response(http::header<true, Fields> const& req,
response_type res;
res.result(http::status::upgrade_required);
res.version = req.version;
res.fields.insert("Sec-WebSocket-Version", "13");
res.insert("Sec-WebSocket-Version", "13");
prepare(res);
decorate(res);
return res;
@@ -257,18 +256,17 @@ build_response(http::header<true, Fields> const& req,
{
detail::pmd_offer offer;
detail::pmd_offer unused;
pmd_read(offer, req.fields);
pmd_negotiate(
res.fields, unused, offer, pmd_opts_);
pmd_read(offer, req);
pmd_negotiate(res, unused, offer, pmd_opts_);
}
res.result(http::status::switching_protocols);
res.version = req.version;
res.fields.insert("Upgrade", "websocket");
res.fields.insert("Connection", "upgrade");
res.insert("Upgrade", "websocket");
res.insert("Connection", "upgrade");
{
detail::sec_ws_accept_type accept;
detail::make_sec_ws_accept(accept, key);
res.fields.insert("Sec-WebSocket-Accept", accept);
res.insert("Sec-WebSocket-Accept", accept);
}
decorate(res);
return res;
@@ -288,14 +286,14 @@ do_response(http::header<false> const& res,
return false;
if(! is_upgrade(res))
return false;
if(! http::token_list{res.fields["Upgrade"]}.exists("websocket"))
if(! http::token_list{res["Upgrade"]}.exists("websocket"))
return false;
if(! res.fields.exists("Sec-WebSocket-Accept"))
if(! res.exists("Sec-WebSocket-Accept"))
return false;
detail::sec_ws_accept_type accept;
detail::make_sec_ws_accept(accept, key);
if(accept.compare(
res.fields["Sec-WebSocket-Accept"]) != 0)
res["Sec-WebSocket-Accept"]) != 0)
return false;
return true;
}();
@@ -305,7 +303,7 @@ do_response(http::header<false> const& res,
return;
}
detail::pmd_offer offer;
pmd_read(offer, res.fields);
pmd_read(offer, res);
// VFALCO see if offer satisfies pmd_config_,
// return an error if not.
pmd_config_ = offer; // overwrite for now

View File

@@ -1563,7 +1563,7 @@ public:
ws.handshake("localhost", "/",
[](request_type& req)
{
req.fields.insert("User-Agent", "Beast");
req.insert("User-Agent", "Beast");
});
}
catch(...)
@@ -1625,7 +1625,7 @@ public:
ws.handshake(res, "localhost", "/",
[](request_type& req)
{
req.fields.insert("User-Agent", "Beast");
req.insert("User-Agent", "Beast");
});
}
catch(...)
@@ -1771,7 +1771,7 @@ public:
ws.handshake("localhost", "/",
[](request_type& req)
{
req.fields.insert("User-Agent", "Beast");
req.insert("User-Agent", "Beast");
},
ec);
if(ec)
@@ -1833,7 +1833,7 @@ public:
ws.handshake(res, "localhost", "/",
[](request_type& req)
{
req.fields.insert("User-Agent", "Beast");
req.insert("User-Agent", "Beast");
},
ec);
if(ec)

View File

@@ -66,11 +66,11 @@ public:
[&](yield_context)
{
flat_buffer buffer;
request<string_body, fields> req;
request<string_body> req;
req.version = 11;
req.method("POST");
req.target("/");
req.fields.insert("User-Agent", "test");
req.insert("User-Agent", "test");
req.body = "Hello, world!";
prepare(req);
@@ -99,11 +99,11 @@ public:
void
doRelay()
{
request<string_body, fields> req;
request<string_body> req;
req.version = 11;
req.method("POST");
req.target("/");
req.fields.insert("User-Agent", "test");
req.insert("User-Agent", "test");
req.body = "Hello, world!";
prepare(req);
@@ -121,8 +121,8 @@ public:
relay<true>(upstream.client, downstream.server, buffer, ec,
[&](header<true, fields>& h, error_code& ec)
{
h.fields.erase("Content-Length");
h.fields.replace("Transfer-Encoding", "chunked");
h.erase("Content-Length");
h.replace("Transfer-Encoding", "chunked");
});
BEAST_EXPECTS(! ec, ec.message());
BEAST_EXPECT(equal_body<true>(
@@ -155,7 +155,7 @@ public:
req.version = 11;
req.method(verb::get);
req.target("/");
req.fields.insert("User-Agent", "test");
req.insert("User-Agent", "test");
error_code ec;
write_ostream(os, req, ec);
BEAST_EXPECTS(! ec, ec.message());

View File

@@ -99,24 +99,11 @@ public:
BEAST_EXPECT(size(f) == 2);
}
void
testMethodString()
{
f_t f;
f.method_impl("CRY");
BEAST_EXPECTS(f.method_impl() == "CRY", f.method_impl());
f.method_impl("PUT");
BEAST_EXPECTS(f.method_impl() == "PUT", f.method_impl());
f.method_impl({});
BEAST_EXPECTS(f.method_impl().empty(), f.method_impl());
}
void run() override
{
testHeaders();
testRFC2616();
testErase();
testMethodString();
}
};

View File

@@ -118,14 +118,14 @@ public:
h.insert("User-Agent", "test");
message<true, one_arg_body, fields> m{Arg1{}, h};
BEAST_EXPECT(h["User-Agent"] == "test");
BEAST_EXPECT(m.fields["User-Agent"] == "test");
BEAST_EXPECT(m["User-Agent"] == "test");
}
{
fields h;
h.insert("User-Agent", "test");
message<true, one_arg_body, fields> m{Arg1{}, std::move(h)};
BEAST_EXPECT(! h.exists("User-Agent"));
BEAST_EXPECT(m.fields["User-Agent"] == "test");
BEAST_EXPECT(m["User-Agent"] == "test");
}
// swap
@@ -133,7 +133,7 @@ public:
message<true, string_body, fields> m2;
m1.target("u");
m1.body = "1";
m1.fields.insert("h", "v");
m1.insert("h", "v");
m2.method("G");
m2.body = "2";
swap(m1, m2);
@@ -143,8 +143,8 @@ public:
BEAST_EXPECT(m2.target() == "u");
BEAST_EXPECT(m1.body == "2");
BEAST_EXPECT(m2.body == "1");
BEAST_EXPECT(! m1.fields.exists("h"));
BEAST_EXPECT(m2.fields.exists("h"));
BEAST_EXPECT(! m1.exists("h"));
BEAST_EXPECT(m2.exists("h"));
}
struct MoveFields : fields
@@ -187,10 +187,10 @@ public:
MoveFields h;
header<true, MoveFields> r{std::move(h)};
BEAST_EXPECT(h.moved_from);
BEAST_EXPECT(r.fields.moved_to);
BEAST_EXPECT(r.moved_to);
request<string_body, MoveFields> m{std::move(r)};
BEAST_EXPECT(r.fields.moved_from);
BEAST_EXPECT(m.fields.moved_to);
BEAST_EXPECT(r.moved_from);
BEAST_EXPECT(m.moved_to);
}
}
@@ -202,12 +202,12 @@ public:
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("Upgrade", "test");
m.insert("Upgrade", "test");
BEAST_EXPECT(! is_upgrade(m));
prepare(m, connection::upgrade);
BEAST_EXPECT(is_upgrade(m));
BEAST_EXPECT(m.fields["Connection"] == "upgrade");
BEAST_EXPECT(m["Connection"] == "upgrade");
m.version = 10;
BEAST_EXPECT(! is_upgrade(m));
@@ -220,7 +220,7 @@ public:
request<string_body> m;
m.version = 10;
BEAST_EXPECT(! is_upgrade(m));
m.fields.insert("Transfer-Encoding", "chunked");
m.insert("Transfer-Encoding", "chunked");
try
{
prepare(m);
@@ -229,8 +229,8 @@ public:
catch(std::exception const&)
{
}
m.fields.erase("Transfer-Encoding");
m.fields.insert("Content-Length", "0");
m.erase("Transfer-Encoding");
m.insert("Content-Length", "0");
try
{
prepare(m);
@@ -240,8 +240,8 @@ public:
{
pass();
}
m.fields.erase("Content-Length");
m.fields.insert("Connection", "keep-alive");
m.erase("Content-Length");
m.insert("Connection", "keep-alive");
try
{
prepare(m);
@@ -252,8 +252,8 @@ public:
pass();
}
m.version = 11;
m.fields.erase("Connection");
m.fields.insert("Connection", "close");
m.erase("Connection");
m.insert("Connection", "close");
BEAST_EXPECT(! is_keep_alive(m));
}
@@ -265,7 +265,7 @@ public:
m1.result(status::ok);
m1.version = 10;
m1.body = "1";
m1.fields.insert("h", "v");
m1.insert("h", "v");
m2.result(status::not_found);
m2.body = "2";
m2.version = 11;
@@ -280,8 +280,8 @@ public:
BEAST_EXPECT(m2.version == 10);
BEAST_EXPECT(m1.body == "2");
BEAST_EXPECT(m2.body == "1");
BEAST_EXPECT(! m1.fields.exists("h"));
BEAST_EXPECT(m2.fields.exists("h"));
BEAST_EXPECT(! m1.exists("h"));
BEAST_EXPECT(m2.exists("h"));
}
void

View File

@@ -133,7 +133,7 @@ public:
BEAST_EXPECT(m.version == 10);
BEAST_EXPECT(m.result() == status::ok);
BEAST_EXPECT(m.reason() == "OK");
BEAST_EXPECT(m.fields["Server"] == "test");
BEAST_EXPECT(m["Server"] == "test");
BEAST_EXPECT(m.body == "Hello, world!");
}
);
@@ -160,10 +160,10 @@ public:
BEAST_EXPECT(m.version == 11);
BEAST_EXPECT(m.result() == status::ok);
BEAST_EXPECT(m.reason() == "OK");
BEAST_EXPECT(m.fields["Server"] == "test");
BEAST_EXPECT(m.fields["Transfer-Encoding"] == "chunked");
BEAST_EXPECT(m.fields["Expires"] == "never");
BEAST_EXPECT(m.fields["MD5-Fingerprint"] == "-");
BEAST_EXPECT(m["Server"] == "test");
BEAST_EXPECT(m["Transfer-Encoding"] == "chunked");
BEAST_EXPECT(m["Expires"] == "never");
BEAST_EXPECT(m["MD5-Fingerprint"] == "-");
BEAST_EXPECT(m.body == "*****--");
}
);
@@ -202,7 +202,7 @@ public:
[&](parser_type<true> const& p)
{
auto const& m = p.get();
BEAST_EXPECT(m.fields["X"] == "x");
BEAST_EXPECT(m["X"] == "x");
}
);
@@ -226,7 +226,7 @@ public:
BEAST_EXPECT(m.method() == verb::get);
BEAST_EXPECT(m.target() == "/");
BEAST_EXPECT(m.version == 11);
BEAST_EXPECT(m.fields["User-Agent"] == "test");
BEAST_EXPECT(m["User-Agent"] == "test");
BEAST_EXPECT(m.body == "*");
}
{

View File

@@ -294,8 +294,8 @@ public:
m.version = 10;
m.result(status::ok);
m.reason("OK");
m.fields.insert("Server", "test");
m.fields.insert("Content-Length", "5");
m.insert("Server", "test");
m.insert("Content-Length", "5");
m.body = "*****";
error_code ec;
test::string_ostream ss{ios_};
@@ -313,8 +313,8 @@ public:
m.version = 11;
m.result(status::ok);
m.reason("OK");
m.fields.insert("Server", "test");
m.fields.insert("Transfer-Encoding", "chunked");
m.insert("Server", "test");
m.insert("Transfer-Encoding", "chunked");
m.body = "*****";
error_code ec;
test::string_ostream ss(ios_);
@@ -346,8 +346,8 @@ public:
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
m.fields.insert("Content-Length", "5");
m.insert("User-Agent", "test");
m.insert("Content-Length", "5");
m.body = "*****";
try
{
@@ -377,8 +377,8 @@ public:
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
m.fields.insert("Transfer-Encoding", "chunked");
m.insert("User-Agent", "test");
m.insert("Transfer-Encoding", "chunked");
m.body = "*****";
error_code ec;
write(fs, m, ec);
@@ -410,8 +410,8 @@ public:
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
m.fields.insert("Transfer-Encoding", "chunked");
m.insert("User-Agent", "test");
m.insert("Transfer-Encoding", "chunked");
m.body = "*****";
error_code ec;
async_write(fs, m, do_yield[ec]);
@@ -443,8 +443,8 @@ public:
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
m.fields.insert("Content-Length", "5");
m.insert("User-Agent", "test");
m.insert("Content-Length", "5");
m.body = "*****";
error_code ec;
write(fs, m, ec);
@@ -471,8 +471,8 @@ public:
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
m.fields.insert("Content-Length", "5");
m.insert("User-Agent", "test");
m.insert("Content-Length", "5");
m.body = "*****";
error_code ec;
async_write(fs, m, do_yield[ec]);
@@ -500,7 +500,7 @@ public:
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
m.insert("User-Agent", "test");
m.body = "*";
prepare(m);
BEAST_EXPECT(str(m) ==
@@ -517,7 +517,7 @@ public:
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
m.insert("User-Agent", "test");
m.body = "*";
prepare(m, connection::keep_alive);
BEAST_EXPECT(str(m) ==
@@ -535,7 +535,7 @@ public:
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
m.insert("User-Agent", "test");
m.body = "*";
try
{
@@ -553,7 +553,7 @@ public:
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
m.insert("User-Agent", "test");
m.body = "*";
prepare(m);
test::string_ostream ss(ios_);
@@ -573,7 +573,7 @@ public:
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
m.insert("User-Agent", "test");
m.body = "*";
prepare(m);
BEAST_EXPECT(str(m) ==
@@ -590,7 +590,7 @@ public:
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
m.insert("User-Agent", "test");
m.body = "*";
prepare(m, connection::close);
test::string_ostream ss(ios_);
@@ -612,7 +612,7 @@ public:
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
m.insert("User-Agent", "test");
prepare(m, connection::upgrade);
BEAST_EXPECT(str(m) ==
"GET / HTTP/1.1\r\n"
@@ -627,7 +627,7 @@ public:
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
m.insert("User-Agent", "test");
m.body = "*";
prepare(m);
test::string_ostream ss(ios_);
@@ -652,7 +652,7 @@ public:
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
m.insert("User-Agent", "test");
m.body = "*";
BEAST_EXPECT(boost::lexical_cast<std::string>(m) ==
"GET / HTTP/1.1\r\nUser-Agent: test\r\n\r\n*");
@@ -684,7 +684,7 @@ public:
m.method(verb::get);
m.version = 11;
m.target("/");
m.fields.insert("Content-Length", 5);
m.insert("Content-Length", 5);
m.body = "*****";
async_write(os, m, handler{});
BEAST_EXPECT(handler::count() > 0);
@@ -706,7 +706,7 @@ public:
m.method(verb::get);
m.version = 11;
m.target("/");
m.fields.insert("Content-Length", 5);
m.insert("Content-Length", 5);
m.body = "*****";
async_write(is, m, handler{});
BEAST_EXPECT(handler::count() > 0);
@@ -788,7 +788,7 @@ public:
m0.version = 11;
m0.result(status::ok);
m0.reason("OK");
m0.fields.insert("Server", "test");
m0.insert("Server", "test");
m0.body.s = "Hello, world!\n";
{
@@ -845,7 +845,7 @@ public:
}
}
{
m0.fields.insert("Transfer-Encoding", "chunked");
m0.insert("Transfer-Encoding", "chunked");
{
auto m = m0;
error_code ec;

View File

@@ -28,11 +28,11 @@ public:
req.target("/");
BEAST_EXPECT(! is_upgrade(req));
req.method(http::verb::get);
req.fields.insert("Connection", "upgrade");
req.insert("Connection", "upgrade");
BEAST_EXPECT(! is_upgrade(req));
req.fields.insert("Upgrade", "websocket");
req.insert("Upgrade", "websocket");
BEAST_EXPECT(! is_upgrade(req));
req.fields.insert("Sec-WebSocket-Version", "13");
req.insert("Sec-WebSocket-Version", "13");
BEAST_EXPECT(is_upgrade(req));
}

View File

@@ -225,7 +225,7 @@ private:
d.ws.async_accept_ex(
[](beast::websocket::response_type& res)
{
res.fields.insert(
res.insert(
"Server", "async_ssl_echo_server");
},
d.strand.wrap(std::move(*this)));

View File

@@ -707,11 +707,11 @@ public:
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
req.fields.insert("Upgrade", "websocket");
req.fields.insert("Connection", "upgrade");
req.fields.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.fields.insert("Sec-WebSocket-Version", "13");
req.insert("Host", "localhost");
req.insert("Upgrade", "websocket");
req.insert("Connection", "upgrade");
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.insert("Sec-WebSocket-Version", "13");
stream<test::fail_stream<
test::string_ostream>> ws{fc, ios_};
c.accept(ws, req);
@@ -721,11 +721,11 @@ public:
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
req.fields.insert("Upgrade", "websocket");
req.fields.insert("Connection", "upgrade");
req.fields.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.fields.insert("Sec-WebSocket-Version", "13");
req.insert("Host", "localhost");
req.insert("Upgrade", "websocket");
req.insert("Connection", "upgrade");
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.insert("Sec-WebSocket-Version", "13");
stream<test::fail_stream<
test::string_ostream>> ws{fc, ios_};
bool called = false;
@@ -739,11 +739,11 @@ public:
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
req.fields.insert("Upgrade", "websocket");
req.fields.insert("Connection", "upgrade");
req.fields.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.fields.insert("Sec-WebSocket-Version", "13");
req.insert("Host", "localhost");
req.insert("Upgrade", "websocket");
req.insert("Connection", "upgrade");
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.insert("Sec-WebSocket-Version", "13");
stream<test::fail_stream<
test::string_ostream>> ws{fc, ios_};
c.accept(ws, req,
@@ -766,11 +766,11 @@ public:
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
req.fields.insert("Upgrade", "websocket");
req.fields.insert("Connection", "upgrade");
req.fields.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.fields.insert("Sec-WebSocket-Version", "13");
req.insert("Host", "localhost");
req.insert("Upgrade", "websocket");
req.insert("Connection", "upgrade");
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.insert("Sec-WebSocket-Version", "13");
stream<test::fail_stream<
test::string_ostream>> ws{fc, ios_};
bool called = false;
@@ -797,11 +797,11 @@ public:
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
req.fields.insert("Upgrade", "websocket");
req.fields.insert("Connection", "upgrade");
req.fields.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.fields.insert("Sec-WebSocket-Version", "13");
req.insert("Host", "localhost");
req.insert("Upgrade", "websocket");
req.insert("Connection", "upgrade");
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.insert("Sec-WebSocket-Version", "13");
stream<test::fail_stream<
test::string_iostream>> ws{fc, ios_,
"\x88\x82\xff\xff\xff\xff\xfc\x17"};
@@ -825,11 +825,11 @@ public:
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
req.fields.insert("Upgrade", "websocket");
req.fields.insert("Connection", "upgrade");
req.fields.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.fields.insert("Sec-WebSocket-Version", "13");
req.insert("Host", "localhost");
req.insert("Upgrade", "websocket");
req.insert("Connection", "upgrade");
req.insert("Sec-WebSocket-Key", "dGhlIHNhbXBsZSBub25jZQ==");
req.insert("Sec-WebSocket-Version", "13");
stream<test::fail_stream<
test::string_iostream>> ws{fc, ios_,
"xff\xff\xfc\x17"};

View File

@@ -263,7 +263,7 @@ private:
d.ws.async_accept_ex(
[](beast::websocket::response_type& res)
{
res.fields.insert(
res.insert(
"Server", "async_echo_server");
},
std::move(*this));

View File

@@ -293,7 +293,7 @@ private:
ws.accept_ex(
[](beast::websocket::response_type& res)
{
res.fields.insert(
res.insert(
"Server", "sync_echo_server");
},
ec);