| 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/worker_host/worker_process_host.h" | 5 #include "content/browser/worker_host/worker_process_host.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 } // namespace | 87 } // namespace |
| 88 | 88 |
| 89 // Notifies RenderViewHost that one or more worker objects crashed. | 89 // Notifies RenderViewHost that one or more worker objects crashed. |
| 90 void WorkerCrashCallback(int render_process_unique_id, int render_view_id) { | 90 void WorkerCrashCallback(int render_process_unique_id, int render_view_id) { |
| 91 RenderViewHostImpl* host = | 91 RenderViewHostImpl* host = |
| 92 RenderViewHostImpl::FromID(render_process_unique_id, render_view_id); | 92 RenderViewHostImpl::FromID(render_process_unique_id, render_view_id); |
| 93 if (host) | 93 if (host) |
| 94 host->GetDelegate()->WorkerCrashed(); | 94 host->GetDelegate()->WorkerCrashed(); |
| 95 } | 95 } |
| 96 | 96 |
| 97 WorkerProcessHost::WorkerProcessHost(ResourceContext* resource_context) | 97 WorkerProcessHost::WorkerProcessHost( |
| 98 : resource_context_(resource_context) { | 98 ResourceContext* resource_context, |
| 99 const WorkerStoragePartition& partition) |
| 100 : resource_context_(resource_context), |
| 101 partition_(partition) { |
| 99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 102 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 100 DCHECK(resource_context); | 103 DCHECK(resource_context_); |
| 101 process_.reset( | 104 process_.reset( |
| 102 new BrowserChildProcessHostImpl(content::PROCESS_TYPE_WORKER, this)); | 105 new BrowserChildProcessHostImpl(content::PROCESS_TYPE_WORKER, this)); |
| 103 } | 106 } |
| 104 | 107 |
| 105 WorkerProcessHost::~WorkerProcessHost() { | 108 WorkerProcessHost::~WorkerProcessHost() { |
| 106 // If we crashed, tell the RenderViewHosts. | 109 // If we crashed, tell the RenderViewHosts. |
| 107 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { | 110 for (Instances::iterator i = instances_.begin(); i != instances_.end(); ++i) { |
| 108 const WorkerDocumentSet::DocumentInfoSet& parents = | 111 const WorkerDocumentSet::DocumentInfoSet& parents = |
| 109 i->worker_document_set()->documents(); | 112 i->worker_document_set()->documents(); |
| 110 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = | 113 for (WorkerDocumentSet::DocumentInfoSet::const_iterator parent_iter = |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 | 196 |
| 194 process_->Launch( | 197 process_->Launch( |
| 195 #if defined(OS_WIN) | 198 #if defined(OS_WIN) |
| 196 FilePath(), | 199 FilePath(), |
| 197 #elif defined(OS_POSIX) | 200 #elif defined(OS_POSIX) |
| 198 use_zygote, | 201 use_zygote, |
| 199 base::EnvironmentVector(), | 202 base::EnvironmentVector(), |
| 200 #endif | 203 #endif |
| 201 cmd_line); | 204 cmd_line); |
| 202 | 205 |
| 203 fileapi::FileSystemContext* file_system_context = | |
| 204 GetFileSystemContextForResourceContext(resource_context_); | |
| 205 ChildProcessSecurityPolicyImpl::GetInstance()->AddWorker( | 206 ChildProcessSecurityPolicyImpl::GetInstance()->AddWorker( |
| 206 process_->GetData().id, render_process_id); | 207 process_->GetData().id, render_process_id); |
| 207 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 208 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
| 208 switches::kDisableFileSystem)) { | 209 switches::kDisableFileSystem)) { |
| 209 // Grant most file permissions to this worker. | 210 // Grant most file permissions to this worker. |
| 210 // PLATFORM_FILE_TEMPORARY, PLATFORM_FILE_HIDDEN and | 211 // PLATFORM_FILE_TEMPORARY, PLATFORM_FILE_HIDDEN and |
| 211 // PLATFORM_FILE_DELETE_ON_CLOSE are not granted, because no existing API | 212 // PLATFORM_FILE_DELETE_ON_CLOSE are not granted, because no existing API |
| 212 // requests them. | 213 // requests them. |
| 213 // This is for the filesystem sandbox. | 214 // This is for the filesystem sandbox. |
| 214 ChildProcessSecurityPolicyImpl::GetInstance()->GrantPermissionsForFile( | 215 ChildProcessSecurityPolicyImpl::GetInstance()->GrantPermissionsForFile( |
| 215 process_->GetData().id, | 216 process_->GetData().id, |
| 216 file_system_context->sandbox_provider()->new_base_path(), | 217 partition_.filesystem_context()->sandbox_provider()->new_base_path(), |
| 217 base::PLATFORM_FILE_OPEN | | 218 base::PLATFORM_FILE_OPEN | |
| 218 base::PLATFORM_FILE_CREATE | | 219 base::PLATFORM_FILE_CREATE | |
| 219 base::PLATFORM_FILE_OPEN_ALWAYS | | 220 base::PLATFORM_FILE_OPEN_ALWAYS | |
| 220 base::PLATFORM_FILE_CREATE_ALWAYS | | 221 base::PLATFORM_FILE_CREATE_ALWAYS | |
| 221 base::PLATFORM_FILE_OPEN_TRUNCATED | | 222 base::PLATFORM_FILE_OPEN_TRUNCATED | |
| 222 base::PLATFORM_FILE_READ | | 223 base::PLATFORM_FILE_READ | |
| 223 base::PLATFORM_FILE_WRITE | | 224 base::PLATFORM_FILE_WRITE | |
| 224 base::PLATFORM_FILE_EXCLUSIVE_READ | | 225 base::PLATFORM_FILE_EXCLUSIVE_READ | |
| 225 base::PLATFORM_FILE_EXCLUSIVE_WRITE | | 226 base::PLATFORM_FILE_EXCLUSIVE_WRITE | |
| 226 base::PLATFORM_FILE_ASYNC | | 227 base::PLATFORM_FILE_ASYNC | |
| 227 base::PLATFORM_FILE_WRITE_ATTRIBUTES | | 228 base::PLATFORM_FILE_WRITE_ATTRIBUTES | |
| 228 base::PLATFORM_FILE_ENUMERATE); | 229 base::PLATFORM_FILE_ENUMERATE); |
| 229 // This is so that we can read and move stuff out of the old filesystem | 230 // This is so that we can read and move stuff out of the old filesystem |
| 230 // sandbox. | 231 // sandbox. |
| 231 ChildProcessSecurityPolicyImpl::GetInstance()->GrantPermissionsForFile( | 232 ChildProcessSecurityPolicyImpl::GetInstance()->GrantPermissionsForFile( |
| 232 process_->GetData().id, | 233 process_->GetData().id, |
| 233 file_system_context->sandbox_provider()->old_base_path(), | 234 partition_.filesystem_context()->sandbox_provider()->old_base_path(), |
| 234 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE | | 235 base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE | |
| 235 base::PLATFORM_FILE_WRITE_ATTRIBUTES | | 236 base::PLATFORM_FILE_WRITE_ATTRIBUTES | |
| 236 base::PLATFORM_FILE_ENUMERATE); | 237 base::PLATFORM_FILE_ENUMERATE); |
| 237 // This is so that we can rename the old sandbox out of the way so that | 238 // This is so that we can rename the old sandbox out of the way so that |
| 238 // we know we've taken care of it. | 239 // we know we've taken care of it. |
| 239 ChildProcessSecurityPolicyImpl::GetInstance()->GrantPermissionsForFile( | 240 ChildProcessSecurityPolicyImpl::GetInstance()->GrantPermissionsForFile( |
| 240 process_->GetData().id, | 241 process_->GetData().id, |
| 241 file_system_context->sandbox_provider()->renamed_old_base_path(), | 242 partition_.filesystem_context()->sandbox_provider()-> |
| 243 renamed_old_base_path(), |
| 242 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_CREATE_ALWAYS | | 244 base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_CREATE_ALWAYS | |
| 243 base::PLATFORM_FILE_WRITE); | 245 base::PLATFORM_FILE_WRITE); |
| 244 } | 246 } |
| 245 | 247 |
| 246 CreateMessageFilters(render_process_id); | 248 CreateMessageFilters(render_process_id); |
| 247 | 249 |
| 248 return true; | 250 return true; |
| 249 } | 251 } |
| 250 | 252 |
| 251 void WorkerProcessHost::CreateMessageFilters(int render_process_id) { | 253 void WorkerProcessHost::CreateMessageFilters(int render_process_id) { |
| 252 net::URLRequestContext* request_context = | 254 net::URLRequestContext* request_context = |
| 253 resource_context_->GetRequestContext(); | 255 resource_context_->GetRequestContext(); |
| 254 | 256 |
| 255 ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( | 257 ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( |
| 256 process_->GetData().id, content::PROCESS_TYPE_WORKER, resource_context_, | 258 process_->GetData().id, content::PROCESS_TYPE_WORKER, resource_context_, |
| 257 new URLRequestContextSelector(request_context)); | 259 new URLRequestContextSelector(request_context)); |
| 258 process_->GetHost()->AddFilter(resource_message_filter); | 260 process_->GetHost()->AddFilter(resource_message_filter); |
| 259 | 261 |
| 260 worker_message_filter_ = new WorkerMessageFilter( | 262 worker_message_filter_ = new WorkerMessageFilter( |
| 261 render_process_id, resource_context_, | 263 render_process_id, resource_context_, partition_, |
| 262 base::Bind(&WorkerServiceImpl::next_worker_route_id, | 264 base::Bind(&WorkerServiceImpl::next_worker_route_id, |
| 263 base::Unretained(WorkerServiceImpl::GetInstance()))); | 265 base::Unretained(WorkerServiceImpl::GetInstance()))); |
| 264 process_->GetHost()->AddFilter(worker_message_filter_); | 266 process_->GetHost()->AddFilter(worker_message_filter_); |
| 265 process_->GetHost()->AddFilter(new AppCacheDispatcherHost( | 267 process_->GetHost()->AddFilter(new AppCacheDispatcherHost( |
| 266 static_cast<ChromeAppCacheService*>( | 268 static_cast<ChromeAppCacheService*>( |
| 267 ResourceContext::GetAppCacheService(resource_context_)), | 269 ResourceContext::GetAppCacheService(resource_context_)), |
| 268 process_->GetData().id)); | 270 process_->GetData().id)); |
| 269 process_->GetHost()->AddFilter(new FileAPIMessageFilter( | 271 process_->GetHost()->AddFilter(new FileAPIMessageFilter( |
| 270 process_->GetData().id, | 272 process_->GetData().id, |
| 271 request_context, | 273 request_context, |
| 272 GetFileSystemContextForResourceContext(resource_context_), | 274 partition_.filesystem_context(), |
| 273 content::GetChromeBlobStorageContextForResourceContext( | 275 content::GetChromeBlobStorageContextForResourceContext( |
| 274 resource_context_))); | 276 resource_context_))); |
| 275 process_->GetHost()->AddFilter(new FileUtilitiesMessageFilter( | 277 process_->GetHost()->AddFilter(new FileUtilitiesMessageFilter( |
| 276 process_->GetData().id)); | 278 process_->GetData().id)); |
| 277 process_->GetHost()->AddFilter(new MimeRegistryMessageFilter()); | 279 process_->GetHost()->AddFilter(new MimeRegistryMessageFilter()); |
| 278 process_->GetHost()->AddFilter(new DatabaseMessageFilter( | 280 process_->GetHost()->AddFilter( |
| 279 content::GetDatabaseTrackerForResourceContext(resource_context_))); | 281 new DatabaseMessageFilter(partition_.database_tracker())); |
| 280 | 282 |
| 281 SocketStreamDispatcherHost* socket_stream_dispatcher_host = | 283 SocketStreamDispatcherHost* socket_stream_dispatcher_host = |
| 282 new SocketStreamDispatcherHost(render_process_id, | 284 new SocketStreamDispatcherHost(render_process_id, |
| 283 new URLRequestContextSelector(request_context), resource_context_); | 285 new URLRequestContextSelector(request_context), resource_context_); |
| 284 process_->GetHost()->AddFilter(socket_stream_dispatcher_host); | 286 process_->GetHost()->AddFilter(socket_stream_dispatcher_host); |
| 285 process_->GetHost()->AddFilter( | 287 process_->GetHost()->AddFilter( |
| 286 new content::WorkerDevToolsMessageFilter(process_->GetData().id)); | 288 new content::WorkerDevToolsMessageFilter(process_->GetData().id)); |
| 287 process_->GetHost()->AddFilter(new IndexedDBDispatcherHost( | 289 process_->GetHost()->AddFilter(new IndexedDBDispatcherHost( |
| 288 process_->GetData().id, | 290 process_->GetData().id, partition_.indexed_db_context())); |
| 289 content::GetIndexedDBContextForResourceContext(resource_context_))); | |
| 290 } | 291 } |
| 291 | 292 |
| 292 void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) { | 293 void WorkerProcessHost::CreateWorker(const WorkerInstance& instance) { |
| 293 ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL( | 294 ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL( |
| 294 process_->GetData().id, instance.url()); | 295 process_->GetData().id, instance.url()); |
| 295 | 296 |
| 296 instances_.push_back(instance); | 297 instances_.push_back(instance); |
| 297 | 298 |
| 298 WorkerProcessMsg_CreateWorker_Params params; | 299 WorkerProcessMsg_CreateWorker_Params params; |
| 299 params.url = instance.url(); | 300 params.url = instance.url(); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 } | 572 } |
| 572 return result; | 573 return result; |
| 573 } | 574 } |
| 574 | 575 |
| 575 WorkerProcessHost::WorkerInstance::WorkerInstance( | 576 WorkerProcessHost::WorkerInstance::WorkerInstance( |
| 576 const GURL& url, | 577 const GURL& url, |
| 577 const string16& name, | 578 const string16& name, |
| 578 int worker_route_id, | 579 int worker_route_id, |
| 579 int parent_process_id, | 580 int parent_process_id, |
| 580 int64 main_resource_appcache_id, | 581 int64 main_resource_appcache_id, |
| 581 content::ResourceContext* resource_context) | 582 content::ResourceContext* resource_context, |
| 583 const WorkerStoragePartition& partition) |
| 582 : url_(url), | 584 : url_(url), |
| 583 closed_(false), | 585 closed_(false), |
| 584 name_(name), | 586 name_(name), |
| 585 worker_route_id_(worker_route_id), | 587 worker_route_id_(worker_route_id), |
| 586 parent_process_id_(parent_process_id), | 588 parent_process_id_(parent_process_id), |
| 587 main_resource_appcache_id_(main_resource_appcache_id), | 589 main_resource_appcache_id_(main_resource_appcache_id), |
| 588 worker_document_set_(new WorkerDocumentSet()), | 590 worker_document_set_(new WorkerDocumentSet()), |
| 589 resource_context_(resource_context) { | 591 resource_context_(resource_context), |
| 592 partition_(partition) { |
| 590 DCHECK(resource_context_); | 593 DCHECK(resource_context_); |
| 591 } | 594 } |
| 592 | 595 |
| 593 WorkerProcessHost::WorkerInstance::WorkerInstance( | 596 WorkerProcessHost::WorkerInstance::WorkerInstance( |
| 594 const GURL& url, | 597 const GURL& url, |
| 595 bool shared, | 598 bool shared, |
| 596 const string16& name, | 599 const string16& name, |
| 597 content::ResourceContext* resource_context) | 600 content::ResourceContext* resource_context, |
| 601 const WorkerStoragePartition& partition) |
| 598 : url_(url), | 602 : url_(url), |
| 599 closed_(false), | 603 closed_(false), |
| 600 name_(name), | 604 name_(name), |
| 601 worker_route_id_(MSG_ROUTING_NONE), | 605 worker_route_id_(MSG_ROUTING_NONE), |
| 602 parent_process_id_(0), | 606 parent_process_id_(0), |
| 603 main_resource_appcache_id_(0), | 607 main_resource_appcache_id_(0), |
| 604 worker_document_set_(new WorkerDocumentSet()), | 608 worker_document_set_(new WorkerDocumentSet()), |
| 605 resource_context_(resource_context) { | 609 resource_context_(resource_context), |
| 610 partition_(partition) { |
| 606 DCHECK(resource_context_); | 611 DCHECK(resource_context_); |
| 607 } | 612 } |
| 608 | 613 |
| 609 WorkerProcessHost::WorkerInstance::~WorkerInstance() { | 614 WorkerProcessHost::WorkerInstance::~WorkerInstance() { |
| 610 } | 615 } |
| 611 | 616 |
| 612 // Compares an instance based on the algorithm in the WebWorkers spec - an | 617 // Compares an instance based on the algorithm in the WebWorkers spec - an |
| 613 // instance matches if the origins of the URLs match, and: | 618 // instance matches if the origins of the URLs match, and: |
| 614 // a) the names are non-empty and equal | 619 // a) the names are non-empty and equal |
| 615 // -or- | 620 // -or- |
| 616 // b) the names are both empty, and the urls are equal | 621 // b) the names are both empty, and the urls are equal |
| 617 bool WorkerProcessHost::WorkerInstance::Matches( | 622 bool WorkerProcessHost::WorkerInstance::Matches( |
| 618 const GURL& match_url, | 623 const GURL& match_url, |
| 619 const string16& match_name, | 624 const string16& match_name, |
| 625 const WorkerStoragePartition& partition, |
| 620 content::ResourceContext* resource_context) const { | 626 content::ResourceContext* resource_context) const { |
| 621 // Only match open shared workers. | 627 // Only match open shared workers. |
| 622 if (closed_) | 628 if (closed_) |
| 623 return false; | 629 return false; |
| 624 | 630 |
| 625 // ResourceContext equivalence is being used as a proxy to ensure we only | 631 // ResourceContext equivalence is being used as a proxy to ensure we only |
| 626 // matched shared workers within the same BrowserContext. | 632 // matched shared workers within the same BrowserContext. |
| 627 if (resource_context_ != resource_context) | 633 if (resource_context_ != resource_context) |
| 628 return false; | 634 return false; |
| 629 | 635 |
| 636 // We must be in the same storage partition otherwise sharing will violate |
| 637 // isolation. |
| 638 if (!partition_.Equals(partition)) |
| 639 return false; |
| 640 |
| 630 if (url_.GetOrigin() != match_url.GetOrigin()) | 641 if (url_.GetOrigin() != match_url.GetOrigin()) |
| 631 return false; | 642 return false; |
| 632 | 643 |
| 633 if (name_.empty() && match_name.empty()) | 644 if (name_.empty() && match_name.empty()) |
| 634 return url_ == match_url; | 645 return url_ == match_url; |
| 635 | 646 |
| 636 return name_ == match_name; | 647 return name_ == match_name; |
| 637 } | 648 } |
| 638 | 649 |
| 639 void WorkerProcessHost::WorkerInstance::AddFilter(WorkerMessageFilter* filter, | 650 void WorkerProcessHost::WorkerInstance::AddFilter(WorkerMessageFilter* filter, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 } | 701 } |
| 691 } | 702 } |
| 692 return false; | 703 return false; |
| 693 } | 704 } |
| 694 | 705 |
| 695 WorkerProcessHost::WorkerInstance::FilterInfo | 706 WorkerProcessHost::WorkerInstance::FilterInfo |
| 696 WorkerProcessHost::WorkerInstance::GetFilter() const { | 707 WorkerProcessHost::WorkerInstance::GetFilter() const { |
| 697 DCHECK(NumFilters() == 1); | 708 DCHECK(NumFilters() == 1); |
| 698 return *filters_.begin(); | 709 return *filters_.begin(); |
| 699 } | 710 } |
| OLD | NEW |