nghttpx: Use Header to store custom request/response header fields
This commit is contained in:
parent
63a13ccb18
commit
b440f585bc
|
@ -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) {
|
||||||
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) {
|
||||||
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,
|
||||||
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 @@
|
||||||
|
|
||||||
#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 {
|
||||||
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);
|
||||||
// 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 {
|
||||||
|
|
||||||
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() {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
Loading…
Reference in New Issue