src: Rewrite http:create_via_header_value

This commit is contained in:
Tatsuhiro Tsujikawa 2016-03-12 18:36:05 +09:00
parent d64051fedc
commit 67569486d1
10 changed files with 71 additions and 28 deletions

View File

@ -123,6 +123,8 @@ int main(int argc, char *argv[]) {
shrpx::test_shrpx_worker_match_downstream_addr_group) || shrpx::test_shrpx_worker_match_downstream_addr_group) ||
!CU_add_test(pSuite, "http_create_forwarded", !CU_add_test(pSuite, "http_create_forwarded",
shrpx::test_shrpx_http_create_forwarded) || shrpx::test_shrpx_http_create_forwarded) ||
!CU_add_test(pSuite, "http_create_via_header_value",
shrpx::test_shrpx_http_create_via_header_value) ||
!CU_add_test(pSuite, "util_streq", shrpx::test_util_streq) || !CU_add_test(pSuite, "util_streq", shrpx::test_util_streq) ||
!CU_add_test(pSuite, "util_strieq", shrpx::test_util_strieq) || !CU_add_test(pSuite, "util_strieq", shrpx::test_util_strieq) ||
!CU_add_test(pSuite, "util_inp_strlower", !CU_add_test(pSuite, "util_inp_strlower",

View File

@ -50,17 +50,6 @@ std::string create_error_html(unsigned int status_code) {
return res; return res;
} }
std::string create_via_header_value(int major, int minor) {
std::string hdrs;
hdrs += static_cast<char>(major + '0');
if (major < 2) {
hdrs += '.';
hdrs += static_cast<char>(minor + '0');
}
hdrs += " nghttpx";
return hdrs;
}
std::string create_forwarded(int params, const StringRef &node_by, std::string create_forwarded(int params, const StringRef &node_by,
const StringRef &node_for, const StringRef &host, const StringRef &node_for, const StringRef &host,
const StringRef &proto) { const StringRef &proto) {

View File

@ -31,13 +31,23 @@
#include <nghttp2/nghttp2.h> #include <nghttp2/nghttp2.h>
#include "util.h"
namespace shrpx { namespace shrpx {
namespace http { namespace http {
std::string create_error_html(unsigned int status_code); std::string create_error_html(unsigned int status_code);
std::string create_via_header_value(int major, int minor); template <typename OutputIt>
OutputIt create_via_header_value(OutputIt dst, int major, int minor) {
*dst++ = static_cast<char>(major + '0');
if (major < 2) {
*dst++ = '.';
*dst++ = static_cast<char>(minor + '0');
}
return util::copy_lit(dst, " nghttpx");
}
// Returns generated RFC 7239 Forwarded header field value. The // Returns generated RFC 7239 Forwarded header field value. The
// |params| is bitwise-OR of zero or more of shrpx_forwarded_param // |params| is bitwise-OR of zero or more of shrpx_forwarded_param

View File

@ -266,6 +266,8 @@ int Http2DownstreamConnection::push_request_headers() {
const auto &req = downstream_->request(); const auto &req = downstream_->request();
auto &balloc = downstream_->get_block_allocator();
auto &httpconf = get_config()->http; auto &httpconf = get_config()->http;
auto &http2conf = get_config()->http2; auto &http2conf = get_config()->http2;
@ -403,19 +405,28 @@ int Http2DownstreamConnection::push_request_headers() {
nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-proto", req.scheme)); nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-proto", req.scheme));
} }
std::string via_value;
auto via = req.fs.header(http2::HD_VIA); auto via = req.fs.header(http2::HD_VIA);
if (httpconf.no_via) { if (httpconf.no_via) {
if (via) { if (via) {
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value)); nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
} }
} else { } else {
size_t vialen = 16;
if (via) { if (via) {
via_value = (*via).value.str(); vialen += via->value.size() + 2;
via_value += ", ";
} }
via_value += http::create_via_header_value(req.http_major, req.http_minor);
nva.push_back(http2::make_nv_ls("via", via_value)); auto iov = make_byte_ref(balloc, vialen + 1);
auto p = iov.base;
if (via) {
p = std::copy(std::begin(via->value), std::end(via->value), p);
p = util::copy_lit(p, ", ");
}
p = http::create_via_header_value(p, req.http_major, req.http_minor);
*p = '\0';
nva.push_back(http2::make_nv_ls_nocopy("via", StringRef{iov.base, p}));
} }
auto te = req.fs.header(http2::HD_TE); auto te = req.fs.header(http2::HD_TE);

View File

@ -1399,7 +1399,6 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
// field. // field.
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;
auto response_status = http2::stringify_status(resp.http_status); auto response_status = http2::stringify_status(resp.http_status);
if (response_status.empty()) { if (response_status.empty()) {
@ -1453,13 +1452,23 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value)); nva.push_back(http2::make_nv_ls_nocopy("via", (*via).value));
} }
} else { } else {
// we don't create more than 16 bytes in
// http::create_via_header_value.
size_t len = 16;
if (via) { if (via) {
via_value = (*via).value.str(); len += via->value.size() + 2;
via_value += ", ";
} }
via_value +=
http::create_via_header_value(resp.http_major, resp.http_minor); auto iov = make_byte_ref(balloc, len + 1);
nva.push_back(http2::make_nv_ls("via", via_value)); auto p = iov.base;
if (via) {
p = std::copy(std::begin(via->value), std::end(via->value), p);
p = util::copy_lit(p, ", ");
}
p = http::create_via_header_value(p, resp.http_major, resp.http_minor);
*p = '\0';
nva.push_back(http2::make_nv_ls_nocopy("via", StringRef{iov.base, p}));
} }
for (auto &p : httpconf.add_response_headers) { for (auto &p : httpconf.add_response_headers) {

View File

@ -424,7 +424,10 @@ int HttpDownstreamConnection::push_request_headers() {
buf->append((*via).value); buf->append((*via).value);
buf->append(", "); buf->append(", ");
} }
buf->append(http::create_via_header_value(req.http_major, req.http_minor)); std::array<char, 16> viabuf;
auto end = http::create_via_header_value(viabuf.data(), req.http_major,
req.http_minor);
buf->append(viabuf.data(), end - viabuf.data());
buf->append("\r\n"); buf->append("\r\n");
} }

