Index: chrome/browser/extensions/extension_protocols.cc |
diff --git a/chrome/browser/extensions/extension_protocols.cc b/chrome/browser/extensions/extension_protocols.cc |
index d52e81f2c8f9bc732e4573cf07d2fbec9fff557c..e865876b88195b8d9813a947b084d849bc4d86f5 100644 |
--- a/chrome/browser/extensions/extension_protocols.cc |
+++ b/chrome/browser/extensions/extension_protocols.cc |
@@ -6,12 +6,15 @@ |
#include <algorithm> |
+#include "base/base64.h" |
#include "base/compiler_specific.h" |
+#include "base/file_util.h" |
#include "base/files/file_path.h" |
#include "base/logging.h" |
#include "base/memory/weak_ptr.h" |
#include "base/message_loop.h" |
#include "base/path_service.h" |
+#include "base/sha1.h" |
#include "base/string_util.h" |
#include "base/stringprintf.h" |
#include "base/threading/thread_restrictions.h" |
@@ -52,7 +55,8 @@ using extensions::SharedModuleInfo; |
namespace { |
net::HttpResponseHeaders* BuildHttpHeaders( |
- const std::string& content_security_policy, bool send_cors_header) { |
+ const std::string& content_security_policy, bool send_cors_header, |
+ const base::Time& last_modified_time) { |
std::string raw_headers; |
raw_headers.append("HTTP/1.1 200 OK"); |
if (!content_security_policy.empty()) { |
@@ -65,6 +69,24 @@ net::HttpResponseHeaders* BuildHttpHeaders( |
raw_headers.append(1, '\0'); |
raw_headers.append("Access-Control-Allow-Origin: *"); |
} |
+ |
+ if (!last_modified_time.is_null()) { |
+ // Hash the time and make an etag to avoid exposing the exact |
+ // user installation time of the extension. |
+ std::string hash = base::StringPrintf("%f", last_modified_time.ToDoubleT()); |
rvargas (doing something else)
2013/06/03 21:12:37
nit: ToInternalValue ?
jvoung (off chromium)
2013/06/03 22:08:22
Done.
|
+ hash = base::SHA1HashString(hash); |
+ std::string etag; |
+ if (base::Base64Encode(hash, &etag)) { |
+ raw_headers.append(1, '\0'); |
+ raw_headers.append("ETag: \""); |
+ raw_headers.append(etag); |
+ raw_headers.append("\""); |
+ // Also force revalidation. |
+ raw_headers.append(1, '\0'); |
+ raw_headers.append("cache-control: no-cache"); |
+ } |
+ } |
+ |
raw_headers.append(2, '\0'); |
return new net::HttpResponseHeaders(raw_headers); |
} |
@@ -75,6 +97,15 @@ void ReadMimeTypeFromFile(const base::FilePath& filename, |
*result = net::GetMimeTypeFromFile(filename, mime_type); |
} |
+void GetLastModifiedTime(const base::FilePath& filename, |
+ base::Time* last_modified_time) { |
+ if (file_util::PathExists(filename)) { |
+ base::PlatformFileInfo info; |
+ if (file_util::GetFileInfo(filename, &info)) |
+ *last_modified_time = info.last_modified; |
+ } |
+} |
+ |
class URLRequestResourceBundleJob : public net::URLRequestSimpleJob { |
public: |
URLRequestResourceBundleJob(net::URLRequest* request, |
@@ -87,8 +118,10 @@ class URLRequestResourceBundleJob : public net::URLRequestSimpleJob { |
filename_(filename), |
resource_id_(resource_id), |
weak_factory_(this) { |
+ // Leave cache headers out of resource bundle requests. |
response_info_.headers = BuildHttpHeaders(content_security_policy, |
- send_cors_header); |
+ send_cors_header, |
+ base::Time()); |
} |
// Overridden from URLRequestSimpleJob: |
@@ -162,8 +195,10 @@ class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob { |
: net::URLRequestSimpleJob(request, network_delegate), |
extension_(extension) { |
const bool send_cors_headers = false; |
+ // Leave cache headers out of generated background page jobs. |
response_info_.headers = BuildHttpHeaders(content_security_policy, |
- send_cors_headers); |
+ send_cors_headers, |
+ base::Time()); |
} |
// Overridden from URLRequestSimpleJob: |
@@ -197,9 +232,12 @@ class GeneratedBackgroundPageJob : public net::URLRequestSimpleJob { |
net::HttpResponseInfo response_info_; |
}; |
-void ReadResourceFilePath(const extensions::ExtensionResource& resource, |
- base::FilePath* file_path) { |
+void ReadResourceFilePathAndLastModifiedTime( |
+ const extensions::ExtensionResource& resource, |
+ base::FilePath* file_path, |
+ base::Time* last_modified_time) { |
*file_path = resource.GetFilePath(); |
+ GetLastModifiedTime(*file_path, last_modified_time); |
} |
class URLRequestExtensionJob : public net::URLRequestFileJob { |
@@ -215,9 +253,9 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { |
// TODO(tc): Move all of these files into resources.pak so we don't break |
// when updating on Linux. |
resource_(extension_id, directory_path, relative_path), |
+ content_security_policy_(content_security_policy), |
+ send_cors_header_(send_cors_header), |
weak_factory_(this) { |
- response_info_.headers = BuildHttpHeaders(content_security_policy, |
- send_cors_header); |
} |
virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE { |
@@ -226,13 +264,16 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { |
virtual void Start() OVERRIDE { |
base::FilePath* read_file_path = new base::FilePath; |
+ base::Time* last_modified_time = new base::Time(); |
bool posted = base::WorkerPool::PostTaskAndReply( |
FROM_HERE, |
- base::Bind(&ReadResourceFilePath, resource_, |
- base::Unretained(read_file_path)), |
- base::Bind(&URLRequestExtensionJob::OnFilePathRead, |
+ base::Bind(&ReadResourceFilePathAndLastModifiedTime, resource_, |
+ base::Unretained(read_file_path), |
+ base::Unretained(last_modified_time)), |
+ base::Bind(&URLRequestExtensionJob::OnFilePathAndLastModifiedTimeRead, |
weak_factory_.GetWeakPtr(), |
- base::Owned(read_file_path)), |
+ base::Owned(read_file_path), |
+ base::Owned(last_modified_time)), |
true /* task is slow */); |
DCHECK(posted); |
} |
@@ -240,13 +281,20 @@ class URLRequestExtensionJob : public net::URLRequestFileJob { |
private: |
virtual ~URLRequestExtensionJob() {} |
- void OnFilePathRead(base::FilePath* read_file_path) { |
+ void OnFilePathAndLastModifiedTimeRead(base::FilePath* read_file_path, |
+ base::Time* last_modified_time) { |
file_path_ = *read_file_path; |
+ response_info_.headers = BuildHttpHeaders( |
+ content_security_policy_, |
+ send_cors_header_, |
+ *last_modified_time); |
URLRequestFileJob::Start(); |
} |
net::HttpResponseInfo response_info_; |
extensions::ExtensionResource resource_; |
+ std::string content_security_policy_; |
+ bool send_cors_header_; |
base::WeakPtrFactory<URLRequestExtensionJob> weak_factory_; |
}; |