summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc18
-rw-r--r--chrome/browser/renderer_host/resource_request_details.h10
-rw-r--r--chrome/browser/ssl/ssl_browser_tests.cc130
-rw-r--r--chrome/browser/worker_host/worker_service.cc15
-rw-r--r--chrome/browser/worker_host/worker_service.h5
-rw-r--r--chrome/common/child_process_host.cc6
-rw-r--r--chrome/test/data/ssl/imported.js1
-rw-r--r--chrome/test/data/ssl/page_with_unsafe_worker.html26
-rw-r--r--chrome/test/data/ssl/unsafe_worker.js6
9 files changed, 172 insertions, 45 deletions
diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc
index 9e7af2f..3e01326 100644
--- a/chrome/browser/renderer_host/resource_dispatcher_host.cc
+++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc
@@ -43,6 +43,7 @@
#include "chrome/browser/renderer_host/sync_resource_handler.h"
#include "chrome/browser/ssl/ssl_client_auth_handler.h"
#include "chrome/browser/ssl/ssl_manager.h"
+#include "chrome/browser/worker_host/worker_service.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
@@ -1487,8 +1488,21 @@ bool ResourceDispatcherHost::RenderViewForRequest(const URLRequest* request,
return false;
}
- *render_process_host_id = info->child_id();
- *render_view_host_id = info->route_id();
+ // If the request is from the worker process, find a tab that owns the worker.
+ if (info->process_type() == ChildProcessInfo::WORKER_PROCESS) {
+ const WorkerProcessHost::WorkerInstance* worker_instance =
+ WorkerService::GetInstance()->FindWorkerInstance(info->child_id());
+ if (!worker_instance) {
+ *render_process_host_id = -1;
+ *render_view_host_id = -1;
+ return false;
+ }
+ *render_process_host_id = worker_instance->renderer_id;
+ *render_view_host_id = worker_instance->render_view_route_id;
+ } else {
+ *render_process_host_id = info->child_id();
+ *render_view_host_id = info->route_id();
+ }
return true;
}
diff --git a/chrome/browser/renderer_host/resource_request_details.h b/chrome/browser/renderer_host/resource_request_details.h
index e7e1c02..bf84964 100644
--- a/chrome/browser/renderer_host/resource_request_details.h
+++ b/chrome/browser/renderer_host/resource_request_details.h
@@ -14,6 +14,7 @@
#include "chrome/browser/cert_store.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host_request_info.h"
+#include "chrome/browser/worker_host/worker_service.h"
#include "googleurl/src/gurl.h"
#include "net/url_request/url_request_status.h"
@@ -39,7 +40,14 @@ class ResourceRequestDetails {
frame_origin_ = info->frame_origin();
main_frame_origin_ = info->main_frame_origin();
filter_policy_ = info->filter_policy();
- origin_child_id_ = info->child_id();
+
+ // If request is from the worker process on behalf of a renderer, use
+ // the renderer process id, since it consumes the notification response
+ // such as ssl state etc.
+ const WorkerProcessHost::WorkerInstance* worker_instance =
+ WorkerService::GetInstance()->FindWorkerInstance(info->child_id());
+ origin_child_id_ =
+ worker_instance ? worker_instance->renderer_id : info->child_id();
}
virtual ~ResourceRequestDetails() {}
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc
index 84b2cdf..ef1711a 100644
--- a/chrome/browser/ssl/ssl_browser_tests.cc
+++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/time.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/interstitial_page.h"
@@ -69,6 +70,46 @@ class SSLUITest : public InProcessBrowserTest {
EXPECT_FALSE(entry->ssl().has_unsafe_content());
}
+ void CheckWorkerLoadResult(TabContents* tab, bool expectLoaded) {
+ // Workers are async and we don't have notifications for them passing
+ // messages since they do it between renderer and worker processes.
+ // So have a polling loop, check every 200ms, timeout at 30s.
+ const int timeout_ms = 200;
+ base::Time timeToQuit = base::Time::Now() +
+ base::TimeDelta::FromMilliseconds(30000);
+
+ while(base::Time::Now() < timeToQuit) {
+ bool workerFinished = false;
+ ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ tab->render_view_host(), L"",
+ L"window.domAutomationController.send(IsWorkerFinished());",
+ &workerFinished));
+
+ if (workerFinished)
+ break;
+
+ // Wait a bit.
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, new MessageLoop::QuitTask, timeout_ms);
+ ui_test_utils::RunMessageLoop();
+ }
+
+ bool actuallyLoadedContent = false;
+ ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ tab->render_view_host(), L"",
+ L"window.domAutomationController.send(IsContentLoaded());",
+ &actuallyLoadedContent));
+ EXPECT_EQ(expectLoaded, actuallyLoadedContent);
+ }
+
+ void ProceedThroughInterstitial(TabContents* tab) {
+ InterstitialPage* interstitial_page = tab->interstitial_page();
+ ASSERT_TRUE(interstitial_page);
+ interstitial_page->Proceed();
+ // Wait for the navigation to be done.
+ ui_test_utils::WaitForNavigation(&(tab->controller()));
+ }
+
private:
DISALLOW_COPY_AND_ASSIGN(SSLUITest);
};
@@ -124,12 +165,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestHTTPSExpiredCertAndProceed) {
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing
- // Proceed through the interstitial.
- InterstitialPage* interstitial_page = tab->interstitial_page();
- ASSERT_TRUE(interstitial_page);
- interstitial_page->Proceed();
- // Wait for the navigation to be done.
- ui_test_utils::WaitForNavigation(&(tab->controller()));
+ ProceedThroughInterstitial(tab);
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
false); // No interstitial showing
@@ -396,12 +432,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestCNInvalidStickiness) {
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
true); // Interstitial showing.
- // We proceed through the interstitial page.
- InterstitialPage* interstitial_page = tab->interstitial_page();
- ASSERT_TRUE(interstitial_page);
- interstitial_page->Proceed();
- // Wait for the navigation to be done.
- ui_test_utils::WaitForNavigation(&(tab->controller()));
+ ProceedThroughInterstitial(tab);
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_COMMON_NAME_INVALID,
false); // No interstitial showing.
@@ -443,11 +474,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestRefNavigation) {
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing.
- InterstitialPage* interstitial_page = tab->interstitial_page();
- ASSERT_TRUE(interstitial_page);
- interstitial_page->Proceed();
- // Wait for the navigation to be done.
- ui_test_utils::WaitForNavigation(&(tab->controller()));
+ ProceedThroughInterstitial(tab);
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
false); // No interstitial showing.
@@ -516,12 +543,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) {
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing.
- // We proceed through the interstitial page.
- InterstitialPage* interstitial_page = tab->interstitial_page();
- ASSERT_TRUE(interstitial_page);
- interstitial_page->Proceed();
- // Wait for the navigation to be done.
- ui_test_utils::WaitForNavigation(&(tab->controller()));
+ ProceedThroughInterstitial(tab);
// We have been redirected to the good page.
CheckAuthenticatedState(tab, false, false); // No mixed/unsafe content.
@@ -542,12 +564,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectGoodToBadHTTPS) {
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing.
- // We proceed through the interstitial page.
- InterstitialPage* interstitial_page = tab->interstitial_page();
- ASSERT_TRUE(interstitial_page);
- interstitial_page->Proceed();
- // Wait for the navigation to be done.
- ui_test_utils::WaitForNavigation(&(tab->controller()));
+ ProceedThroughInterstitial(tab);
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
false); // No interstitial showing.
@@ -589,12 +606,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestRedirectHTTPToBadHTTPS) {
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing.
- // Continue on the interstitial.
- InterstitialPage* interstitial_page = tab->interstitial_page();
- ASSERT_TRUE(interstitial_page);
- interstitial_page->Proceed();
- // Wait for the navigation to be done.
- ui_test_utils::WaitForNavigation(&(tab->controller()));
+ ProceedThroughInterstitial(tab);
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
false); // No interstitial showing.
@@ -725,11 +737,7 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestBadFrameNavigation) {
CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
true); // Interstitial showing
- // Continue on the interstitial.
- InterstitialPage* interstitial_page = tab->interstitial_page();
- ASSERT_TRUE(interstitial_page);
- interstitial_page->Proceed();
- ui_test_utils::WaitForNavigation(&(tab->controller()));
+ ProceedThroughInterstitial(tab);
// Navigate to a good frame.
bool success = false;
@@ -797,6 +805,48 @@ IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnauthenticatedFrameNavigation) {
EXPECT_FALSE(is_content_evil);
}
+IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorkerFiltered) {
+ scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
+ ASSERT_TRUE(good_https_server.get() != NULL);
+ scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
+ ASSERT_TRUE(bad_https_server.get() != NULL);
+
+ // This page will spawn a Worker which will try to load content from
+ // BadCertServer.
+ ui_test_utils::NavigateToURL(browser(), good_https_server->TestServerPage(
+ "files/ssl/page_with_unsafe_worker.html"));
+ TabContents* tab = browser()->GetSelectedTabContents();
+ // Expect Worker not to load mixed content.
+ CheckWorkerLoadResult(tab, false);
+ // The bad content is filtered, expect the state to be authenticated.
+ CheckAuthenticatedState(tab, false, false);
+}
+
+IN_PROC_BROWSER_TEST_F(SSLUITest, TestUnsafeContentsInWorker) {
+ scoped_refptr<HTTPSTestServer> good_https_server = GoodCertServer();
+ ASSERT_TRUE(good_https_server.get() != NULL);
+ scoped_refptr<HTTPSTestServer> bad_https_server = BadCertServer();
+ ASSERT_TRUE(bad_https_server.get() != NULL);
+
+ // Navigate to an unsafe site. Proceed with interstitial page to indicate
+ // the user approves the bad certificate.
+ ui_test_utils::NavigateToURL(browser(), bad_https_server->TestServerPage(
+ "files/ssl/blank_page.html"));
+ TabContents* tab = browser()->GetSelectedTabContents();
+ CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
+ true); // Interstitial showing
+ ProceedThroughInterstitial(tab);
+ CheckAuthenticationBrokenState(tab, net::CERT_STATUS_DATE_INVALID,
+ false); // No Interstitial
+
+ // Navigate to safe page that has Worker loading unsafe content.
+ // Expect content to load but 'mixed' indicators show up.
+ ui_test_utils::NavigateToURL(browser(), good_https_server->TestServerPage(
+ "files/ssl/page_with_unsafe_worker.html"));
+ CheckWorkerLoadResult(tab, true); // Worker loads mixed content
+ CheckAuthenticatedState(tab, true, false); // Mixed content UI shown.
+}
+
// TODO(jcampan): more tests to do below.
// Visit a page over https that contains a frame with a redirect.
diff --git a/chrome/browser/worker_host/worker_service.cc b/chrome/browser/worker_host/worker_service.cc
index a8ce3f0..d37314b 100644
--- a/chrome/browser/worker_host/worker_service.cc
+++ b/chrome/browser/worker_host/worker_service.cc
@@ -265,3 +265,18 @@ void WorkerService::WorkerProcessDestroyed(WorkerProcessHost* process) {
}
}
}
+
+const WorkerProcessHost::WorkerInstance* WorkerService::FindWorkerInstance(
+ int worker_process_id) {
+ for (ChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
+ !iter.Done(); ++iter) {
+ if (iter->id() != worker_process_id)
+ continue;
+
+ WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
+ WorkerProcessHost::Instances::const_iterator instance =
+ worker->instances().begin();
+ return instance == worker->instances().end() ? NULL : &*instance;
+ }
+ return NULL;
+}
diff --git a/chrome/browser/worker_host/worker_service.h b/chrome/browser/worker_host/worker_service.h
index 0887b32..a3e71031 100644
--- a/chrome/browser/worker_host/worker_service.h
+++ b/chrome/browser/worker_host/worker_service.h
@@ -46,6 +46,11 @@ class WorkerService : public NotificationObserver {
int next_worker_route_id() { return ++next_worker_route_id_; }
+ // TODO(dimich): This code assumes there is 1 worker per worker process, which
+ // is how it is today until V8 can run in separate threads.
+ const WorkerProcessHost::WorkerInstance* FindWorkerInstance(
+ int worker_process_id);
+
// Used when multiple workers can run in the same process.
static const int kMaxWorkerProcessesWhenSharing;
diff --git a/chrome/common/child_process_host.cc b/chrome/common/child_process_host.cc
index 1d48350..7327769 100644
--- a/chrome/common/child_process_host.cc
+++ b/chrome/common/child_process_host.cc
@@ -250,8 +250,10 @@ ChildProcessHost::Iterator::Iterator()
ChildProcessHost::Iterator::Iterator(ProcessType type)
: all_(false), type_(type) {
- DCHECK(MessageLoop::current() ==
- ChromeThread::GetMessageLoop(ChromeThread::IO)) <<
+ // IO loop can be NULL in unit tests.
+ DCHECK(!ChromeThread::GetMessageLoop(ChromeThread::IO) ||
+ MessageLoop::current() ==
+ ChromeThread::GetMessageLoop(ChromeThread::IO)) <<
"ChildProcessInfo::Iterator must be used on the IO thread.";
iterator_ = Singleton<ChildProcessList>::get()->begin();
if (!Done() && (*iterator_)->type() != type_)
diff --git a/chrome/test/data/ssl/imported.js b/chrome/test/data/ssl/imported.js
new file mode 100644
index 0000000..0d712a1
--- /dev/null
+++ b/chrome/test/data/ssl/imported.js
@@ -0,0 +1 @@
+message = "loaded";
diff --git a/chrome/test/data/ssl/page_with_unsafe_worker.html b/chrome/test/data/ssl/page_with_unsafe_worker.html
new file mode 100644
index 0000000..db8dbfb
--- /dev/null
+++ b/chrome/test/data/ssl/page_with_unsafe_worker.html
@@ -0,0 +1,26 @@
+<html>
+<script>
+
+var isWorkerFinished = false;
+var isContentLoaded = false;
+
+function IsWorkerFinished() {
+ return isWorkerFinished;
+}
+
+function IsContentLoaded() {
+ return isContentLoaded;
+}
+
+var worker;
+function test() {
+ worker = new Worker("unsafe_worker.js");
+ worker.onmessage = function(e) {
+ isContentLoaded = (e.data == "loaded");
+ isWorkerFinished = true;
+ };
+}
+
+</script>
+<body onload="test()"></body>
+</html>
diff --git a/chrome/test/data/ssl/unsafe_worker.js b/chrome/test/data/ssl/unsafe_worker.js
new file mode 100644
index 0000000..984223d
--- /dev/null
+++ b/chrome/test/data/ssl/unsafe_worker.js
@@ -0,0 +1,6 @@
+var message = "failed";
+try {
+ importScripts("https://127.0.0.1:9666/files/ssl/imported.js");
+} catch(ex) {
+}
+postMessage(message);