Tidy up basic_fields, header, and concepts

This commit is contained in:
Vinnie Falco
2017-06-06 16:20:59 -07:00
parent fb2f777b4d
commit f363654300
7 changed files with 253 additions and 167 deletions

View File

@@ -5,6 +5,8 @@ Version 50
* Use allocator more in basic_fields
* Fix basic_fields allocator awareness
* Use field in basic_fields and call sites
* Use field in basic_parser
* Tidy up basic_fields, header, and field concepts
API Changes:

View File

@@ -64,39 +64,70 @@ In this table:
[/
/** OutputFields
[section:Fields Fields]
Can be serialized by `beast::http::serializer`
*/
public:
// This algorithm produces a set of buffers
// corresponding to the serialized representation
// of the fields
//
struct reader
{
using const_buffers_type = implementation-defined
A type meeting the requirements of [*Fields] represents a container
used to store HTTP header fields.
...
};
In this table:
protected:
string_view method_impl() const;
string_view target_impl() const;
string_view reason_impl() const;
* `X` denotes a type that meets the requirements of [*Fields].
* `c` is a value of type `X const`.
bool close_impl () const;
bool chunked_impl () const;
bool content_length_impl () const;
[table FieldSequence requirements
[[expression][type][semantics, pre/post-conditions]]
[
[]
[]
[
]
]
]
[endsect]
/** InputFields
Operations we'd like to perform
Can be parsed by `beast::http::parser`
*/
public:
void insert (field f, string_view value);
void insert (string_view name, string_view value);
Determine if a field exists
bool exists(field f) const;
bool exists(string_view s) const;
iterator find(field f) const;
iterator find(string_view s);
protected:
void method_impl (string_view s);
void target_impl (string_view s);
void reason_impl (string_view s);
/** Fields
Has a container interface and supports input and output.
`beast::http:basic_fields` is a model.
*/
public:
bool exists(field f) const;
bool exists(string_view s) const;
iterator find(field f) const;
iterator find(string_view s);
std::size_t erase (field f);
std::size_t erase (string_view s);
iterator erase (iterator);
protected:
void content_length_impl(std::uint64_t n);
void connection_impl(close_t);
void connection_impl(keep_alive_t);
void connection_impl(upgrade_t);
void chunked_impl();
]

View File

