src: Use std::vector to store name/value pairs

This commit is contained in:
Tatsuhiro Tsujikawa 2013-10-23 23:18:24 +09:00
parent 7b87d71121
commit 8c855c5567
6 changed files with 66 additions and 68 deletions

View File

@ -450,19 +450,20 @@ int Http2Handler::submit_response
{
std::string date_str = util::http_date(time(0));
const size_t static_size = 6;
auto nv = util::make_unique<const char*[]>(static_size+headers.size()*2+1);
nv[0] = ":status";
nv[1] = status.c_str();
nv[2] = "server";
nv[3] = NGHTTPD_SERVER.c_str();
nv[4] = "date";
nv[5] = date_str.c_str();
for(int i = 0; i < (int)headers.size(); ++i) {
nv[static_size+i*2] = headers[i].first.c_str();
nv[static_size+i*2+1] = headers[i].second.c_str();
auto nv = std::vector<const char*>();
nv.reserve(static_size + headers.size() * 2 + 1);
nv.push_back(":status");
nv.push_back(status.c_str());
nv.push_back("server");
nv.push_back(NGHTTPD_SERVER.c_str());
nv.push_back("date");
nv.push_back(date_str.c_str());
for(size_t i = 0; i < headers.size(); ++i) {
nv.push_back(headers[i].first.c_str());
nv.push_back(headers[i].second.c_str());
}
nv[static_size+headers.size()*2] = nullptr;
int r = nghttp2_submit_response(session_, stream_id, nv.get(), data_prd);
nv.push_back(nullptr);
int r = nghttp2_submit_response(session_, stream_id, nv.data(), data_prd);
return r;
}

View File

@ -269,16 +269,16 @@ bool value_lws(const nghttp2_nv *nv)
return true;
}
size_t copy_norm_headers_to_nv
(const char **nv,
void copy_norm_headers_to_nv
(std::vector<const char*>& nv,
const std::vector<std::pair<std::string, std::string>>& headers)
{
size_t i, j, nvlen = 0;
size_t i, j;
for(i = 0, j = 0; i < headers.size() && j < IGN_HDLEN;) {
int rv = strcmp(headers[i].first.c_str(), IGN_HD[j]);
if(rv < 0) {
nv[nvlen++] = headers[i].first.c_str();
nv[nvlen++] = headers[i].second.c_str();
nv.push_back(headers[i].first.c_str());
nv.push_back(headers[i].second.c_str());
++i;
} else if(rv > 0) {
++j;
@ -287,10 +287,9 @@ size_t copy_norm_headers_to_nv
}
}
for(; i < headers.size(); ++i) {
nv[nvlen++] = headers[i].first.c_str();
nv[nvlen++] = headers[i].second.c_str();
nv.push_back(headers[i].first.c_str());
nv.push_back(headers[i].second.c_str());
}
return nvlen;
}
void build_http1_headers_from_norm_headers

View File

@ -89,11 +89,11 @@ std::string value_to_str(const nghttp2_nv *nv);
// Returns true if the value of |nv| includes only ' ' (0x20) or '\t'.
bool value_lws(const nghttp2_nv *nv);
// Copies headers in |headers| to |nv|. Certain headers, including
// Appends headers in |headers| to |nv|. Certain headers, including
// disallowed headers in HTTP/2.0 spec and headers which require
// special handling (i.e. via), are not copied.
size_t copy_norm_headers_to_nv
(const char **nv,
void copy_norm_headers_to_nv
(std::vector<const char*>& nv,
const std::vector<std::pair<std::string, std::string>>& headers);
// Appends HTTP/1.1 style header lines to |hdrs| from headers in

View File

@ -132,9 +132,9 @@ auto headers = std::vector<std::pair<std::string, std::string>>
void test_http2_copy_norm_headers_to_nv(void)
{
const char* nv[30];
size_t nvlen = http2::copy_norm_headers_to_nv(nv, headers);
CU_ASSERT(12 == nvlen);
std::vector<const char*> nv;
http2::copy_norm_headers_to_nv(nv, headers);
CU_ASSERT(12 == nv.size());
CU_ASSERT(strcmp(nv[0], "alpha") == 0);
CU_ASSERT(strcmp(nv[1], "0") == 0);
CU_ASSERT(strcmp(nv[2], "bravo") == 0);

View File

@ -863,20 +863,19 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream)
auto end_headers = std::end(downstream->get_response_headers());
size_t nheader = downstream->get_response_headers().size();
// 4 means :status and possible via header field.
auto nv = util::make_unique<const char*[]>(nheader * 2 + 4 + 1);
size_t hdidx = 0;
auto nv = std::vector<const char*>();
nv.reserve(nheader * 2 + 4 + 1);
std::string via_value;
auto response_status = util::utos(downstream->get_response_http_status());
nv[hdidx++] = ":status";
nv[hdidx++] = response_status.c_str();
nv.push_back(":status");
nv.push_back(response_status.c_str());
hdidx += http2::copy_norm_headers_to_nv(&nv[hdidx],
downstream->get_response_headers());
http2::copy_norm_headers_to_nv(nv, downstream->get_response_headers());
auto via = downstream->get_norm_response_header("via");
if(get_config()->no_via) {
if(via != end_headers) {
nv[hdidx++] = "via";
nv[hdidx++] = (*via).second.c_str();
nv.push_back("via");
nv.push_back((*via).second.c_str());
}
} else {
if(via != end_headers) {
@ -885,10 +884,10 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream)
}
via_value += http::create_via_header_value
(downstream->get_response_major(), downstream->get_response_minor());
nv[hdidx++] = "via";
nv[hdidx++] = via_value.c_str();
nv.push_back("via");
nv.push_back(via_value.c_str());
}
nv[hdidx++] = nullptr;
nv.push_back(nullptr);
if(LOG_ENABLED(INFO)) {
std::stringstream ss;
for(size_t i = 0; nv[i]; i += 2) {
@ -903,8 +902,8 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream)
data_prd.read_callback = spdy_data_read_callback;
int rv;
rv = nghttp2_submit_response(session_, downstream->get_stream_id(), nv.get(),
&data_prd);
rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
nv.data(), &data_prd);
if(rv != 0) {
ULOG(FATAL, this) << "nghttp2_submit_response() failed";
return -1;

View File

@ -236,15 +236,15 @@ int SpdyDownstreamConnection::push_request_headers()
// 10 means :method, :scheme, :path and possible via and
// x-forwarded-for header fields. We rename host header field as
// :host.
auto nv = util::make_unique<const char*[]>(nheader * 2 + 10 + 1);
size_t hdidx = 0;
auto nv = std::vector<const char*>();
nv.reserve(nheader * 2 + 10 + 1);
std::string via_value;
std::string xff_value;
std::string scheme, path, query;
if(downstream_->get_request_method() == "CONNECT") {
// No :scheme header field for CONNECT method.
nv[hdidx++] = ":path";
nv[hdidx++] = downstream_->get_request_path().c_str();
nv.push_back(":path");
nv.push_back(downstream_->get_request_path().c_str());
} else {
http_parser_url u;
const char *url = downstream_->get_request_path().c_str();
@ -264,27 +264,26 @@ int SpdyDownstreamConnection::push_request_headers()
path += query;
}
}
nv[hdidx++] = ":scheme";
nv.push_back(":scheme");
if(scheme.empty()) {
// The default scheme is http. For SPDY upstream, the path must
// be absolute URI, so scheme should be provided.
nv[hdidx++] = "http";
nv.push_back("http");
} else {
nv[hdidx++] = scheme.c_str();
nv.push_back(scheme.c_str());
}
nv[hdidx++] = ":path";
nv.push_back(":path");
if(path.empty()) {
nv[hdidx++] = downstream_->get_request_path().c_str();
nv.push_back(downstream_->get_request_path().c_str());
} else {
nv[hdidx++] = path.c_str();
nv.push_back(path.c_str());
}
}
nv[hdidx++] = ":method";
nv[hdidx++] = downstream_->get_request_method().c_str();
nv.push_back(":method");
nv.push_back(downstream_->get_request_method().c_str());
hdidx += http2::copy_norm_headers_to_nv(&nv[hdidx],
downstream_->get_request_headers());
http2::copy_norm_headers_to_nv(nv, downstream_->get_request_headers());
auto host = downstream_->get_norm_request_header("host");
if(host == end_headers) {
@ -293,8 +292,8 @@ int SpdyDownstreamConnection::push_request_headers()
}
return -1;
}
nv[hdidx++] = ":host";
nv[hdidx++] = (*host).second.c_str();
nv.push_back(":host");
nv.push_back((*host).second.c_str());
bool content_length = false;
if(downstream_->get_norm_request_header("content-length") != end_headers) {
@ -304,8 +303,8 @@ int SpdyDownstreamConnection::push_request_headers()
auto expect = downstream_->get_norm_request_header("expect");
if(expect != end_headers &&
!util::strifind((*expect).second.c_str(), "100-continue")) {
nv[hdidx++] = "expect";
nv[hdidx++] = (*expect).second.c_str();
nv.push_back("expect");
nv.push_back((*expect).second.c_str());
}
bool chunked_encoding = false;
@ -318,24 +317,24 @@ int SpdyDownstreamConnection::push_request_headers()
auto xff = downstream_->get_norm_request_header("x-forwarded-for");
if(get_config()->add_x_forwarded_for) {
nv[hdidx++] = "x-forwarded-for";
nv.push_back("x-forwarded-for");
if(xff != end_headers) {
xff_value = (*xff).second;
xff_value += ", ";
}
xff_value += downstream_->get_upstream()->get_client_handler()->
get_ipaddr();
nv[hdidx++] = xff_value.c_str();
nv.push_back(xff_value.c_str());
} else if(xff != end_headers) {
nv[hdidx++] = "x-forwarded-for";
nv[hdidx++] = (*xff).second.c_str();
nv.push_back("x-forwarded-for");
nv.push_back((*xff).second.c_str());
}
auto via = downstream_->get_norm_request_header("via");
if(get_config()->no_via) {
if(via != end_headers) {
nv[hdidx++] = "via";
nv[hdidx++] = (*via).second.c_str();
nv.push_back("via");
nv.push_back((*via).second.c_str());
}
} else {
if(via != end_headers) {
@ -344,10 +343,10 @@ int SpdyDownstreamConnection::push_request_headers()
}
via_value += http::create_via_header_value
(downstream_->get_request_major(), downstream_->get_request_minor());
nv[hdidx++] = "via";
nv[hdidx++] = via_value.c_str();
nv.push_back("via");
nv.push_back(via_value.c_str());
}
nv[hdidx++] = nullptr;
nv.push_back(nullptr);
if(LOG_ENABLED(INFO)) {
std::stringstream ss;
@ -363,9 +362,9 @@ int SpdyDownstreamConnection::push_request_headers()
nghttp2_data_provider data_prd;
data_prd.source.ptr = this;
data_prd.read_callback = spdy_data_read_callback;
rv = spdy_->submit_request(this, 0, nv.get(), &data_prd);
rv = spdy_->submit_request(this, 0, nv.data(), &data_prd);
} else {
rv = spdy_->submit_request(this, 0, nv.get(), 0);
rv = spdy_->submit_request(this, 0, nv.data(), nullptr);
}
if(rv != 0) {
DCLOG(FATAL, this) << "nghttp2_submit_request() failed";