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

Side by Side Diff: content/browser/storage_partition_impl_map.cc

Issue 10909182: Make FileSystemContext respect StoragePartitions. filesystem:// urls will be properly isolated (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch unittest fix from michael Created 8 years, 3 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 | 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 "content/browser/storage_partition_impl_map.h" 5 #include "content/browser/storage_partition_impl_map.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "content/browser/appcache/chrome_appcache_service.h" 12 #include "content/browser/appcache/chrome_appcache_service.h"
13 #include "content/browser/fileapi/browser_file_system_helper.h"
14 #include "content/browser/fileapi/chrome_blob_storage_context.h"
15 #include "content/browser/histogram_internals_request_job.h"
16 #include "content/browser/net/view_blob_internals_job_factory.h"
17 #include "content/browser/net/view_http_cache_job_factory.h"
18 #include "content/browser/renderer_host/resource_request_info_impl.h"
13 #include "content/browser/resource_context_impl.h" 19 #include "content/browser/resource_context_impl.h"
14 #include "content/browser/storage_partition_impl.h" 20 #include "content/browser/storage_partition_impl.h"
21 #include "content/browser/tcmalloc_internals_request_job.h"
15 #include "content/public/browser/browser_context.h" 22 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/storage_partition.h"
17 #include "content/public/common/content_constants.h" 25 #include "content/public/common/content_constants.h"
26 #include "content/public/common/url_constants.h"
18 #include "net/url_request/url_request_context_getter.h" 27 #include "net/url_request/url_request_context_getter.h"
28 #include "net/url_request/url_request_context.h"
29 #include "webkit/appcache/view_appcache_internals_job.h"
30 #include "webkit/blob/blob_data.h"
31 #include "webkit/blob/blob_url_request_job_factory.h"
32 #include "webkit/fileapi/file_system_url_request_job_factory.h"
33
34 using appcache::AppCacheService;
35 using content::BrowserThread;
36 using fileapi::FileSystemContext;
37 using webkit_blob::BlobStorageController;
19 38
20 namespace content { 39 namespace content {
21 40
41 namespace {
42
43 class BlobProtocolHandler : public webkit_blob::BlobProtocolHandler {
44 public:
45 BlobProtocolHandler(
46 webkit_blob::BlobStorageController* blob_storage_controller,
47 base::MessageLoopProxy* loop_proxy)
48 : webkit_blob::BlobProtocolHandler(blob_storage_controller,
49 loop_proxy) {}
50
51 virtual ~BlobProtocolHandler() {}
52
53 private:
54 virtual scoped_refptr<webkit_blob::BlobData>
55 LookupBlobData(net::URLRequest* request) const {
56 const ResourceRequestInfoImpl* info =
57 ResourceRequestInfoImpl::ForRequest(request);
58 if (!info)
59 return NULL;
60 return info->requested_blob_data();
61 }
62
63 DISALLOW_COPY_AND_ASSIGN(BlobProtocolHandler);
64 };
65
66 // Adds a bunch of debugging urls. We use an interceptor instead of a protocol
67 // handler because we want to reuse the chrome://scheme (everyone is familiar
68 // with it, and no need to expose the content/chrome separation through our UI).
69 class DeveloperProtocolHandler
70 : public net::URLRequestJobFactory::Interceptor {
71 public:
72 DeveloperProtocolHandler(
73 AppCacheService* appcache_service,
74 BlobStorageController* blob_storage_controller)
75 : appcache_service_(appcache_service),
76 blob_storage_controller_(blob_storage_controller) {}
77 virtual ~DeveloperProtocolHandler() {}
78
79 virtual net::URLRequestJob* MaybeIntercept(
80 net::URLRequest* request,
81 net::NetworkDelegate* network_delegate) const OVERRIDE {
82 // Check for chrome://view-http-cache/*, which uses its own job type.
83 if (ViewHttpCacheJobFactory::IsSupportedURL(request->url()))
84 return ViewHttpCacheJobFactory::CreateJobForRequest(request,
85 network_delegate);
86
87 // Next check for chrome://appcache-internals/, which uses its own job type.
88 if (request->url().SchemeIs(chrome::kChromeUIScheme) &&
89 request->url().host() == chrome::kChromeUIAppCacheInternalsHost) {
90 return appcache::ViewAppCacheInternalsJobFactory::CreateJobForRequest(
91 request, network_delegate, appcache_service_);
92 }
93
94 // Next check for chrome://blob-internals/, which uses its own job type.
95 if (ViewBlobInternalsJobFactory::IsSupportedURL(request->url())) {
96 return ViewBlobInternalsJobFactory::CreateJobForRequest(
97 request, network_delegate, blob_storage_controller_);
98 }
99
100 #if defined(USE_TCMALLOC)
101 // Next check for chrome://tcmalloc/, which uses its own job type.
102 if (request->url().SchemeIs(chrome::kChromeUIScheme) &&
103 request->url().host() == chrome::kChromeUITcmallocHost) {
104 return new TcmallocInternalsRequestJob(request, network_delegate);
105 }
106 #endif
107
108 // Next check for chrome://histograms/, which uses its own job type.
109 if (request->url().SchemeIs(chrome::kChromeUIScheme) &&
110 request->url().host() == chrome::kChromeUIHistogramHost) {
111 return new HistogramInternalsRequestJob(request, network_delegate);
112 }
113
114 return NULL;
115 }
116
117 virtual net::URLRequestJob* MaybeInterceptRedirect(
118 const GURL& location,
119 net::URLRequest* request,
120 net::NetworkDelegate* network_delegate) const OVERRIDE {
121 return NULL;
122 }
123
124 virtual net::URLRequestJob* MaybeInterceptResponse(
125 net::URLRequest* request,
126 net::NetworkDelegate* network_delegate) const OVERRIDE {
127 return NULL;
128 }
129
130 virtual bool WillHandleProtocol(const std::string& protocol) const {
131 return protocol == chrome::kChromeUIScheme;
132 }
133
134 private:
135 AppCacheService* appcache_service_;
136 BlobStorageController* blob_storage_controller_;
137 };
138
139 void InitializeURLRequestContext(
140 scoped_refptr<net::URLRequestContextGetter> context_getter,
michaeln 2012/09/15 01:48:33 this first argument could be a raw ptr like the ot
awong 2012/09/15 02:05:02 Done.
141 AppCacheService* appcache_service,
142 FileSystemContext* file_system_context,
143 ChromeBlobStorageContext* blob_storage_context) {
144 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
145 if (!context_getter)
146 return; // tests.
147 net::URLRequestContext* context = context_getter->GetURLRequestContext();
148 net::URLRequestJobFactory* job_factory =
149 const_cast<net::URLRequestJobFactory*>(context->job_factory());
150 if (job_factory->IsHandledProtocol(chrome::kBlobScheme))
151 return; // Already initialized this RequestContext.
152
153 bool set_protocol = job_factory->SetProtocolHandler(
154 chrome::kBlobScheme,
155 new BlobProtocolHandler(
156 blob_storage_context->controller(),
157 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)));
158 DCHECK(set_protocol);
159 set_protocol = job_factory->SetProtocolHandler(
160 chrome::kFileSystemScheme,
161 CreateFileSystemProtocolHandler(file_system_context));
162 DCHECK(set_protocol);
163
164 job_factory->AddInterceptor(
165 new DeveloperProtocolHandler(appcache_service,
166 blob_storage_context->controller()));
167
168 // TODO(jam): Add the ProtocolHandlerRegistryIntercepter here!
169 }
170
171 } // namespace
172
22 StoragePartitionImplMap::StoragePartitionImplMap( 173 StoragePartitionImplMap::StoragePartitionImplMap(
23 BrowserContext* browser_context) 174 BrowserContext* browser_context)
24 : browser_context_(browser_context) { 175 : browser_context_(browser_context) {
25 } 176 }
26 177
27 StoragePartitionImplMap::~StoragePartitionImplMap() { 178 StoragePartitionImplMap::~StoragePartitionImplMap() {
28 STLDeleteContainerPairSecondPointers(partitions_.begin(), 179 STLDeleteContainerPairSecondPointers(partitions_.begin(),
29 partitions_.end()); 180 partitions_.end());
30 } 181 }
31 182
32 StoragePartitionImpl* StoragePartitionImplMap::Get( 183 StoragePartitionImpl* StoragePartitionImplMap::Get(
33 const std::string& partition_id) { 184 const std::string& partition_id) {
34 // Find the previously created partition if it's available. 185 // Find the previously created partition if it's available.
35 std::map<std::string, StoragePartitionImpl*>::const_iterator it = 186 std::map<std::string, StoragePartitionImpl*>::const_iterator it =
36 partitions_.find(partition_id); 187 partitions_.find(partition_id);
37 if (it != partitions_.end()) 188 if (it != partitions_.end())
38 return it->second; 189 return it->second;
39 190
40 // There was no previous partition, so let's make a new one. 191 // There was no previous partition, so let's make a new one.
41 FilePath partition_path = browser_context_->GetPath(); 192 FilePath partition_path = browser_context_->GetPath();
42 if (!partition_id.empty()) { 193 if (!partition_id.empty()) {
43 // TODO(ajwong): This should check the path is valid? 194 // TODO(ajwong): This should check the path is valid?
44 CHECK(IsStringASCII(partition_id)); 195 CHECK(IsStringASCII(partition_id));
45 partition_path = partition_path.Append(kStoragePartitionDirname) 196 partition_path = partition_path.Append(kStoragePartitionDirname)
46 .AppendASCII(partition_id); 197 .AppendASCII(partition_id);
47 } 198 }
48 199
49 StoragePartitionImpl* storage_partition = 200 StoragePartitionImpl* partition =
50 StoragePartitionImpl::Create(browser_context_, partition_path); 201 StoragePartitionImpl::Create(browser_context_, partition_path);
51 partitions_[partition_id] = storage_partition; 202 partitions_[partition_id] = partition;
52 203
53 net::URLRequestContextGetter* request_context = partition_id.empty() ? 204 // These calls must happen after StoragePartitionImpl::Create().
205 partition->SetURLRequestContext(
206 partition_id.empty() ?
54 browser_context_->GetRequestContext() : 207 browser_context_->GetRequestContext() :
55 browser_context_->GetRequestContextForStoragePartition(partition_id); 208 browser_context_->GetRequestContextForStoragePartition(partition_id));
209 partition->SetMediaURLRequestContext(
210 partition_id.empty() ? browser_context_->GetMediaRequestContext() :
michaeln 2012/09/15 01:48:33 nit: using a more consistent wrapping style for th
awong 2012/09/15 02:05:02 Done.
211 browser_context_->GetMediaRequestContextForStoragePartition(
212 partition_id));
56 213
57 PostCreateInitialization(storage_partition, partition_path, request_context); 214 PostCreateInitialization(partition, partition_path);
58 215
59 // TODO(ajwong): We need to remove this conditional by making 216 // TODO(ajwong): ResourceContexts no longer have any storage related state.
60 // InitializeResourceContext() understand having different partition data 217 // We should move this into a place where it is called once per
61 // based on the renderer_id. 218 // BrowserContext creation rather than piggybacking off the default context
219 // creation.
62 if (partition_id.empty()) { 220 if (partition_id.empty()) {
63 InitializeResourceContext(browser_context_); 221 InitializeResourceContext(browser_context_);
64 } 222 }
65 223
66 return storage_partition; 224 return partition;
67 } 225 }
68 226
69 void StoragePartitionImplMap::ForEach( 227 void StoragePartitionImplMap::ForEach(
70 const BrowserContext::StoragePartitionCallback& callback) { 228 const BrowserContext::StoragePartitionCallback& callback) {
71 for (std::map<std::string, StoragePartitionImpl*>::const_iterator it = 229 for (std::map<std::string, StoragePartitionImpl*>::const_iterator it =
72 partitions_.begin(); 230 partitions_.begin();
73 it != partitions_.end(); 231 it != partitions_.end();
74 ++it) { 232 ++it) {
75 callback.Run(it->first, it->second); 233 callback.Run(it->first, it->second);
76 } 234 }
77 } 235 }
78 236
79 void StoragePartitionImplMap::PostCreateInitialization( 237 void StoragePartitionImplMap::PostCreateInitialization(
80 StoragePartitionImpl* partition, 238 StoragePartitionImpl* partition,
81 const FilePath& partition_path, 239 const FilePath& partition_path) {
82 net::URLRequestContextGetter* request_context_getter) {
83 // Check first to avoid memory leak in unittests. 240 // Check first to avoid memory leak in unittests.
84 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) { 241 if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) {
85 BrowserThread::PostTask( 242 BrowserThread::PostTask(
86 BrowserThread::IO, FROM_HERE, 243 BrowserThread::IO, FROM_HERE,
87 base::Bind(&ChromeAppCacheService::InitializeOnIOThread, 244 base::Bind(&ChromeAppCacheService::InitializeOnIOThread,
88 partition->GetAppCacheService(), 245 partition->GetAppCacheService(),
89 browser_context_->IsOffTheRecord() ? FilePath() : 246 browser_context_->IsOffTheRecord() ? FilePath() :
90 partition_path.Append(kAppCacheDirname), 247 partition_path.Append(kAppCacheDirname),
91 browser_context_->GetResourceContext(), 248 browser_context_->GetResourceContext(),
92 make_scoped_refptr(request_context_getter), 249 make_scoped_refptr(partition->GetURLRequestContext()),
93 make_scoped_refptr( 250 make_scoped_refptr(
94 browser_context_->GetSpecialStoragePolicy()))); 251 browser_context_->GetSpecialStoragePolicy())));
252
253 // Add content's URLRequestContext's hooks.
254 BrowserThread::PostTask(
255 BrowserThread::IO, FROM_HERE,
256 base::Bind(
257 &InitializeURLRequestContext,
258 make_scoped_refptr(partition->GetURLRequestContext()),
259 make_scoped_refptr(partition->GetAppCacheService()),
260 make_scoped_refptr(partition->GetFileSystemContext()),
261 make_scoped_refptr(
262 ChromeBlobStorageContext::GetFor(browser_context_))));
263 BrowserThread::PostTask(
264 BrowserThread::IO, FROM_HERE,
265 base::Bind(
266 &InitializeURLRequestContext,
267 make_scoped_refptr(partition->GetMediaURLRequestContext()),
268 make_scoped_refptr(partition->GetAppCacheService()),
269 make_scoped_refptr(partition->GetFileSystemContext()),
270 make_scoped_refptr(
271 ChromeBlobStorageContext::GetFor(browser_context_))));
95 } 272 }
96 } 273 }
97 274
98 } // namespace content 275 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698