nghttpx: Don't push resource if link header has non empty loadpolicy
This commit is contained in:
parent
889e705f35
commit
7451a73def
47
src/http2.cc
47
src/http2.cc
|
@ -718,6 +718,30 @@ InputIt skip_to_right_dquote(InputIt first, InputIt last) {
|
|||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
// Returns true if link-param does not match pattern |pat| of length
|
||||
// |patlen| or it has empty value (""). |pat| should be parmname
|
||||
// followed by "=".
|
||||
bool check_link_param_empty(const char *first, const char *last,
|
||||
const char *pat, size_t patlen) {
|
||||
if (first + patlen <= last) {
|
||||
if (std::equal(pat, pat + patlen, first, util::CaseCmp())) {
|
||||
// we only accept URI if pat is followd by "" (e.g.,
|
||||
// loadpolicy="") here.
|
||||
if (first + patlen + 2 <= last) {
|
||||
if (*(first + patlen) != '"' || *(first + patlen + 1) != '"') {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// here we got invalid production (anchor=") or anchor=?
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace {
|
||||
std::pair<LinkHeader, const char *>
|
||||
parse_next_link_header_once(const char *first, const char *last) {
|
||||
|
@ -836,18 +860,17 @@ parse_next_link_header_once(const char *first, const char *last) {
|
|||
// we have to reject URI if we have nonempty anchor parameter.
|
||||
static const char ANCHOR[] = "anchor=";
|
||||
static const size_t ANCHORLEN = sizeof(ANCHOR) - 1;
|
||||
if (!ign && first + ANCHORLEN <= last) {
|
||||
if (std::equal(ANCHOR, ANCHOR + ANCHORLEN, first, util::CaseCmp())) {
|
||||
// we only accept URI if anchor="" here.
|
||||
if (first + ANCHORLEN + 2 <= last) {
|
||||
if (*(first + ANCHORLEN) != '"' || *(first + ANCHORLEN + 1) != '"') {
|
||||
ign = true;
|
||||
}
|
||||
} else {
|
||||
// here we got invalid production (anchor=") or anchor=?
|
||||
ign = true;
|
||||
}
|
||||
}
|
||||
if (!ign && !check_link_param_empty(first, last, ANCHOR, ANCHORLEN)) {
|
||||
ign = true;
|
||||
}
|
||||
|
||||
// reject URI if we have non-empty loadpolicy. This could be
|
||||
// tightened up to just pick up "next" or "insert".
|
||||
static const char LOADPOLICY[] = "loadpolicy=";
|
||||
static const size_t LOADPOLICYLEN = sizeof(LOADPOLICY) - 1;
|
||||
if (!ign &&
|
||||
!check_link_param_empty(first, last, LOADPOLICY, LOADPOLICYLEN)) {
|
||||
ign = true;
|
||||
}
|
||||
|
||||
auto param_first = first;
|
||||
|
|
|
@ -627,6 +627,19 @@ void test_http2_parse_link_header(void) {
|
|||
CU_ASSERT(1 == res.size());
|
||||
CU_ASSERT(std::make_pair(&s[36], &s[39]) == res[0].uri);
|
||||
}
|
||||
{
|
||||
// With loadpolicy="next", url should be ignored
|
||||
const char s[] = R"(<url>; rel=preload; loadpolicy="next")";
|
||||
auto res = http2::parse_link_header(s, sizeof(s) - 1);
|
||||
CU_ASSERT(0 == res.size());
|
||||
}
|
||||
{
|
||||
// url should be picked up if empty loadpolicy is specified
|
||||
const char s[] = R"(<url>; rel=preload; loadpolicy="")";
|
||||
auto res = http2::parse_link_header(s, sizeof(s) - 1);
|
||||
CU_ASSERT(1 == res.size());
|
||||
CU_ASSERT(std::make_pair(&s[1], &s[4]) == res[0].uri);
|
||||
}
|
||||
{
|
||||
// case-insensitive match
|
||||
const char s[] = R"(<url>; rel=preload; ANCHOR="#foo", <url>; )"
|
||||
|
|
Loading…
Reference in New Issue