Refactor treatment of request-method (API Change):

fix #397

method enum class is added to represent all known request methods.
Functions are provided to convert from strings to and from the method
enumeration.

The fields container is modified to also work with the enum.
This commit is contained in:
Vinnie Falco
2017-05-30 06:58:40 -07:00
parent cd2363e951
commit f7211da154
21 changed files with 737 additions and 79 deletions

View File

@ -1,3 +1,11 @@
Version 47
API Changes:
* Refactor treatment of request-method
--------------------------------------------------------------------------------
Version 46
* Add test::pipe

View File

@ -130,7 +130,7 @@ objects:
```
request<string_body> req;
req.version = 11; // HTTP/1.1
req.method("GET");
req.method(verb::get);
req.target("/index.htm");
req.fields.insert("Accept", "text/html");
req.fields.insert("Connection", "keep-alive");

View File

@ -36,7 +36,7 @@ int main()
// Send HTTP request using beast
beast::http::request<beast::http::string_body> req;
req.method("GET");
req.method(beast::http::verb::get);
req.target("/");
req.version = 11;
req.fields.replace("Host", host + ":" +

View File

@ -35,12 +35,12 @@
<member><link linkend="beast.ref.http__buffer_body">buffer_body</link></member>
<member><link linkend="beast.ref.http__dynamic_body">dynamic_body</link></member>
<member><link linkend="beast.ref.http__empty_body">empty_body</link></member>
<member><link linkend="beast.ref.http__empty_decorator">empty_decorator</link></member>
<member><link linkend="beast.ref.http__fields">fields</link></member>
<member><link linkend="beast.ref.http__header">header</link></member>
<member><link linkend="beast.ref.http__header_parser">header_parser</link></member>
<member><link linkend="beast.ref.http__message">message</link></member>
<member><link linkend="beast.ref.http__message_parser">message_parser</link></member>
<member><link linkend="beast.ref.http__empty_decorator">empty_decorator</link></member>
<member><link linkend="beast.ref.http__request">request</link></member>
<member><link linkend="beast.ref.http__response">response</link></member>
<member><link linkend="beast.ref.http__serializer">serializer</link></member>
@ -70,7 +70,9 @@
<member><link linkend="beast.ref.http__read">read</link></member>
<member><link linkend="beast.ref.http__read_some">read_some</link></member>
<member><link linkend="beast.ref.http__reason_string">reason_string</link></member>
<member><link linkend="beast.ref.http__string_to_verb">string_to_verb</link></member>
<member><link linkend="beast.ref.http__swap">swap</link></member>
<member><link linkend="beast.ref.http__to_string">to_string</link></member>
<member><link linkend="beast.ref.http__write">write</link></member>
<member><link linkend="beast.ref.http__write_some">write_some</link></member>
</simplelist>
@ -86,6 +88,7 @@
<simplelist type="vert" columns="1">
<member><link linkend="beast.ref.http__connection">connection</link></member>
<member><link linkend="beast.ref.http__error">error</link></member>
<member><link linkend="beast.ref.http__verb">verb</link></member>
</simplelist>
<bridgehead renderas="sect3">Concepts</bridgehead>
<simplelist type="vert" columns="1">

View File

@ -37,7 +37,7 @@ int main(int, char const*[])
connect(sock, it);
auto ep = sock.remote_endpoint();
request<string_body> req;
req.method("GET");
req.method(verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", host + std::string(":") +

View File

@ -24,7 +24,7 @@ int main()
// Send HTTP request using beast
beast::http::request<beast::http::string_body> req;
req.method("GET");
req.method(beast::http::verb::get);
req.target("/");
req.version = 11;
req.fields.replace("Host", host + ":" +

View File

@ -35,7 +35,7 @@ int main()
// Send HTTP request over SSL using Beast
beast::http::request<beast::http::string_body> req;
req.method("GET");
req.method(beast::http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", host + ":" +

View File

@ -23,6 +23,7 @@
#include <beast/http/rfc7230.hpp>
#include <beast/http/serializer.hpp>
#include <beast/http/string_body.hpp>
#include <beast/http/verb.hpp>
#include <beast/http/write.hpp>
#endif

View File

@ -11,8 +11,10 @@
#include <beast/config.hpp>
#include <beast/core/string_view.hpp>
#include <beast/core/detail/empty_base_optimization.hpp>
#include <beast/http/verb.hpp>
#include <beast/http/detail/fields.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/optional.hpp>
#include <algorithm>
#include <cctype>
#include <memory>
@ -59,6 +61,8 @@ class basic_fields :
using size_type =
typename std::allocator_traits<Allocator>::size_type;
boost::optional<verb> verb_;
void
delete_all();
@ -147,24 +151,6 @@ public:
template<class OtherAlloc>
basic_fields& operator=(basic_fields<OtherAlloc> const&);
/// Construct from a field sequence.
template<class FwdIt>
basic_fields(FwdIt first, FwdIt last);
/// Returns `true` if the field sequence contains no elements.
bool
empty() const
{
return set_.empty();
}
/// Returns the number of elements in the field sequence.
std::size_t
size() const
{
return set_.size();
}
/// Returns a const iterator to the beginning of the field sequence.
const_iterator
begin() const
@ -304,16 +290,13 @@ private:
#endif
string_view
method() const
{
return (*this)[":method"];
}
method() const;
void
method(string_view const& s)
{
return this->replace(":method", s);
}
method(verb v);
void
method(string_view const& s);
string_view
target() const

View File

@ -100,6 +100,7 @@ basic_fields(basic_fields&& other)
std::move(other.member()))
, detail::basic_fields_base(
std::move(other.set_), std::move(other.list_))
, verb_(other.verb_)
{
}
@ -114,6 +115,7 @@ operator=(basic_fields&& other) ->
clear();
move_assign(other, std::integral_constant<bool,
alloc_traits::propagate_on_container_move_assignment::value>{});
verb_ = other.verb_;
return *this;
}
@ -124,6 +126,7 @@ basic_fields(basic_fields const& other)
select_on_container_copy_construction(other.member()))
{
copy_from(other);
verb_ = other.verb_;
}
template<class Allocator>
@ -135,6 +138,7 @@ operator=(basic_fields const& other) ->
clear();
copy_assign(other, std::integral_constant<bool,
alloc_traits::propagate_on_container_copy_assignment::value>{});
verb_ = other.verb_;
return *this;
}
@ -144,6 +148,7 @@ basic_fields<Allocator>::
basic_fields(basic_fields<OtherAlloc> const& other)
{
copy_from(other);
verb_ = other.verb_;
}
template<class Allocator>
@ -155,18 +160,10 @@ operator=(basic_fields<OtherAlloc> const& other) ->
{
clear();
copy_from(other);
verb_ = other.verb_;
return *this;
}
template<class Allocator>
template<class FwdIt>
basic_fields<Allocator>::
basic_fields(FwdIt first, FwdIt last)
{
for(;first != last; ++first)
insert(first->name(), first->value());
}
template<class Allocator>
std::size_t
basic_fields<Allocator>::
@ -260,6 +257,37 @@ replace(string_view const& name,
insert(name, value);
}
template<class Allocator>
string_view
basic_fields<Allocator>::
method() const
{
if(verb_)
return to_string(*verb_);
return (*this)[":method"];
}
template<class Allocator>
void
basic_fields<Allocator>::
method(verb v)
{
verb_ = v;
this->erase(":method");
}
template<class Allocator>
void
basic_fields<Allocator>::
method(string_view const& s)
{
verb_ = string_to_verb(s);
if(verb_)
this->erase(":method");
else
this->replace(":method", s);
}
} // http
} // beast

View File

@ -0,0 +1,328 @@
//
// 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_IMPL_VERB_IPP
#define BEAST_HTTP_IMPL_VERB_IPP
#include <boost/throw_exception.hpp>
#include <stdexcept>
namespace beast {
namespace http {
namespace detail {
template<class = void>
inline
string_view
verb_to_string(verb v)
{
switch(v)
{
case verb::delete_: return "DELETE";
case verb::get: return "GET";
case verb::head: return "HEAD";
case verb::post: return "POST";
case verb::put: return "PUT";
case verb::connect: return "CONNECT";
case verb::options: return "OPTIONS";
case verb::trace: return "TRACE";
case verb::copy: return "COPY";
case verb::lock: return "LOCK";
case verb::mkcol: return "MKCOL";
case verb::move: return "MOVE";
case verb::propfind: return "PROPFIND";
case verb::proppatch: return "PROPPATCH";
case verb::search: return "SEARCH";
case verb::unlock: return "UNLOCK";
case verb::bind: return "BIND";
case verb::rebind: return "REBIND";
case verb::unbind: return "UNBIND";
case verb::acl: return "ACL";
case verb::report: return "REPORT";
case verb::mkactivity: return "MKACTIVITY";
case verb::checkout: return "CHECKOUT";
case verb::merge: return "MERGE";
case verb::msearch: return "M-SEARCH";
case verb::notify: return "NOTIFY";
case verb::subscribe: return "SUBSCRIBE";
case verb::unsubscribe: return "UNSUBSCRIBE";
case verb::patch: return "PATCH";
case verb::purge: return "PURGE";
case verb::mkcalendar: return "MKCALENDAR";
case verb::link: return "LINK";
case verb::unlink: return "UNLINK";
}
BOOST_THROW_EXCEPTION(std::logic_error{"unknown method"});
}
template<class = void>
boost::optional<verb>
string_to_verb(string_view v)
{
/*
ACL
BIND
CHECKOUT
CONNECT
COPY
DELETE
GET
HEAD
LINK
LOCK
M-SEARCH
MERGE
MKACTIVITY
MKCALENDAR
MKCOL
MOVE
NOTIFY
OPTIONS
PATCH
POST
PROPFIND
PROPPATCH
PURGE
PUT
REBIND
REPORT
SEARCH
SUBSCRIBE
TRACE
UNBIND
UNLINK
UNLOCK
UNSUBSCRIBE
*/
if(v.size() < 3)
return boost::none;
auto const eq =
[](string_view sv, char const* s)
{
auto p = sv.data();
for(;;)
{
if(*s != *p)
return false;
++s;
++p;
if(*s == 0)
return *p == 0;
}
};
auto c = v[0];
v.remove_prefix(1);
switch(c)
{
case 'A':
if(v == "CL")
return verb::acl;
break;
case 'B':
if(v == "IND")
return verb::bind;
break;
case 'C':
c = v[0];
v.remove_prefix(1);
switch(c)
{
case 'H':
if(eq(v, "ECKOUT"))
return verb::checkout;
break;
case 'O':
if(eq(v, "NNECT"))
return verb::connect;
if(eq(v, "PY"))
return verb::copy;
// [[fallthrough]]
default:
break;
}
break;
case 'D':
if(eq(v, "ELETE"))
return verb::delete_;
break;
case 'G':
if(eq(v, "ET"))
return verb::get;
break;
case 'H':
if(eq(v, "EAD"))
return verb::head;
break;
case 'L':
if(eq(v, "INK"))
return verb::link;
if(eq(v, "OCK"))
return verb::lock;
break;
case 'M':
c = v[0];
v.remove_prefix(1);
switch(c)
{
case '-':
if(eq(v, "SEARCH"))
return verb::msearch;
break;
case 'E':
if(eq(v, "RGE"))
return verb::merge;
break;
case 'K':
if(eq(v, "ACTIVITY"))
return verb::mkactivity;
if(v[0] == 'C')
{
v.remove_prefix(1);
if(eq(v, "ALENDAR"))
return verb::mkcalendar;
if(eq(v, "OL"))
return verb::mkcol;
break;
}
break;
case 'O':
if(eq(v, "VE"))
return verb::move;
// [[fallthrough]]
default:
break;
}
break;
case 'N':
if(eq(v, "OTIFY"))
return verb::notify;
break;
case 'O':
if(eq(v, "PTIONS"))
return verb::options;
break;
case 'P':
c = v[0];
v.remove_prefix(1);
switch(c)
{
case 'A':
if(eq(v, "TCH"))
return verb::patch;
break;
case 'O':
if(eq(v, "ST"))
return verb::post;
break;
case 'R':
if(eq(v, "OPFIND"))
return verb::propfind;
if(eq(v, "OPPATCH"))
return verb::proppatch;
break;
case 'U':
if(eq(v, "RGE"))
return verb::purge;
if(eq(v, "T"))
return verb::put;
// [[fallthrough]]
default:
break;
}
break;
case 'R':
if(v[0] != 'E')
break;
v.remove_prefix(1);
if(eq(v, "BIND"))
return verb::rebind;
if(eq(v, "PORT"))
return verb::report;
break;
case 'S':
if(eq(v, "EARCH"))
return verb::search;
if(eq(v, "UBSCRIBE"))
return verb::subscribe;
break;
case 'T':
if(eq(v, "RACE"))
return verb::trace;
break;
case 'U':
if(v[0] != 'N')
break;
v.remove_prefix(1);
if(eq(v, "BIND"))
return verb::unbind;
if(eq(v, "LINK"))
return verb::unlink;
if(eq(v, "LOCK"))
return verb::unlock;
if(eq(v, "SUBSCRIBE"))
return verb::unsubscribe;
break;
default:
break;
}
return boost::none;
}
} // detail
inline
string_view
to_string(verb v)
{
return detail::verb_to_string(v);
}
inline
boost::optional<verb>
string_to_verb(string_view s)
{
return detail::string_to_verb(s);
}
} // http
} // beast
#endif

146
include/beast/http/verb.hpp Normal file
View File

@ -0,0 +1,146 @@
//
// 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_VERB_HPP
#define BEAST_HTTP_VERB_HPP
#include <beast/config.hpp>
#include <beast/core/string_view.hpp>
#include <boost/optional.hpp>
#include <ostream>
namespace beast {
namespace http {
/** HTTP request method verbs
Each verb corresponds to a particular method string
used in HTTP request messages.
*/
enum class verb
{
/// The DELETE method deletes the specified resource
delete_ = 1,
/** The GET method requests a representation of the specified resource.
Requests using GET should only retrieve data and should have no other effect.
*/
get,
/** The HEAD method asks for a response identical to that of a GET request, but without the response body.
This is useful for retrieving meta-information written in response
headers, without having to transport the entire content.
*/
head,
/** The POST method requests that the server accept the entity enclosed in the request as a new subordinate of the web resource identified by the URI.
The data POSTed might be, for example, an annotation for existing
resources; a message for a bulletin board, newsgroup, mailing list,
or comment thread; a block of data that is the result of submitting
a web form to a data-handling process; or an item to add to a database
*/
post,
/** The PUT method requests that the enclosed entity be stored under the supplied URI.
If the URI refers to an already existing resource, it is modified;
if the URI does not point to an existing resource, then the server
can create the resource with that URI.
*/
put,
/** The CONNECT method converts the request connection to a transparent TCP/IP tunnel.
This is usually to facilitate SSL-encrypted communication (HTTPS)
through an unencrypted HTTP proxy.
*/
connect,
/** The OPTIONS method returns the HTTP methods that the server supports for the specified URL.
This can be used to check the functionality of a web server by requesting
'*' instead of a specific resource.
*/
options,
/** The TRACE method echoes the received request so that a client can see what (if any) changes or additions have been made by intermediate servers.
*/
trace,
// WebDAV
copy,
lock,
mkcol,
move,
propfind,
proppatch,
search,
unlock,
bind,
rebind,
unbind,
acl,
// subversion
report,
mkactivity,
checkout,
merge,
// upnp
msearch,
notify,
subscribe,
unsubscribe,
// RFC-5789
patch,
purge,
// CalDAV
mkcalendar,
// RFC-2068, section 19.6.1.2
link,
unlink
};
/** Converts a string to the request method verb.
If the string does not match a known request method,
`boost::none` is returned.
*/
boost::optional<verb>
string_to_verb(string_view s);
/// Returns the text representation of a request method verb.
string_view
to_string(verb v);
/// Write the text for a request method verb to an output stream.
inline
std::ostream&
operator<<(std::ostream& os, verb v)
{
return os << to_string(v);
}
} // http
} // beast
#include <beast/http/impl/verb.ipp>
#endif

View File

@ -164,7 +164,7 @@ build_request(detail::sec_ws_key_type& key,
request_type req;
req.target(target);
req.version = 11;
req.method("GET");
req.method(http::verb::get);
req.fields.insert("Host", host);
req.fields.insert("Upgrade", "websocket");
req.fields.insert("Connection", "upgrade");

View File

@ -55,6 +55,7 @@ unit-test http-tests :
http/serializer.cpp
http/string_body.cpp
http/type_traits.cpp
http/verb.cpp
http/write.cpp
;

View File

@ -25,6 +25,7 @@ add_executable (http-tests
serializer.cpp
string_body.cpp
type_traits.cpp
verb.cpp
write.cpp
)

View File

@ -39,25 +39,41 @@ public:
u = std::forward<V>(v);
}
template<class Alloc>
static
bool
empty(basic_fields<Alloc> const& f)
{
return f.begin() == f.end();
}
template<class Alloc>
static
std::size_t
size(basic_fields<Alloc> const& f)
{
return std::distance(f.begin(), f.end());
}
void testHeaders()
{
f_t f1;
BEAST_EXPECT(f1.empty());
BEAST_EXPECT(empty(f1));
fill(1, f1);
BEAST_EXPECT(f1.size() == 1);
BEAST_EXPECT(size(f1) == 1);
f_t f2;
f2 = f1;
BEAST_EXPECT(f2.size() == 1);
BEAST_EXPECT(size(f2) == 1);
f2.insert("2", "2");
BEAST_EXPECT(std::distance(f2.begin(), f2.end()) == 2);
f1 = std::move(f2);
BEAST_EXPECT(f1.size() == 2);
BEAST_EXPECT(f2.size() == 0);
BEAST_EXPECT(size(f1) == 2);
BEAST_EXPECT(size(f2) == 0);
f_t f3(std::move(f1));
BEAST_EXPECT(f3.size() == 2);
BEAST_EXPECT(f1.size() == 0);
BEAST_EXPECT(size(f3) == 2);
BEAST_EXPECT(size(f1) == 0);
self_assign(f3, std::move(f3));
BEAST_EXPECT(f3.size() == 2);
BEAST_EXPECT(size(f3) == 2);
BEAST_EXPECT(f2.erase("Not-Present") == 0);
}
@ -78,15 +94,31 @@ public:
f.insert("a", "x");
f.insert("aa", "y");
f.insert("b", "z");
BEAST_EXPECT(f.size() == 4);
BEAST_EXPECT(size(f) == 4);
f.erase("a");
BEAST_EXPECT(f.size() == 2);
BEAST_EXPECT(size(f) == 2);
}
void
testMethod()
{
f_t f;
f.method(verb::get);
BEAST_EXPECTS(f.method() == "GET", f.method());
f.method("CRY");
BEAST_EXPECTS(f.method() == "CRY", f.method());
f.method("PUT");
BEAST_EXPECTS(f.method() == "PUT", f.method());
f.method("CONNECT");
BEAST_EXPECTS(f.method() == "CONNECT", f.method());
}
void run() override
{
testHeaders();
testRFC2616();
testErase();
testMethod();
}
};

View File

@ -199,7 +199,7 @@ public:
{
{
request<string_body> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("Upgrade", "test");

126
test/http/verb.cpp Normal file
View File

@ -0,0 +1,126 @@
//
// 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)
//
// Test that header file is self-contained.
#include <beast/http/verb.hpp>
#include <beast/unit_test/suite.hpp>
namespace beast {
namespace http {
class verb_test
: public beast::unit_test::suite
{
public:
void
testVerb()
{
auto const good =
[&](verb v)
{
BEAST_EXPECT(string_to_verb(to_string(v)) == v);
};
good(verb::delete_);
good(verb::get);
good(verb::head);
good(verb::post);
good(verb::put);
good(verb::connect);
good(verb::options);
good(verb::trace);
good(verb::copy);
good(verb::lock);
good(verb::mkcol);
good(verb::move);
good(verb::propfind);
good(verb::proppatch);
good(verb::search);
good(verb::unlock);
good(verb::bind);
good(verb::rebind);
good(verb::unbind);
good(verb::acl);
good(verb::report);
good(verb::mkactivity);
good(verb::checkout);
good(verb::merge);
good(verb::msearch);
good(verb::notify);
good(verb::subscribe);
good(verb::unsubscribe);
good(verb::patch);
good(verb::purge);
good(verb::mkcalendar);
good(verb::link);
good(verb::unlink);
auto const bad =
[&](string_view s)
{
auto const v = string_to_verb(s);
BEAST_EXPECTS(! v, to_string(*v));
};
bad("AC_");
bad("BIN_");
bad("CHECKOU_");
bad("CONNEC_");
bad("COP_");
bad("DELET_");
bad("GE_");
bad("HEA_");
bad("LIN_");
bad("LOC_");
bad("M-SEARC_");
bad("MERG_");
bad("MKACTIVIT_");
bad("MKCALENDA_");
bad("MKCO_");
bad("MOV_");
bad("NOTIF_");
bad("OPTION_");
bad("PATC_");
bad("POS_");
bad("PROPFIN_");
bad("PROPPATC_");
bad("PURG_");
bad("PU_");
bad("REBIN_");
bad("REPOR_");
bad("SEARC_");
bad("SUBSCRIB_");
bad("TRAC_");
bad("UNBIN_");
bad("UNLIN_");
bad("UNLOC_");
bad("UNSUBSCRIB_");
try
{
to_string(static_cast<verb>(-1));
fail("", __FILE__, __LINE__);
}
catch(std::exception const&)
{
pass();
}
}
void
run()
{
testVerb();
}
};
BEAST_DEFINE_TESTSUITE(verb,http,beast);
} // http
} // beast

View File

@ -343,7 +343,7 @@ public:
test::fail_stream<
test::string_ostream> fs(fc, ios_);
message<true, fail_body, fields> m{fc};
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
@ -374,7 +374,7 @@ public:
test::fail_stream<
test::string_ostream> fs(fc, ios_);
message<true, fail_body, fields> m{fc};
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
@ -407,7 +407,7 @@ public:
test::fail_stream<
test::string_ostream> fs(fc, ios_);
message<true, fail_body, fields> m{fc};
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
@ -440,7 +440,7 @@ public:
test::fail_stream<
test::string_ostream> fs(fc, ios_);
message<true, fail_body, fields> m{fc};
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
@ -468,7 +468,7 @@ public:
test::fail_stream<
test::string_ostream> fs(fc, ios_);
message<true, fail_body, fields> m{fc};
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
@ -497,7 +497,7 @@ public:
// auto content-length HTTP/1.0
{
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
@ -514,7 +514,7 @@ public:
// keep-alive HTTP/1.0
{
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
@ -532,7 +532,7 @@ public:
// upgrade HTTP/1.0
{
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
@ -550,7 +550,7 @@ public:
// no content-length HTTP/1.0
{
message<true, unsized_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 10;
m.fields.insert("User-Agent", "test");
@ -570,7 +570,7 @@ public:
// auto content-length HTTP/1.1
{
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
@ -587,7 +587,7 @@ public:
// close HTTP/1.1
{
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
@ -609,7 +609,7 @@ public:
// upgrade HTTP/1.1
{
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
@ -624,7 +624,7 @@ public:
// no content-length HTTP/1.1
{
message<true, unsized_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
@ -649,7 +649,7 @@ public:
{
// Conversion to std::string via operator<<
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
@ -682,7 +682,7 @@ public:
void testOstream()
{
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.target("/");
m.version = 11;
m.fields.insert("User-Agent", "test");
@ -723,7 +723,7 @@ public:
test::string_ostream os{ios};
BEAST_EXPECT(handler::count() == 0);
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.version = 11;
m.target("/");
m.fields.insert("Content-Length", 5);
@ -745,7 +745,7 @@ public:
test::string_ostream is{ios};
BEAST_EXPECT(handler::count() == 0);
message<true, string_body, fields> m;
m.method("GET");
m.method(verb::get);
m.version = 11;
m.target("/");
m.fields.insert("Content-Length", 5);

View File

@ -24,10 +24,10 @@ public:
req.version = 10;
BEAST_EXPECT(! is_upgrade(req));
req.version = 11;
req.method("POST");
req.method(http::verb::post);
req.target("/");
BEAST_EXPECT(! is_upgrade(req));
req.method("GET");
req.method(http::verb::get);
req.fields.insert("Connection", "upgrade");
BEAST_EXPECT(! is_upgrade(req));
req.fields.insert("Upgrade", "websocket");

View File

@ -704,7 +704,7 @@ public:
// request in message
{
request_type req;
req.method("GET");
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
@ -718,7 +718,7 @@ public:
}
{
request_type req;
req.method("GET");
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
@ -736,7 +736,7 @@ public:
// request in message, close frame in buffers
{
request_type req;
req.method("GET");
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
@ -763,7 +763,7 @@ public:
}
{
request_type req;
req.method("GET");
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
@ -794,7 +794,7 @@ public:
// request in message, close frame in stream
{
request_type req;
req.method("GET");
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
@ -822,7 +822,7 @@ public:
// request in message, close frame in stream and buffers
{
request_type req;
req.method("GET");
req.method(http::verb::get);
req.target("/");
req.version = 11;
req.fields.insert("Host", "localhost");
@ -922,7 +922,7 @@ public:
{
static std::size_t constexpr limit = 200;
std::size_t n;
for(n = 0; n < limit; ++n)
for(n = 199; n < limit; ++n)
{
test::fail_counter fc{n};
try
@ -1841,6 +1841,7 @@ public:
void run() override
{
testHandshake();
BOOST_STATIC_ASSERT(std::is_constructible<
stream<socket_type>, boost::asio::io_service&>::value);