nghttpx: Fix broken server push after HTTP upgrade

This commit is contained in:
Tatsuhiro Tsujikawa 2015-03-01 11:03:48 +09:00
parent 185ebd7b79
commit cf5ac0f363
1 changed files with 45 additions and 7 deletions

View File

@ -106,6 +106,35 @@ int on_stream_close_callback(nghttp2_session *session, int32_t stream_id,
int Http2Upstream::upgrade_upstream(HttpsUpstream *http) {
int rv;
// to deduce :scheme and :authority, first we have to parse request
// URI.
http_parser_url u = {};
auto &url = http->get_downstream()->get_request_path();
std::string scheme, authority;
rv = http_parser_parse_url(url.c_str(), url.size(), 0, &u);
if (rv == 0) {
http2::copy_url_component(scheme, &u, UF_SCHEMA, url.c_str());
http2::copy_url_component(authority, &u, UF_HOST, url.c_str());
}
if (scheme.empty()) {
if (handler_->get_ssl()) {
scheme = "https";
} else {
scheme = "http";
}
}
if (!authority.empty()) {
if (authority.find(":") != std::string::npos) {
authority = "[" + authority;
authority += "]";
}
if (u.field_set & (1 << UF_PORT)) {
authority += ":";
authority += util::utos(u.port);
}
}
auto http2_settings = http->get_downstream()->get_http2_settings();
util::to_base64(http2_settings);
@ -129,6 +158,8 @@ int Http2Upstream::upgrade_upstream(HttpsUpstream *http) {
downstream->reset_upstream_rtimer();
downstream->set_stream_id(1);
downstream->set_priority(0);
downstream->set_request_http2_authority(authority);
downstream->set_request_http2_scheme(scheme);
downstream_queue_.add_active(std::move(downstream));
@ -1525,11 +1556,25 @@ int Http2Upstream::submit_push_promise(const std::string &path,
int rv;
std::vector<nghttp2_nv> nva;
nva.reserve(downstream->get_request_headers().size());
// juse use "GET" for now
nva.push_back(http2::make_nv_ll(":method", "GET"));
nva.push_back(
http2::make_nv(":scheme", downstream->get_request_http2_scheme()));
nva.push_back(http2::make_nv_ls(":path", path));
auto &authority = downstream->get_request_http2_authority();
if (!authority.empty()) {
nva.push_back(http2::make_nv(":authority", authority));
}
for (auto &kv : downstream->get_request_headers()) {
switch (kv.token) {
// TODO generate referer
case http2::HD__AUTHORITY:
case http2::HD__SCHEME:
case http2::HD__METHOD:
case http2::HD__PATH:
continue;
case http2::HD_ACCEPT_ENCODING:
case http2::HD_ACCEPT_LANGUAGE:
case http2::HD_CACHE_CONTROL:
@ -1537,13 +1582,6 @@ int Http2Upstream::submit_push_promise(const std::string &path,
case http2::HD_USER_AGENT:
nva.push_back(http2::make_nv(kv.name, kv.value, kv.no_index));
break;
case http2::HD__METHOD:
// juse use "GET" for now
nva.push_back(http2::make_nv_lc(":method", "GET"));
continue;
case http2::HD__PATH:
nva.push_back(http2::make_nv_ls(":path", path));
continue;
}
}