Commit b440f585 authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

nghttpx: Use Header to store custom request/response header fields

parent 63a13ccb
...@@ -54,9 +54,7 @@ ...@@ -54,9 +54,7 @@
#include "shrpx_log.h" #include "shrpx_log.h"
#include "shrpx_ssl.h" #include "shrpx_ssl.h"
#include "shrpx_http.h" #include "shrpx_http.h"
#include "http2.h"
#include "util.h" #include "util.h"
#include "template.h"
#include "base64.h" #include "base64.h"
namespace shrpx { namespace shrpx {
...@@ -279,7 +277,7 @@ std::string read_passwd_from_file(const char *filename) { ...@@ -279,7 +277,7 @@ std::string read_passwd_from_file(const char *filename) {
return line; return line;
} }
std::pair<std::string, std::string> parse_header(const char *optarg) { Headers::value_type parse_header(const char *optarg) {
const auto *colon = strchr(optarg, ':'); const auto *colon = strchr(optarg, ':');
if (colon == nullptr || colon == optarg) { if (colon == nullptr || colon == optarg) {
...@@ -290,16 +288,15 @@ std::pair<std::string, std::string> parse_header(const char *optarg) { ...@@ -290,16 +288,15 @@ std::pair<std::string, std::string> parse_header(const char *optarg) {
for (; *value == '\t' || *value == ' '; ++value) for (; *value == '\t' || *value == ' '; ++value)
; ;
auto p = std::make_pair(std::string(optarg, colon), auto p =
std::string(value, strlen(value))); Header(std::string(optarg, colon), std::string(value, strlen(value)));
util::inp_strlower(p.first); util::inp_strlower(p.name);
if (!nghttp2_check_header_name( if (!nghttp2_check_header_name(
reinterpret_cast<const uint8_t *>(p.first.c_str()), p.first.size()) || reinterpret_cast<const uint8_t *>(p.name.c_str()), p.name.size()) ||
!nghttp2_check_header_value( !nghttp2_check_header_value(
reinterpret_cast<const uint8_t *>(p.second.c_str()), reinterpret_cast<const uint8_t *>(p.value.c_str()), p.value.size())) {
p.second.size())) { return Header();
return {"", ""};
} }
return p; return p;
...@@ -2028,7 +2025,7 @@ int parse_config(const char *opt, const char *optarg, ...@@ -2028,7 +2025,7 @@ int parse_config(const char *opt, const char *optarg,
case SHRPX_OPTID_ADD_REQUEST_HEADER: case SHRPX_OPTID_ADD_REQUEST_HEADER:
case SHRPX_OPTID_ADD_RESPONSE_HEADER: { case SHRPX_OPTID_ADD_RESPONSE_HEADER: {
auto p = parse_header(optarg); auto p = parse_header(optarg);
if (p.first.empty()) { if (p.name.empty()) {
LOG(ERROR) << opt << ": invalid header field: " << optarg; LOG(ERROR) << opt << ": invalid header field: " << optarg;
return -1; return -1;
} }
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "shrpx_router.h" #include "shrpx_router.h"
#include "template.h" #include "template.h"
#include "http2.h"
using namespace nghttp2; using namespace nghttp2;
...@@ -461,8 +462,8 @@ struct HttpConfig { ...@@ -461,8 +462,8 @@ struct HttpConfig {
bool strip_incoming; bool strip_incoming;
} xff; } xff;
std::vector<AltSvc> altsvcs; std::vector<AltSvc> altsvcs;
std::vector<std::pair<std::string, std::string>> add_request_headers; Headers add_request_headers;
std::vector<std::pair<std::string, std::string>> add_response_headers; Headers add_response_headers;
StringRef server_name; StringRef server_name;
size_t request_header_field_buffer; size_t request_header_field_buffer;
size_t max_request_header_fields; size_t max_request_header_fields;
...@@ -633,7 +634,7 @@ std::string read_passwd_from_file(const char *filename); ...@@ -633,7 +634,7 @@ std::string read_passwd_from_file(const char *filename);
// like "NAME: VALUE". We require that NAME is non empty string. ":" // like "NAME: VALUE". We require that NAME is non empty string. ":"
// is allowed at the start of the NAME, but NAME == ":" is not // is allowed at the start of the NAME, but NAME == ":" is not
// allowed. This function returns pair of NAME and VALUE. // allowed. This function returns pair of NAME and VALUE.
std::pair<std::string, std::string> parse_header(const char *optarg); Headers::value_type parse_header(const char *optarg);
std::vector<LogFragment> parse_log_format(const char *optarg); std::vector<LogFragment> parse_log_format(const char *optarg);
......
...@@ -38,32 +38,32 @@ namespace shrpx { ...@@ -38,32 +38,32 @@ namespace shrpx {
void test_shrpx_config_parse_header(void) { void test_shrpx_config_parse_header(void) {
auto p = parse_header("a: b"); auto p = parse_header("a: b");
CU_ASSERT("a" == p.first); CU_ASSERT("a" == p.name);
CU_ASSERT("b" == p.second); CU_ASSERT("b" == p.value);
p = parse_header("a: b"); p = parse_header("a: b");
CU_ASSERT("a" == p.first); CU_ASSERT("a" == p.name);
CU_ASSERT("b" == p.second); CU_ASSERT("b" == p.value);
p = parse_header(":a: b"); p = parse_header(":a: b");
CU_ASSERT(p.first.empty()); CU_ASSERT(p.name.empty());
p = parse_header("a: :b"); p = parse_header("a: :b");
CU_ASSERT("a" == p.first); CU_ASSERT("a" == p.name);
CU_ASSERT(":b" == p.second); CU_ASSERT(":b" == p.value);
p = parse_header(": b"); p = parse_header(": b");
CU_ASSERT(p.first.empty()); CU_ASSERT(p.name.empty());
p = parse_header("alpha: bravo charlie"); p = parse_header("alpha: bravo charlie");
CU_ASSERT("alpha" == p.first); CU_ASSERT("alpha" == p.name);
CU_ASSERT("bravo charlie" == p.second); CU_ASSERT("bravo charlie" == p.value);
p = parse_header("a,: b"); p = parse_header("a,: b");
CU_ASSERT(p.first.empty()); CU_ASSERT(p.name.empty());
p = parse_header("a: b\x0a"); p = parse_header("a: b\x0a");
CU_ASSERT(p.first.empty()); CU_ASSERT(p.name.empty());
} }
void test_shrpx_config_parse_log_format(void) { void test_shrpx_config_parse_log_format(void) {
......
...@@ -422,7 +422,7 @@ int Http2DownstreamConnection::push_request_headers() { ...@@ -422,7 +422,7 @@ int Http2DownstreamConnection::push_request_headers() {
} }
for (auto &p : httpconf.add_request_headers) { for (auto &p : httpconf.add_request_headers) {
nva.push_back(http2::make_nv_nocopy(p.first, p.second)); nva.push_back(http2::make_nv_nocopy(p.name, p.value));
} }
if (LOG_ENABLED(INFO)) { if (LOG_ENABLED(INFO)) {
......
...@@ -1436,7 +1436,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) { ...@@ -1436,7 +1436,7 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream) {
} }
for (auto &p : httpconf.add_response_headers) { for (auto &p : httpconf.add_response_headers) {
nva.push_back(http2::make_nv_nocopy(p.first, p.second)); nva.push_back(http2::make_nv_nocopy(p.name, p.value));
} }
if (downstream->get_stream_id() % 2 == 0) { if (downstream->get_stream_id() % 2 == 0) {
......
...@@ -418,9 +418,9 @@ int HttpDownstreamConnection::push_request_headers() { ...@@ -418,9 +418,9 @@ int HttpDownstreamConnection::push_request_headers() {
} }
for (auto &p : httpconf.add_request_headers) { for (auto &p : httpconf.add_request_headers) {
buf->append(p.first); buf->append(p.name);
buf->append(": "); buf->append(": ");
buf->append(p.second); buf->append(p.value);
buf->append("\r\n"); buf->append("\r\n");
} }
......
...@@ -1022,9 +1022,9 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) { ...@@ -1022,9 +1022,9 @@ int HttpsUpstream::on_downstream_header_complete(Downstream *downstream) {
} }
for (auto &p : httpconf.add_response_headers) { for (auto &p : httpconf.add_response_headers) {
buf->append(p.first); buf->append(p.name);
buf->append(": "); buf->append(": ");
buf->append(p.second); buf->append(p.value);
buf->append("\r\n"); buf->append("\r\n");
} }
......
...@@ -1064,8 +1064,8 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) { ...@@ -1064,8 +1064,8 @@ int SpdyUpstream::on_downstream_header_complete(Downstream *downstream) {
} }
for (auto &p : httpconf.add_response_headers) { for (auto &p : httpconf.add_response_headers) {
nv[hdidx++] = p.first.c_str(); nv[hdidx++] = p.name.c_str();
nv[hdidx++] = p.second.c_str(); nv[hdidx++] = p.value.c_str();
} }
nv[hdidx++] = 0; nv[hdidx++] = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment