Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[core] finish must-revalidate support
Browse files Browse the repository at this point in the history
  • Loading branch information
kkaefer committed Aug 8, 2017
1 parent 68f470f commit f0a7c45
Show file tree
Hide file tree
Showing 22 changed files with 316 additions and 142 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ xcuserdata
/test/fixtures/offline_database/offline.db-*
/test/fixtures/offline_database/invalid.db
/test/fixtures/offline_database/invalid.db-*
/test/fixtures/offline_database/v*.db
/test/fixtures/offline_database/v*.db-*
/test/fixtures/offline_database/migrated.db
/test/fixtures/offline_database/migrated.db-*
/test/fixtures/**/actual.png
/test/fixtures/**/diff.png
/test/output
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/storage/resource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class Resource {
optional<Timestamp> priorModified = {};
optional<Timestamp> priorExpires = {};
optional<std::string> priorEtag = {};
std::shared_ptr<const std::string> priorData;
};

} // namespace mbgl
10 changes: 10 additions & 0 deletions include/mbgl/storage/response.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ class Response {
// This is set to true for 304 Not Modified responses.
bool notModified = false;

// This is set to true when the server requested that no expired resources be used by
// specifying "Cache-Control: must-revalidate".
bool mustRevalidate = false;

// The actual data of the response. Present only for non-error, non-notModified responses.
std::shared_ptr<const std::string> data;

Expand All @@ -37,6 +41,12 @@ class Response {
bool isFresh() const {
return expires ? *expires > util::now() : !error;
}

// Indicates whether we are allowed to use this response according to HTTP caching rules.
// It may or may not be stale.
bool isUsable() const {
return !mustRevalidate || (expires && *expires > util::now());
}
};

class Response::Error {
Expand Down
4 changes: 3 additions & 1 deletion platform/android/src/http_file_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ void HTTPRequest::onResponse(jni::JNIEnv& env, int code,
}

if (cacheControl) {
response.expires = http::CacheControl::parse(jni::Make<std::string>(env, cacheControl).c_str()).toTimePoint();
const auto cc = http::CacheControl::parse(jni::Make<std::string>(env, cacheControl).c_str());
response.expires = cc.toTimePoint();
response.mustRevalidate = cc.mustRevalidate;
}

if (expires) {
Expand Down
4 changes: 3 additions & 1 deletion platform/darwin/src/http_file_source.mm
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@ void cancel() {
NSDictionary *headers = [(NSHTTPURLResponse *)res allHeaderFields];
NSString *cache_control = [headers objectForKey:@"Cache-Control"];
if (cache_control) {
response.expires = http::CacheControl::parse([cache_control UTF8String]).toTimePoint();
const auto cc = http::CacheControl::parse([cache_control UTF8String]);
response.expires = cc.toTimePoint();
response.mustRevalidate = cc.mustRevalidate;
}

NSString *expires = [headers objectForKey:@"Expires"];
Expand Down
12 changes: 11 additions & 1 deletion platform/default/default_file_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,17 @@ class DefaultFileSource::Impl {
revalidation.priorModified = offlineResponse->modified;
revalidation.priorExpires = offlineResponse->expires;
revalidation.priorEtag = offlineResponse->etag;
callback(*offlineResponse);

// Don't return resources the server requested not to show when they're stale.
// Even if we can't directly use the response, we may still use it to send a
// conditional HTTP request.
if (offlineResponse->isUsable()) {
callback(*offlineResponse);
} else {
// Since we can't return the data immediately, we'll have to hold on so that
// we can return it later in case we get a 304 Not Modified response.
revalidation.priorData = offlineResponse->data;
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion platform/default/http_file_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,9 @@ size_t HTTPRequest::headerCallback(char *const buffer, const size_t size, const
baton->response->etag = std::string(buffer + begin, length - begin - 2); // remove \r\n
} else if ((begin = headerMatches("cache-control: ", buffer, length)) != std::string::npos) {
const std::string value { buffer + begin, length - begin - 2 }; // remove \r\n
baton->response->expires = http::CacheControl::parse(value.c_str()).toTimePoint();
const auto cc = http::CacheControl::parse(value.c_str());
baton->response->expires = cc.toTimePoint();
baton->response->mustRevalidate = cc.mustRevalidate;
} else if ((begin = headerMatches("expires: ", buffer, length)) != std::string::npos) {
const std::string value { buffer + begin, length - begin - 2 }; // remove \r\n
baton->response->expires = Timestamp{ Seconds(curl_getdate(value.c_str(), nullptr)) };
Expand Down
Loading

0 comments on commit f0a7c45

Please sign in to comment.