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
2017-06-04 17:26:20 -07:00
parent 60f044aff0
commit e67c0abe79
31 changed files with 588 additions and 220 deletions
+4 -5
View File
@@ -46,7 +46,7 @@ class custom_parser
/// Called after receiving the start-line (isRequest == false).
void
on_response(
int status, // The status-code
int code, // The status-code
string_view reason, // The obsolete reason-phrase
int version, // The HTTP-version
error_code& ec); // The error returned to the caller, if any
@@ -238,7 +238,7 @@ public:
read(stream, buffer, res, ec);
if(ec)
return;
if(res.status != 100)
if(res.result() != status::continue_)
{
// The server indicated that it will not
// accept the request, so skip sending the body.
@@ -291,8 +291,7 @@ public:
// send 100 response
response<empty_body> res;
res.version = 11;
res.status = 100;
res.reason("Continue");
res.result(status::continue_);
res.fields.insert("Server", "test");
write(stream, res, ec);
if(ec)
@@ -383,7 +382,7 @@ public:
// allowing serialization to use manually provided buffers.
message<false, buffer_body, fields> res;
res.status = 200;
res.result(status::ok);
res.version = 11;
res.fields.insert("Server", "Beast");
res.fields.insert("Transfer-Encoding", "chunked");
+6 -6
View File
@@ -103,12 +103,12 @@ public:
testMethodString()
{
f_t f;
f.method_string("CRY");
BEAST_EXPECTS(f.method_string() == "CRY", f.method_string());
f.method_string("PUT");
BEAST_EXPECTS(f.method_string() == "PUT", f.method_string());
f.method_string({});
BEAST_EXPECTS(f.method_string().empty(), f.method_string());
f.method_impl("CRY");
BEAST_EXPECTS(f.method_impl() == "CRY", f.method_impl());
f.method_impl("PUT");
BEAST_EXPECTS(f.method_impl() == "PUT", f.method_impl());
f.method_impl({});
BEAST_EXPECTS(f.method_impl().empty(), f.method_impl());
}
void run() override
+39 -7
View File
@@ -262,19 +262,20 @@ public:
{
message<false, string_body, fields> m1;
message<false, string_body, fields> m2;
m1.status = 200;
m1.result(status::ok);
m1.version = 10;
m1.body = "1";
m1.fields.insert("h", "v");
m2.status = 404;
m2.reason("OK");
m2.result(status::not_found);
m2.body = "2";
m2.version = 11;
swap(m1, m2);
BEAST_EXPECT(m1.status == 404);
BEAST_EXPECT(m2.status == 200);
BEAST_EXPECT(m1.reason() == "OK");
BEAST_EXPECT(m2.reason().empty());
BEAST_EXPECT(m1.result() == status::not_found);
BEAST_EXPECT(m1.result_int() == 404);
BEAST_EXPECT(m2.result() == status::ok);
BEAST_EXPECT(m2.result_int() == 200);
BEAST_EXPECT(m1.reason() == "Not Found");
BEAST_EXPECT(m2.reason() == "OK");
BEAST_EXPECT(m1.version == 11);
BEAST_EXPECT(m2.version == 10);
BEAST_EXPECT(m1.body == "2");
@@ -321,6 +322,35 @@ public:
scheck("XYZ");
}
void
testStatus()
{
header<false> h;
h.result(200);
BEAST_EXPECT(h.result_int() == 200);
BEAST_EXPECT(h.result() == status::ok);
h.result(status::switching_protocols);
BEAST_EXPECT(h.result_int() == 101);
BEAST_EXPECT(h.result() == status::switching_protocols);
h.result(1);
BEAST_EXPECT(h.result_int() == 1);
BEAST_EXPECT(h.result() == status::unknown);
}
void
testReason()
{
header<false> h;
h.result(status::ok);
BEAST_EXPECT(h.reason() == "OK");
h.reason("Pepe");
BEAST_EXPECT(h.reason() == "Pepe");
h.result(status::not_found);
BEAST_EXPECT(h.reason() == "Pepe");
h.reason({});
BEAST_EXPECT(h.reason() == "Not Found");
}
void
run() override
{
@@ -331,6 +361,8 @@ public:
testSwap();
testSpecialMembers();
testMethod();
testStatus();
testReason();
}
};
+2 -2
View File
@@ -182,7 +182,7 @@ public:
BEAST_EXPECT(p.need_eof());
BEAST_EXPECT(p.content_length() == boost::none);
BEAST_EXPECT(m.version == 10);
BEAST_EXPECT(m.status == 200);
BEAST_EXPECT(m.result() == status::ok);
BEAST_EXPECT(m.reason() == "OK");
BEAST_EXPECT(m.fields["Server"] == "test");
BEAST_EXPECT(m.body == "Hello, world!");
@@ -209,7 +209,7 @@ public:
BEAST_EXPECT(p.is_chunked());
BEAST_EXPECT(p.content_length() == boost::none);
BEAST_EXPECT(m.version == 11);
BEAST_EXPECT(m.status == 200);
BEAST_EXPECT(m.result() == status::ok);
BEAST_EXPECT(m.reason() == "OK");
BEAST_EXPECT(m.fields["Server"] == "test");
BEAST_EXPECT(m.fields["Transfer-Encoding"] == "chunked");
+76
View File
@@ -20,6 +20,82 @@ public:
void
testStatus()
{
auto const check = [&](status s, int i, status_class sc)
{
BEAST_EXPECT(int_to_status(i) == s);
BEAST_EXPECT(to_status_class(i) == sc);
BEAST_EXPECT(to_status_class(int_to_status(i)) == sc);
};
check(status::continue_ ,100, status_class::informational);
check(status::switching_protocols ,101, status_class::informational);
check(status::processing ,102, status_class::informational);
check(status::ok ,200, status_class::successful);
check(status::created ,201, status_class::successful);
check(status::accepted ,202, status_class::successful);
check(status::non_authoritative_information ,203, status_class::successful);
check(status::no_content ,204, status_class::successful);
check(status::reset_content ,205, status_class::successful);
check(status::partial_content ,206, status_class::successful);
check(status::multi_status ,207, status_class::successful);
check(status::already_reported ,208, status_class::successful);
check(status::im_used ,226, status_class::successful);
check(status::multiple_choices ,300, status_class::redirection);
check(status::moved_permanently ,301, status_class::redirection);
check(status::found ,302, status_class::redirection);
check(status::see_other ,303, status_class::redirection);
check(status::not_modified ,304, status_class::redirection);
check(status::use_proxy ,305, status_class::redirection);
check(status::temporary_redirect ,307, status_class::redirection);
check(status::permanent_redirect ,308, status_class::redirection);
check(status::bad_request ,400, status_class::client_error);
check(status::unauthorized ,401, status_class::client_error);
check(status::payment_required ,402, status_class::client_error);
check(status::forbidden ,403, status_class::client_error);
check(status::not_found ,404, status_class::client_error);
check(status::method_not_allowed ,405, status_class::client_error);
check(status::not_acceptable ,406, status_class::client_error);
check(status::proxy_authentication_required ,407, status_class::client_error);
check(status::request_timeout ,408, status_class::client_error);
check(status::conflict ,409, status_class::client_error);
check(status::gone ,410, status_class::client_error);
check(status::length_required ,411, status_class::client_error);
check(status::precondition_failed ,412, status_class::client_error);
check(status::payload_too_large ,413, status_class::client_error);
check(status::uri_too_long ,414, status_class::client_error);
check(status::unsupported_media_type ,415, status_class::client_error);
check(status::range_not_satisfiable ,416, status_class::client_error);
check(status::expectation_failed ,417, status_class::client_error);
check(status::misdirected_request ,421, status_class::client_error);
check(status::unprocessable_entity ,422, status_class::client_error);
check(status::locked ,423, status_class::client_error);
check(status::failed_dependency ,424, status_class::client_error);
check(status::upgrade_required ,426, status_class::client_error);
check(status::precondition_required ,428, status_class::client_error);
check(status::too_many_requests ,429, status_class::client_error);
check(status::request_header_fields_too_large ,431, status_class::client_error);
check(status::connection_closed_without_response ,444, status_class::client_error);
check(status::unavailable_for_legal_reasons ,451, status_class::client_error);
check(status::client_closed_request ,499, status_class::client_error);
check(status::internal_server_error ,500, status_class::server_error);
check(status::not_implemented ,501, status_class::server_error);
check(status::bad_gateway ,502, status_class::server_error);
check(status::service_unavailable ,503, status_class::server_error);
check(status::gateway_timeout ,504, status_class::server_error);
check(status::http_version_not_supported ,505, status_class::server_error);
check(status::variant_also_negotiates ,506, status_class::server_error);
check(status::insufficient_storage ,507, status_class::server_error);
check(status::loop_detected ,508, status_class::server_error);
check(status::not_extended ,510, status_class::server_error);
check(status::network_authentication_required ,511, status_class::server_error);
check(status::network_connect_timeout_error ,599, status_class::server_error);
BEAST_EXPECT(to_status_class(1) == status_class::unknown);
BEAST_EXPECT(to_status_class(status::unknown) == status_class::unknown);
auto const good =
[&](status v)
{
+2 -2
View File
@@ -62,11 +62,11 @@ public:
}
void
on_response(int status_,
on_response(int code,
string_view reason_,
int version_, error_code& ec)
{
status = status_;
status = code;
reason = std::string(
reason_.data(), reason_.size());
version = version_;
+3 -3
View File
@@ -292,7 +292,7 @@ public:
{
message<false, string_body, fields> m;
m.version = 10;
m.status = 200;
m.result(status::ok);
m.reason("OK");
m.fields.insert("Server", "test");
m.fields.insert("Content-Length", "5");
@@ -311,7 +311,7 @@ public:
{
message<false, string_body, fields> m;
m.version = 11;
m.status = 200;
m.result(status::ok);
m.reason("OK");
m.fields.insert("Server", "test");
m.fields.insert("Transfer-Encoding", "chunked");
@@ -786,7 +786,7 @@ public:
message<false, Body, fields> m0;
m0.version = 11;
m0.status = 200;
m0.result(status::ok);
m0.reason("OK");
m0.fields.insert("Server", "test");
m0.body.s = "Hello, world!\n";