Merge branch 'master' into hpack-exp
This commit is contained in:
commit
b193069110
|
@ -450,19 +450,20 @@ int Http2Handler::submit_response
|
||||||
{
|
{
|
||||||
std::string date_str = util::http_date(time(0));
|
std::string date_str = util::http_date(time(0));
|
||||||
const size_t static_size = 6;
|
const size_t static_size = 6;
|
||||||
auto nv = util::make_unique<const char*[]>(static_size+headers.size()*2+1);
|
auto nv = std::vector<const char*>();
|
||||||
nv[0] = ":status";
|
nv.reserve(static_size + headers.size() * 2 + 1);
|
||||||
nv[1] = status.c_str();
|
nv.push_back(":status");
|
||||||
nv[2] = "server";
|
nv.push_back(status.c_str());
|
||||||
nv[3] = NGHTTPD_SERVER.c_str();
|
nv.push_back("server");
|
||||||
nv[4] = "date";
|
nv.push_back(NGHTTPD_SERVER.c_str());
|
||||||
nv[5] = date_str.c_str();
|
nv.push_back("date");
|
||||||
for(int i = 0; i < (int)headers.size(); ++i) {
|
nv.push_back(date_str.c_str());
|
||||||
nv[static_size+i*2] = headers[i].first.c_str();
|
for(size_t i = 0; i < headers.size(); ++i) {
|
||||||
nv[static_size+i*2+1] = headers[i].second.c_str();
|
nv.push_back(headers[i].first.c_str());
|
||||||
|
nv.push_back(headers[i].second.c_str());
|
||||||
}
|
}
|
||||||
nv[static_size+headers.size()*2] = nullptr;
|
nv.push_back(nullptr);
|
||||||
int r = nghttp2_submit_response(session_, stream_id, nv.get(), data_prd);
|
int r = nghttp2_submit_response(session_, stream_id, nv.data(), data_prd);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
src/http2.cc
15
src/http2.cc
|
@ -269,16 +269,16 @@ bool value_lws(const nghttp2_nv *nv)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t copy_norm_headers_to_nv
|
void copy_norm_headers_to_nv
|
||||||
(const char **nv,
|
(std::vector<const char*>& nv,
|
||||||
const std::vector<std::pair<std::string, std::string>>& headers)
|
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;) {
|
for(i = 0, j = 0; i < headers.size() && j < IGN_HDLEN;) {
|
||||||
int rv = strcmp(headers[i].first.c_str(), IGN_HD[j]);
|
int rv = strcmp(headers[i].first.c_str(), IGN_HD[j]);
|
||||||
if(rv < 0) {
|
if(rv < 0) {
|
||||||
nv[nvlen++] = headers[i].first.c_str();
|
nv.push_back(headers[i].first.c_str());
|
||||||
nv[nvlen++] = headers[i].second.c_str();
|
nv.push_back(headers[i].second.c_str());
|
||||||
++i;
|
++i;
|
||||||
} else if(rv > 0) {
|
} else if(rv > 0) {
|
||||||
++j;
|
++j;
|
||||||
|
@ -287,10 +287,9 @@ size_t copy_norm_headers_to_nv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(; i < headers.size(); ++i) {
|
for(; i < headers.size(); ++i) {
|
||||||
nv[nvlen++] = headers[i].first.c_str();
|
nv.push_back(headers[i].first.c_str());
|
||||||
nv[nvlen++] = headers[i].second.c_str();
|
nv.push_back(headers[i].second.c_str());
|
||||||
}
|
}
|
||||||
return nvlen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void build_http1_headers_from_norm_headers
|
void build_http1_headers_from_norm_headers
|
||||||
|
|
|
@ -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'.
|
// Returns true if the value of |nv| includes only ' ' (0x20) or '\t'.
|
||||||
bool value_lws(const nghttp2_nv *nv);
|
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
|
// disallowed headers in HTTP/2.0 spec and headers which require
|
||||||
// special handling (i.e. via), are not copied.
|
// special handling (i.e. via), are not copied.
|
||||||
size_t copy_norm_headers_to_nv
|
void copy_norm_headers_to_nv
|
||||||
(const char **nv,
|
(std::vector<const char*>& nv,
|
||||||
const std::vector<std::pair<std::string, std::string>>& headers);
|
const std::vector<std::pair<std::string, std::string>>& headers);
|
||||||
|
|
||||||
// Appends HTTP/1.1 style header lines to |hdrs| from headers in
|
// Appends HTTP/1.1 style header lines to |hdrs| from headers in
|
||||||
|
|
|
@ -132,9 +132,9 @@ auto headers = std::vector<std::pair<std::string, std::string>>
|
||||||
|
|
||||||
void test_http2_copy_norm_headers_to_nv(void)
|
void test_http2_copy_norm_headers_to_nv(void)
|
||||||
{
|
{
|
||||||
const char* nv[30];
|
std::vector<const char*> nv;
|
||||||
size_t nvlen = http2::copy_norm_headers_to_nv(nv, headers);
|
http2::copy_norm_headers_to_nv(nv, headers);
|
||||||
CU_ASSERT(12 == nvlen);
|
CU_ASSERT(12 == nv.size());
|
||||||
CU_ASSERT(strcmp(nv[0], "alpha") == 0);
|
CU_ASSERT(strcmp(nv[0], "alpha") == 0);
|
||||||
CU_ASSERT(strcmp(nv[1], "0") == 0);
|
CU_ASSERT(strcmp(nv[1], "0") == 0);
|
||||||
CU_ASSERT(strcmp(nv[2], "bravo") == 0);
|
CU_ASSERT(strcmp(nv[2], "bravo") == 0);
|
||||||
|
|
|
@ -863,20 +863,19 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream)
|
||||||
auto end_headers = std::end(downstream->get_response_headers());
|
auto end_headers = std::end(downstream->get_response_headers());
|
||||||
size_t nheader = downstream->get_response_headers().size();
|
size_t nheader = downstream->get_response_headers().size();
|
||||||
// 4 means :status and possible via header field.
|
// 4 means :status and possible via header field.
|
||||||
auto nv = util::make_unique<const char*[]>(nheader * 2 + 4 + 1);
|
auto nv = std::vector<const char*>();
|
||||||
size_t hdidx = 0;
|
nv.reserve(nheader * 2 + 4 + 1);
|
||||||
std::string via_value;
|
std::string via_value;
|
||||||
auto response_status = util::utos(downstream->get_response_http_status());
|
auto response_status = util::utos(downstream->get_response_http_status());
|
||||||
nv[hdidx++] = ":status";
|
nv.push_back(":status");
|
||||||
nv[hdidx++] = response_status.c_str();
|
nv.push_back(response_status.c_str());
|
||||||
|
|
||||||
hdidx += http2::copy_norm_headers_to_nv(&nv[hdidx],
|
http2::copy_norm_headers_to_nv(nv, downstream->get_response_headers());
|
||||||
downstream->get_response_headers());
|
|
||||||
auto via = downstream->get_norm_response_header("via");
|
auto via = downstream->get_norm_response_header("via");
|
||||||
if(get_config()->no_via) {
|
if(get_config()->no_via) {
|
||||||
if(via != end_headers) {
|
if(via != end_headers) {
|
||||||
nv[hdidx++] = "via";
|
nv.push_back("via");
|
||||||
nv[hdidx++] = (*via).second.c_str();
|
nv.push_back((*via).second.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(via != end_headers) {
|
if(via != end_headers) {
|
||||||
|
@ -885,10 +884,10 @@ int Http2Upstream::on_downstream_header_complete(Downstream *downstream)
|
||||||
}
|
}
|
||||||
via_value += http::create_via_header_value
|
via_value += http::create_via_header_value
|
||||||
(downstream->get_response_major(), downstream->get_response_minor());
|
(downstream->get_response_major(), downstream->get_response_minor());
|
||||||
nv[hdidx++] = "via";
|
nv.push_back("via");
|
||||||
nv[hdidx++] = via_value.c_str();
|
nv.push_back(via_value.c_str());
|
||||||
}
|
}
|
||||||
nv[hdidx++] = nullptr;
|
nv.push_back(nullptr);
|
||||||
if(LOG_ENABLED(INFO)) {
|
if(LOG_ENABLED(INFO)) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
for(size_t i = 0; nv[i]; i += 2) {
|
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;
|
data_prd.read_callback = spdy_data_read_callback;
|
||||||
|
|
||||||
int rv;
|
int rv;
|
||||||
rv = nghttp2_submit_response(session_, downstream->get_stream_id(), nv.get(),
|
rv = nghttp2_submit_response(session_, downstream->get_stream_id(),
|
||||||
&data_prd);
|
nv.data(), &data_prd);
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
ULOG(FATAL, this) << "nghttp2_submit_response() failed";
|
ULOG(FATAL, this) << "nghttp2_submit_response() failed";
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -236,15 +236,15 @@ int SpdyDownstreamConnection::push_request_headers()
|
||||||
// 10 means :method, :scheme, :path and possible via and
|
// 10 means :method, :scheme, :path and possible via and
|
||||||
// x-forwarded-for header fields. We rename host header field as
|
// x-forwarded-for header fields. We rename host header field as
|
||||||
// :host.
|
// :host.
|
||||||
auto nv = util::make_unique<const char*[]>(nheader * 2 + 10 + 1);
|
auto nv = std::vector<const char*>();
|
||||||
size_t hdidx = 0;
|
nv.reserve(nheader * 2 + 10 + 1);
|
||||||
std::string via_value;
|
std::string via_value;
|
||||||
std::string xff_value;
|
std::string xff_value;
|
||||||
std::string scheme, path, query;
|
std::string scheme, path, query;
|
||||||
if(downstream_->get_request_method() == "CONNECT") {
|
if(downstream_->get_request_method() == "CONNECT") {
|
||||||
// No :scheme header field for CONNECT method.
|
// No :scheme header field for CONNECT method.
|
||||||
nv[hdidx++] = ":path";
|
nv.push_back(":path");
|
||||||
nv[hdidx++] = downstream_->get_request_path().c_str();
|
nv.push_back(downstream_->get_request_path().c_str());
|
||||||
} else {
|
} else {
|
||||||
http_parser_url u;
|
http_parser_url u;
|
||||||
const char *url = downstream_->get_request_path().c_str();
|
const char *url = downstream_->get_request_path().c_str();
|
||||||
|
@ -264,27 +264,26 @@ int SpdyDownstreamConnection::push_request_headers()
|
||||||
path += query;
|
path += query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nv[hdidx++] = ":scheme";
|
nv.push_back(":scheme");
|
||||||
if(scheme.empty()) {
|
if(scheme.empty()) {
|
||||||
// The default scheme is http. For SPDY upstream, the path must
|
// The default scheme is http. For SPDY upstream, the path must
|
||||||
// be absolute URI, so scheme should be provided.
|
// be absolute URI, so scheme should be provided.
|
||||||
nv[hdidx++] = "http";
|
nv.push_back("http");
|
||||||
} else {
|
} else {
|
||||||
nv[hdidx++] = scheme.c_str();
|
nv.push_back(scheme.c_str());
|
||||||
}
|
}
|
||||||
nv[hdidx++] = ":path";
|
nv.push_back(":path");
|
||||||
if(path.empty()) {
|
if(path.empty()) {
|
||||||
nv[hdidx++] = downstream_->get_request_path().c_str();
|
nv.push_back(downstream_->get_request_path().c_str());
|
||||||
} else {
|
} else {
|
||||||
nv[hdidx++] = path.c_str();
|
nv.push_back(path.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nv[hdidx++] = ":method";
|
nv.push_back(":method");
|
||||||
nv[hdidx++] = downstream_->get_request_method().c_str();
|
nv.push_back(downstream_->get_request_method().c_str());
|
||||||
|
|
||||||
hdidx += http2::copy_norm_headers_to_nv(&nv[hdidx],
|
http2::copy_norm_headers_to_nv(nv, downstream_->get_request_headers());
|
||||||
downstream_->get_request_headers());
|
|
||||||
|
|
||||||
auto host = downstream_->get_norm_request_header("host");
|
auto host = downstream_->get_norm_request_header("host");
|
||||||
if(host == end_headers) {
|
if(host == end_headers) {
|
||||||
|
@ -293,8 +292,8 @@ int SpdyDownstreamConnection::push_request_headers()
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
nv[hdidx++] = ":host";
|
nv.push_back(":host");
|
||||||
nv[hdidx++] = (*host).second.c_str();
|
nv.push_back((*host).second.c_str());
|
||||||
|
|
||||||
bool content_length = false;
|
bool content_length = false;
|
||||||
if(downstream_->get_norm_request_header("content-length") != end_headers) {
|
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");
|
auto expect = downstream_->get_norm_request_header("expect");
|
||||||
if(expect != end_headers &&
|
if(expect != end_headers &&
|
||||||
!util::strifind((*expect).second.c_str(), "100-continue")) {
|
!util::strifind((*expect).second.c_str(), "100-continue")) {
|
||||||
nv[hdidx++] = "expect";
|
nv.push_back("expect");
|
||||||
nv[hdidx++] = (*expect).second.c_str();
|
nv.push_back((*expect).second.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool chunked_encoding = false;
|
bool chunked_encoding = false;
|
||||||
|
@ -318,24 +317,24 @@ int SpdyDownstreamConnection::push_request_headers()
|
||||||
|
|
||||||
auto xff = downstream_->get_norm_request_header("x-forwarded-for");
|
auto xff = downstream_->get_norm_request_header("x-forwarded-for");
|
||||||
if(get_config()->add_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) {
|
if(xff != end_headers) {
|
||||||
xff_value = (*xff).second;
|
xff_value = (*xff).second;
|
||||||
xff_value += ", ";
|
xff_value += ", ";
|
||||||
}
|
}
|
||||||
xff_value += downstream_->get_upstream()->get_client_handler()->
|
xff_value += downstream_->get_upstream()->get_client_handler()->
|
||||||
get_ipaddr();
|
get_ipaddr();
|
||||||
nv[hdidx++] = xff_value.c_str();
|
nv.push_back(xff_value.c_str());
|
||||||
} else if(xff != end_headers) {
|
} else if(xff != end_headers) {
|
||||||
nv[hdidx++] = "x-forwarded-for";
|
nv.push_back("x-forwarded-for");
|
||||||
nv[hdidx++] = (*xff).second.c_str();
|
nv.push_back((*xff).second.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto via = downstream_->get_norm_request_header("via");
|
auto via = downstream_->get_norm_request_header("via");
|
||||||
if(get_config()->no_via) {
|
if(get_config()->no_via) {
|
||||||
if(via != end_headers) {
|
if(via != end_headers) {
|
||||||
nv[hdidx++] = "via";
|
nv.push_back("via");
|
||||||
nv[hdidx++] = (*via).second.c_str();
|
nv.push_back((*via).second.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(via != end_headers) {
|
if(via != end_headers) {
|
||||||
|
@ -344,10 +343,10 @@ int SpdyDownstreamConnection::push_request_headers()
|
||||||
}
|
}
|
||||||
via_value += http::create_via_header_value
|
via_value += http::create_via_header_value
|
||||||
(downstream_->get_request_major(), downstream_->get_request_minor());
|
(downstream_->get_request_major(), downstream_->get_request_minor());
|
||||||
nv[hdidx++] = "via";
|
nv.push_back("via");
|
||||||
nv[hdidx++] = via_value.c_str();
|
nv.push_back(via_value.c_str());
|
||||||
}
|
}
|
||||||
nv[hdidx++] = nullptr;
|
nv.push_back(nullptr);
|
||||||
|
|
||||||
if(LOG_ENABLED(INFO)) {
|
if(LOG_ENABLED(INFO)) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
@ -363,9 +362,9 @@ int SpdyDownstreamConnection::push_request_headers()
|
||||||
nghttp2_data_provider data_prd;
|
nghttp2_data_provider data_prd;
|
||||||
data_prd.source.ptr = this;
|
data_prd.source.ptr = this;
|
||||||
data_prd.read_callback = spdy_data_read_callback;
|
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 {
|
} else {
|
||||||
rv = spdy_->submit_request(this, 0, nv.get(), 0);
|
rv = spdy_->submit_request(this, 0, nv.data(), nullptr);
|
||||||
}
|
}
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
DCLOG(FATAL, this) << "nghttp2_submit_request() failed";
|
DCLOG(FATAL, this) << "nghttp2_submit_request() failed";
|
||||||
|
|
Loading…
Reference in New Issue