View File

@ -72,4 +72,18 @@ void test_shrpx_http_create_forwarded(void) {
StringRef::from_lit(""), StringRef::from_lit(""))); StringRef::from_lit(""), StringRef::from_lit("")));
} }
void test_shrpx_http_create_via_header_value(void) {
std::array<char, 16> buf;
auto end = http::create_via_header_value(std::begin(buf), 1, 1);
CU_ASSERT(("1.1 nghttpx" == StringRef{std::begin(buf), end}));
std::fill(std::begin(buf), std::end(buf), '\0');
end = http::create_via_header_value(std::begin(buf), 2, 0);
CU_ASSERT(("2 nghttpx" == StringRef{std::begin(buf), end}));
}
} // namespace shrpx } // namespace shrpx

View File

@ -32,6 +32,7 @@
namespace shrpx { namespace shrpx {
void test_shrpx_http_create_forwarded(void); void test_shrpx_http_create_forwarded(void);
void test_shrpx_http_create_via_header_value(void);
} // namespace shrpx } // namespace shrpx

View File

@ -1074,8 +1074,10 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
buf->append((*via).value); buf->append((*via).value);
buf->append(", "); buf->append(", ");
} }
buf->append( std::array<char, 16> viabuf;
http::create_via_header_value(resp.http_major, resp.http_minor)); auto end = http::create_via_header_value(viabuf.data(), resp.http_major,
resp.http_minor);
buf->append(viabuf.data(), end - std::begin(viabuf));
buf->append("\r\n"); buf->append("\r\n");
} }

View File

@ -1075,8 +1075,10 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
via_value = via->value.str(); via_value = via->value.str();
via_value += ", "; via_value += ", ";
} }
via_value += std::array<char, 16> viabuf;
http::create_via_header_value(resp.http_major, resp.http_minor); auto end = http::create_via_header_value(std::begin(viabuf),
resp.http_major, resp.http_minor);
via_value.append(std::begin(viabuf), end);
nv[hdidx++] = "via"; nv[hdidx++] = "via";
nv[hdidx++] = via_value.c_str(); nv[hdidx++] = via_value.c_str();
} }