Commit e19d5efc authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

nghttpx: Allow absolute URI in Link header field for push

parent 6b38f7e0
......@@ -59,17 +59,12 @@ header field to initiate server push:
Link: </fonts/font.woff>; rel=preload
Link: </css/theme.css>; rel=preload
Currently, the following restrictions are applied for server push:
Currently, the following restriction is applied for server push:
1. URI-reference must not contain authority. If it exists, it is not
pushed. ``/fonts/font.woff`` and ``css/theme.css`` are eligible to
be pushed. ``https://example.org/fonts/font.woff`` and
``//example.org/css/theme.css`` are not.
2. The associated stream must have method "GET" or "POST". The
1. The associated stream must have method "GET" or "POST". The
associated stream's status code must be 200.
These limitations may be loosened in the future release.
This limitation may be loosened in the future release.
UNIX DOMAIN SOCKET
------------------
......
......@@ -1501,6 +1501,7 @@ int Http2Upstream::prepare_push_promise(Downstream *downstream) {
const char *relq = nullptr;
size_t relqlen = 0;
std::string authority, scheme;
http_parser_url v{};
rv = http_parser_parse_url(link_url, link_urllen, 0, &v);
if (rv != 0) {
......@@ -1518,9 +1519,18 @@ int Http2Upstream::prepare_push_promise(Downstream *downstream) {
relqlen = end - relq;
}
} else {
if (v.field_set & (1 << UF_SCHEMA)) {
http2::copy_url_component(scheme, &v, UF_SCHEMA, link_url);
}
if (v.field_set & (1 << UF_HOST)) {
continue;
http2::copy_url_component(authority, &v, UF_HOST, link_url);
if (v.field_set & (1 << UF_PORT)) {
authority += ":";
authority += util::utos(v.port);
}
}
if (v.field_set & (1 << UF_PATH)) {
auto &f = v.field_data[UF_PATH];
rel = link_url + f.off;
......@@ -1536,9 +1546,18 @@ int Http2Upstream::prepare_push_promise(Downstream *downstream) {
relqlen = f.len;
}
}
if (scheme.empty()) {
scheme = downstream->get_request_http2_scheme();
}
if (authority.empty()) {
authority = downstream->get_request_http2_authority();
}
auto path = http2::path_join(base, baselen, nullptr, 0, rel, rellen, relq,
relqlen);
rv = submit_push_promise(path, downstream);
rv = submit_push_promise(scheme, authority, path, downstream);
if (rv != 0) {
return -1;
}
......@@ -1547,7 +1566,9 @@ int Http2Upstream::prepare_push_promise(Downstream *downstream) {
return 0;
}
int Http2Upstream::submit_push_promise(const std::string &path,
int Http2Upstream::submit_push_promise(const std::string &scheme,
const std::string &authority,
const std::string &path,
Downstream *downstream) {
int rv;
std::vector<nghttp2_nv> nva;
......@@ -1555,13 +1576,9 @@ int Http2Upstream::submit_push_promise(const std::string &path,
// juse use "GET" for now
nva.push_back(http2::make_nv_ll(":method", "GET"));
nva.push_back(
http2::make_nv_ls(":scheme", downstream->get_request_http2_scheme()));
nva.push_back(http2::make_nv_ls(":scheme", 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_ls(":authority", authority));
}
nva.push_back(http2::make_nv_ls(":authority", authority));
for (auto &kv : downstream->get_request_headers()) {
switch (kv.token) {
......
......@@ -96,7 +96,9 @@ public:
void check_shutdown();
int prepare_push_promise(Downstream *downstream);
int submit_push_promise(const std::string &path, Downstream *downstream);
int submit_push_promise(const std::string &scheme,
const std::string &authority, const std::string &path,
Downstream *downstream);
int on_request_headers(Downstream *downstream, const nghttp2_frame *frame);
......
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