Commit fdabbaf4 authored by Dave Tapuska's avatar Dave Tapuska Committed by Commit Bot

Add parsing of stale-while-revalidate cache control field.

Add the ability to fetch the stale while revalidate field out of the
cache control header.

BUG=348877

Change-Id: I7e6132b71c10c462019687a150e259e02fe9c332
Reviewed-on: https://chromium-review.googlesource.com/1101242
Commit-Queue: Dave Tapuska <dtapuska@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#568002}
parent 00e7301b
......@@ -404,6 +404,15 @@ double ResourceResponse::CacheControlMaxAge() const {
return cache_control_header_.max_age;
}
double ResourceResponse::CacheControlStaleWhileRevalidate() const {
if (!cache_control_header_.parsed) {
cache_control_header_ = ParseCacheControlDirectives(
http_header_fields_.Get(kCacheControlHeader),
http_header_fields_.Get(kPragmaHeader));
}
return cache_control_header_.stale_while_revalidate;
}
static double ParseDateValueInHeader(const HTTPHeaderMap& headers,
const AtomicString& header_name) {
const AtomicString& header_value = headers.Get(header_name);
......
......@@ -218,6 +218,7 @@ class PLATFORM_EXPORT ResourceResponse final {
bool CacheControlContainsMustRevalidate() const;
bool HasCacheValidatorFields() const;
double CacheControlMaxAge() const;
double CacheControlStaleWhileRevalidate() const;
double Date() const;
double Age() const;
double Expires() const;
......
......@@ -507,11 +507,14 @@ CacheControlHeader ParseCacheControlDirectives(
CacheControlHeader cache_control_header;
cache_control_header.parsed = true;
cache_control_header.max_age = std::numeric_limits<double>::quiet_NaN();
cache_control_header.stale_while_revalidate =
std::numeric_limits<double>::quiet_NaN();
static const char kNoCacheDirective[] = "no-cache";
static const char kNoStoreDirective[] = "no-store";
static const char kMustRevalidateDirective[] = "must-revalidate";
static const char kMaxAgeDirective[] = "max-age";
static const char kStaleWhileRevalidateDirective[] = "stale-while-revalidate";
if (!cache_control_value.IsEmpty()) {
Vector<std::pair<String, String>> directives;
......@@ -540,6 +543,17 @@ CacheControlHeader ParseCacheControlDirectives(
double max_age = directives[i].second.ToDouble(&ok);
if (ok)
cache_control_header.max_age = max_age;
} else if (DeprecatedEqualIgnoringCase(directives[i].first,
kStaleWhileRevalidateDirective)) {
if (!std::isnan(cache_control_header.stale_while_revalidate)) {
// First stale-while-revalidate directive wins if there are multiple
// ones.
continue;
}
bool ok;
double stale_while_revalidate = directives[i].second.ToDouble(&ok);
if (ok)
cache_control_header.stale_while_revalidate = stale_while_revalidate;
}
}
}
......
......@@ -72,13 +72,15 @@ struct CacheControlHeader {
bool contains_no_store : 1;
bool contains_must_revalidate : 1;
double max_age;
double stale_while_revalidate;
CacheControlHeader()
: parsed(false),
contains_no_cache(false),
contains_no_store(false),
contains_must_revalidate(false),
max_age(0.0) {}
max_age(0.0),
stale_while_revalidate(0.0) {}
};
using ServerTimingHeaderVector = Vector<std::unique_ptr<ServerTimingHeader>>;
......
......@@ -22,6 +22,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives("no-cache no-store", AtomicString());
EXPECT_TRUE(header.parsed);
......@@ -29,6 +30,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header =
ParseCacheControlDirectives("no-store must-revalidate", AtomicString());
......@@ -37,6 +39,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_TRUE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives("max-age=0", AtomicString());
EXPECT_TRUE(header.parsed);
......@@ -44,6 +47,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_EQ(0.0, header.max_age);
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives("max-age", AtomicString());
EXPECT_TRUE(header.parsed);
......@@ -51,6 +55,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives("max-age=0 no-cache", AtomicString());
EXPECT_TRUE(header.parsed);
......@@ -58,6 +63,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_EQ(0.0, header.max_age);
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives("no-cache=foo", AtomicString());
EXPECT_TRUE(header.parsed);
......@@ -65,6 +71,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives("nonsense", AtomicString());
EXPECT_TRUE(header.parsed);
......@@ -72,6 +79,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives("\rno-cache\n\t\v\0\b", AtomicString());
EXPECT_TRUE(header.parsed);
......@@ -79,6 +87,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives(" no-cache ", AtomicString());
EXPECT_TRUE(header.parsed);
......@@ -86,6 +95,7 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives(AtomicString(), "no-cache");
EXPECT_TRUE(header.parsed);
......@@ -93,6 +103,16 @@ TEST(HTTPParsersTest, ParseCacheControl) {
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_TRUE(std::isnan(header.stale_while_revalidate));
header = ParseCacheControlDirectives(
"stale-while-revalidate=2,stale-while-revalidate=3", AtomicString());
EXPECT_TRUE(header.parsed);
EXPECT_FALSE(header.contains_no_cache);
EXPECT_FALSE(header.contains_no_store);
EXPECT_FALSE(header.contains_must_revalidate);
EXPECT_TRUE(std::isnan(header.max_age));
EXPECT_EQ(2.0, header.stale_while_revalidate);
}
TEST(HTTPParsersTest, CommaDelimitedHeaderSet) {
......
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