| 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/webui/url_data_manager_backend.h" | 5 #include "content/browser/webui/url_data_manager_backend.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 #include <utility> |
| 8 | 9 |
| 9 #include "base/bind.h" | 10 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 11 #include "base/compiler_specific.h" | 12 #include "base/compiler_specific.h" |
| 12 #include "base/debug/alias.h" | 13 #include "base/debug/alias.h" |
| 13 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
| 14 #include "base/location.h" | 15 #include "base/location.h" |
| 15 #include "base/macros.h" | 16 #include "base/macros.h" |
| 16 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
| 17 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 #include "url/url_util.h" | 51 #include "url/url_util.h" |
| 51 | 52 |
| 52 namespace content { | 53 namespace content { |
| 53 | 54 |
| 54 namespace { | 55 namespace { |
| 55 | 56 |
| 56 const char kChromeURLContentSecurityPolicyHeaderBase[] = | 57 const char kChromeURLContentSecurityPolicyHeaderBase[] = |
| 57 "Content-Security-Policy: "; | 58 "Content-Security-Policy: "; |
| 58 | 59 |
| 59 const char kChromeURLXFrameOptionsHeader[] = "X-Frame-Options: DENY"; | 60 const char kChromeURLXFrameOptionsHeader[] = "X-Frame-Options: DENY"; |
| 60 static const char kNetworkErrorKey[] = "netError"; | 61 const char kNetworkErrorKey[] = "netError"; |
| 61 | 62 |
| 62 bool SchemeIsInSchemes(const std::string& scheme, | 63 bool SchemeIsInSchemes(const std::string& scheme, |
| 63 const std::vector<std::string>& schemes) { | 64 const std::vector<std::string>& schemes) { |
| 64 return std::find(schemes.begin(), schemes.end(), scheme) != schemes.end(); | 65 return std::find(schemes.begin(), schemes.end(), scheme) != schemes.end(); |
| 65 } | 66 } |
| 66 | 67 |
| 67 // Returns whether |url| passes some sanity checks and is a valid GURL. | 68 // Returns whether |url| passes some sanity checks and is a valid GURL. |
| 68 bool CheckURLIsValid(const GURL& url) { | 69 bool CheckURLIsValid(const GURL& url) { |
| 69 std::vector<std::string> additional_schemes; | 70 std::vector<std::string> additional_schemes; |
| 70 DCHECK(url.SchemeIs(kChromeDevToolsScheme) || url.SchemeIs(kChromeUIScheme) || | 71 DCHECK(url.SchemeIs(kChromeDevToolsScheme) || url.SchemeIs(kChromeUIScheme) || |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 251 std::string access_control_allow_origin_; | 252 std::string access_control_allow_origin_; |
| 252 | 253 |
| 253 // True when job is generated from an incognito profile. | 254 // True when job is generated from an incognito profile. |
| 254 const bool is_incognito_; | 255 const bool is_incognito_; |
| 255 | 256 |
| 256 // True when gzip encoding should be used. NOTE: this requires the original | 257 // True when gzip encoding should be used. NOTE: this requires the original |
| 257 // resources in resources.pak use compress="gzip". | 258 // resources in resources.pak use compress="gzip". |
| 258 bool is_gzipped_; | 259 bool is_gzipped_; |
| 259 | 260 |
| 260 // The backend is owned by net::URLRequestContext and always outlives us. | 261 // The backend is owned by net::URLRequestContext and always outlives us. |
| 261 URLDataManagerBackend* backend_; | 262 URLDataManagerBackend* const backend_; |
| 262 | 263 |
| 263 base::WeakPtrFactory<URLRequestChromeJob> weak_factory_; | 264 base::WeakPtrFactory<URLRequestChromeJob> weak_factory_; |
| 264 | 265 |
| 265 DISALLOW_COPY_AND_ASSIGN(URLRequestChromeJob); | 266 DISALLOW_COPY_AND_ASSIGN(URLRequestChromeJob); |
| 266 }; | 267 }; |
| 267 | 268 |
| 268 URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request, | 269 URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request, |
| 269 net::NetworkDelegate* network_delegate, | 270 net::NetworkDelegate* network_delegate, |
| 270 URLDataManagerBackend* backend, | 271 URLDataManagerBackend* backend, |
| 271 bool is_incognito) | 272 bool is_incognito) |
| 272 : net::URLRequestJob(request, network_delegate), | 273 : net::URLRequestJob(request, network_delegate), |
| 273 data_offset_(0), | 274 data_offset_(0), |
| 274 pending_buf_size_(0), | 275 pending_buf_size_(0), |
| 275 allow_caching_(true), | 276 allow_caching_(true), |
| 276 add_content_security_policy_(true), | 277 add_content_security_policy_(true), |
| 277 deny_xframe_options_(true), | 278 deny_xframe_options_(true), |
| 278 send_content_type_header_(false), | 279 send_content_type_header_(false), |
| 279 is_incognito_(is_incognito), | 280 is_incognito_(is_incognito), |
| 281 is_gzipped_(false), |
| 280 backend_(backend), | 282 backend_(backend), |
| 281 weak_factory_(this) { | 283 weak_factory_(this) { |
| 282 DCHECK(backend); | 284 DCHECK(backend); |
| 283 } | 285 } |
| 284 | 286 |
| 285 URLRequestChromeJob::~URLRequestChromeJob() { | 287 URLRequestChromeJob::~URLRequestChromeJob() { |
| 286 CHECK(!backend_->HasPendingJob(this)); | 288 CHECK(!backend_->HasPendingJob(this)); |
| 287 } | 289 } |
| 288 | 290 |
| 289 void URLRequestChromeJob::Start() { | 291 void URLRequestChromeJob::Start() { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 NotifyHeadersComplete(); | 381 NotifyHeadersComplete(); |
| 380 } | 382 } |
| 381 | 383 |
| 382 void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) { | 384 void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) { |
| 383 TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this); | 385 TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this); |
| 384 if (bytes) { | 386 if (bytes) { |
| 385 data_ = bytes; | 387 data_ = bytes; |
| 386 if (pending_buf_.get()) { | 388 if (pending_buf_.get()) { |
| 387 CHECK(pending_buf_->data()); | 389 CHECK(pending_buf_->data()); |
| 388 int result = CompleteRead(pending_buf_.get(), pending_buf_size_); | 390 int result = CompleteRead(pending_buf_.get(), pending_buf_size_); |
| 389 pending_buf_ = NULL; | 391 pending_buf_ = nullptr; |
| 390 ReadRawDataComplete(result); | 392 ReadRawDataComplete(result); |
| 391 } | 393 } |
| 392 } else { | 394 } else { |
| 393 // The request failed. | 395 // The request failed. |
| 394 ReadRawDataComplete(net::ERR_FAILED); | 396 ReadRawDataComplete(net::ERR_FAILED); |
| 395 } | 397 } |
| 396 } | 398 } |
| 397 | 399 |
| 398 base::WeakPtr<URLRequestChromeJob> URLRequestChromeJob::AsWeakPtr() { | 400 base::WeakPtr<URLRequestChromeJob> URLRequestChromeJob::AsWeakPtr() { |
| 399 return weak_factory_.GetWeakPtr(); | 401 return weak_factory_.GetWeakPtr(); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 request, network_delegate, | 549 request, network_delegate, |
| 548 GetURLDataManagerForResourceContext(resource_context_), is_incognito_); | 550 GetURLDataManagerForResourceContext(resource_context_), is_incognito_); |
| 549 } | 551 } |
| 550 | 552 |
| 551 bool IsSafeRedirectTarget(const GURL& location) const override { | 553 bool IsSafeRedirectTarget(const GURL& location) const override { |
| 552 return false; | 554 return false; |
| 553 } | 555 } |
| 554 | 556 |
| 555 private: | 557 private: |
| 556 // These members are owned by ProfileIOData, which owns this ProtocolHandler. | 558 // These members are owned by ProfileIOData, which owns this ProtocolHandler. |
| 557 content::ResourceContext* const resource_context_; | 559 ResourceContext* const resource_context_; |
| 558 | 560 |
| 559 // True when generated from an incognito profile. | 561 // True when generated from an incognito profile. |
| 560 const bool is_incognito_; | 562 const bool is_incognito_; |
| 561 ChromeBlobStorageContext* blob_storage_context_; | 563 ChromeBlobStorageContext* blob_storage_context_; |
| 562 | 564 |
| 563 DISALLOW_COPY_AND_ASSIGN(ChromeProtocolHandler); | 565 DISALLOW_COPY_AND_ASSIGN(ChromeProtocolHandler); |
| 564 }; | 566 }; |
| 565 | 567 |
| 566 } // namespace | 568 } // namespace |
| 567 | 569 |
| 568 URLDataManagerBackend::URLDataManagerBackend() | 570 URLDataManagerBackend::URLDataManagerBackend() |
| 569 : next_request_id_(0) { | 571 : next_request_id_(0) { |
| 570 URLDataSource* shared_source = new SharedResourcesDataSource(); | 572 URLDataSource* shared_source = new SharedResourcesDataSource(); |
| 571 URLDataSourceImpl* source_impl = | 573 URLDataSourceImpl* source_impl = |
| 572 new URLDataSourceImpl(shared_source->GetSource(), shared_source); | 574 new URLDataSourceImpl(shared_source->GetSource(), shared_source); |
| 573 AddDataSource(source_impl); | 575 AddDataSource(source_impl); |
| 574 } | 576 } |
| 575 | 577 |
| 576 URLDataManagerBackend::~URLDataManagerBackend() { | 578 URLDataManagerBackend::~URLDataManagerBackend() { |
| 577 for (DataSourceMap::iterator i = data_sources_.begin(); | 579 for (const auto& i : data_sources_) |
| 578 i != data_sources_.end(); ++i) { | 580 i.second->backend_ = nullptr; |
| 579 i->second->backend_ = NULL; | |
| 580 } | |
| 581 data_sources_.clear(); | 581 data_sources_.clear(); |
| 582 } | 582 } |
| 583 | 583 |
| 584 // static | 584 // static |
| 585 std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler> | 585 std::unique_ptr<net::URLRequestJobFactory::ProtocolHandler> |
| 586 URLDataManagerBackend::CreateProtocolHandler( | 586 URLDataManagerBackend::CreateProtocolHandler( |
| 587 content::ResourceContext* resource_context, | 587 ResourceContext* resource_context, |
| 588 bool is_incognito, | 588 bool is_incognito, |
| 589 ChromeBlobStorageContext* blob_storage_context) { | 589 ChromeBlobStorageContext* blob_storage_context) { |
| 590 DCHECK(resource_context); | 590 DCHECK(resource_context); |
| 591 return base::WrapUnique(new ChromeProtocolHandler( | 591 return base::WrapUnique(new ChromeProtocolHandler( |
| 592 resource_context, is_incognito, blob_storage_context)); | 592 resource_context, is_incognito, blob_storage_context)); |
| 593 } | 593 } |
| 594 | 594 |
| 595 void URLDataManagerBackend::AddDataSource( | 595 void URLDataManagerBackend::AddDataSource( |
| 596 URLDataSourceImpl* source) { | 596 URLDataSourceImpl* source) { |
| 597 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 597 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 598 DataSourceMap::iterator i = data_sources_.find(source->source_name()); | 598 DataSourceMap::iterator i = data_sources_.find(source->source_name()); |
| 599 if (i != data_sources_.end()) { | 599 if (i != data_sources_.end()) { |
| 600 if (!source->source()->ShouldReplaceExistingSource()) | 600 if (!source->source()->ShouldReplaceExistingSource()) |
| 601 return; | 601 return; |
| 602 i->second->backend_ = NULL; | 602 i->second->backend_ = nullptr; |
| 603 } | 603 } |
| 604 data_sources_[source->source_name()] = source; | 604 data_sources_[source->source_name()] = source; |
| 605 source->backend_ = this; | 605 source->backend_ = this; |
| 606 } | 606 } |
| 607 | 607 |
| 608 bool URLDataManagerBackend::HasPendingJob( | 608 bool URLDataManagerBackend::HasPendingJob( |
| 609 URLRequestChromeJob* job) const { | 609 URLRequestChromeJob* job) const { |
| 610 for (PendingRequestMap::const_iterator i = pending_requests_.begin(); | 610 for (PendingRequestMap::const_iterator i = pending_requests_.begin(); |
| 611 i != pending_requests_.end(); ++i) { | 611 i != pending_requests_.end(); ++i) { |
| 612 if (i->second == job) | 612 if (i->second == job) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 ResourceRequestInfo::GetRenderFrameForRequest(request, | 669 ResourceRequestInfo::GetRenderFrameForRequest(request, |
| 670 &render_process_id, | 670 &render_process_id, |
| 671 &render_frame_id); | 671 &render_frame_id); |
| 672 | 672 |
| 673 // Forward along the request to the data source. | 673 // Forward along the request to the data source. |
| 674 base::MessageLoop* target_message_loop = | 674 base::MessageLoop* target_message_loop = |
| 675 source->source()->MessageLoopForRequestPath(path); | 675 source->source()->MessageLoopForRequestPath(path); |
| 676 if (!target_message_loop) { | 676 if (!target_message_loop) { |
| 677 job->MimeTypeAvailable(source->source()->GetMimeType(path)); | 677 job->MimeTypeAvailable(source->source()->GetMimeType(path)); |
| 678 // Eliminate potentially dangling pointer to avoid future use. | 678 // Eliminate potentially dangling pointer to avoid future use. |
| 679 job = NULL; | 679 job = nullptr; |
| 680 | 680 |
| 681 // The DataSource is agnostic to which thread StartDataRequest is called | 681 // The DataSource is agnostic to which thread StartDataRequest is called |
| 682 // on for this path. Call directly into it from this thread, the IO | 682 // on for this path. Call directly into it from this thread, the IO |
| 683 // thread. | 683 // thread. |
| 684 source->source()->StartDataRequest( | 684 source->source()->StartDataRequest( |
| 685 path, render_process_id, render_frame_id, | 685 path, render_process_id, render_frame_id, |
| 686 base::Bind(&URLDataSourceImpl::SendResponse, source, request_id)); | 686 base::Bind(&URLDataSourceImpl::SendResponse, source, request_id)); |
| 687 } else { | 687 } else { |
| 688 // URLRequestChromeJob should receive mime type before data. This | 688 // URLRequestChromeJob should receive mime type before data. This |
| 689 // is guaranteed because request for mime type is placed in the | 689 // is guaranteed because request for mime type is placed in the |
| (...skipping 21 matching lines...) Expand all Loading... |
| 711 if (i != data_sources_.end()) | 711 if (i != data_sources_.end()) |
| 712 return i->second.get(); | 712 return i->second.get(); |
| 713 | 713 |
| 714 // No match using the host of the URL, so do a lookup using the scheme for | 714 // No match using the host of the URL, so do a lookup using the scheme for |
| 715 // URLs on the form source_name://extra_bits/foo . | 715 // URLs on the form source_name://extra_bits/foo . |
| 716 i = data_sources_.find(url.scheme() + "://"); | 716 i = data_sources_.find(url.scheme() + "://"); |
| 717 if (i != data_sources_.end()) | 717 if (i != data_sources_.end()) |
| 718 return i->second.get(); | 718 return i->second.get(); |
| 719 | 719 |
| 720 // No matches found, so give up. | 720 // No matches found, so give up. |
| 721 return NULL; | 721 return nullptr; |
| 722 } | 722 } |
| 723 | 723 |
| 724 void URLDataManagerBackend::CallStartRequest( | 724 void URLDataManagerBackend::CallStartRequest( |
| 725 scoped_refptr<URLDataSourceImpl> source, | 725 scoped_refptr<URLDataSourceImpl> source, |
| 726 const std::string& path, | 726 const std::string& path, |
| 727 int render_process_id, | 727 int render_process_id, |
| 728 int render_frame_id, | 728 int render_frame_id, |
| 729 int request_id) { | 729 int request_id) { |
| 730 if (BrowserThread::CurrentlyOn(BrowserThread::UI) && | 730 if (BrowserThread::CurrentlyOn(BrowserThread::UI) && |
| 731 render_process_id != -1 && | 731 render_process_id != -1 && |
| 732 !RenderProcessHost::FromID(render_process_id)) { | 732 !RenderProcessHost::FromID(render_process_id)) { |
| 733 // Make the request fail if its initiating renderer is no longer valid. | 733 // Make the request fail if its initiating renderer is no longer valid. |
| 734 // This can happen when the IO thread posts this task just before the | 734 // This can happen when the IO thread posts this task just before the |
| 735 // renderer shuts down. | 735 // renderer shuts down. |
| 736 source->SendResponse(request_id, NULL); | 736 source->SendResponse(request_id, nullptr); |
| 737 return; | 737 return; |
| 738 } | 738 } |
| 739 source->source()->StartDataRequest( | 739 source->source()->StartDataRequest( |
| 740 path, | 740 path, |
| 741 render_process_id, | 741 render_process_id, |
| 742 render_frame_id, | 742 render_frame_id, |
| 743 base::Bind(&URLDataSourceImpl::SendResponse, source, request_id)); | 743 base::Bind(&URLDataSourceImpl::SendResponse, source, request_id)); |
| 744 } | 744 } |
| 745 | 745 |
| 746 void URLDataManagerBackend::RemoveRequest(URLRequestChromeJob* job) { | 746 void URLDataManagerBackend::RemoveRequest(URLRequestChromeJob* job) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 766 job->DataAvailable(bytes); | 766 job->DataAvailable(bytes); |
| 767 } | 767 } |
| 768 } | 768 } |
| 769 | 769 |
| 770 namespace { | 770 namespace { |
| 771 | 771 |
| 772 class DevToolsJobFactory | 772 class DevToolsJobFactory |
| 773 : public net::URLRequestJobFactory::ProtocolHandler { | 773 : public net::URLRequestJobFactory::ProtocolHandler { |
| 774 public: | 774 public: |
| 775 // |is_incognito| should be set for incognito profiles. | 775 // |is_incognito| should be set for incognito profiles. |
| 776 DevToolsJobFactory(content::ResourceContext* resource_context, | 776 DevToolsJobFactory(ResourceContext* resource_context, bool is_incognito); |
| 777 bool is_incognito); | |
| 778 ~DevToolsJobFactory() override; | 777 ~DevToolsJobFactory() override; |
| 779 | 778 |
| 780 net::URLRequestJob* MaybeCreateJob( | 779 net::URLRequestJob* MaybeCreateJob( |
| 781 net::URLRequest* request, | 780 net::URLRequest* request, |
| 782 net::NetworkDelegate* network_delegate) const override; | 781 net::NetworkDelegate* network_delegate) const override; |
| 783 | 782 |
| 784 private: | 783 private: |
| 785 // |resource_context_| and |network_delegate_| are owned by ProfileIOData, | 784 // |resource_context_| and |network_delegate_| are owned by ProfileIOData, |
| 786 // which owns this ProtocolHandler. | 785 // which owns this ProtocolHandler. |
| 787 content::ResourceContext* const resource_context_; | 786 ResourceContext* const resource_context_; |
| 788 | 787 |
| 789 // True when generated from an incognito profile. | 788 // True when generated from an incognito profile. |
| 790 const bool is_incognito_; | 789 const bool is_incognito_; |
| 791 | 790 |
| 792 DISALLOW_COPY_AND_ASSIGN(DevToolsJobFactory); | 791 DISALLOW_COPY_AND_ASSIGN(DevToolsJobFactory); |
| 793 }; | 792 }; |
| 794 | 793 |
| 795 DevToolsJobFactory::DevToolsJobFactory( | 794 DevToolsJobFactory::DevToolsJobFactory(ResourceContext* resource_context, |
| 796 content::ResourceContext* resource_context, | 795 bool is_incognito) |
| 797 bool is_incognito) | 796 : resource_context_(resource_context), is_incognito_(is_incognito) { |
| 798 : resource_context_(resource_context), | |
| 799 is_incognito_(is_incognito) { | |
| 800 DCHECK(resource_context_); | 797 DCHECK(resource_context_); |
| 801 } | 798 } |
| 802 | 799 |
| 803 DevToolsJobFactory::~DevToolsJobFactory() {} | 800 DevToolsJobFactory::~DevToolsJobFactory() {} |
| 804 | 801 |
| 805 net::URLRequestJob* | 802 net::URLRequestJob* |
| 806 DevToolsJobFactory::MaybeCreateJob( | 803 DevToolsJobFactory::MaybeCreateJob( |
| 807 net::URLRequest* request, net::NetworkDelegate* network_delegate) const { | 804 net::URLRequest* request, net::NetworkDelegate* network_delegate) const { |
| 808 return new URLRequestChromeJob( | 805 return new URLRequestChromeJob( |
| 809 request, network_delegate, | 806 request, network_delegate, |
| 810 GetURLDataManagerForResourceContext(resource_context_), is_incognito_); | 807 GetURLDataManagerForResourceContext(resource_context_), is_incognito_); |
| 811 } | 808 } |
| 812 | 809 |
| 813 } // namespace | 810 } // namespace |
| 814 | 811 |
| 815 net::URLRequestJobFactory::ProtocolHandler* | 812 net::URLRequestJobFactory::ProtocolHandler* CreateDevToolsProtocolHandler( |
| 816 CreateDevToolsProtocolHandler(content::ResourceContext* resource_context, | 813 ResourceContext* resource_context, |
| 817 bool is_incognito) { | 814 bool is_incognito) { |
| 818 return new DevToolsJobFactory(resource_context, is_incognito); | 815 return new DevToolsJobFactory(resource_context, is_incognito); |
| 819 } | 816 } |
| 820 | 817 |
| 821 } // namespace content | 818 } // namespace content |
| OLD | NEW |