Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(784)

Side by Side Diff: chrome/browser/ui/extensions/hosted_app_browsertest.cc

Issue 2840383002: Disable top-document-isolation if the parent SiteInstance is a hosted app. (Closed)
Patch Set: Added a test. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string> 5 #include <string>
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/strings/stringprintf.h"
9 #include "base/test/scoped_feature_list.h" 10 #include "base/test/scoped_feature_list.h"
10 #include "chrome/browser/extensions/extension_browsertest.h" 11 #include "chrome/browser/extensions/extension_browsertest.h"
11 #include "chrome/browser/extensions/extension_service.h" 12 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/extension_util.h" 13 #include "chrome/browser/extensions/extension_util.h"
14 #include "chrome/browser/extensions/test_extension_dir.h"
13 #include "chrome/browser/ui/browser_list.h" 15 #include "chrome/browser/ui/browser_list.h"
14 #include "chrome/browser/ui/extensions/app_launch_params.h" 16 #include "chrome/browser/ui/extensions/app_launch_params.h"
15 #include "chrome/browser/ui/extensions/application_launch.h" 17 #include "chrome/browser/ui/extensions/application_launch.h"
16 #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" 18 #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h" 19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/browser/web_applications/web_app.h" 20 #include "chrome/browser/web_applications/web_app.h"
19 #include "chrome/test/base/ui_test_utils.h" 21 #include "chrome/test/base/ui_test_utils.h"
22 #include "content/public/browser/render_frame_host.h"
20 #include "content/public/browser/web_contents.h" 23 #include "content/public/browser/web_contents.h"
24 #include "content/public/common/content_switches.h"
25 #include "content/public/test/browser_test_utils.h"
26 #include "content/public/test/test_utils.h"
21 #include "extensions/browser/extension_registry.h" 27 #include "extensions/browser/extension_registry.h"
22 #include "extensions/common/constants.h" 28 #include "extensions/common/constants.h"
23 #include "extensions/common/extension.h" 29 #include "extensions/common/extension.h"
24 #include "extensions/common/extension_set.h" 30 #include "extensions/common/extension_set.h"
31 #include "net/dns/mock_host_resolver.h"
32 #include "net/test/embedded_test_server/embedded_test_server.h"
25 33
26 #if defined(OS_MACOSX) 34 #if defined(OS_MACOSX)
27 #include "chrome/common/chrome_features.h" 35 #include "chrome/common/chrome_features.h"
28 #endif 36 #endif
29 37
30 using content::WebContents; 38 using content::WebContents;
31 using extensions::Extension; 39 using extensions::Extension;
32 40
33 namespace { 41 namespace {
34 42
(...skipping 18 matching lines...) Expand all
53 // testing::Test: 61 // testing::Test:
54 void SetUp() override { 62 void SetUp() override {
55 ExtensionBrowserTest::SetUp(); 63 ExtensionBrowserTest::SetUp();
56 #if defined(OS_MACOSX) 64 #if defined(OS_MACOSX)
57 scoped_feature_list_.InitAndEnableFeature(features::kBookmarkApps); 65 scoped_feature_list_.InitAndEnableFeature(features::kBookmarkApps);
58 #endif 66 #endif
59 } 67 }
60 68
61 protected: 69 protected:
62 void SetupApp(const std::string& app_folder, bool is_bookmark_app) { 70 void SetupApp(const std::string& app_folder, bool is_bookmark_app) {
71 SetupApp(test_data_dir_.AppendASCII(app_folder), is_bookmark_app);
72 }
73
74 void SetupApp(const base::FilePath& app_folder, bool is_bookmark_app) {
63 const Extension* app = InstallExtensionWithSourceAndFlags( 75 const Extension* app = InstallExtensionWithSourceAndFlags(
64 test_data_dir_.AppendASCII(app_folder), 1, 76 app_folder, 1, extensions::Manifest::INTERNAL,
65 extensions::Manifest::INTERNAL,
66 is_bookmark_app ? extensions::Extension::FROM_BOOKMARK 77 is_bookmark_app ? extensions::Extension::FROM_BOOKMARK
67 : extensions::Extension::NO_FLAGS); 78 : extensions::Extension::NO_FLAGS);
68 ASSERT_TRUE(app); 79 ASSERT_TRUE(app);
69 80
70 // Launch it in a window. 81 // Launch it in a window.
71 ASSERT_TRUE(OpenApplication(AppLaunchParams( 82 ASSERT_TRUE(OpenApplication(AppLaunchParams(
72 browser()->profile(), app, extensions::LAUNCH_CONTAINER_WINDOW, 83 browser()->profile(), app, extensions::LAUNCH_CONTAINER_WINDOW,
73 WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_TEST))); 84 WindowOpenDisposition::NEW_WINDOW, extensions::SOURCE_TEST)));
74 85
75 for (auto* b : *BrowserList::GetInstance()) { 86 for (auto* b : *BrowserList::GetInstance()) {
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 190
180 // Navigate to the app's launch page with the 'www.' prefis; the location bar 191 // Navigate to the app's launch page with the 'www.' prefis; the location bar
181 // should be hidden. 192 // should be hidden.
182 NavigateAndCheckForLocationBar( 193 NavigateAndCheckForLocationBar(
183 app_browser_, "http://www.example.com/empty.html", false); 194 app_browser_, "http://www.example.com/empty.html", false);
184 195
185 // Navigate to different origin; the location bar should now be visible. 196 // Navigate to different origin; the location bar should now be visible.
186 NavigateAndCheckForLocationBar( 197 NavigateAndCheckForLocationBar(
187 app_browser_, "http://www.foo.com/blah", true); 198 app_browser_, "http://www.foo.com/blah", true);
188 } 199 }
200
201 class HostedAppVsTdiTest : public HostedAppTest {
202 public:
203 HostedAppVsTdiTest() {}
204 ~HostedAppVsTdiTest() override {}
205
206 void SetUpCommandLine(base::CommandLine* command_line) override {
207 HostedAppTest::SetUpCommandLine(command_line);
208 command_line->AppendSwitch(switches::kTopDocumentIsolation);
209 }
210
211 void SetUpOnMainThread() override {
212 HostedAppTest::SetUpOnMainThread();
213 host_resolver()->AddRule("*", "127.0.0.1");
214 ASSERT_TRUE(embedded_test_server()->Start());
215 }
216 };
217
218 // Tests that even with --top-document-isolation, app.site.com (covered by app's
219 // web extent) main frame and foo.site.com (not covered by app's web extent)
220 // share the same renderer process. See also https://crbug.com/679011.
221 //
222 // Relevant frames in the test:
223 // - |app| - app.site.com/frame_tree/cross_origin_but_same_site_frames.html
224 // Main frame, launch URL of the hosted app (i.e. app.launch.web_url).
225 // - |same_dir| - app.site.com/frame_tree/simple.htm
226 // Another URL, but still covered by hosted app's web extent
227 // (i.e. by app.urls).
228 // - |diff_dir| - app.site.com/save_page/a.htm
229 // Same origin as |same_dir| and |app|, but not covered by app's
230 // extent.
231 // - |same_site| - other.site.com/title1.htm
232 // Different domain, but same site as |app|, |same_dir|,
233 // |diff_dir|.
234 // - |cross_site| - cross.domain.com/title1.htm
235 // Cross-site from all the other frames.
236 //
237 // Verifications of |*_site| (e.g. EXPECT_EQ(same_dir_site, app_site) are
238 // sanity checks of the test setup.
239 //
240 // First real verification in the test is whether |same_dir| and |diff_dir| can
241 // script each other (despite their effective URLs being cross-site, because
242 // |same_dir| is mapped to a chrome-extension URL). This was a functionality
243 // problem caused by https://crbug.com/679011.
244 //
245 // The test also verifies that all same-site frames (i.e. |app|, |same_dir|,
246 // |diff_dir|, |same_site|) share the same renderer process. This was a small
247 // performance problem caused by https://crbug.com/679011.
248 IN_PROC_BROWSER_TEST_F(HostedAppVsTdiTest, ProcessAllocation) {
249 //
250 // Setup and launch the app.
251 //
252
253 GURL url = embedded_test_server()->GetURL(
254 "app.site.com", "/frame_tree/cross_origin_but_same_site_frames.html");
255
256 extensions::TestExtensionDir test_app_dir;
257 test_app_dir.WriteManifestWithSingleQuotes(
258 base::StringPrintf("{\n"
259 " 'name': 'Hosted App vs TDI Test',\n"
260 " 'version': '1',\n"
261 " 'manifest_version': 2,\n"
262 " 'app': {\n"
263 " 'launch': {\n"
264 " 'web_url': '%s'\n"
265 " },\n"
266 " 'urls': ['*://app.site.com/frame_tree']\n"
267 " }\n"
268 "}\n",
269 url.spec().c_str()));
ncarter (slow) 2017/04/28 18:50:14 You could also use C++11 raw string literals here:
270 SetupApp(test_app_dir.UnpackedPath(), false);
271
272 content::WebContents* web_contents =
273 app_browser_->tab_strip_model()->GetActiveWebContents();
274 content::WaitForLoadStop(web_contents);
275
276 auto find_frame = [web_contents](const std::string& name) {
277 return content::FrameMatchingPredicate(
278 web_contents, base::Bind(&content::FrameMatchesName, name));
279 };
Łukasz Anforowicz 2017/04/28 17:30:27 I guess the above might need to be refactored depe
280 content::RenderFrameHost* app = web_contents->GetMainFrame();
281 content::RenderFrameHost* same_dir = find_frame("SameOrigin-SamePath");
282 content::RenderFrameHost* diff_dir = find_frame("SameOrigin-DifferentPath");
283 content::RenderFrameHost* same_site = find_frame("OtherSubdomain-SameSite");
284 content::RenderFrameHost* cross_site = find_frame("CrossSite");
285
286 //
287 // Sanity-check sites of all relevant frames to verify test setup.
288 //
289
290 GURL app_site = content::SiteInstance::GetSiteForURL(
291 app_browser_->profile(), app->GetLastCommittedURL());
292 EXPECT_EQ(extensions::kExtensionScheme, app_site.scheme());
293
294 GURL same_dir_site = content::SiteInstance::GetSiteForURL(
295 app_browser_->profile(), same_dir->GetLastCommittedURL());
296 EXPECT_EQ(extensions::kExtensionScheme, same_dir_site.scheme());
297 EXPECT_EQ(same_dir_site, app_site);
298
299 GURL diff_dir_site = content::SiteInstance::GetSiteForURL(
300 app_browser_->profile(), diff_dir->GetLastCommittedURL());
301 EXPECT_NE(extensions::kExtensionScheme, diff_dir_site.scheme());
302 EXPECT_NE(diff_dir_site, app_site);
303
304 GURL same_site_site = content::SiteInstance::GetSiteForURL(
305 app_browser_->profile(), same_site->GetLastCommittedURL());
306 EXPECT_NE(extensions::kExtensionScheme, same_site_site.scheme());
307 EXPECT_NE(same_site_site, app_site);
308 EXPECT_EQ(same_site_site, diff_dir_site);
309
310 GURL cross_site_site = content::SiteInstance::GetSiteForURL(
311 app_browser_->profile(), cross_site->GetLastCommittedURL());
312 EXPECT_NE(cross_site_site, app_site);
313 EXPECT_NE(cross_site_site, same_site_site);
314
315 //
316 // Verify that |same_dir| and |diff_dir| can script each other.
317 // (they should - they have the same origin).
318 //
319
320 std::string same_dir_origin;
321 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
322 same_dir, "domAutomationController.send(window.origin)",
323 &same_dir_origin));
324
325 std::string diff_dir_origin;
326 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
327 diff_dir, "domAutomationController.send(window.origin)",
328 &diff_dir_origin));
329
330 EXPECT_EQ(diff_dir_origin, same_dir_origin);
331
332 std::string inner_text_from_other_frame;
333 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
334 diff_dir,
335 "var w = window.open('', 'SameOrigin-SamePath')\n"
336 "domAutomationController.send(w.document.body.innerText)",
337 &inner_text_from_other_frame));
338 EXPECT_EQ("Simple test page.", inner_text_from_other_frame);
339
340 //
341 // Verify there are no additional processes for same-site frames.
342 //
343
344 EXPECT_EQ(same_dir->GetProcess(), app->GetProcess());
345 EXPECT_EQ(diff_dir->GetProcess(), app->GetProcess());
346 EXPECT_EQ(same_site->GetProcess(), app->GetProcess());
347 // For now it is okay for |cross_site| to be in any process - see
348 // https://crbug.com/679011#c2.
349 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698