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

Side by Side Diff: chrome/browser/chrome_content_browser_client.cc

Issue 11234032: Webview tag creation should be using storage partitions. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixes for Charlie's initial comments. Created 8 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/chrome_content_browser_client.h" 5 #include "chrome/browser/chrome_content_browser_client.h"
6 6
7 #include <set> 7 #include <set>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/path_service.h" 13 #include "base/path_service.h"
14 #include "base/string_tokenizer.h" 14 #include "base/string_tokenizer.h"
15 #include "base/string_util.h"
15 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
16 #include "chrome/app/breakpad_mac.h" 17 #include "chrome/app/breakpad_mac.h"
17 #include "chrome/browser/browser_about_handler.h" 18 #include "chrome/browser/browser_about_handler.h"
18 #include "chrome/browser/browser_process.h" 19 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/browsing_data/browsing_data_helper.h" 20 #include "chrome/browser/browsing_data/browsing_data_helper.h"
20 #include "chrome/browser/browsing_data/browsing_data_remover.h" 21 #include "chrome/browser/browsing_data/browsing_data_remover.h"
21 #include "chrome/browser/character_encoding.h" 22 #include "chrome/browser/character_encoding.h"
22 #include "chrome/browser/chrome_benchmarking_message_filter.h" 23 #include "chrome/browser/chrome_benchmarking_message_filter.h"
23 #include "chrome/browser/chrome_quota_permission_context.h" 24 #include "chrome/browser/chrome_quota_permission_context.h"
24 #include "chrome/browser/content_settings/content_settings_utils.h" 25 #include "chrome/browser/content_settings/content_settings_utils.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 #include "content/public/browser/render_process_host.h" 94 #include "content/public/browser/render_process_host.h"
94 #include "content/public/browser/render_view_host.h" 95 #include "content/public/browser/render_view_host.h"
95 #include "content/public/browser/resource_context.h" 96 #include "content/public/browser/resource_context.h"
96 #include "content/public/browser/site_instance.h" 97 #include "content/public/browser/site_instance.h"
97 #include "content/public/browser/web_contents.h" 98 #include "content/public/browser/web_contents.h"
98 #include "content/public/browser/web_contents_view.h" 99 #include "content/public/browser/web_contents_view.h"
99 #include "content/public/common/child_process_host.h" 100 #include "content/public/common/child_process_host.h"
100 #include "content/public/common/content_descriptors.h" 101 #include "content/public/common/content_descriptors.h"
101 #include "grit/generated_resources.h" 102 #include "grit/generated_resources.h"
102 #include "grit/ui_resources.h" 103 #include "grit/ui_resources.h"
104 #include "net/base/escape.h"
103 #include "net/base/ssl_cert_request_info.h" 105 #include "net/base/ssl_cert_request_info.h"
104 #include "net/cookies/canonical_cookie.h" 106 #include "net/cookies/canonical_cookie.h"
105 #include "net/cookies/cookie_options.h" 107 #include "net/cookies/cookie_options.h"
106 #include "ppapi/host/ppapi_host.h" 108 #include "ppapi/host/ppapi_host.h"
107 #include "ui/base/l10n/l10n_util.h" 109 #include "ui/base/l10n/l10n_util.h"
108 #include "ui/base/resource/resource_bundle.h" 110 #include "ui/base/resource/resource_bundle.h"
109 #include "webkit/glue/webpreferences.h" 111 #include "webkit/glue/webpreferences.h"
110 #include "webkit/plugins/plugin_switches.h" 112 #include "webkit/plugins/plugin_switches.h"
111 113
112 #if defined(OS_WIN) 114 #if defined(OS_WIN)
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 return main_parts; 463 return main_parts;
462 } 464 }
463 465
464 content::WebContentsView* 466 content::WebContentsView*
465 ChromeContentBrowserClient::OverrideCreateWebContentsView( 467 ChromeContentBrowserClient::OverrideCreateWebContentsView(
466 WebContents* web_contents, 468 WebContents* web_contents,
467 content::RenderViewHostDelegateView** render_view_host_delegate_view) { 469 content::RenderViewHostDelegateView** render_view_host_delegate_view) {
468 return NULL; 470 return NULL;
469 } 471 }
470 472
471 std::string ChromeContentBrowserClient::GetStoragePartitionIdForChildProcess( 473 std::string ChromeContentBrowserClient::GetStoragePartitionIdForSite(
474 content::BrowserContext* browser_context,
awong 2012/11/05 20:11:18 4-spaces, not 6.
nasko 2012/11/05 23:06:58 Done.
475 const GURL& site) {
476 std::string app_id;
477 std::string partition_name;
478 bool in_memory = false;
479
480 // We need to get all the pieces that will go into the storage partition
481 // identifier first, before we compose it.
482 GetStoragePartitionConfigForSite(browser_context, site, &app_id,
483 &partition_name, &in_memory);
484
485 // If there is no app, we are in the default browser partition, so return
486 // an empty string.
487 if (app_id.empty())
488 return std::string();
489
490 // A non-empty storage partition id string is of the form
491 // "app_id:in_memory:partition_name", where each of the three parts is
492 // optional and the ':' separators are mandatory. Since "in_memory" is fixed
awong 2012/11/05 20:11:18 in-memory
nasko 2012/11/05 23:06:58 Done.
493 // string and the app_id cannot contain the separator, it is safe to parse
494 // the string based on the two separators.
495 std::string partition_id = base::StringPrintf("%s:%s:%s",
496 app_id.c_str(),
497 in_memory ? "in-memory" : "",
498 partition_name.c_str());
499
500 DCHECK(IsValidStoragePartitionId(browser_context,partition_id));
501 return partition_id;
502 }
503
504 bool ChromeContentBrowserClient::IsValidStoragePartitionId(
472 content::BrowserContext* browser_context, 505 content::BrowserContext* browser_context,
473 int child_process_id) { 506 const std::string& partition_id) {
474 const Extension* extension = NULL; 507 // The default ID is empty and is always valid.
508 if (partition_id.empty())
509 return true;
510
475 Profile* profile = Profile::FromBrowserContext(browser_context); 511 Profile* profile = Profile::FromBrowserContext(browser_context);
476 ExtensionService* extension_service = 512 ExtensionService* extension_service =
477 extensions::ExtensionSystem::Get(profile)->extension_service(); 513 extensions::ExtensionSystem::Get(profile)->extension_service();
478 if (extension_service) { 514
479 std::set<std::string> extension_ids = 515 // Now, parse the three parts of the partition ID, so we can verify them.
480 extension_service->process_map()-> 516 // Set the tokenizer to return delimiters, otherwise we won't get the correct
481 GetExtensionsInProcess(child_process_id); 517 // count of delimiters and will fail validation.
482 if (!extension_ids.empty()) 518 int tokens = 0;
483 // Since All the apps in a process share the same storage partition, 519 StringTokenizer t(partition_id, ":");
484 // we can pick any of them to retrieve the storage partition id. 520 t.set_options(StringTokenizer::RETURN_DELIMS);
485 extension = 521
486 extension_service->extensions()->GetByID(*(extension_ids.begin())); 522 while (t.GetNext()) {
523 if (t.token_is_delim()) {
524 tokens++;
525 continue;
526 }
527 switch (tokens) {
528 // Starting off with the app id, verify it exists.
529 case 0:
530 if (!t.token().empty()) {
531 // No extension service means no storage partitions in Chrome.
532 if (!extension_service)
533 return false;
534 if (extension_service->GetExtensionById(t.token(), false) == NULL)
535 return false;
536 }
537 break;
538 // The second token is either empty or the "in-memory" string.
539 case 1:
540 if (!t.token().empty() && t.token() != "in-memory")
541 return false;
542 break;
543 // We don't verify the partition_name, as it is user supplied and there is
544 // no format constraints to it.
545 case 2:
546 break;
547 }
487 } 548 }
488 return GetStoragePartitionIdForExtension(browser_context, extension); 549
550 // If there were less than three tokens, then it is not a valid partition id.
551 return (tokens >= 2);
489 } 552 }
490 553
491 std::string ChromeContentBrowserClient::GetStoragePartitionIdForSite( 554 void ChromeContentBrowserClient::GetStoragePartitionConfigForSite(
492 content::BrowserContext* browser_context, 555 content::BrowserContext* browser_context,
493 const GURL& site) { 556 const GURL& site,
557 std::string* app_id,
558 std::string* partition_name,
559 bool* in_memory) {
560 // If the site URL is the special guest format, extract the separate pieces
561 // out of it. The format is: guest://app_id/persist?partition_name
Charlie Reis 2012/11/06 00:17:18 nit: chrome-guest
562 if (site.SchemeIs(chrome::kGuestScheme)) {
563 // Since guest URLs are only used for packaged apps, there must be an app
564 // id in the URL.
565 CHECK(site.has_host());
566 *app_id = site.host();
567 // Since persistence is optional, the path must either be empty or the
568 // literal string.
569 *in_memory = ((site.path() == "/persist") ? false : true);
awong 2012/11/05 20:11:18 *in_memory = site.path() != "/persist";
nasko 2012/11/05 23:06:58 Done.
570 // The partition name is user supplied value, which we have encoded when the
571 // URL was created, so it needs to be decoded.
572 *partition_name = net::UnescapeURLComponent(site.query(),
573 net::UnescapeRule::NORMAL);
574 return;
575 }
576
494 const Extension* extension = NULL; 577 const Extension* extension = NULL;
495 Profile* profile = Profile::FromBrowserContext(browser_context); 578 Profile* profile = Profile::FromBrowserContext(browser_context);
496 ExtensionService* extension_service = 579 ExtensionService* extension_service =
497 extensions::ExtensionSystem::Get(profile)->extension_service(); 580 extensions::ExtensionSystem::Get(profile)->extension_service();
498 if (extension_service) { 581 if (extension_service) {
499 extension = extension_service->extensions()-> 582 extension = extension_service->extensions()->
500 GetExtensionOrAppByURL(ExtensionURLInfo(site)); 583 GetExtensionOrAppByURL(ExtensionURLInfo(site));
584 if (extension && extension->is_storage_isolated()) {
585 *app_id = extension->id();
586 *partition_name = std::string();
587 *in_memory = false;
588 return;
589 }
501 } 590 }
502 591
503 return GetStoragePartitionIdForExtension(browser_context, extension); 592 *app_id = std::string();
504 } 593 *partition_name = std::string();
505 594 *in_memory = false;
506 bool ChromeContentBrowserClient::IsValidStoragePartitionId(
507 content::BrowserContext* browser_context,
508 const std::string& partition_id) {
509 // The default ID is empty which is always allowed.
510 if (partition_id.empty())
511 return true;
512
513 // If it isn't empty, then it must belong to an extension of some sort. Parse
514 // out the extension ID and make sure it is still installed.
515 Profile* profile = Profile::FromBrowserContext(browser_context);
516 ExtensionService* extension_service =
517 extensions::ExtensionSystem::Get(profile)->extension_service();
518 if (!extension_service) {
519 // No extension service means no storage partitions in Chrome.
520 return false;
521 }
522
523 // See if we can find an extension. The |partition_id| is the extension ID so
524 // no parsing needed to be done.
525 return extension_service->GetExtensionById(partition_id, false) != NULL;
526 } 595 }
527 596
528 content::WebContentsViewDelegate* 597 content::WebContentsViewDelegate*
529 ChromeContentBrowserClient::GetWebContentsViewDelegate( 598 ChromeContentBrowserClient::GetWebContentsViewDelegate(
530 content::WebContents* web_contents) { 599 content::WebContents* web_contents) {
531 return chrome::CreateWebContentsViewDelegate(web_contents); 600 return chrome::CreateWebContentsViewDelegate(web_contents);
532 } 601 }
533 602
534 void ChromeContentBrowserClient::RenderViewHostCreated( 603 void ChromeContentBrowserClient::RenderViewHostCreated(
535 RenderViewHost* render_view_host) { 604 RenderViewHost* render_view_host) {
(...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after
1601 if (web_prefs->default_encoding.empty()) { 1670 if (web_prefs->default_encoding.empty()) {
1602 prefs->ClearPref(prefs::kDefaultCharset); 1671 prefs->ClearPref(prefs::kDefaultCharset);
1603 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset); 1672 web_prefs->default_encoding = prefs->GetString(prefs::kDefaultCharset);
1604 } 1673 }
1605 DCHECK(!web_prefs->default_encoding.empty()); 1674 DCHECK(!web_prefs->default_encoding.empty());
1606 1675
1607 WebContents* web_contents = WebContents::FromRenderViewHost(rvh); 1676 WebContents* web_contents = WebContents::FromRenderViewHost(rvh);
1608 chrome::ViewType view_type = chrome::GetViewType(web_contents); 1677 chrome::ViewType view_type = chrome::GetViewType(web_contents);
1609 ExtensionService* service = profile->GetExtensionService(); 1678 ExtensionService* service = profile->GetExtensionService();
1610 if (service) { 1679 if (service) {
1611 const Extension* extension = service->extensions()->GetByID( 1680 const GURL& url = rvh->GetSiteInstance()->GetSiteURL();
1612 rvh->GetSiteInstance()->GetSiteURL().host()); 1681 const Extension* extension = service->extensions()->GetByID(url.host());
1613 extension_webkit_preferences::SetPreferences( 1682 // Ensure that we are only granting extension preferences to URLs with
1614 extension, view_type, web_prefs); 1683 // the correct scheme. Without this check, guest:// schemes used by
1684 // webview tags as well as hosts that happen to match the id of an
1685 // installed extension would get the wrong preferences.
1686 if (url.SchemeIs(chrome::kExtensionScheme)) {
1687 extension_webkit_preferences::SetPreferences(
1688 extension, view_type, web_prefs);
1689 }
1615 } 1690 }
1616 1691
1617 if (content::IsForceCompositingModeEnabled()) 1692 if (content::IsForceCompositingModeEnabled())
1618 web_prefs->force_compositing_mode = true; 1693 web_prefs->force_compositing_mode = true;
1619 1694
1620 if (view_type == chrome::VIEW_TYPE_NOTIFICATION) { 1695 if (view_type == chrome::VIEW_TYPE_NOTIFICATION) {
1621 web_prefs->allow_scripts_to_close_windows = true; 1696 web_prefs->allow_scripts_to_close_windows = true;
1622 } else if (view_type == chrome::VIEW_TYPE_BACKGROUND_CONTENTS) { 1697 } else if (view_type == chrome::VIEW_TYPE_BACKGROUND_CONTENTS) {
1623 // Disable all kinds of acceleration for background pages. 1698 // Disable all kinds of acceleration for background pages.
1624 // See http://crbug.com/96005 and http://crbug.com/96006 1699 // See http://crbug.com/96005 and http://crbug.com/96006
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 base::Unretained(this), locale))) 1936 base::Unretained(this), locale)))
1862 io_thread_application_locale_ = locale; 1937 io_thread_application_locale_ = locale;
1863 } 1938 }
1864 1939
1865 void ChromeContentBrowserClient::SetApplicationLocaleOnIOThread( 1940 void ChromeContentBrowserClient::SetApplicationLocaleOnIOThread(
1866 const std::string& locale) { 1941 const std::string& locale) {
1867 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 1942 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
1868 io_thread_application_locale_ = locale; 1943 io_thread_application_locale_ = locale;
1869 } 1944 }
1870 1945
1871 std::string ChromeContentBrowserClient::GetStoragePartitionIdForExtension(
1872 content::BrowserContext* browser_context, const Extension* extension) {
1873 // In chrome, we use the extension ID as the partition ID. This works well
1874 // because the extension ID fits the partition ID pattern and currently only
1875 // apps can designate that storage should be isolated.
1876 //
1877 // If |extension| is NULL, then the default, empty string, partition id is
1878 // used.
1879 std::string partition_id;
1880 if (extension && extension->is_storage_isolated()) {
1881 partition_id = extension->id();
1882 }
1883
1884 // Enforce that IsValidStoragePartitionId() implementation stays in sync.
1885 DCHECK(IsValidStoragePartitionId(browser_context, partition_id));
1886 return partition_id;
1887 }
1888
1889
1890 } // namespace chrome 1946 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698