OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |