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

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

Issue 11308362: Add StoragePartition's ProtocolHandlers at URLRequestContext construction time. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Get ShellBrowserContext working Created 8 years 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/file_util.h" 10 #include "base/file_util.h"
(...skipping 26 matching lines...) Expand all
37 #include "webkit/fileapi/file_system_url_request_job_factory.h" 37 #include "webkit/fileapi/file_system_url_request_job_factory.h"
38 38
39 using appcache::AppCacheService; 39 using appcache::AppCacheService;
40 using fileapi::FileSystemContext; 40 using fileapi::FileSystemContext;
41 using webkit_blob::BlobStorageController; 41 using webkit_blob::BlobStorageController;
42 42
43 namespace content { 43 namespace content {
44 44
45 namespace { 45 namespace {
46 46
47 class BlobProtocolHandler : public webkit_blob::BlobProtocolHandler { 47 class BlobProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler {
48 public: 48 public:
49 BlobProtocolHandler( 49 BlobProtocolHandler(ChromeBlobStorageContext* blob_storage_context,
50 webkit_blob::BlobStorageController* blob_storage_controller, 50 fileapi::FileSystemContext* file_system_context)
51 fileapi::FileSystemContext* file_system_context, 51 : delegate_(new Delegate()) {
52 base::MessageLoopProxy* loop_proxy) 52 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
53 : webkit_blob::BlobProtocolHandler(blob_storage_controller, 53 &BlobProtocolHandler::Delegate::Init,
54 file_system_context, 54 base::Unretained(delegate_.get()),
55 loop_proxy) {} 55 make_scoped_refptr(blob_storage_context),
56 make_scoped_refptr(file_system_context)));
57 }
56 58
57 virtual ~BlobProtocolHandler() {} 59 virtual ~BlobProtocolHandler() {
60 BrowserThread::DeleteSoon(BrowserThread::IO,
61 FROM_HERE,
62 delegate_.release());
63 }
64
65 virtual net::URLRequestJob* MaybeCreateJob(
66 net::URLRequest* request,
67 net::NetworkDelegate* network_delegate) const OVERRIDE {
68 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
69 return delegate_->core_->MaybeCreateJob(request, network_delegate);
70 }
58 71
59 private: 72 private:
60 virtual scoped_refptr<webkit_blob::BlobData> 73 // Constructed on any thread and then lives on IO thread.
61 LookupBlobData(net::URLRequest* request) const { 74 class Delegate {
62 const ResourceRequestInfoImpl* info = 75 public:
63 ResourceRequestInfoImpl::ForRequest(request); 76 Delegate() {}
64 if (!info) 77 virtual ~Delegate() {
65 return NULL; 78 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
66 return info->requested_blob_data(); 79 }
67 } 80
81 void Init(ChromeBlobStorageContext* blob_storage_context,
82 fileapi::FileSystemContext* file_system_context) {
83 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
84 core_.reset(new Core(blob_storage_context->controller(),
85 file_system_context));
86 }
87
88 // |Core| is needed because |BlobProtocolHandler| is constructed on UI
89 // thread while ChromeBlobStorageContext::controller() must be called on
90 // IO thread and must be called prior to webkit_blob::BlobProtocolHandler().
91 class Core : public webkit_blob::BlobProtocolHandler {
92 public:
93 Core(webkit_blob::BlobStorageController* blob_storage_controller,
94 fileapi::FileSystemContext* file_system_context)
95 : webkit_blob::BlobProtocolHandler(
96 blob_storage_controller, file_system_context,
97 BrowserThread::GetMessageLoopProxyForThread(
98 BrowserThread::FILE)) {
99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
100 }
101
102 virtual ~Core() {
103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
104 }
105
106 private:
107 virtual scoped_refptr<webkit_blob::BlobData>
108 LookupBlobData(net::URLRequest* request) const OVERRIDE {
109 const ResourceRequestInfoImpl* info =
110 ResourceRequestInfoImpl::ForRequest(request);
111 if (!info)
112 return NULL;
113 return info->requested_blob_data();
114 }
115
116 DISALLOW_COPY_AND_ASSIGN(Core);
117 };
118
119 scoped_ptr<Core> core_;
120
121 DISALLOW_COPY_AND_ASSIGN(Delegate);
122 };
123
124 scoped_ptr<Delegate> delegate_;
68 125
69 DISALLOW_COPY_AND_ASSIGN(BlobProtocolHandler); 126 DISALLOW_COPY_AND_ASSIGN(BlobProtocolHandler);
70 }; 127 };
71 128
72 // Adds a bunch of debugging urls. We use an interceptor instead of a protocol 129 // Adds a bunch of debugging urls. We use an interceptor instead of a protocol
73 // handler because we want to reuse the chrome://scheme (everyone is familiar 130 // handler because we want to reuse the chrome://scheme (everyone is familiar
74 // with it, and no need to expose the content/chrome separation through our UI). 131 // with it, and no need to expose the content/chrome separation through our UI).
75 class DeveloperProtocolHandler 132 class DeveloperProtocolHandler
76 : public net::URLRequestJobFactory::Interceptor { 133 : public net::URLRequestJobFactory::Interceptor {
77 public: 134 public:
78 DeveloperProtocolHandler( 135 DeveloperProtocolHandler(
79 AppCacheService* appcache_service, 136 AppCacheService* appcache_service,
80 BlobStorageController* blob_storage_controller) 137 ChromeBlobStorageContext* blob_storage_context)
81 : appcache_service_(appcache_service), 138 : appcache_service_(appcache_service),
82 blob_storage_controller_(blob_storage_controller) {} 139 blob_storage_context_(blob_storage_context) {}
83 virtual ~DeveloperProtocolHandler() {} 140 virtual ~DeveloperProtocolHandler() {}
84 141
85 virtual net::URLRequestJob* MaybeIntercept( 142 virtual net::URLRequestJob* MaybeIntercept(
86 net::URLRequest* request, 143 net::URLRequest* request,
87 net::NetworkDelegate* network_delegate) const OVERRIDE { 144 net::NetworkDelegate* network_delegate) const OVERRIDE {
88 // Check for chrome://view-http-cache/*, which uses its own job type. 145 // Check for chrome://view-http-cache/*, which uses its own job type.
89 if (ViewHttpCacheJobFactory::IsSupportedURL(request->url())) 146 if (ViewHttpCacheJobFactory::IsSupportedURL(request->url()))
90 return ViewHttpCacheJobFactory::CreateJobForRequest(request, 147 return ViewHttpCacheJobFactory::CreateJobForRequest(request,
91 network_delegate); 148 network_delegate);
92 149
93 // Next check for chrome://appcache-internals/, which uses its own job type. 150 // Next check for chrome://appcache-internals/, which uses its own job type.
94 if (request->url().SchemeIs(chrome::kChromeUIScheme) && 151 if (request->url().SchemeIs(chrome::kChromeUIScheme) &&
95 request->url().host() == chrome::kChromeUIAppCacheInternalsHost) { 152 request->url().host() == chrome::kChromeUIAppCacheInternalsHost) {
96 return appcache::ViewAppCacheInternalsJobFactory::CreateJobForRequest( 153 return appcache::ViewAppCacheInternalsJobFactory::CreateJobForRequest(
97 request, network_delegate, appcache_service_); 154 request, network_delegate, appcache_service_);
98 } 155 }
99 156
100 // Next check for chrome://blob-internals/, which uses its own job type. 157 // Next check for chrome://blob-internals/, which uses its own job type.
101 if (ViewBlobInternalsJobFactory::IsSupportedURL(request->url())) { 158 if (ViewBlobInternalsJobFactory::IsSupportedURL(request->url())) {
102 return ViewBlobInternalsJobFactory::CreateJobForRequest( 159 return ViewBlobInternalsJobFactory::CreateJobForRequest(
103 request, network_delegate, blob_storage_controller_); 160 request, network_delegate, blob_storage_context_->controller());
104 } 161 }
105 162
106 #if defined(USE_TCMALLOC) 163 #if defined(USE_TCMALLOC)
107 // Next check for chrome://tcmalloc/, which uses its own job type. 164 // Next check for chrome://tcmalloc/, which uses its own job type.
108 if (request->url().SchemeIs(chrome::kChromeUIScheme) && 165 if (request->url().SchemeIs(chrome::kChromeUIScheme) &&
109 request->url().host() == chrome::kChromeUITcmallocHost) { 166 request->url().host() == chrome::kChromeUITcmallocHost) {
110 return new TcmallocInternalsRequestJob(request, network_delegate); 167 return new TcmallocInternalsRequestJob(request, network_delegate);
111 } 168 }
112 #endif 169 #endif
113 170
(...skipping 18 matching lines...) Expand all
132 net::NetworkDelegate* network_delegate) const OVERRIDE { 189 net::NetworkDelegate* network_delegate) const OVERRIDE {
133 return NULL; 190 return NULL;
134 } 191 }
135 192
136 virtual bool WillHandleProtocol(const std::string& protocol) const { 193 virtual bool WillHandleProtocol(const std::string& protocol) const {
137 return protocol == chrome::kChromeUIScheme; 194 return protocol == chrome::kChromeUIScheme;
138 } 195 }
139 196
140 private: 197 private:
141 AppCacheService* appcache_service_; 198 AppCacheService* appcache_service_;
142 BlobStorageController* blob_storage_controller_; 199 ChromeBlobStorageContext* blob_storage_context_;
143 }; 200 };
144 201
145 void InitializeURLRequestContext(
146 net::URLRequestContextGetter* context_getter,
147 AppCacheService* appcache_service,
148 FileSystemContext* file_system_context,
149 ChromeBlobStorageContext* blob_storage_context) {
150 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
151 if (!context_getter)
152 return; // tests.
153
154 // This code only modifies the URLRequestJobFactory on the context
155 // to handle blob: URLs, filesystem: URLs, and to let AppCache intercept
156 // the appropriate requests. This is in addition to the slew of other
157 // initializtion that is done in during creation of the URLRequestContext.
158 // We cannot yet centralize this code because URLRequestContext needs
159 // to be created before the StoragePartition context.
160 //
161 // TODO(ajwong): Fix the ordering so all the initialization is in one spot.
162 net::URLRequestContext* context = context_getter->GetURLRequestContext();
163 net::URLRequestJobFactory* job_factory =
164 const_cast<net::URLRequestJobFactory*>(context->job_factory());
165
166 // Note: if this is called twice with 2 request contexts that share one job
167 // factory (as is the case with a media request context and its related
168 // normal request context) then this will early exit.
169 if (job_factory->IsHandledProtocol(chrome::kBlobScheme))
170 return; // Already initialized this JobFactory.
171
172 bool set_protocol = job_factory->SetProtocolHandler(
173 chrome::kBlobScheme,
174 new BlobProtocolHandler(
175 blob_storage_context->controller(),
176 file_system_context,
177 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)));
178 DCHECK(set_protocol);
179 set_protocol = job_factory->SetProtocolHandler(
180 chrome::kFileSystemScheme,
181 CreateFileSystemProtocolHandler(file_system_context));
182 DCHECK(set_protocol);
183
184 job_factory->AddInterceptor(
185 new DeveloperProtocolHandler(appcache_service,
186 blob_storage_context->controller()));
187
188 // TODO(jam): Add the ProtocolHandlerRegistryIntercepter here!
189 }
190
191 // These constants are used to create the directory structure under the profile 202 // These constants are used to create the directory structure under the profile
192 // where renderers with a non-default storage partition keep their persistent 203 // where renderers with a non-default storage partition keep their persistent
193 // state. This will contain a set of directories that partially mirror the 204 // state. This will contain a set of directories that partially mirror the
194 // directory structure of BrowserContext::GetPath(). 205 // directory structure of BrowserContext::GetPath().
195 // 206 //
196 // The kStoragePartitionDirname contains an extensions directory which is 207 // The kStoragePartitionDirname contains an extensions directory which is
197 // further partitioned by extension id, followed by another level of directories 208 // further partitioned by extension id, followed by another level of directories
198 // for the "default" extension storage partition and one directory for each 209 // for the "default" extension storage partition and one directory for each
199 // persistent partition used by a webview tag. Example: 210 // persistent partition used by a webview tag. Example:
200 // 211 //
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 return it->second; 405 return it->second;
395 406
396 FilePath partition_path = 407 FilePath partition_path =
397 browser_context_->GetPath().Append( 408 browser_context_->GetPath().Append(
398 GetStoragePartitionPath(partition_domain, partition_name)); 409 GetStoragePartitionPath(partition_domain, partition_name));
399 StoragePartitionImpl* partition = 410 StoragePartitionImpl* partition =
400 StoragePartitionImpl::Create(browser_context_, in_memory, 411 StoragePartitionImpl::Create(browser_context_, in_memory,
401 partition_path); 412 partition_path);
402 partitions_[partition_config] = partition; 413 partitions_[partition_config] = partition;
403 414
415 ChromeBlobStorageContext* blob_storage_context =
416 ChromeBlobStorageContext::GetFor(browser_context_);
417 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler> blob_protocol_handler(
418 new BlobProtocolHandler(blob_storage_context,
419 partition->GetFileSystemContext()));
420 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>
421 file_system_protocol_handler(
422 CreateFileSystemProtocolHandler(partition->GetFileSystemContext()));
423 scoped_ptr<net::URLRequestJobFactory::Interceptor> developer_protocol_handler(
424 new DeveloperProtocolHandler(partition->GetAppCacheService(),
425 blob_storage_context));
426
404 // These calls must happen after StoragePartitionImpl::Create(). 427 // These calls must happen after StoragePartitionImpl::Create().
405 partition->SetURLRequestContext( 428 partition->SetURLRequestContext(
406 partition_domain.empty() ? 429 partition_domain.empty() ?
407 browser_context_->GetRequestContext() : 430 browser_context_->CreateRequestContext(
408 browser_context_->GetRequestContextForStoragePartition( 431 blob_protocol_handler.Pass(), file_system_protocol_handler.Pass(),
409 partition->GetPath(), in_memory)); 432 developer_protocol_handler.Pass()) :
433 browser_context_->CreateRequestContextForStoragePartition(
434 partition->GetPath(), in_memory, blob_protocol_handler.Pass(),
435 file_system_protocol_handler.Pass(),
436 developer_protocol_handler.Pass()));
410 partition->SetMediaURLRequestContext( 437 partition->SetMediaURLRequestContext(
411 partition_domain.empty() ? 438 partition_domain.empty() ?
412 browser_context_->GetMediaRequestContext() : 439 browser_context_->GetMediaRequestContext() :
413 browser_context_->GetMediaRequestContextForStoragePartition( 440 browser_context_->GetMediaRequestContextForStoragePartition(
414 partition->GetPath(), in_memory)); 441 partition->GetPath(), in_memory));
415 442
416 PostCreateInitialization(partition, in_memory); 443 PostCreateInitialization(partition, in_memory);
417 444
418 return partition; 445 return partition;
419 } 446 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 BrowserThread::IO, FROM_HERE, 513 BrowserThread::IO, FROM_HERE,
487 base::Bind(&ChromeAppCacheService::InitializeOnIOThread, 514 base::Bind(&ChromeAppCacheService::InitializeOnIOThread,
488 partition->GetAppCacheService(), 515 partition->GetAppCacheService(),
489 in_memory ? FilePath() : 516 in_memory ? FilePath() :
490 partition->GetPath().Append(kAppCacheDirname), 517 partition->GetPath().Append(kAppCacheDirname),
491 browser_context_->GetResourceContext(), 518 browser_context_->GetResourceContext(),
492 make_scoped_refptr(partition->GetURLRequestContext()), 519 make_scoped_refptr(partition->GetURLRequestContext()),
493 make_scoped_refptr( 520 make_scoped_refptr(
494 browser_context_->GetSpecialStoragePolicy()))); 521 browser_context_->GetSpecialStoragePolicy())));
495 522
496 // Add content's URLRequestContext's hooks.
497 BrowserThread::PostTask(
498 BrowserThread::IO, FROM_HERE,
499 base::Bind(
500 &InitializeURLRequestContext,
501 make_scoped_refptr(partition->GetURLRequestContext()),
502 make_scoped_refptr(partition->GetAppCacheService()),
503 make_scoped_refptr(partition->GetFileSystemContext()),
504 make_scoped_refptr(
505 ChromeBlobStorageContext::GetFor(browser_context_))));
506
507 // We do not call InitializeURLRequestContext() for media contexts because, 523 // We do not call InitializeURLRequestContext() for media contexts because,
508 // other than the HTTP cache, the media contexts share the same backing 524 // other than the HTTP cache, the media contexts share the same backing
509 // objects as their associated "normal" request context. Thus, the previous 525 // objects as their associated "normal" request context. Thus, the previous
510 // call serves to initialize the media request context for this storage 526 // call serves to initialize the media request context for this storage
511 // partition as well. 527 // partition as well.
512 } 528 }
513 } 529 }
514 530
515 } // namespace content 531 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698