src: Return StringRef from http2::stringify_status

This commit is contained in:
Tatsuhiro Tsujikawa 2016-03-12 18:00:50 +09:00
parent c897d5b294
commit d64051fedc
8 changed files with 105 additions and 88 deletions

View File

@ -134,107 +134,107 @@ std::string get_status_string(unsigned int status_code) {
}
}
const char *stringify_status(unsigned int status_code) {
StringRef stringify_status(unsigned int status_code) {
switch (status_code) {
case 100:
return "100";
return StringRef::from_lit("100");
case 101:
return "101";
return StringRef::from_lit("101");
case 200:
return "200";
return StringRef::from_lit("200");
case 201:
return "201";
return StringRef::from_lit("201");
case 202:
return "202";
return StringRef::from_lit("202");
case 203:
return "203";
return StringRef::from_lit("203");
case 204:
return "204";
return StringRef::from_lit("204");
case 205:
return "205";
return StringRef::from_lit("205");
case 206:
return "206";
return StringRef::from_lit("206");
case 300:
return "300";
return StringRef::from_lit("300");
case 301:
return "301";
return StringRef::from_lit("301");
case 302:
return "302";
return StringRef::from_lit("302");
case 303:
return "303";
return StringRef::from_lit("303");
case 304:
return "304";
return StringRef::from_lit("304");
case 305:
return "305";
// case 306: return "306";
return StringRef::from_lit("305");
// case 306: return StringRef::from_lit("306");
case 307:
return "307";
return StringRef::from_lit("307");
case 308:
return "308";
return StringRef::from_lit("308");
case 400:
return "400";
return StringRef::from_lit("400");
case 401:
return "401";
return StringRef::from_lit("401");
case 402:
return "402";
return StringRef::from_lit("402");
case 403:
return "403";
return StringRef::from_lit("403");
case 404:
return "404";
return StringRef::from_lit("404");
case 405:
return "405";
return StringRef::from_lit("405");
case 406:
return "406";
return StringRef::from_lit("406");
case 407:
return "407";
return StringRef::from_lit("407");
case 408:
return "408";
return StringRef::from_lit("408");
case 409:
return "409";
return StringRef::from_lit("409");
case 410:
return "410";
return StringRef::from_lit("410");
case 411:
return "411";
return StringRef::from_lit("411");
case 412:
return "412";
return StringRef::from_lit("412");
case 413:
return "413";
return StringRef::from_lit("413");
case 414:
return "414";
return StringRef::from_lit("414");
case 415:
return "415";
return StringRef::from_lit("415");
case 416:
return "416";
return StringRef::from_lit("416");
case 417:
return "417";
return StringRef::from_lit("417");
case 421:
return "421";
return StringRef::from_lit("421");
case 426:
return "426";
return StringRef::from_lit("426");
case 428:
return "428";
return StringRef::from_lit("428");
case 429:
return "429";
return StringRef::from_lit("429");
case 431:
return "431";
return StringRef::from_lit("431");
case 451:
return "451";
return StringRef::from_lit("451");
case 500:
return "500";
return StringRef::from_lit("500");
case 501:
return "501";
return StringRef::from_lit("501");
case 502:
return "502";
return StringRef::from_lit("502");
case 503:
return "503";
return StringRef::from_lit("503");
case 504:
return "504";
return StringRef::from_lit("504");
case 505:
return "505";
return StringRef::from_lit("505");
case 511:
return "511";
return StringRef::from_lit("511");
default:
return nullptr;
return StringRef{};
}
}

View File

@ -98,7 +98,7 @@ std::string get_status_string(unsigned int status_code);
// Returns string version of |status_code|. This function can handle
// only predefined status code. Otherwise, returns nullptr.
const char *stringify_status(unsigned int status_code);
StringRef stringify_status(unsigned int status_code);
void capitalize(DefaultMemchunks *buf, const StringRef &s);

View File

@ -143,6 +143,8 @@ int main(int argc, char *argv[]) {
!CU_add_test(pSuite, "util_ipv6_numeric_addr",
shrpx::test_util_ipv6_numeric_addr) ||
!CU_add_test(pSuite, "util_utos", shrpx::test_util_utos) ||
!CU_add_test(pSuite, "util_make_string_ref_uint",
shrpx::test_util_make_string_ref_uint) ||
!CU_add_test(pSuite, "util_utos_unit", shrpx::test_util_utos_unit) ||
!CU_add_test(pSuite, "util_utos_funit", shrpx::test_util_utos_funit) ||
!CU_add_test(pSuite, "util_parse_uint_with_unit",

View File

@ -1229,20 +1229,20 @@ int Http2Upstream::send_reply(Downstream *downstream, const uint8_t *body,
const auto &resp = downstream->response();
auto &httpconf = get_config()->http;
auto &balloc = downstream->get_block_allocator();
const auto &headers = resp.fs.headers();
auto nva = std::vector<nghttp2_nv>();
// 2 for :status and server
nva.reserve(2 + headers.size() + httpconf.add_response_headers.size());
std::string status_code_str;
auto response_status_const = http2::stringify_status(resp.http_status);
if (response_status_const) {
nva.push_back(http2::make_nv_lc_nocopy(":status", response_status_const));
} else {
status_code_str = util::utos(resp.http_status);
nva.push_back(http2::make_nv_ls(":status", status_code_str));
auto response_status = http2::stringify_status(resp.http_status);
if (response_status.empty()) {
response_status = util::make_string_ref_uint(balloc, resp.http_status);
}
nva.push_back(http2::make_nv_ls_nocopy(":status", response_status));
for (auto &kv : headers) {
if (kv.name.empty() || kv.name[0] == ':') {
continue;
@ -1290,6 +1290,8 @@ int Http2Upstream::error_reply(Downstream *downstream,
int rv;
auto &resp = downstream->response();
auto &balloc = downstream->get_block_allocator();
auto html = http::create_error_html(status_code);
resp.http_status = status_code;
auto body = downstream->get_response_buf();
@ -1303,20 +1305,20 @@ int Http2Upstream::error_reply(Downstream *downstream,
auto lgconf = log_config();
lgconf->update_tstamp(std::chrono::system_clock::now());
auto response_status_const = http2::stringify_status(status_code);
auto content_length = util::utos(html.size());
auto response_status = http2::stringify_status(status_code);
if (response_status.empty()) {
response_status = util::make_string_ref_uint(balloc, status_code);
}
std::string status_code_str;
auto content_length = util::make_string_ref_uint(balloc, html.size());
auto date = make_string_ref(balloc, StringRef{lgconf->time_http_str});
auto nva = make_array(
response_status_const
? http2::make_nv_lc_nocopy(":status", response_status_const)
: http2::make_nv_ls(":status",
(status_code_str = util::utos(status_code))),
http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
http2::make_nv_ls_nocopy("server", get_config()->http.server_name),
http2::make_nv_ls("content-length", content_length),
http2::make_nv_ls("date", lgconf->time_http_str));
auto nva = std::array<nghttp2_nv, 5>{
{http2::make_nv_ls_nocopy(":status", response_status),
http2::make_nv_ll("content-type", "text/html; charset=UTF-8"),
http2::make_nv_ls_nocopy("server", get_config()->http.server_name),
http2::make_nv_ls_nocopy("content-length", content_length),
http2::make_nv_ls_nocopy("date", date)}};
rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
nva.data(), nva.size(), &data_prd);
@ -1357,6 +1359,8 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
const auto &req = downstream->request();
auto &resp = downstream->response();
auto &balloc = downstream->get_block_allocator();
if (LOG_ENABLED(INFO)) {
if (downstream->get_non_final_response()) {
DLOG(INFO, downstream) << "HTTP non-final response header";
@ -1396,16 +1400,14 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
nva.reserve(resp.fs.headers().size() + 4 +
httpconf.add_response_headers.size());
std::string via_value;
std::string response_status;
auto response_status_const = http2::stringify_status(resp.http_status);
if (response_status_const) {
nva.push_back(http2::make_nv_lc_nocopy(":status", response_status_const));
} else {
response_status = util::utos(resp.http_status);
nva.push_back(http2::make_nv_ls(":status", response_status));
auto response_status = http2::stringify_status(resp.http_status);
if (response_status.empty()) {
response_status = util::make_string_ref_uint(balloc, resp.http_status);
}
nva.push_back(http2::make_nv_ls_nocopy(":status", response_status));
if (downstream->get_non_final_response()) {
http2::copy_headers_to_nva(nva, resp.fs.headers());

View File

@ -215,14 +215,7 @@ mrb_value response_return(mrb_state *mrb, mrb_value self) {
bodylen = vallen;
}
StringRef content_length;
{
auto iov = make_byte_ref(balloc, str_size("18446744073709551615") + 1);
auto p = iov.base;
p = util::utos(p, bodylen);
*p = '\0';
content_length = StringRef{iov.base, p};
}
auto content_length = util::make_string_ref_uint(balloc, bodylen);
auto cl = resp.fs.header(http2::HD_CONTENT_LENGTH);
if (cl) {

View File

@ -51,6 +51,7 @@
#include "template.h"
#include "network.h"
#include "allocator.h"
namespace nghttp2 {
@ -405,6 +406,15 @@ template <typename T, typename OutputIt> OutputIt utos(OutputIt dst, T n) {
return res;
}
template <typename T>
StringRef make_string_ref_uint(BlockAllocator &balloc, T n) {
auto iov = make_byte_ref(balloc, str_size("18446744073709551615") + 1);
auto p = iov.base;
p = util::utos(p, n);
*p = '\0';
return StringRef{iov.base, p};
}
template <typename T> std::string utos_unit(T n) {
char u = 0;
if (n >= (1 << 30)) {

View File

@ -239,8 +239,17 @@ void test_util_utos(void) {
CU_ASSERT(("0" == StringRef{buf, util::utos(buf, 0)}));
CU_ASSERT(("123" == StringRef{buf, util::utos(buf, 123)}));
CU_ASSERT(("9223372036854775808" ==
StringRef{buf, util::utos(buf, 9223372036854775808ULL)}));
CU_ASSERT(("18446744073709551615" ==
StringRef{buf, util::utos(buf, 18446744073709551615ULL)}));
}
void test_util_make_string_ref_uint(void) {
BlockAllocator balloc(1024, 1024);
CU_ASSERT("0" == util::make_string_ref_uint(balloc, 0));
CU_ASSERT("123" == util::make_string_ref_uint(balloc, 123));
CU_ASSERT("18446744073709551615" ==
util::make_string_ref_uint(balloc, 18446744073709551615ULL));
}
void test_util_utos_unit(void) {

View File

@ -45,6 +45,7 @@ void test_util_http_date(void);
void test_util_select_h2(void);
void test_util_ipv6_numeric_addr(void);
void test_util_utos(void);
void test_util_make_string_ref_uint(void);
void test_util_utos_unit(void);
void test_util_utos_funit(void);
void test_util_parse_uint_with_unit(void);