@@ -338,45 +338,57 @@ public:
swap(basic_fields<Alloc>& lhs, basic_fields<Alloc>& rhs);
protected:
//--------------------------------------------------------------------------
//
// for `header
// for serializing
//
/** Returns the stored request-method string.
@note This is called by the @ref header implementation.
*/
string_view method_impl() const;
string_view get_method_impl() const;
/** Returns the stored request-target string.
@note This is called by the @ref header implementation.
*/
string_view target_impl() const;
string_view get_target_impl() const;
/** Returns the stored obsolete reason-phrase string.
@note This is called by the @ref header implementation.
*/
string_view reason_impl() const;
string_view get_reason_impl() const;
//--------------------------------------------------------------------------
//
// for parsing
//
/** Set or clear the stored request-method string.
@note This is called by the @ref header implementation.
*/
void method_impl(string_view s);
void set_method_impl(string_view s);
/** Set or clear the stored request-target string.
@note This is called by the @ref header implementation.
*/
void target_impl(string_view s);
void set_target_impl(string_view s);
/** Set or clear the stored obsolete reason-phrase string.
@note This is called by the @ref header implementation.
*/
void reason_impl(string_view s);
void set_reason_impl(string_view s);
//--------------------------------------------------------------------------
//
// for container
//
/** Set the Content-Length field to the specified value.

View File

@@ -365,7 +365,7 @@ template<class Allocator>
inline
string_view
basic_fields<Allocator>::
method_impl() const
get_method_impl() const
{
return method_;
}
@@ -374,7 +374,7 @@ template<class Allocator>
inline
string_view
basic_fields<Allocator>::
target_impl() const
get_target_impl() const
{
return target_or_reason_;
}
@@ -383,7 +383,7 @@ template<class Allocator>
inline
string_view
basic_fields<Allocator>::
reason_impl() const
get_reason_impl() const
{
return target_or_reason_;
}
@@ -392,7 +392,7 @@ template<class Allocator>
inline
void
basic_fields<Allocator>::
method_impl(string_view s)
set_method_impl(string_view s)
{
realloc_string(method_, s);
}
@@ -401,7 +401,7 @@ template<class Allocator>
inline
void
basic_fields<Allocator>::
target_impl(string_view s)
set_target_impl(string_view s)
{
realloc_string(target_or_reason_, s);
}
@@ -410,11 +410,13 @@ template<class Allocator>
inline
void
basic_fields<Allocator>::
reason_impl(string_view s)
set_reason_impl(string_view s)
{
realloc_string(target_or_reason_, s);
}
//---
template<class Allocator>
inline
void

View File

@@ -19,60 +19,176 @@ namespace beast {
namespace http {
template<class Fields>
template<class>
string_view
template<class Arg1, class... ArgN, class>
header<true, Fields>::
get_method_string() const
header(Arg1&& arg1, ArgN&&... argn)
: Fields(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
if(method_ != verb::unknown)
return to_string(method_);
return this->method_impl();
}
template<class Fields>
template<class>
inline
verb
header<true, Fields>::
method() const
{
return method_;
}
template<class Fields>
void
header<true, Fields>::
set_method(verb v)
method(verb v)
{
if(v == verb::unknown)
BOOST_THROW_EXCEPTION(
std::invalid_argument{"unknown verb"});
method_ = v;
this->method_impl({});
this->set_method_impl({});
}
template<class Fields>
string_view
header<true, Fields>::
method_string() const
{
if(method_ != verb::unknown)
return to_string(method_);
return this->get_method_impl();
}
template<class Fields>
template<class>
void
header<true, Fields>::
set_method(string_view s)
method(string_view s)
{
method_ = string_to_verb(s);
if(method_ != verb::unknown)
this->method_impl({});
this->set_method_impl({});
else
this->method_impl(s);
this->set_method_impl(s);
}
template<class Fields>
inline
string_view
header<true, Fields>::
target() const
{
return this->get_target_impl();
}
template<class Fields>
inline
void
header<true, Fields>::
target(string_view s)
{
this->set_target_impl(s);
}
template<class Fields>
void
swap(
header<true, Fields>& h1,
header<true, Fields>& h2)
{
using std::swap;
swap(
static_cast<Fields&>(h1),
static_cast<Fields&>(h2));
swap(h1.version, h2.version);
swap(h1.method_, h2.method_);
}
//------------------------------------------------------------------------------
template<class Fields>
template<class Arg1, class... ArgN, class>
header<false, Fields>::
header(Arg1&& arg1, ArgN&&... argn)
: Fields(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
}
template<class Fields>
inline
status
header<false, Fields>::
result() const
{
return int_to_status(
static_cast<int>(result_));
}
template<class Fields>
inline
void
header<false, Fields>::
result(status v)
{
result_ = v;
}
template<class Fields>
inline
void
header<false, Fields>::
result(unsigned v)
{
if(v > 999)
BOOST_THROW_EXCEPTION(
std::invalid_argument{
"invalid result-code"});
result_ = static_cast<status>(v);
}
template<class Fields>
inline
unsigned
header<false, Fields>::
result_int() const
{
return static_cast<unsigned>(result_);
}
template<class Fields>
template<class>
string_view
header<false, Fields>::
get_reason() const
reason() const
{
auto const s = this->reason_impl();
auto const s = this->get_reason_impl();
if(! s.empty())
return s;
return obsolete_reason(result_);
}
template<class Fields>
inline
void
header<false, Fields>::
reason(string_view s)
{
this->set_reason_impl(s);
}
template<class Fields>
void
swap(
header<false, Fields>& h1,
header<false, Fields>& h2)
{
using std::swap;
swap(
static_cast<Fields&>(h1),
static_cast<Fields&>(h2));
swap(h1.version, h2.version);
swap(h1.result_, h2.result_);
}
//------------------------------------------------------------------------------
namespace detail {
} // detail
template<bool isRequest, class Body, class Fields>
bool
message<isRequest, Body, Fields>::
@@ -239,34 +355,6 @@ prepare_payload(std::false_type)
//------------------------------------------------------------------------------
template<class Fields>
void
swap(
header<true, Fields>& h1,
header<true, Fields>& h2)
{
using std::swap;
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>& h1,
header<false, Fields>& h2)
{
using std::swap;
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>
void
swap(

View File

@@ -104,11 +104,7 @@ struct header<true, Fields> : Fields
typename std::decay<Arg1>::type,
header>::value>::type>
explicit
header(Arg1&& arg1, ArgN&&... argn)
: Fields(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
}
header(Arg1&& arg1, ArgN&&... argn);
/** Return the request-method verb.
@@ -121,10 +117,7 @@ struct header<true, Fields> : Fields
@see @ref method_string
*/
verb
method() const
{
return method_;
}
method() const;
/** Set the request-method verb.
@@ -136,10 +129,7 @@ struct header<true, Fields> : Fields
@throw std::invalid_argument when `v == verb::unknown`.
*/
void
method(verb v)
{
set_method(v);
}
method(verb v);
/** Return the request-method string.
@@ -148,10 +138,7 @@ struct header<true, Fields> : Fields
@see @ref method
*/
string_view
method_string() const
{
return get_method_string();
}
method_string() const;
/** Set the request-method string.
@@ -164,20 +151,14 @@ struct header<true, Fields> : Fields
@note This function is only available when `isRequest == true`.
*/
void
method(string_view s)
{
set_method(s);
}
method(string_view s);
/** Returns the request-target string.
@note This function is only available when `isRequest == true`.
*/
string_view
target() const
{
return this->target_impl();
}
target() const;
/** Set the request-target string.
@@ -186,10 +167,7 @@ struct header<true, Fields> : Fields
@note This function is only available when `isRequest == true`.
*/
void
target(string_view s)
{
this->target_impl(s);
}
target(string_view s);
private:
template<bool, class, class>
@@ -200,18 +178,6 @@ private:
void
swap(header<true, T>& m1, header<true, T>& m2);
template<class = void>
string_view
get_method_string() const;
template<class = void>
void
set_method(verb v);
template<class = void>
void
set_method(string_view v);
verb method_ = verb::unknown;
};
@@ -277,11 +243,7 @@ struct header<false, Fields> : Fields
typename std::decay<Arg1>::type,
header>::value>::type>
explicit
header(Arg1&& arg1, ArgN&&... argn)
: Fields(std::forward<Arg1>(arg1),
std::forward<ArgN>(argn)...)
{
}
header(Arg1&& arg1, ArgN&&... argn);
#endif
/** The response status-code result.
@@ -293,25 +255,18 @@ struct header<false, Fields> : Fields
@note This member is only available when `isRequest == false`.
*/
status
result() const
{
return int_to_status(
static_cast<int>(result_));
}
result() const;
/** Set the response status-code result.
/** Set the response status-code.
@param v The code to set.
@note This member is only available when `isRequest == false`.
*/
void
result(status v)
{
result_ = v;
}
result(status v);
/** Set the raw status-code result as an integer.
/** Set the response status-code as an integer.
This sets the status code to the exact number passed in.
If the number does not correspond to one of the known
@@ -320,26 +275,21 @@ struct header<false, Fields> : Fields
original raw status-code.
@param v The status-code integer to set.
@throw std::invalid_argument if `v > 999`.
*/
void
result(int v)
{
result_ = static_cast<status>(v);
}
result(unsigned v);
/** The response status-code result expressed as an integer.
/** The response status-code expressed as an integer.
This returns the raw status code as an integer, even
when that code is not in the list of known status codes.
@note This member is only available when `isRequest == false`.
*/
int
result_int() const
{
return static_cast<int>(result_);
}
unsigned
result_int() const;
/** Return the response reason-phrase.
@@ -348,10 +298,7 @@ struct header<false, Fields> : Fields
@note This function is only available when `isRequest == false`.
*/
string_view
reason() const
{
return get_reason();
}
reason() const;
/** Set the response reason-phrase (deprecated)
@@ -372,10 +319,7 @@ struct header<false, Fields> : Fields
@note This function is only available when `isRequest == false`.
*/
void
reason(string_view s)
{
this->reason_impl(s);
}
reason(string_view s);
private:
template<bool, class, class>
@@ -386,10 +330,6 @@ private:
void
swap(header<false, T>& m1, header<false, T>& m2);
template<class = void>
string_view
get_reason() const;
status result_;
};

View File

@@ -208,11 +208,22 @@ private:
string_view value, error_code&)
{
if(f != field::unknown)
// VFALCO Note we are not preserving the
// capitalization of the field name.
{
#if 1
// This preserves capitalization of field names
if(to_string(f) == name)
m_.insert(f, value);
else
m_.insert(name, value);
#else
// This doesn't.
m_.insert(f, value);
#endif
}
else
{
m_.insert(name, value);
}
}
void