Refactor header status, reason, and target (API Change):

* header::result is a family of functions to replace header::status

* header interface now uses status enum and also ints

* reason-phrase is no longer stored unless the user explicitly
  requests it.

* When serializing, the standard reason is used for the
  corresponding status code unless the user has changed it.
This commit is contained in:
Vinnie Falco committed 2017-06-04 17:26:20 -07:00
1 parent 60f044aff0
commit e67c0abe79
31 files changed
+588 -220

No files matched your search

+2
View File
@@ -42,6 +42,8 @@ public:
case error::end_of_stream: return "end of stream";
case error::partial_message: return "partial message";
case error::need_more: return "need more";
case error::unexpected_body: return "unexpected body";
case error::need_buffer: return "need buffer";
case error::buffer_overflow: return "buffer overflow";
case error::bad_line_ending: return "bad line ending";
case error::bad_method: return "bad method";
+2 -23
View File
@@ -230,8 +230,7 @@ erase(string_view name)
template<class Allocator>
void
basic_fields<Allocator>::
insert(string_view name,
string_view value)
insert(string_view name, string_view value)
{
value = detail::trim(value);
auto const p = alloc_traits::allocate(this->member(), 1);
@@ -243,33 +242,13 @@ insert(string_view name,
template<class Allocator>
void
basic_fields<Allocator>::
replace(string_view name,
string_view value)
replace(string_view name, string_view value)
{
value = detail::trim(value);
erase(name);
insert(name, value);
}
template<class Allocator>
string_view
basic_fields<Allocator>::
method_string() const
{
return (*this)[":method"];
}
template<class Allocator>
void
basic_fields<Allocator>::
method_string(string_view s)
{
if(s.empty())
this->erase(":method");
else
this->replace(":method", s);
}
} // http
} // beast
+20 -8
View File
@@ -30,7 +30,7 @@ get_method_string() const
{
if(method_ != verb::unknown)
return to_string(method_);
return fields.method_string();
return fields.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_string({});
fields.method_impl({});
}
template<class Fields>
@@ -54,9 +54,21 @@ set_method(string_view s)
{
method_ = string_to_verb(s);
if(method_ != verb::unknown)
fields.method_string({});
fields.method_impl({});
else
fields.method_string(s);
fields.method_impl(s);
}
template<class Fields>
template<class>
string_view
header<false, Fields>::
get_reason() const
{
auto const s = fields.reason_impl();
if(! s.empty())
return s;
return obsolete_reason(result_);
}
template<class Fields>
@@ -79,8 +91,8 @@ swap(
{
using std::swap;
swap(a.version, b.version);
swap(a.status, b.status);
swap(a.fields, b.fields);
swap(a.result_, b.result_);
}
template<bool isRequest, class Body, class Fields>
@@ -242,9 +254,9 @@ prepare(message<isRequest, Body, Fields>& msg,
operator()(message<false, Body, Fields>& msg,
detail::prepare_info const& pi) const
{
if((msg.status / 100 ) != 1 &&
msg.status != 204 &&
msg.status != 304)
if(to_status_class(msg.result()) != status_class::informational &&
msg.result() != status::no_content &&
msg.result() != status::not_modified)
{
msg.fields.insert(
"Content-Length", *pi.content_length);
+3 -6
View File
@@ -23,6 +23,7 @@ void
write_start_line(std::ostream& os,
header<true, Fields> const& msg)
{
// VFALCO This should all be done without dynamic allocation
BOOST_ASSERT(msg.version == 10 || msg.version == 11);
os << msg.method() << " " << msg.target();
switch(msg.version)
@@ -37,18 +38,14 @@ void
write_start_line(std::ostream& os,
header<false, Fields> const& msg)
{
// VFALCO This should all be done without dynamic allocation
BOOST_ASSERT(msg.version == 10 || msg.version == 11);
switch(msg.version)
{
case 10: os << "HTTP/1.0 "; break;
case 11: os << "HTTP/1.1 "; break;
}
auto const reason = msg.reason();
if(reason.empty())
os << msg.status << " " << msg.reason() << "\r\n";
else
os << msg.status << " " <<
obsolete_reason(static_cast<status>(msg.status)) << "\r\n";
os << msg.result_int() << " " << msg.reason() << "\r\n";
}
template<class FieldSequence>
+130 -1
View File
@@ -8,10 +8,101 @@
#ifndef BEAST_HTTP_IMPL_STATUS_IPP
#define BEAST_HTTP_IMPL_STATUS_IPP
#include <boost/throw_exception.hpp>
namespace beast {
namespace http {
namespace detail {
template<class = void>
status
int_to_status(int v)
{
switch(static_cast<status>(v))
{
// 1xx
case status::continue_:
case status::switching_protocols:
case status::processing:
// [[fallthrough]]
// 2xx
case status::ok:
case status::created:
case status::accepted:
case status::non_authoritative_information:
case status::no_content:
case status::reset_content:
case status::partial_content:
case status::multi_status:
case status::already_reported:
case status::im_used:
// [[fallthrough]]
// 3xx
case status::multiple_choices:
case status::moved_permanently:
case status::found:
case status::see_other:
case status::not_modified:
case status::use_proxy:
case status::temporary_redirect:
case status::permanent_redirect:
// [[fallthrough]]
// 4xx
case status::bad_request:
case status::unauthorized:
case status::payment_required:
case status::forbidden:
case status::not_found:
case status::method_not_allowed:
case status::not_acceptable:
case status::proxy_authentication_required:
case status::request_timeout:
case status::conflict:
case status::gone:
case status::length_required:
case status::precondition_failed:
case status::payload_too_large:
case status::uri_too_long:
case status::unsupported_media_type:
case status::range_not_satisfiable:
case status::expectation_failed:
case status::misdirected_request:
case status::unprocessable_entity:
case status::locked:
case status::failed_dependency:
case status::upgrade_required:
case status::precondition_required:
case status::too_many_requests:
case status::request_header_fields_too_large:
case status::connection_closed_without_response:
case status::unavailable_for_legal_reasons:
case status::client_closed_request:
// [[fallthrough]]
// 5xx
case status::internal_server_error:
case status::not_implemented:
case status::bad_gateway:
case status::service_unavailable:
case status::gateway_timeout:
case status::http_version_not_supported:
case status::variant_also_negotiates:
case status::insufficient_storage:
case status::loop_detected:
case status::not_extended:
case status::network_authentication_required:
case status::network_connect_timeout_error:
return static_cast<status>(v);
default:
break;
}
return status::unknown;
}
template<class = void>
string_view
status_to_string(int v)
@@ -92,11 +183,49 @@ status_to_string(int v)
default:
break;
}
return "Unknown Status";
return "<unknown-status>";
}
template<class = void>
status_class
to_status_class(int v)
{
switch(v / 100)
{
case 1: return status_class::informational;
case 2: return status_class::successful;
case 3: return status_class::redirection;
case 4: return status_class::client_error;
case 5: return status_class::server_error;
default:
break;
}
return status_class::unknown;
}
} // detail
inline
status
int_to_status(int v)
{
return detail::int_to_status(v);
}
inline
status_class
to_status_class(int v)
{
return detail::to_status_class(v);
}
inline
status_class
to_status_class(status v)
{
return to_status_class(static_cast<int>(v));
}
inline
string_view
obsolete_reason(status v)