Refactor http::header contents (API Change):

fix #124

The http::header data members "method", "url", and "reason"
are changed from data members, to pairs of get and set
functions which forward the call to the Fields type used
to instantiate the template.

Previously, these data members were implemented using
std::string. With this change, the implementation of the
Fields type used to instantiate the template is now in
control of the representation of those values. This permits
custom memory allocation strategies including uniform use of
the Allocator type already provided to beast::http::basic_fields.
This commit is contained in:
Vinnie Falco committed 2017-05-07 13:40:04 -07:00
1 parent dd02097d26
commit ff5e659545
30 files changed
+319 -213

No files matched your search

+1 -1
View File
@@ -94,7 +94,7 @@ enum class parse_state
void
on_request(
boost::string_ref const& method,
boost::string_ref const& path,
boost::string_ref const& target,
int version,
error_code& ec);
+1 -1
View File
@@ -285,7 +285,7 @@ protected:
static
boost::string_ref
parse_path(char const*& it)
parse_target(char const*& it)
{
auto const first = it;
while(is_pathchar(*it))
+41
View File
@@ -12,6 +12,7 @@
#include <beast/core/detail/empty_base_optimization.hpp>
#include <beast/http/detail/fields.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/utility/string_ref.hpp>
#include <algorithm>
#include <cctype>
#include <memory>
@@ -297,6 +298,46 @@ public:
replace(name,
boost::lexical_cast<std::string>(value));
}
#if BEAST_DOXYGEN
private:
#endif
boost::string_ref
method() const
{
return (*this)[":method"];
}
void
method(boost::string_ref const& s)
{
return this->replace(":method", s);
}
boost::string_ref
target() const
{
return (*this)[":target"];
}
void
target(boost::string_ref const& s)
{
return this->replace(":target", s);
}
boost::string_ref
reason() const
{
return (*this)[":reason"];
}
void
reason(boost::string_ref const& s)
{
return this->replace(":reason", s);
}
};
/// A typical HTTP header fields container
+3 -6
View File
@@ -112,10 +112,8 @@ private:
boost::string_ref const& path,
int version, error_code&)
{
h_.url = std::string{
path.data(), path.size()};
h_.method = std::string{
method.data(), method.size()};
h_.target(path);
h_.method(method);
h_.version = version;
}
@@ -125,9 +123,8 @@ private:
int version, error_code&)
{
h_.status = status;
h_.reason = std::string{
reason.data(), reason.size()};
h_.version = version;
h_.reason(reason);
}
void
+3 -3
View File
@@ -396,8 +396,8 @@ parse_startline(char const*& it,
return;
}
auto const path = parse_path(it);
if(path.empty())
auto const target = parse_target(it);
if(target.empty())
{
ec = error::bad_path;
return;
@@ -416,7 +416,7 @@ parse_startline(char const*& it,
}
impl().on_request(
method, path, version, ec);
method, target, version, ec);
if(ec)
return;
}
+1 -4
View File
@@ -28,8 +28,6 @@ swap(
{
using std::swap;
swap(m1.version, m2.version);
swap(m1.method, m2.method);
swap(m1.url, m2.url);
swap(m1.fields, m2.fields);
}
@@ -42,7 +40,6 @@ swap(
using std::swap;
swap(a.version, b.version);
swap(a.status, b.status);
swap(a.reason, b.reason);
swap(a.fields, b.fields);
}
@@ -199,7 +196,7 @@ prepare(message<isRequest, Body, Fields>& msg,
{
using beast::detail::ci_equal;
if(*pi.content_length > 0 ||
ci_equal(msg.method, "POST"))
ci_equal(msg.method(), "POST"))
{
msg.fields.insert(
"Content-Length", *pi.content_length);
+7 -3
View File
@@ -37,9 +37,9 @@ write_start_line(DynamicBuffer& dynabuf,
header<true, Fields> const& msg)
{
BOOST_ASSERT(msg.version == 10 || msg.version == 11);
write(dynabuf, msg.method);
write(dynabuf, msg.method());
write(dynabuf, " ");
write(dynabuf, msg.url);
write(dynabuf, msg.target());
switch(msg.version)
{
case 10:
@@ -68,7 +68,7 @@ write_start_line(DynamicBuffer& dynabuf,
}
write(dynabuf, msg.status);
write(dynabuf, " ");
write(dynabuf, msg.reason);
write(dynabuf, msg.reason());
write(dynabuf, "\r\n");
}
@@ -82,6 +82,10 @@ write_fields(DynamicBuffer& dynabuf, FieldSequence const& fields)
// "FieldSequence requirements not met");
for(auto const& field : fields)
{
auto const name = field.name();
BOOST_ASSERT(! name.empty());
if(name[0] == ':')
continue;
write(dynabuf, field.name());
write(dynabuf, ": ");
write(dynabuf, field.value());
+66 -10
View File
@@ -11,6 +11,7 @@
#include <beast/config.hpp>
#include <beast/http/fields.hpp>
#include <beast/core/detail/integer_sequence.hpp>
#include <boost/utility/string_ref.hpp>
#include <memory>
#include <string>
#include <tuple>
@@ -65,17 +66,53 @@ struct header<true, Fields>
*/
int version;
/** The Request Method
/** Return the Request Method
@note This field is present only if `isRequest == true`.
@note This function is only available if `isRequest == true`.
*/
std::string method;
auto
method() const ->
decltype(std::declval<Fields>().method()) const
{
return fields.method();
}
/** The Request URI
/** Set the Request Method
@note This field is present only if `isRequest == true`.
@param value A value that represents the request method.
@note This function is only available if `isRequest == true`.
*/
std::string url;
template<class Value>
void
method(Value&& value)
{
fields.method(std::forward<Value>(value));
}
/** Return the Request Target
@note This function is only available if `isRequest == true`.
*/
auto
target() const ->
decltype(std::declval<Fields>().target()) const
{
return fields.target();
}
/** Set the Request Target
@param value A value that represents the request method.
@note This function is only available if `isRequest == true`.
*/
template<class Value>
void
target(Value&& value)
{
fields.target(std::forward<Value>(value));
}
/// The HTTP field values.
fields_type fields;
@@ -197,17 +234,36 @@ struct header<false, Fields>
/** The Response Status-Code.
@note This field is present only if `isRequest == false`.
@note This member is only available if `isRequest == false`.
*/
int status;
/** The Response Reason-Phrase.
/** Return the Reason-Phrase.
The Reason-Phrase is obsolete as of rfc7230.
@note This field is present only if `isRequest == false`.
@note This function is only available if `isRequest == false`.
*/
std::string reason;
auto
reason() const ->
decltype(std::declval<Fields>().method()) const
{
return fields.reason();
}
/** Set the Reason-Phrase
@param value A value that represents the reason phrase.
@note This function is only available if `isRequest == false`.
*/
template<class Value>
void
reason(Value&& value)
{
fields.reason(std::forward<Value>(value));
}
};
/** A container for a complete HTTP message.
+4 -7
View File
@@ -158,13 +158,11 @@ private:
void
on_request(
boost::string_ref const& method,
boost::string_ref const& path,
boost::string_ref const& target,
int version, error_code&)
{
m_.url = std::string{
path.data(), path.size()};
m_.method = std::string{
method.data(), method.size()};
m_.target(target);
m_.method(method);
m_.version = version;
}
@@ -174,9 +172,8 @@ private:
int version, error_code&)
{
m_.status = status;
m_.reason = std::string{
reason.data(), reason.size()};
m_.version = version;
m_.reason(reason);
}
void