src: Add missing mandatory SP after status code

This commit is contained in:
Tatsuhiro Tsujikawa 2016-11-04 02:18:42 +09:00
parent 25fbc7b435
commit 208d71561a
7 changed files with 94 additions and 70 deletions

View File

@ -1921,13 +1921,18 @@ namespace {
FileEntry make_status_body(int status, uint16_t port) { FileEntry make_status_body(int status, uint16_t port) {
BlockAllocator balloc(1024, 1024); BlockAllocator balloc(1024, 1024);
auto status_string = http2::get_status_string(balloc, status); auto status_string = http2::stringify_status(balloc, status);
auto reason_pharase = http2::get_reason_phrase(status);
std::string body; std::string body;
body = "<html><head><title>"; body = "<html><head><title>";
body += status_string; body += status_string;
body += ' ';
body += reason_pharase;
body += "</title></head><body><h1>"; body += "</title></head><body><h1>";
body += status_string; body += status_string;
body += ' ';
body += reason_pharase;
body += "</h1><hr><address>"; body += "</h1><hr><address>";
body += NGHTTPD_SERVER; body += NGHTTPD_SERVER;
body += " at port "; body += " at port ";

View File

@ -36,11 +36,16 @@ std::string create_html(int status_code) {
BlockAllocator balloc(1024, 1024); BlockAllocator balloc(1024, 1024);
std::string res; std::string res;
res.reserve(512); res.reserve(512);
auto status = ::nghttp2::http2::get_status_string(balloc, status_code); auto status_string = ::nghttp2::http2::stringify_status(balloc, status_code);
auto reason_phrase = ::nghttp2::http2::get_reason_phrase(status_code);
res += R"(<!DOCTYPE html><html lang="en"><title>)"; res += R"(<!DOCTYPE html><html lang="en"><title>)";
res += status; res += status_string;
res += ' ';
res += reason_phrase;
res += "</title><body><h1>"; res += "</title><body><h1>";
res += status; res += status_string;
res += ' ';
res += reason_phrase;
res += "</h1></body></html>"; res += "</h1></body></html>";
return res; return res;
} }

View File

@ -30,107 +30,107 @@ namespace nghttp2 {
namespace http2 { namespace http2 {
StringRef get_status_string(BlockAllocator &balloc, unsigned int status_code) { StringRef get_reason_phrase(unsigned int status_code) {
switch (status_code) { switch (status_code) {
case 100: case 100:
return StringRef::from_lit("100 Continue"); return StringRef::from_lit("Continue");
case 101: case 101:
return StringRef::from_lit("101 Switching Protocols"); return StringRef::from_lit("Switching Protocols");
case 200: case 200:
return StringRef::from_lit("200 OK"); return StringRef::from_lit("OK");
case 201: case 201:
return StringRef::from_lit("201 Created"); return StringRef::from_lit("Created");
case 202: case 202:
return StringRef::from_lit("202 Accepted"); return StringRef::from_lit("Accepted");
case 203: case 203:
return StringRef::from_lit("203 Non-Authoritative Information"); return StringRef::from_lit("Non-Authoritative Information");
case 204: case 204:
return StringRef::from_lit("204 No Content"); return StringRef::from_lit("No Content");
case 205: case 205:
return StringRef::from_lit("205 Reset Content"); return StringRef::from_lit("Reset Content");
case 206: case 206:
return StringRef::from_lit("206 Partial Content"); return StringRef::from_lit("Partial Content");
case 300: case 300:
return StringRef::from_lit("300 Multiple Choices"); return StringRef::from_lit("Multiple Choices");
case 301: case 301:
return StringRef::from_lit("301 Moved Permanently"); return StringRef::from_lit("Moved Permanently");
case 302: case 302:
return StringRef::from_lit("302 Found"); return StringRef::from_lit("Found");
case 303: case 303:
return StringRef::from_lit("303 See Other"); return StringRef::from_lit("See Other");
case 304: case 304:
return StringRef::from_lit("304 Not Modified"); return StringRef::from_lit("Not Modified");
case 305: case 305:
return StringRef::from_lit("305 Use Proxy"); return StringRef::from_lit("Use Proxy");
// case 306: return StringRef::from_lit("306 (Unused)"); // case 306: return StringRef::from_lit("(Unused)");
case 307: case 307:
return StringRef::from_lit("307 Temporary Redirect"); return StringRef::from_lit("Temporary Redirect");
case 308: case 308:
return StringRef::from_lit("308 Permanent Redirect"); return StringRef::from_lit("Permanent Redirect");
case 400: case 400:
return StringRef::from_lit("400 Bad Request"); return StringRef::from_lit("Bad Request");
case 401: case 401:
return StringRef::from_lit("401 Unauthorized"); return StringRef::from_lit("Unauthorized");
case 402: case 402:
return StringRef::from_lit("402 Payment Required"); return StringRef::from_lit("Payment Required");
case 403: case 403:
return StringRef::from_lit("403 Forbidden"); return StringRef::from_lit("Forbidden");
case 404: case 404:
return StringRef::from_lit("404 Not Found"); return StringRef::from_lit("Not Found");
case 405: case 405:
return StringRef::from_lit("405 Method Not Allowed"); return StringRef::from_lit("Method Not Allowed");
case 406: case 406:
return StringRef::from_lit("406 Not Acceptable"); return StringRef::from_lit("Not Acceptable");
case 407: case 407:
return StringRef::from_lit("407 Proxy Authentication Required"); return StringRef::from_lit("Proxy Authentication Required");
case 408: case 408:
return StringRef::from_lit("408 Request Timeout"); return StringRef::from_lit("Request Timeout");
case 409: case 409:
return StringRef::from_lit("409 Conflict"); return StringRef::from_lit("Conflict");
case 410: case 410:
return StringRef::from_lit("410 Gone"); return StringRef::from_lit("Gone");
case 411: case 411:
return StringRef::from_lit("411 Length Required"); return StringRef::from_lit("Length Required");
case 412: case 412:
return StringRef::from_lit("412 Precondition Failed"); return StringRef::from_lit("Precondition Failed");
case 413: case 413:
return StringRef::from_lit("413 Payload Too Large"); return StringRef::from_lit("Payload Too Large");
case 414: case 414:
return StringRef::from_lit("414 URI Too Long"); return StringRef::from_lit("URI Too Long");
case 415: case 415:
return StringRef::from_lit("415 Unsupported Media Type"); return StringRef::from_lit("Unsupported Media Type");
case 416: case 416:
return StringRef::from_lit("416 Requested Range Not Satisfiable"); return StringRef::from_lit("Requested Range Not Satisfiable");
case 417: case 417:
return StringRef::from_lit("417 Expectation Failed"); return StringRef::from_lit("Expectation Failed");
case 421: case 421:
return StringRef::from_lit("421 Misdirected Request"); return StringRef::from_lit("Misdirected Request");
case 426: case 426:
return StringRef::from_lit("426 Upgrade Required"); return StringRef::from_lit("Upgrade Required");
case 428: case 428:
return StringRef::from_lit("428 Precondition Required"); return StringRef::from_lit("Precondition Required");
case 429: case 429:
return StringRef::from_lit("429 Too Many Requests"); return StringRef::from_lit("Too Many Requests");
case 431: case 431:
return StringRef::from_lit("431 Request Header Fields Too Large"); return StringRef::from_lit("Request Header Fields Too Large");
case 451: case 451:
return StringRef::from_lit("451 Unavailable For Legal Reasons"); return StringRef::from_lit("Unavailable For Legal Reasons");
case 500: case 500:
return StringRef::from_lit("500 Internal Server Error"); return StringRef::from_lit("Internal Server Error");
case 501: case 501:
return StringRef::from_lit("501 Not Implemented"); return StringRef::from_lit("Not Implemented");
case 502: case 502:
return StringRef::from_lit("502 Bad Gateway"); return StringRef::from_lit("Bad Gateway");
case 503: case 503:
return StringRef::from_lit("503 Service Unavailable"); return StringRef::from_lit("Service Unavailable");
case 504: case 504:
return StringRef::from_lit("504 Gateway Timeout"); return StringRef::from_lit("Gateway Timeout");
case 505: case 505:
return StringRef::from_lit("505 HTTP Version Not Supported"); return StringRef::from_lit("HTTP Version Not Supported");
case 511: case 511:
return StringRef::from_lit("511 Network Authentication Required"); return StringRef::from_lit("Network Authentication Required");
default: default:
return util::make_string_ref_uint(balloc, status_code); return StringRef{};
} }
} }

View File

@ -94,9 +94,9 @@ using HeaderRefs = std::vector<HeaderRef>;
namespace http2 { namespace http2 {
// Returns string version of |status code| followed by reason // Returns reason-phrase for given |status code|. If there is no
// string. (e.g., "404 Not Found"). // known reason-phrase for the given code, returns empty string.
StringRef get_status_string(BlockAllocator &balloc, unsigned int status_code); StringRef get_reason_phrase(unsigned int status_code);
// Returns string version of |status_code|. (e.g., "404") // Returns string version of |status_code|. (e.g., "404")
StringRef stringify_status(BlockAllocator &balloc, unsigned int status_code); StringRef stringify_status(BlockAllocator &balloc, unsigned int status_code);

View File

@ -45,11 +45,14 @@ StringRef create_error_html(BlockAllocator &balloc, unsigned int http_status) {
} }
} }
auto status_string = http2::get_status_string(balloc, http_status); auto status_string = http2::stringify_status(balloc, http_status);
auto reason_phrase = http2::get_reason_phrase(http_status);
return concat_string_ref( return concat_string_ref(
balloc, StringRef::from_lit(R"(<!DOCTYPE html><html lang="en"><title>)"), balloc, StringRef::from_lit(R"(<!DOCTYPE html><html lang="en"><title>)"),
status_string, StringRef::from_lit("</title><body><h1>"), status_string, status_string, StringRef::from_lit(" "), reason_phrase,
StringRef::from_lit("</title><body><h1>"), status_string,
StringRef::from_lit(" "), reason_phrase,
StringRef::from_lit("</h1><footer>"), httpconf.server_name, StringRef::from_lit("</h1><footer>"), httpconf.server_name,
StringRef::from_lit("</footer></body></html>")); StringRef::from_lit("</footer></body></html>"));
} }

View File

@ -863,7 +863,9 @@ int HttpsUpstream::send_reply(Downstream *downstream, const uint8_t *body,
auto output = downstream->get_response_buf(); auto output = downstream->get_response_buf();
output->append("HTTP/1.1 "); output->append("HTTP/1.1 ");
output->append(http2::get_status_string(balloc, resp.http_status)); output->append(http2::stringify_status(balloc, resp.http_status));
output->append(' ');
output->append(http2::get_reason_phrase(resp.http_status));
output->append("\r\n"); output->append("\r\n");
for (auto &kv : resp.fs.headers()) { for (auto &kv : resp.fs.headers()) {
@ -923,8 +925,9 @@ void HttpsUpstream::error_reply(unsigned int status_code) {
auto output = downstream->get_response_buf(); auto output = downstream->get_response_buf();
output->append("HTTP/1.1 "); output->append("HTTP/1.1 ");
auto status_str = http2::get_status_string(balloc, status_code); output->append(http2::stringify_status(balloc, status_code));
output->append(status_str); output->append(' ');
output->append(http2::get_reason_phrase(status_code));
output->append("\r\nServer: "); output->append("\r\nServer: ");
output->append(get_config()->http.server_name); output->append(get_config()->http.server_name);
output->append("\r\nContent-Length: "); output->append("\r\nContent-Length: ");
@ -1011,7 +1014,9 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
buf->append("."); buf->append(".");
buf->append(util::utos(req.http_minor)); buf->append(util::utos(req.http_minor));
buf->append(" "); buf->append(" ");
buf->append(http2::get_status_string(balloc, resp.http_status)); buf->append(http2::stringify_status(balloc, resp.http_status));
buf->append(' ');
buf->append(http2::get_reason_phrase(resp.http_status));
buf->append("\r\n"); buf->append("\r\n");
auto config = get_config(); auto config = get_config();

View File

@ -918,7 +918,9 @@ int SpdyUpstream::send_reply(Downstream *downstream, const uint8_t *body,
const auto &resp = downstream->response(); const auto &resp = downstream->response();
auto &balloc = downstream->get_block_allocator(); auto &balloc = downstream->get_block_allocator();
auto status_string = http2::get_status_string(balloc, resp.http_status); auto status_line = concat_string_ref(
balloc, http2::stringify_status(balloc, resp.http_status),
StringRef::from_lit(" "), http2::get_reason_phrase(resp.http_status));
const auto &headers = resp.fs.headers(); const auto &headers = resp.fs.headers();
@ -931,7 +933,7 @@ int SpdyUpstream::send_reply(Downstream *downstream, const uint8_t *body,
httpconf.add_response_headers.size() * 2 + 1); httpconf.add_response_headers.size() * 2 + 1);
nva.push_back(":status"); nva.push_back(":status");
nva.push_back(status_string.c_str()); nva.push_back(status_line.c_str());
nva.push_back(":version"); nva.push_back(":version");
nva.push_back("HTTP/1.1"); nva.push_back("HTTP/1.1");
@ -999,9 +1001,11 @@ int SpdyUpstream::error_reply(Downstream *downstream,
lgconf->update_tstamp(std::chrono::system_clock::now()); lgconf->update_tstamp(std::chrono::system_clock::now());
auto content_length = util::make_string_ref_uint(balloc, html.size()); auto content_length = util::make_string_ref_uint(balloc, html.size());
auto status_string = http2::get_status_string(balloc, status_code); auto status_line = concat_string_ref(
balloc, http2::stringify_status(balloc, status_code),
StringRef::from_lit(" "), http2::get_reason_phrase(status_code));
const char *nv[] = {":status", status_string.c_str(), const char *nv[] = {":status", status_line.c_str(),
":version", "http/1.1", ":version", "http/1.1",
"content-type", "text/html; charset=UTF-8", "content-type", "text/html; charset=UTF-8",
"server", get_config()->http.server_name.c_str(), "server", get_config()->http.server_name.c_str(),
@ -1104,9 +1108,11 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
size_t hdidx = 0; size_t hdidx = 0;
std::string via_value; std::string via_value;
auto status_string = http2::get_status_string(balloc, resp.http_status); auto status_line = concat_string_ref(
balloc, http2::stringify_status(balloc, resp.http_status),
StringRef::from_lit(" "), http2::get_reason_phrase(resp.http_status));
nv[hdidx++] = ":status"; nv[hdidx++] = ":status";
nv[hdidx++] = status_string.c_str(); nv[hdidx++] = status_line.c_str();
nv[hdidx++] = ":version"; nv[hdidx++] = ":version";
nv[hdidx++] = "HTTP/1.1"; nv[hdidx++] = "HTTP/1.1";
for (auto &hd : resp.fs.headers()) { for (auto &hd : resp.fs.headers()) {