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) { switch (status_code) {
case 100: case 100:
return "100"; return StringRef::from_lit("100");
case 101: case 101:
return "101"; return StringRef::from_lit("101");
case 200: case 200:
return "200"; return StringRef::from_lit("200");
case 201: case 201:
return "201"; return StringRef::from_lit("201");
case 202: case 202:
return "202"; return StringRef::from_lit("202");
case 203: case 203:
return "203"; return StringRef::from_lit("203");
case 204: case 204:
return "204"; return StringRef::from_lit("204");
case 205: case 205:
return "205"; return StringRef::from_lit("205");
case 206: case 206:
return "206"; return StringRef::from_lit("206");
case 300: case 300:
return "300"; return StringRef::from_lit("300");
case 301: case 301:
return "301"; return StringRef::from_lit("301");
case 302: case 302:
return "302"; return StringRef::from_lit("302");
case 303: case 303:
return "303"; return StringRef::from_lit("303");
case 304: case 304:
return "304"; return StringRef::from_lit("304");
case 305: case 305:
return "305"; return StringRef::from_lit("305");
// case 306: return "306"; // case 306: return StringRef::from_lit("306");
case 307: case 307:
return "307"; return StringRef::from_lit("307");
case 308: case 308:
return "308"; return StringRef::from_lit("308");
case 400: case 400:
return "400"; return StringRef::from_lit("400");
case 401: case 401:
return "401"; return StringRef::from_lit("401");
case 402: case 402:
return "402"; return StringRef::from_lit("402");
case 403: case 403:
return "403"; return StringRef::from_lit("403");
case 404: case 404:
return "404"; return StringRef::from_lit("404");
case 405: case 405:
return "405"; return StringRef::from_lit("405");
case 406: case 406:
return "406"; return StringRef::from_lit("406");
case 407: case 407:
return "407"; return StringRef::from_lit("407");
case 408: case 408:
return "408"; return StringRef::from_lit("408");
case 409: case 409:
return "409"; return StringRef::from_lit("409");
case 410: case 410:
return "410"; return StringRef::from_lit("410");
case 411: case 411:
return "411"; return StringRef::from_lit("411");
case 412: case 412:
return "412"; return StringRef::from_lit("412");
case 413: case 413:
return "413"; return StringRef::from_lit("413");
case 414: case 414:
return "414"; return StringRef::from_lit("414");
case 415: case 415:
return "415"; return StringRef::from_lit("415");
case 416: case 416:
return "416"; return StringRef::from_lit("416");
case 417: case 417:
return "417"; return StringRef::from_lit("417");
case 421: case 421:
return "421"; return StringRef::from_lit("421");
case 426: case 426:
return "426"; return StringRef::from_lit("426");
case 428: case 428:
return "428"; return StringRef::from_lit("428");
case 429: case 429:
return "429"; return StringRef::from_lit("429");
case 431: case 431:
return "431"; return StringRef::from_lit("431");
case 451: case 451:
return "451"; return StringRef::from_lit("451");
case 500: case 500:
return "500"; return StringRef::from_lit("500");
case 501: case 501:
return "501"; return StringRef::from_lit("501");
case 502: case 502:
return "502"; return StringRef::from_lit("502");
case 503: case 503:
return "503"; return StringRef::from_lit("503");
case 504: case 504:
return "504"; return StringRef::from_lit("504");
case 505: case 505:
return "505"; return StringRef::from_lit("505");
case 511: case 511:
return "511"; return StringRef::from_lit("511");
default: 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 // Returns string version of |status_code|. This function can handle
// only predefined status code. Otherwise, returns nullptr. // 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); 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", !CU_add_test(pSuite, "util_ipv6_numeric_addr",
shrpx::test_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_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_unit", shrpx::test_util_utos_unit) ||
!CU_add_test(pSuite, "util_utos_funit", shrpx::test_util_utos_funit) || !CU_add_test(pSuite, "util_utos_funit", shrpx::test_util_utos_funit) ||
!CU_add_test(pSuite, "util_parse_uint_with_unit", !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(); const auto &resp = downstream->response();
auto &httpconf = get_config()->http; auto &httpconf = get_config()->http;
auto &balloc = downstream->get_block_allocator();
const auto &headers = resp.fs.headers(); const auto &headers = resp.fs.headers();
auto nva = std::vector<nghttp2_nv>(); auto nva = std::vector<nghttp2_nv>();
// 2 for :status and server // 2 for :status and server
nva.reserve(2 + headers.size() + httpconf.add_response_headers.size()); nva.reserve(2 + headers.size() + httpconf.add_response_headers.size());
std::string status_code_str; auto response_status = http2::stringify_status(resp.http_status);
auto response_status_const = http2::stringify_status(resp.http_status); if (response_status.empty()) {
if (response_status_const) { response_status = util::make_string_ref_uint(balloc, resp.http_status);
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));
} }
nva.push_back(http2::make_nv_ls_nocopy(":status", response_status));
for (auto &kv : headers) { for (auto &kv : headers) {
if (kv.name.empty() || kv.name[0] == ':') { if (kv.name.empty() || kv.name[0] == ':') {
continue; continue;
@ -1290,6 +1290,8 @@ int Http2Upstream::error_reply(Downstream *downstream,
int rv; int rv;
auto &resp = downstream->response(); auto &resp = downstream->response();
auto &balloc = downstream->get_block_allocator();
auto html = http::create_error_html(status_code); auto html = http::create_error_html(status_code);
resp.http_status = status_code; resp.http_status = status_code;
auto body = downstream->get_response_buf(); auto body = downstream->get_response_buf();
@ -1303,20 +1305,20 @@ int Http2Upstream::error_reply(Downstream *downstream,
auto lgconf = log_config(); auto lgconf = log_config();
lgconf->update_tstamp(std::chrono::system_clock::now()); lgconf->update_tstamp(std::chrono::system_clock::now());
auto response_status_const = http2::stringify_status(status_code); auto response_status = http2::stringify_status(status_code);
auto content_length = util::utos(html.size()); 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( auto nva = std::array<nghttp2_nv, 5>{
response_status_const {http2::make_nv_ls_nocopy(":status", response_status),
? 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_ll("content-type", "text/html; charset=UTF-8"),
http2::make_nv_ls_nocopy("server", get_config()->http.server_name), http2::make_nv_ls_nocopy("server", get_config()->http.server_name),
http2::make_nv_ls("content-length", content_length), http2::make_nv_ls_nocopy("content-length", content_length),
http2::make_nv_ls("date", lgconf->time_http_str)); http2::make_nv_ls_nocopy("date", date)}};
rv = nghttp2_submit_response(session_, downstream->get_stream_id(), rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
nva.data(), nva.size(), &data_prd); nva.data(), nva.size(), &data_prd);
@ -1357,6 +1359,8 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
const auto &req = downstream->request(); const auto &req = downstream->request();
auto &resp = downstream->response(); auto &resp = downstream->response();
auto &balloc = downstream->get_block_allocator();
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
if (downstream->get_non_final_response()) { if (downstream->get_non_final_response()) {
DLOG(INFO, downstream) << "HTTP non-final response header"; 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 + nva.reserve(resp.fs.headers().size() + 4 +
httpconf.add_response_headers.size()); httpconf.add_response_headers.size());
std::string via_value; std::string via_value;
std::string response_status;
auto response_status_const = http2::stringify_status(resp.http_status); auto response_status = http2::stringify_status(resp.http_status);
if (response_status_const) { if (response_status.empty()) {
nva.push_back(http2::make_nv_lc_nocopy(":status", response_status_const)); response_status = util::make_string_ref_uint(balloc, resp.http_status);
} else {
response_status = util::utos(resp.http_status);
nva.push_back(http2::make_nv_ls(":status", response_status));
} }
nva.push_back(http2::make_nv_ls_nocopy(":status", response_status));
if (downstream->get_non_final_response()) { if (downstream->get_non_final_response()) {
http2::copy_headers_to_nva(nva, resp.fs.headers()); 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; bodylen = vallen;
} }
StringRef content_length; auto content_length = util::make_string_ref_uint(balloc, bodylen);
{
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 cl = resp.fs.header(http2::HD_CONTENT_LENGTH); auto cl = resp.fs.header(http2::HD_CONTENT_LENGTH);
if (cl) { if (cl) {

View File

@ -51,6 +51,7 @@
#include "template.h" #include "template.h"
#include "network.h" #include "network.h"
#include "allocator.h"
namespace nghttp2 { namespace nghttp2 {
@ -405,6 +406,15 @@ template <typename T, typename OutputIt> OutputIt utos(OutputIt dst, T n) {
return res; 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) { template <typename T> std::string utos_unit(T n) {
char u = 0; char u = 0;
if (n >= (1 << 30)) { 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(("0" == StringRef{buf, util::utos(buf, 0)}));
CU_ASSERT(("123" == StringRef{buf, util::utos(buf, 123)})); CU_ASSERT(("123" == StringRef{buf, util::utos(buf, 123)}));
CU_ASSERT(("9223372036854775808" == CU_ASSERT(("18446744073709551615" ==
StringRef{buf, util::utos(buf, 9223372036854775808ULL)})); 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) { 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_select_h2(void);
void test_util_ipv6_numeric_addr(void); void test_util_ipv6_numeric_addr(void);
void test_util_utos(void); void test_util_utos(void);
void test_util_make_string_ref_uint(void);
void test_util_utos_unit(void); void test_util_utos_unit(void);
void test_util_utos_funit(void); void test_util_utos_funit(void);
void test_util_parse_uint_with_unit(void); void test_util_parse_uint_with_unit(void);