nghttpx: Don't push resource if link header has non empty loadpolicy

This commit is contained in:
Tatsuhiro Tsujikawa 2015-04-12 17:42:25 +09:00
parent 889e705f35
commit 7451a73def
2 changed files with 48 additions and 12 deletions

View File

@ -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;

View File

@ -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>; )"