15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/webui/url_data_manager_backend.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/debug/alias.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 199ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/stringprintf.h" 2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "content/browser/appcache/view_appcache_internals_job.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/fileapi/chrome_blob_storage_context.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/histogram_internals_request_job.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/net/view_blob_internals_job_factory.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/net/view_http_cache_job_factory.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/resource_context_impl.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/tcmalloc_internals_request_job.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/webui/shared_resources_data_source.h" 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/webui/url_data_source_impl.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/browser_context.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/content_browser_client.h" 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/render_process_host.h" 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/resource_request_info.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/url_constants.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/io_buffer.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_response_headers.h" 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/http/http_status_code.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_job_factory.h" 457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/url_util.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(tsepez) remove unsafe-eval when bidichecker_packaged.js fixed. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kChromeURLContentSecurityPolicyHeaderBase[] = 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Content-Security-Policy: script-src chrome://resources " 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "'self' 'unsafe-eval'; "; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kChromeURLXFrameOptionsHeader[] = "X-Frame-Options: DENY"; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kNoRenderProcessId = -1; 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SchemeIsInSchemes(const std::string& scheme, 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::vector<std::string>& schemes) { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::find(schemes.begin(), schemes.end(), scheme) != schemes.end(); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Returns whether |url| passes some sanity checks and is a valid GURL. 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool CheckURLIsValid(const GURL& url) { 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<std::string> additional_schemes; 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(url.SchemeIs(kChromeDevToolsScheme) || url.SchemeIs(kChromeUIScheme) || 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (GetContentClient()->browser()->GetAdditionalWebUISchemes( 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &additional_schemes), 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SchemeIsInSchemes(url.scheme(), additional_schemes))); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!url.is_valid()) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Parse |url| to get the path which will be used to resolve the request. The 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// path is the remaining portion after the scheme and hostname. 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void URLToRequestPath(const GURL& url, std::string* path) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& spec = url.possibly_invalid_spec(); 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const url::Parsed& parsed = url.parsed_for_possibly_invalid_spec(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // + 1 to skip the slash at the beginning of the path. 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu int offset = parsed.CountCharactersBefore(url::Parsed::PATH, false) + 1; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (offset < static_cast<int>(spec.size())) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path->assign(spec.substr(offset)); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// URLRequestChromeJob is a net::URLRequestJob that manages running 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// chrome-internal resource requests asynchronously. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It hands off URL requests to ChromeURLDataManager, which asynchronously 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calls back once the data is available. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestChromeJob : public net::URLRequestJob, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::SupportsWeakPtr<URLRequestChromeJob> { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |is_incognito| set when job is generated from an incognito profile. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestChromeJob(net::URLRequest* request, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate* network_delegate, 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataManagerBackend* backend, 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_incognito); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // net::URLRequestJob implementation. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Start() OVERRIDE; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Kill() OVERRIDE; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool ReadRawData(net::IOBuffer* buf, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buf_size, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* bytes_read) OVERRIDE; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual int GetResponseCode() const OVERRIDE; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetResponseInfo(net::HttpResponseInfo* info) OVERRIDE; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used to notify that the requested data's |mime_type| is ready. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void MimeTypeAvailable(const std::string& mime_type); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called by ChromeURLDataManager to notify us that the data blob is ready 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for us. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DataAvailable(base::RefCountedMemory* bytes); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_mime_type(const std::string& mime_type) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mime_type_ = mime_type; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_allow_caching(bool allow_caching) { 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allow_caching_ = allow_caching; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_add_content_security_policy(bool add_content_security_policy) { 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) add_content_security_policy_ = add_content_security_policy; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_content_security_policy_object_source( 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& data) { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_security_policy_object_source_ = data; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_content_security_policy_frame_source( 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& data) { 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_security_policy_frame_source_ = data; 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void set_deny_xframe_options(bool deny_xframe_options) { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) deny_xframe_options_ = deny_xframe_options; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void set_send_content_type_header(bool send_content_type_header) { 152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) send_content_type_header_ = send_content_type_header; 153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Returns true when job was generated from an incognito profile. 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_incognito() const { 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return is_incognito_; 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~URLRequestChromeJob(); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper for Start(), to let us start asynchronously. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (This pattern is shared by most net::URLRequestJob implementations.) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void StartAsync(bool allowed); 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Called on the UI thread to check if this request is allowed. 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void CheckStoragePartitionMatches( 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int render_process_id, 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL& url, 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::WeakPtr<URLRequestChromeJob>& job); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do the actual copy from data_ (the data we're serving) into |buf|. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Separate from ReadRawData so we can handle async I/O. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CompleteRead(net::IOBuffer* buf, int buf_size, int* bytes_read); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The actual data we're serving. NULL until it's been fetched. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::RefCountedMemory> data_; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The current offset into the data that we're handing off to our 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // callers via the Read interfaces. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data_offset_; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For async reads, we keep around a pointer to the buffer that 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we're reading into. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> pending_buf_; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pending_buf_size_; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string mime_type_; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If true, set a header in the response to prevent it from being cached. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool allow_caching_; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If true, set the Content Security Policy (CSP) header. 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool add_content_security_policy_; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These are used with the CSP. 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string content_security_policy_object_source_; 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string content_security_policy_frame_source_; 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If true, sets the "X-Frame-Options: DENY" header. 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool deny_xframe_options_; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If true, sets the "Content-Type: <mime-type>" header. 203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool send_content_type_header_; 204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // True when job is generated from an incognito profile. 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool is_incognito_; 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The backend is owned by net::URLRequestContext and always outlives us. 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataManagerBackend* backend_; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<URLRequestChromeJob> weak_factory_; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(URLRequestChromeJob); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestChromeJob::URLRequestChromeJob(net::URLRequest* request, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate* network_delegate, 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataManagerBackend* backend, 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_incognito) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : net::URLRequestJob(request, network_delegate), 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_offset_(0), 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_buf_size_(0), 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) allow_caching_(true), 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) add_content_security_policy_(true), 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_security_policy_object_source_("object-src 'none';"), 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content_security_policy_frame_source_("frame-src 'none';"), 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) deny_xframe_options_(true), 228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) send_content_type_header_(false), 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_incognito_(is_incognito), 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_(backend), 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_factory_(this) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(backend); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)URLRequestChromeJob::~URLRequestChromeJob() { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!backend_->HasPendingJob(this)); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestChromeJob::Start() { 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int render_process_id, unused; 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool is_renderer_request = ResourceRequestInfo::GetRenderFrameForRequest( 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_, &render_process_id, &unused); 243a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!is_renderer_request) 244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) render_process_id = kNoRenderProcessId; 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask( 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::UI, 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&URLRequestChromeJob::CheckStoragePartitionMatches, 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_process_id, request_->url(), AsWeakPtr())); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN1("browser", "DataManager:Request", this, "URL", 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_->url().possibly_invalid_spec()); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestChromeJob::Kill() { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->RemoveRequest(this); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestChromeJob::GetMimeType(std::string* mime_type) const { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *mime_type = mime_type_; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !mime_type_.empty(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int URLRequestChromeJob::GetResponseCode() const { 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::HTTP_OK; 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestChromeJob::GetResponseInfo(net::HttpResponseInfo* info) { 268868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!info->headers.get()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the headers so that requests serviced by ChromeURLDataManager return a 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // status code of 200. Without this they return a 0, which makes the status 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // indistiguishable from other error types. Instant relies on getting a 200. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK"); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Determine the least-privileged content security policy header, if any, 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that is compatible with a given WebUI URL, and append it to the existing 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // response headers. 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (add_content_security_policy_) { 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string base = kChromeURLContentSecurityPolicyHeaderBase; 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base.append(content_security_policy_object_source_); 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base.append(content_security_policy_frame_source_); 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info->headers->AddHeader(base); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (deny_xframe_options_) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info->headers->AddHeader(kChromeURLXFrameOptionsHeader); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!allow_caching_) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) info->headers->AddHeader("Cache-Control: no-cache"); 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 290f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (send_content_type_header_ && !mime_type_.empty()) { 291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string content_type = 292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::StringPrintf("%s:%s", net::HttpRequestHeaders::kContentType, 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) mime_type_.c_str()); 294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) info->headers->AddHeader(content_type); 295f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestChromeJob::MimeTypeAvailable(const std::string& mime_type) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) set_mime_type(mime_type); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyHeadersComplete(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestChromeJob::DataAvailable(base::RefCountedMemory* bytes) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_ASYNC_END0("browser", "DataManager:Request", this); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request completed, and we have all the data. 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clear any IO pending status. 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(net::URLRequestStatus()); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_ = bytes; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read; 312868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (pending_buf_.get()) { 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(pending_buf_->data()); 314868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CompleteRead(pending_buf_.get(), pending_buf_size_, &bytes_read); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_buf_ = NULL; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyReadComplete(bytes_read); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The request failed. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDone(net::URLRequestStatus(net::URLRequestStatus::FAILED, 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ERR_FAILED)); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool URLRequestChromeJob::ReadRawData(net::IOBuffer* buf, int buf_size, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* bytes_read) { 327868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!data_.get()) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetStatus(net::URLRequestStatus(net::URLRequestStatus::IO_PENDING, 0)); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!pending_buf_.get()); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(buf->data()); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_buf_ = buf; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_buf_size_ = buf_size; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; // Tell the caller we're still waiting for data. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, the data is available. 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompleteRead(buf, buf_size, bytes_read); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void URLRequestChromeJob::CompleteRead(net::IOBuffer* buf, int buf_size, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* bytes_read) { 343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // http://crbug.com/373841 344cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) char url_buf[128]; 345cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::strlcpy(url_buf, request_->url().spec().c_str(), arraysize(url_buf)); 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::debug::Alias(url_buf); 347cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int remaining = static_cast<int>(data_->size()) - data_offset_; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buf_size > remaining) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buf_size = remaining; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (buf_size > 0) { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(buf->data(), data_->front() + data_offset_, buf_size); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_offset_ += buf_size; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *bytes_read = buf_size; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void URLRequestChromeJob::CheckStoragePartitionMatches( 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int render_process_id, 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL& url, 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::WeakPtr<URLRequestChromeJob>& job) { 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The embedder could put some webui pages in separate storage partition. 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // RenderProcessHostImpl::IsSuitableHost would guard against top level pages 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // being in the same process. We do an extra check to guard against an 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // exploited renderer pretending to add them as a subframe. We skip this check 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // for resources. 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool allowed = false; 368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string> hosts; 369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetContentClient()-> 370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) browser()->GetAdditionalWebUIHostsToIgnoreParititionCheck(&hosts); 371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (url.SchemeIs(kChromeUIScheme) && 372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) (url.SchemeIs(kChromeUIScheme) || 373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::find(hosts.begin(), hosts.end(), url.host()) != hosts.end())) { 374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) allowed = true; 375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (render_process_id == kNoRenderProcessId) { 376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Request was not issued by renderer. 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allowed = true; 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RenderProcessHost* process = RenderProcessHost::FromID(render_process_id); 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (process) { 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) StoragePartition* partition = BrowserContext::GetStoragePartitionForSite( 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) process->GetBrowserContext(), url); 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allowed = partition == process->GetStoragePartition(); 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::PostTask( 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::IO, 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FROM_HERE, 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Bind(&URLRequestChromeJob::StartAsync, job, allowed)); 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void URLRequestChromeJob::StartAsync(bool allowed) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!request_) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!allowed || !backend_->StartRequest(request_, this)) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::ERR_INVALID_URL)); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets mime type for data that is available from |source| by |path|. 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After that, notifies |job| that mime type is available. This method 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// should be called on the UI thread, but notification is performed on 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the IO thread. 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void GetMimeTypeOnUI(URLDataSourceImpl* source, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& path, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::WeakPtr<URLRequestChromeJob>& job) { 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string mime_type = source->source()->GetMimeType(path); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::IO, FROM_HERE, 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&URLRequestChromeJob::MimeTypeAvailable, job, mime_type)); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChromeProtocolHandler 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public net::URLRequestJobFactory::ProtocolHandler { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |is_incognito| should be set for incognito profiles. 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChromeProtocolHandler(ResourceContext* resource_context, 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_incognito, 42946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AppCacheServiceImpl* appcache_service, 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChromeBlobStorageContext* blob_storage_context) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : resource_context_(resource_context), 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_incognito_(is_incognito), 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) appcache_service_(appcache_service), 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blob_storage_context_(blob_storage_context) {} 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~ChromeProtocolHandler() {} 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual net::URLRequestJob* MaybeCreateJob( 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::NetworkDelegate* network_delegate) const OVERRIDE { 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(request); 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check for chrome://view-http-cache/*, which uses its own job type. 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ViewHttpCacheJobFactory::IsSupportedURL(request->url())) 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ViewHttpCacheJobFactory::CreateJobForRequest(request, 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) network_delegate); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Next check for chrome://appcache-internals/, which uses its own job type. 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->url().SchemeIs(kChromeUIScheme) && 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request->url().host() == kChromeUIAppCacheInternalsHost) { 45023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return ViewAppCacheInternalsJobFactory::CreateJobForRequest( 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request, network_delegate, appcache_service_); 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Next check for chrome://blob-internals/, which uses its own job type. 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (ViewBlobInternalsJobFactory::IsSupportedURL(request->url())) { 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ViewBlobInternalsJobFactory::CreateJobForRequest( 45758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request, network_delegate, blob_storage_context_->context()); 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_TCMALLOC) 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Next check for chrome://tcmalloc/, which uses its own job type. 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->url().SchemeIs(kChromeUIScheme) && 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request->url().host() == kChromeUITcmallocHost) { 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new TcmallocInternalsRequestJob(request, network_delegate); 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Next check for chrome://histograms/, which uses its own job type. 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (request->url().SchemeIs(kChromeUIScheme) && 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request->url().host() == kChromeUIHistogramHost) { 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new HistogramInternalsRequestJob(request, network_delegate); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fall back to using a custom handler 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new URLRequestChromeJob( 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request, network_delegate, 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetURLDataManagerForResourceContext(resource_context_), is_incognito_); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 480b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE { 481b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return false; 482b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 483b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These members are owned by ProfileIOData, which owns this ProtocolHandler. 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::ResourceContext* const resource_context_; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // True when generated from an incognito profile. 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool is_incognito_; 49046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AppCacheServiceImpl* appcache_service_; 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChromeBlobStorageContext* blob_storage_context_; 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ChromeProtocolHandler); 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)URLDataManagerBackend::URLDataManagerBackend() 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : next_request_id_(0) { 5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataSource* shared_source = new SharedResourcesDataSource(); 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataSourceImpl* source_impl = 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new URLDataSourceImpl(shared_source->GetSource(), shared_source); 5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddDataSource(source_impl); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)URLDataManagerBackend::~URLDataManagerBackend() { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (DataSourceMap::iterator i = data_sources_.begin(); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != data_sources_.end(); ++i) { 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second->backend_ = NULL; 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_sources_.clear(); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequestJobFactory::ProtocolHandler* 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)URLDataManagerBackend::CreateProtocolHandler( 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::ResourceContext* resource_context, 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_incognito, 51946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) AppCacheServiceImpl* appcache_service, 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChromeBlobStorageContext* blob_storage_context) { 5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(resource_context); 5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new ChromeProtocolHandler( 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resource_context, is_incognito, appcache_service, blob_storage_context); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLDataManagerBackend::AddDataSource( 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLDataSourceImpl* source) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DataSourceMap::iterator i = data_sources_.find(source->source_name()); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != data_sources_.end()) { 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!source->source()->ShouldReplaceExistingSource()) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->second->backend_ = NULL; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_sources_[source->source_name()] = source; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source->backend_ = this; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool URLDataManagerBackend::HasPendingJob( 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestChromeJob* job) const { 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PendingRequestMap::const_iterator i = pending_requests_.begin(); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_requests_.end(); ++i) { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->second == job) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool URLDataManagerBackend::StartRequest(const net::URLRequest* request, 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) URLRequestChromeJob* job) { 5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!CheckURLIsValid(request->url())) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) URLDataSourceImpl* source = GetDataSourceFromURL(request->url()); 5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!source) 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 5572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!source->source()->ShouldServiceRequest(request)) 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string path; 5625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) URLToRequestPath(request->url(), &path); 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) source->source()->WillServiceRequest(request, &path); 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save this request so we know where to send the data. 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestID request_id = next_request_id_++; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.insert(std::make_pair(request_id, job)); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job->set_allow_caching(source->source()->AllowCaching()); 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job->set_add_content_security_policy( 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->source()->ShouldAddContentSecurityPolicy()); 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job->set_content_security_policy_object_source( 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->source()->GetContentSecurityPolicyObjectSrc()); 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job->set_content_security_policy_frame_source( 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->source()->GetContentSecurityPolicyFrameSrc()); 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job->set_deny_xframe_options( 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->source()->ShouldDenyXFrameOptions()); 578f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) job->set_send_content_type_header( 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) source->source()->ShouldServeMimeTypeAsContentTypeHeader()); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Look up additional request info to pass down. 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_process_id = -1; 5835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int render_frame_id = -1; 5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResourceRequestInfo::GetRenderFrameForRequest(request, 5855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &render_process_id, 5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &render_frame_id); 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Forward along the request to the data source. 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop* target_message_loop = 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->source()->MessageLoopForRequestPath(path); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!target_message_loop) { 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job->MimeTypeAvailable(source->source()->GetMimeType(path)); 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Eliminate potentially dangling pointer to avoid future use. 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) job = NULL; 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The DataSource is agnostic to which thread StartDataRequest is called 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on for this path. Call directly into it from this thread, the IO 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // thread. 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->source()->StartDataRequest( 6005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) path, render_process_id, render_frame_id, 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLDataSourceImpl::SendResponse, source, request_id)); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // URLRequestChromeJob should receive mime type before data. This 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is guaranteed because request for mime type is placed in the 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message loop before request for data. And correspondingly their 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // replies are put on the IO thread in the same order. 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_message_loop->PostTask( 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetMimeTypeOnUI, 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<URLDataSourceImpl>(source), 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path, job->AsWeakPtr())); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The DataSource wants StartDataRequest to be called on a specific thread, 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // usually the UI thread, for this path. 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) target_message_loop->PostTask( 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLDataManagerBackend::CallStartRequest, 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) make_scoped_refptr(source), path, render_process_id, 6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_frame_id, request_id)); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)URLDataSourceImpl* URLDataManagerBackend::GetDataSourceFromURL( 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL& url) { 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The input usually looks like: chrome://source_name/extra_bits?foo 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // so do a lookup using the host of the URL. 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DataSourceMap::iterator i = data_sources_.find(url.host()); 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (i != data_sources_.end()) 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return i->second.get(); 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No match using the host of the URL, so do a lookup using the scheme for 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // URLs on the form source_name://extra_bits/foo . 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) i = data_sources_.find(url.scheme() + "://"); 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (i != data_sources_.end()) 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return i->second.get(); 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No matches found, so give up. 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLDataManagerBackend::CallStartRequest( 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<URLDataSourceImpl> source, 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& path, 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_process_id, 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int render_frame_id, 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int request_id) { 648c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (BrowserThread::CurrentlyOn(BrowserThread::UI) && 649868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) render_process_id != -1 && 650c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !RenderProcessHost::FromID(render_process_id)) { 651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Make the request fail if its initiating renderer is no longer valid. 652c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This can happen when the IO thread posts this task just before the 653c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // renderer shuts down. 654c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) source->SendResponse(request_id, NULL); 655c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 656c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->source()->StartDataRequest( 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) path, 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) render_process_id, 6605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) render_frame_id, 6612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&URLDataSourceImpl::SendResponse, source, request_id)); 6622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLDataManagerBackend::RemoveRequest(URLRequestChromeJob* job) { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the request from our list of pending requests. 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If/when the source sends the data that was requested, the data will just 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be thrown away. 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PendingRequestMap::iterator i = pending_requests_.begin(); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != pending_requests_.end(); ++i) { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->second == job) { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.erase(i); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void URLDataManagerBackend::DataAvailable(RequestID request_id, 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::RefCountedMemory* bytes) { 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Forward this data on to the pending net::URLRequest, if it exists. 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingRequestMap::iterator i = pending_requests_.find(request_id); 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i != pending_requests_.end()) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLRequestChromeJob* job(i->second); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_requests_.erase(i); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) job->DataAvailable(bytes); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DevToolsJobFactory 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public net::URLRequestJobFactory::ProtocolHandler { 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |is_incognito| should be set for incognito profiles. 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DevToolsJobFactory(content::ResourceContext* resource_context, 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_incognito); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~DevToolsJobFactory(); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual net::URLRequestJob* MaybeCreateJob( 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::NetworkDelegate* network_delegate) const OVERRIDE; 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |resource_context_| and |network_delegate_| are owned by ProfileIOData, 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which owns this ProtocolHandler. 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::ResourceContext* const resource_context_; 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // True when generated from an incognito profile. 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool is_incognito_; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DevToolsJobFactory); 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DevToolsJobFactory::DevToolsJobFactory( 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::ResourceContext* resource_context, 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_incognito) 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : resource_context_(resource_context), 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_incognito_(is_incognito) { 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(resource_context_); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsJobFactory::~DevToolsJobFactory() {} 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequestJob* 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsJobFactory::MaybeCreateJob( 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::URLRequest* request, net::NetworkDelegate* network_delegate) const { 7262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new URLRequestChromeJob( 7272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request, network_delegate, 7282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetURLDataManagerForResourceContext(resource_context_), is_incognito_); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)net::URLRequestJobFactory::ProtocolHandler* 7342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CreateDevToolsProtocolHandler(content::ResourceContext* resource_context, 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_incognito) { 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new DevToolsJobFactory(resource_context, is_incognito); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 740