summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/apps/guest_view/web_view_browsertest.cc79
-rw-r--r--chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc24
-rw-r--r--chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h2
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/embedder.js131
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/guest.html10
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/guest.js33
-rw-r--r--extensions/DEPS1
-rw-r--r--extensions/browser/BUILD.gn1
-rw-r--r--extensions/browser/guest_view/web_view/web_view_guest.cc30
-rw-r--r--extensions/browser/guest_view/web_view/web_view_guest_delegate.h4
-rw-r--r--extensions/extensions.gyp1
11 files changed, 174 insertions, 142 deletions
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 4eb7744..44cc3ae 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -89,6 +89,7 @@ namespace {
const char kEmptyResponsePath[] = "/close-socket";
const char kRedirectResponsePath[] = "/server-redirect";
const char kUserAgentRedirectResponsePath[] = "/detect-user-agent";
+const char kCacheResponsePath[] = "/cache-control-response";
const char kRedirectResponseFullPath[] =
"/extensions/platform_apps/web_view/shim/guest_redirect.html";
@@ -256,40 +257,6 @@ class MockWebContentsDelegate : public content::WebContentsDelegate {
DISALLOW_COPY_AND_ASSIGN(MockWebContentsDelegate);
};
-class MockWebViewGuestDelegate : public extensions::WebViewGuestDelegate {
- public:
- explicit MockWebViewGuestDelegate(extensions::WebViewGuest* web_view_guest)
- : web_view_guest_(web_view_guest), clear_cache_called_(false) {}
- ~MockWebViewGuestDelegate() override {}
-
- // WebViewGuestDelegate implementation.
- void ClearCache(base::Time remove_since,
- const base::Closure& callback) override {
- clear_cache_called_ = true;
- base::MessageLoop::current()->PostTask(FROM_HERE, callback);
- }
- bool HandleContextMenu(const content::ContextMenuParams& params) override {
- return false;
- }
- void OnAttachWebViewHelpers(content::WebContents* contents) override {}
- void OnDidCommitProvisionalLoadForFrame(bool is_main_frame) override {}
- void OnDidInitialize() override {}
- void OnDocumentLoadedInFrame(
- content::RenderFrameHost* render_frame_host) override {}
- void OnGuestDestroyed() override {}
- void OnShowContextMenu(
- int request_id,
- const WebViewGuestDelegate::MenuItemVector* items) override {}
-
- bool clear_cache_called() { return clear_cache_called_; }
-
- private:
- extensions::WebViewGuest* web_view_guest_;
- bool clear_cache_called_;
-
- DISALLOW_COPY_AND_ASSIGN(MockWebViewGuestDelegate);
-};
-
// This class intercepts download request from the guest.
class MockDownloadWebContentsDelegate : public content::WebContentsDelegate {
public:
@@ -608,14 +575,27 @@ class WebViewTest : public extensions::PlatformAppBrowserTest {
static scoped_ptr<net::test_server::HttpResponse> EmptyResponseHandler(
const std::string& path,
const net::test_server::HttpRequest& request) {
- if (StartsWithASCII(path, request.relative_url, true)) {
- return scoped_ptr<net::test_server::HttpResponse>(
- new EmptyHttpResponse);
- }
+ if (StartsWithASCII(path, request.relative_url, true))
+ return scoped_ptr<net::test_server::HttpResponse>(new EmptyHttpResponse);
return scoped_ptr<net::test_server::HttpResponse>();
}
+ // Handles |request| by serving cache-able response.
+ static scoped_ptr<net::test_server::HttpResponse> CacheControlResponseHandler(
+ const std::string& path,
+ const net::test_server::HttpRequest& request) {
+ if (!StartsWithASCII(path, request.relative_url, true))
+ return scoped_ptr<net::test_server::HttpResponse>();
+
+ scoped_ptr<net::test_server::BasicHttpResponse> http_response(
+ new net::test_server::BasicHttpResponse);
+ http_response->AddCustomHeader("Cache-control", "max-age=3600");
+ http_response->set_content_type("text/plain");
+ http_response->set_content("dummy text");
+ return http_response.Pass();
+ }
+
// Shortcut to return the current MenuManager.
extensions::MenuManager* menu_manager() {
return extensions::MenuManager::Get(browser()->profile());
@@ -662,6 +642,9 @@ class WebViewTest : public extensions::PlatformAppBrowserTest {
&WebViewTest::UserAgentResponseHandler,
kUserAgentRedirectResponsePath,
embedded_test_server()->GetURL(kRedirectResponseFullPath)));
+
+ embedded_test_server()->RegisterRequestHandler(base::Bind(
+ &WebViewTest::CacheControlResponseHandler, kCacheResponsePath));
}
LoadAndLaunchPlatformApp(app_location.c_str(), "Launched");
@@ -2434,25 +2417,7 @@ IN_PROC_BROWSER_TEST_F(WebViewTest, ClearData) {
}
IN_PROC_BROWSER_TEST_F(WebViewTest, ClearDataCache) {
- LoadAppWithGuest("web_view/clear_data_cache");
- content::WebContents* guest_web_contents = GetGuestWebContents();
- auto guest = extensions::WebViewGuest::FromWebContents(guest_web_contents);
- ASSERT_TRUE(guest);
- scoped_ptr<extensions::WebViewGuestDelegate> mock_web_view_guest_delegate(
- new MockWebViewGuestDelegate(guest));
- scoped_ptr<extensions::WebViewGuestDelegate> orig_web_view_guest_delegate =
- guest->SetDelegateForTesting(mock_web_view_guest_delegate.Pass());
-
- ASSERT_TRUE(GetEmbedderWebContents());
- ExtensionTestMessageListener clear_data_done_listener(
- "WebViewTest.CLEAR_DATA_DONE", false);
- EXPECT_TRUE(content::ExecuteScript(
- GetEmbedderWebContents(), base::StringPrintf("testClearDataCache()")));
- EXPECT_TRUE(clear_data_done_listener.WaitUntilSatisfied());
-
- // Reset delegate back to original once we're done mocking.
- mock_web_view_guest_delegate =
- guest->SetDelegateForTesting(orig_web_view_guest_delegate.Pass());
+ TestHelper("testClearCache", "web_view/clear_data_cache", NEEDS_TEST_SERVER);
}
// This test is disabled on Win due to being flaky. http://crbug.com/294592
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc
index 03abc79..ffdb52d 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.cc
@@ -11,10 +11,8 @@
#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
#include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h"
#include "chrome/common/chrome_version_info.h"
-#include "components/browsing_data/storage_partition_http_cache_data_remover.h"
#include "components/pdf/browser/pdf_web_contents_helper.h"
#include "components/renderer_context_menu/context_menu_delegate.h"
-#include "components/web_cache/browser/web_cache_manager.h"
#include "content/public/browser/render_process_host.h"
#include "extensions/browser/api/web_request/web_request_api.h"
#include "extensions/browser/guest_view/guest_view_event.h"
@@ -42,28 +40,6 @@ ChromeWebViewGuestDelegate::ChromeWebViewGuestDelegate(
ChromeWebViewGuestDelegate::~ChromeWebViewGuestDelegate() {
}
-void ChromeWebViewGuestDelegate::ClearCache(
- base::Time remove_since,
- const base::Closure& done_callback) {
- int render_process_id = guest_web_contents()->GetRenderProcessHost()->GetID();
- // We need to clear renderer cache separately for our process because
- // StoragePartitionHttpCacheDataRemover::ClearData() does not clear that.
- web_cache::WebCacheManager::GetInstance()->Remove(render_process_id);
- web_cache::WebCacheManager::GetInstance()->ClearCacheForProcess(
- render_process_id);
-
- content::StoragePartition* partition =
- content::BrowserContext::GetStoragePartition(
- guest_web_contents()->GetBrowserContext(),
- guest_web_contents()->GetSiteInstance());
-
- // StoragePartitionHttpCacheDataRemover removes itself when it is done.
- // TODO(lazyboy): Once StoragePartitionHttpCacheDataRemover moves to
- // components/, move |ClearCache| to WebViewGuest: http//crbug.com/471287.
- browsing_data::StoragePartitionHttpCacheDataRemover::CreateForRange(
- partition, remove_since, base::Time::Now())->Remove(done_callback);
-}
-
bool ChromeWebViewGuestDelegate::HandleContextMenu(
const content::ContextMenuParams& params) {
ContextMenuDelegate* menu_delegate =
diff --git a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h
index 9cd1722..aae364a 100644
--- a/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h
+++ b/chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h
@@ -27,8 +27,6 @@ class ChromeWebViewGuestDelegate : public WebViewGuestDelegate {
~ChromeWebViewGuestDelegate() override;
// WebViewGuestDelegate implementation.
- void ClearCache(base::Time remove_since,
- const base::Closure& done_callback) override;
bool HandleContextMenu(const content::ContextMenuParams& params) override;
void OnAttachWebViewHelpers(content::WebContents* contents) override;
void OnDidCommitProvisionalLoadForFrame(bool is_main_frame) override;
diff --git a/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/embedder.js b/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/embedder.js
index 435c5cb..5d41fa5 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/embedder.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/embedder.js
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-var LOG = function(msg) { window.console.log(msg); };
+var LOG = function(var_args) {
+ window.console.log(Array.prototype.slice.call(arguments));
+};
function ClearDataTester() {
this.webview_ = null;
@@ -19,62 +21,123 @@ function ClearDataTester() {
ClearDataTester.prototype.setWebview = function(webview) {
this.webview_ = webview;
+ this.webview_.onconsolemessage = this.onGuestConsoleMessage_.bind(this);
+};
+
+ClearDataTester.prototype.onGuestConsoleMessage_ = function(e) {
+ LOG('G:', e.message);
+ if (e.message == 'ERROR') {
+ this.fail();
+ }
};
+ClearDataTester.prototype.requestXhrFromWebView_ = function() {
+ var msg = ['sendXhr'];
+ this.webview_.contentWindow.postMessage(JSON.stringify(msg), '*');
+};
+
+ClearDataTester.prototype.fail = function() {
+ chrome.test.sendMessage('TEST_FAILED');
+};
+
+ClearDataTester.prototype.pass = function() {
+ chrome.test.sendMessage('TEST_PASSED');
+};
+
+// This test instructs a <webview> to load same resource request via xhr
+// multiple times. That makes some of those requests to be served from
+// http cache.
+// Calling clearData{cache: true} resets the cache and next request
+// from the same resource should not be served from cache.
ClearDataTester.prototype.testClearDataCache = function() {
- this.webview_.clearData(
- {since: 10}, {"cache": true}, function doneCallback() {
- LOG('clearData done');
- chrome.test.sendMessage('WebViewTest.CLEAR_DATA_DONE');
- });
+ // Request same resource multiple times from <webview>, latter
+ // ones would be served from cache.
+ var responseCount = 0;
+ var servedFromCacheCount = 0;
+
+ var responseStartedHandler = function(details) {
+ LOG('onResponseStarted, url:', details.url,
+ 'fromCache:', details.fromCache);
+ if (details.url.indexOf('/cache-control-response') == -1) {
+ return;
+ }
+
+ ++responseCount;
+ if (details.fromCache) {
+ ++servedFromCacheCount;
+ }
+
+ if (responseCount == 5) {
+ // We should see some request getting served from cache.
+ if (servedFromCacheCount <= 0) {
+ this.fail();
+ return;
+ }
+
+ // Clear cache from <webview>.
+ this.webview_.clearData(
+ {since: 10}, {'cache': true}, function doneCallback() {
+ LOG('clearData done');
+ this.requestXhrFromWebView_();
+ // Now request the same resource again, this time it should
+ // not be served from cache.
+ this.requestXhrFromWebView_();
+ }.bind(this));
+ } else if (responseCount == 6) {
+ if (details.fromCache) {
+ // Response received after clearData should not be served from cache.
+ this.fail();
+ } else {
+ this.pass();
+ }
+ }
+ }.bind(this);
+
+ this.webview_.request.onResponseStarted.addListener(
+ responseStartedHandler, {urls: ['<all_urls>']});
+
+ for (var i = 0; i < 5; ++i) {
+ this.requestXhrFromWebView_();
+ }
};
var tester = new ClearDataTester();
// window.* exported functions begin.
-window.testClearDataCache = function() {
- LOG('window.testClearDataCache');
- tester.testClearDataCache();
+window.runTest = function(testName) {
+ switch (testName) {
+ case 'testClearCache':
+ tester.testClearDataCache();
+ break;
+ default:
+ LOG('curious test to run:', testName);
+ tester.fail();
+ break;
+ }
};
// window.* exported functions end.
-function setUpTest(messageCallback) {
- var guestUrl = 'data:text/html,<html><body>guest</body></html>';
+function setUpTest(guestURL, doneCallback) {
var webview = document.createElement('webview');
webview.onloadstop = function(e) {
LOG('webview has loaded.');
- webview.executeScript(
- {file: 'guest.js'},
- function(results) {
- if (!results || !results.length) {
- chrome.test.sendMessage('WebViewTest.FAILURE');
- return;
- }
- LOG('Script has been injected into webview.');
- // Establish a communication channel with the guest.
- var msg = ['connect'];
- webview.contentWindow.postMessage(JSON.stringify(msg), '*');
- });
+ doneCallback(webview);
};
- window.addEventListener('message', function(e) {
- var data = JSON.parse(e.data);
- if (data[0] == 'connected') {
- console.log('A communication channel has been established with webview.');
- }
- messageCallback(webview);
- });
-
- webview.setAttribute('src', guestUrl);
+ webview.setAttribute('src', guestURL);
document.body.appendChild(webview);
}
onload = function() {
chrome.test.getConfig(function(config) {
- setUpTest(function(webview) {
+ LOG('config: ' + config.testServer.port);
+ var guestURL = 'http://localhost:' + config.testServer.port +
+ '/extensions/platform_apps/web_view/clear_data_cache/guest.html';
+ setUpTest(guestURL, function(webview) {
LOG('Guest load completed.');
- chrome.test.sendMessage('WebViewTest.LAUNCHED');
+ //chrome.test.sendMessage('WebViewTest.LAUNCHED');
+ chrome.test.sendMessage('Launched');
tester.setWebview(webview);
});
});
diff --git a/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/guest.html b/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/guest.html
new file mode 100644
index 0000000..74e3cff
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/guest.html
@@ -0,0 +1,10 @@
+<!--
+ * Copyright 2015 The Chromium Authors. All rights reserved. Use of this
+ * source code is governed by a BSD-style license that can be found in the
+ * LICENSE file.
+-->
+<html>
+<body>
+ <script src="guest.js"></script>
+</body>
+</html>
diff --git a/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/guest.js b/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/guest.js
index 6b90df3..72b5aea 100644
--- a/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/guest.js
+++ b/chrome/test/data/extensions/platform_apps/web_view/clear_data_cache/guest.js
@@ -5,24 +5,33 @@
var LOG = function(msg) { window.console.log(msg); };
LOG('Guest script loading.');
-// The window reference of the embedder to send post message reply.
-var embedderWindowChannel = null;
+var fail = function() {
+ // Embedder catches this message and fails the test.
+ LOG('ERROR');
+};
-// A value that uniquely identifies the guest sending the messages to the
-// embedder.
-var channelId = 0;
-var notifyEmbedder = function(msg_array) {
- var msg = msg_array.concat([channelId]);
- embedderWindowChannel.postMessage(JSON.stringify(msg), '*');
+var sendXhr = function() {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function() {
+ LOG('xhr.onload');
+ if (xhr.responseText != 'dummy text') {
+ fail();
+ }
+ };
+ xhr.onerror = function() {
+ fail();
+ };
+ xhr.open('GET', '/cache-control-response', true);
+ xhr.send();
};
var onPostMessageReceived = function(e) {
- embedderWindowChannel = e.source;
var data = JSON.parse(e.data);
- if (data[0] == 'connect') {
- channelId = data[1];
- notifyEmbedder(['connected']);
+ if (data[0] != 'sendXhr') {
+ fail();
return;
}
+
+ sendXhr();
};
window.addEventListener('message', onPostMessageReceived, false);
diff --git a/extensions/DEPS b/extensions/DEPS
index a5faa35..285b7d3 100644
--- a/extensions/DEPS
+++ b/extensions/DEPS
@@ -1,5 +1,6 @@
include_rules = [
# Do not add Chrome dependencies. Much work went into removing them.
+ "+components/browsing_data",
"+components/crx_file",
"+components/url_matcher",
"-content",
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 9ecb71e..6a643160 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -44,6 +44,7 @@ source_set("browser") {
"//extensions")
deps += [
+ "//components/browsing_data",
"//components/onc",
"//components/storage_monitor",
"//components/update_client",
diff --git a/extensions/browser/guest_view/web_view/web_view_guest.cc b/extensions/browser/guest_view/web_view/web_view_guest.cc
index f29e12f..721cb11 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest.cc
+++ b/extensions/browser/guest_view/web_view/web_view_guest.cc
@@ -7,6 +7,8 @@
#include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "components/browsing_data/storage_partition_http_cache_data_remover.h"
+#include "components/web_cache/browser/web_cache_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/child_process_security_policy.h"
@@ -705,15 +707,25 @@ bool WebViewGuest::ClearData(base::Time remove_since,
return false;
if (removal_mask & webview::WEB_VIEW_REMOVE_DATA_MASK_CACHE) {
- if (web_view_guest_delegate_) {
- // First clear http cache data and then clear the rest in
- // |ClearDataInternal|.
- web_view_guest_delegate_->ClearCache(
- remove_since, base::Bind(&WebViewGuest::ClearDataInternal,
- weak_ptr_factory_.GetWeakPtr(), remove_since,
- removal_mask, callback));
- return true;
- }
+ // First clear http cache data and then clear the rest in
+ // |ClearDataInternal|.
+ int render_process_id = web_contents()->GetRenderProcessHost()->GetID();
+ // We need to clear renderer cache separately for our process because
+ // StoragePartitionHttpCacheDataRemover::ClearData() does not clear that.
+ web_cache::WebCacheManager::GetInstance()->Remove(render_process_id);
+ web_cache::WebCacheManager::GetInstance()->ClearCacheForProcess(
+ render_process_id);
+
+ base::Closure cache_removal_done_callback = base::Bind(
+ &WebViewGuest::ClearDataInternal, weak_ptr_factory_.GetWeakPtr(),
+ remove_since, removal_mask, callback);
+ // StoragePartitionHttpCacheDataRemover removes itself when it is done.
+ // components/, move |ClearCache| to WebViewGuest: http//crbug.com/471287.
+ browsing_data::StoragePartitionHttpCacheDataRemover::CreateForRange(
+ partition, remove_since, base::Time::Now())
+ ->Remove(cache_removal_done_callback);
+
+ return true;
}
ClearDataInternal(remove_since, removal_mask, callback);
diff --git a/extensions/browser/guest_view/web_view/web_view_guest_delegate.h b/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
index 7b1dd56..473ffd3d 100644
--- a/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
+++ b/extensions/browser/guest_view/web_view/web_view_guest_delegate.h
@@ -32,10 +32,6 @@ class WebViewGuestDelegate {
typedef std::vector<linked_ptr<api::web_view_internal::ContextMenuItem> >
MenuItemVector;
- // Clears http cache for this guest's StoragePartition.
- virtual void ClearCache(base::Time remove_since,
- const base::Closure& callback) = 0;
-
// Called when context menu operation was handled.
virtual bool HandleContextMenu(const content::ContextMenuParams& params) = 0;
diff --git a/extensions/extensions.gyp b/extensions/extensions.gyp
index 4c12f71..a057839 100644
--- a/extensions/extensions.gyp
+++ b/extensions/extensions.gyp
@@ -124,6 +124,7 @@
'dependencies': [
'../base/base.gyp:base',
'../base/base.gyp:base_prefs',
+ '../components/components.gyp:browsing_data',
'../components/components.gyp:device_event_log_component',
'../components/components.gyp:keyed_service_content',
'../components/components.gyp:keyed_service_core',