mirror of
https://github.com/boostorg/beast.git
synced 2025-08-03 14:54:32 +02:00
Tidy up basic_fields, header, and concepts
This commit is contained in:
@@ -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:
|
||||
|
||||
|
@@ -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();
|
||||
|
||||
|
||||
]
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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(
|
||||
|
@@ -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_;
|
||||
};
|
||||
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user