// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_NET_CHROME_URL_REQUEST_CONTEXT_H_ #define CHROME_BROWSER_NET_CHROME_URL_REQUEST_CONTEXT_H_ #pragma once #include #include #include "base/file_path.h" #include "base/linked_ptr.h" #include "net/base/cookie_monster.h" #include "net/base/cookie_policy.h" #include "chrome/browser/appcache/chrome_appcache_service.h" #include "chrome/browser/host_content_settings_map.h" #include "chrome/browser/host_zoom_map.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/pref_service.h" #include "chrome/browser/net/chrome_cookie_policy.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/net/url_request_context_getter.h" #include "chrome/common/notification_registrar.h" #include "net/url_request/url_request_context.h" #include "webkit/database/database_tracker.h" class CommandLine; class PrefService; class Profile; namespace net { class NetworkDelegate; class ProxyConfig; } class ChromeURLRequestContext; class ChromeURLRequestContextFactory; // Subclass of URLRequestContext which can be used to store extra information // for requests. // // All methods of this class must be called from the IO thread, // including the constructor and destructor. class ChromeURLRequestContext : public URLRequestContext { public: // Maintains some extension-related state we need on the IO thread. // TODO(aa): It would be cool if the Extension objects in ExtensionsService // could be immutable and ref-counted so that we could use them directly from // both threads. There is only a small amount of mutable state in Extension. struct ExtensionInfo { ExtensionInfo(const std::string& name, const FilePath& path, const std::string& default_locale, const ExtensionExtent& extent, const std::vector& api_permissions) : name(name), path(path), default_locale(default_locale), extent(extent), api_permissions(api_permissions) { } const std::string name; FilePath path; std::string default_locale; ExtensionExtent extent; std::vector api_permissions; }; // Map of extension info by extension id. typedef std::map > ExtensionInfoMap; ChromeURLRequestContext(); // Gets the name for the specified extension. std::string GetNameForExtension(const std::string& id); // Gets the path to the directory for the specified extension. FilePath GetPathForExtension(const std::string& id); // Returns an empty string if the extension with |id| doesn't have a default // locale. std::string GetDefaultLocaleForExtension(const std::string& id); // Determine whether a URL has access to the specified extension permission. bool CheckURLAccessToExtensionPermission(const GURL& url, const char* permission_name); // Gets the path to the directory user scripts are stored in. FilePath user_script_dir_path() const { return user_script_dir_path_; } // Gets the appcache service to be used for requests in this context. // May be NULL if requests for this context aren't subject to appcaching. ChromeAppCacheService* appcache_service() const { return appcache_service_.get(); } // Gets the database tracker associated with this context's profile. webkit_database::DatabaseTracker* database_tracker() const { return database_tracker_.get(); } bool is_off_the_record() const { return is_off_the_record_; } bool is_media() const { return is_media_; } virtual const std::string& GetUserAgent(const GURL& url) const; HostContentSettingsMap* host_content_settings_map() { return host_content_settings_map_; } const HostZoomMap* host_zoom_map() const { return host_zoom_map_; } // Callback for when new extensions are loaded. Takes ownership of // |extension_info|. void OnNewExtensions(const std::string& id, ExtensionInfo* extension_info); // Callback for when an extension is unloaded. void OnUnloadedExtension(const std::string& id); // False only if cookies are globally blocked without exception. bool AreCookiesEnabled() const; // Returns true if this context is an external request context, like // ChromeFrame. virtual bool IsExternal() const { return false; } protected: // Copies the dependencies from |other| into |this|. If you use this // constructor, then you should hold a reference to |other|, as we // depend on |other| being alive. explicit ChromeURLRequestContext(ChromeURLRequestContext* other); virtual ~ChromeURLRequestContext(); public: // Setters to simplify initializing from factory objects. void set_accept_language(const std::string& accept_language) { accept_language_ = accept_language; } void set_accept_charset(const std::string& accept_charset) { accept_charset_ = accept_charset; } void set_referrer_charset(const std::string& referrer_charset) { referrer_charset_ = referrer_charset; } void set_extension_info( const ChromeURLRequestContext::ExtensionInfoMap& info) { extension_info_ = info; } void set_transport_security_state( net::TransportSecurityState* state) { transport_security_state_ = state; } void set_ssl_config_service(net::SSLConfigService* service) { ssl_config_service_ = service; } void set_host_resolver(net::HostResolver* resolver) { host_resolver_ = resolver; } void set_http_transaction_factory(net::HttpTransactionFactory* factory) { http_transaction_factory_ = factory; } void set_ftp_transaction_factory(net::FtpTransactionFactory* factory) { ftp_transaction_factory_ = factory; } void set_http_auth_handler_factory(net::HttpAuthHandlerFactory* factory) { http_auth_handler_factory_ = factory; } void set_cookie_store(net::CookieStore* cookie_store) { cookie_store_ = cookie_store; } void set_cookie_policy(ChromeCookiePolicy* cookie_policy) { chrome_cookie_policy_ = cookie_policy; // Take a strong reference. cookie_policy_ = cookie_policy; } void set_proxy_service(net::ProxyService* service) { proxy_service_ = service; } void set_user_script_dir_path(const FilePath& path) { user_script_dir_path_ = path; } void set_is_off_the_record(bool is_off_the_record) { is_off_the_record_ = is_off_the_record; } void set_is_media(bool is_media) { is_media_ = is_media; } void set_host_content_settings_map( HostContentSettingsMap* host_content_settings_map) { host_content_settings_map_ = host_content_settings_map; } void set_host_zoom_map(HostZoomMap* host_zoom_map) { host_zoom_map_ = host_zoom_map; } void set_appcache_service(ChromeAppCacheService* service) { appcache_service_ = service; } void set_database_tracker(webkit_database::DatabaseTracker* tracker) { database_tracker_ = tracker; } void set_net_log(net::NetLog* net_log) { net_log_ = net_log; } void set_network_delegate( net::HttpNetworkDelegate* network_delegate) { network_delegate_ = network_delegate; } // Callback for when the accept language changes. void OnAcceptLanguageChange(const std::string& accept_language); // Callback for when the default charset changes. void OnDefaultCharsetChange(const std::string& default_charset); protected: ExtensionInfoMap extension_info_; // Path to the directory user scripts are stored in. FilePath user_script_dir_path_; scoped_refptr appcache_service_; scoped_refptr database_tracker_; scoped_refptr chrome_cookie_policy_; scoped_refptr host_content_settings_map_; scoped_refptr host_zoom_map_; bool is_media_; bool is_off_the_record_; private: DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContext); }; // A URLRequestContextGetter subclass used by the browser. This returns a // subclass of URLRequestContext which can be used to store extra information // about requests. // // Most methods are expected to be called on the UI thread, except for // the destructor and GetURLRequestContext(). class ChromeURLRequestContextGetter : public URLRequestContextGetter, public NotificationObserver { public: // Constructs a ChromeURLRequestContextGetter that will use |factory| to // create the ChromeURLRequestContext. If |profile| is non-NULL, then the // ChromeURLRequestContextGetter will additionally watch the preferences for // changes to charset/language and CleanupOnUIThread() will need to be // called to unregister. ChromeURLRequestContextGetter(Profile* profile, ChromeURLRequestContextFactory* factory); static void RegisterUserPrefs(PrefService* user_prefs); // Note that GetURLRequestContext() can only be called from the IO // thread (it will assert otherwise). GetCookieStore() and // GetIOMessageLoopProxy however can be called from any thread. // // URLRequestContextGetter implementation. virtual URLRequestContext* GetURLRequestContext(); virtual net::CookieStore* GetCookieStore(); virtual scoped_refptr GetIOMessageLoopProxy(); // Convenience overload of GetURLRequestContext() that returns a // ChromeURLRequestContext* rather than a URLRequestContext*. ChromeURLRequestContext* GetIOContext() { return reinterpret_cast(GetURLRequestContext()); } // Create an instance for use with an 'original' (non-OTR) profile. This is // expected to get called on the UI thread. static ChromeURLRequestContextGetter* CreateOriginal( Profile* profile, const FilePath& cookie_store_path, const FilePath& disk_cache_path, int cache_size); // Create an instance for an original profile for media. This is expected to // get called on UI thread. This method takes a profile and reuses the // 'original' URLRequestContext for common files. static ChromeURLRequestContextGetter* CreateOriginalForMedia( Profile* profile, const FilePath& disk_cache_path, int cache_size); // Create an instance for an original profile for extensions. This is expected // to get called on UI thread. static ChromeURLRequestContextGetter* CreateOriginalForExtensions( Profile* profile, const FilePath& cookie_store_path); // Create an instance for use with an OTR profile. This is expected to get // called on the UI thread. static ChromeURLRequestContextGetter* CreateOffTheRecord(Profile* profile); // Clean up UI thread resources. This is expected to get called on the UI // thread before the instance is deleted on the IO thread. void CleanupOnUIThread(); // These methods simply forward to the corresponding methods on // ChromeURLRequestContext. Takes ownership of |extension_info|. void OnNewExtensions( const std::string& extension_id, ChromeURLRequestContext::ExtensionInfo* extension_info); void OnUnloadedExtension(const std::string& id); // NotificationObserver implementation. virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); private: // Must be called on the IO thread. virtual ~ChromeURLRequestContextGetter(); // Registers an observer on |profile|'s preferences which will be used // to update the context when the default language and charset change. void RegisterPrefsObserver(Profile* profile); // Creates a request context for media resources from a regular request // context. This helper method is called from CreateOriginalForMedia and // CreateOffTheRecordForMedia. static ChromeURLRequestContextGetter* CreateRequestContextForMedia( Profile* profile, const FilePath& disk_cache_path, int cache_size, bool off_the_record); // These methods simply forward to the corresponding method on // ChromeURLRequestContext. void OnAcceptLanguageChange(const std::string& accept_language); void OnDefaultCharsetChange(const std::string& default_charset); // Saves the cookie store to |result| and signals |completion|. void GetCookieStoreAsyncHelper(base::WaitableEvent* completion, net::CookieStore** result); // Access only from the UI thread. PrefService* prefs_; // Deferred logic for creating a ChromeURLRequestContext. // Access only from the IO thread. scoped_ptr factory_; // NULL if not yet initialized. Otherwise, it is the URLRequestContext // instance that was lazilly created by GetURLRequestContext. // Access only from the IO thread. scoped_refptr url_request_context_; DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextGetter); }; // Base class for a ChromeURLRequestContext factory. This includes // the shared functionality like extracting the default language/charset // from a profile. // // Except for the constructor, all methods of this class must be called from // the IO thread. class ChromeURLRequestContextFactory { public: // Extract properties of interested from |profile|, for setting later into // a ChromeURLRequestContext using ApplyProfileParametersToContext(). explicit ChromeURLRequestContextFactory(Profile* profile); virtual ~ChromeURLRequestContextFactory(); // Called to create a new instance (will only be called once). virtual ChromeURLRequestContext* Create() = 0; protected: IOThread* io_thread() { return io_thread_; } // Assigns this factory's properties to |context|. void ApplyProfileParametersToContext(ChromeURLRequestContext* context); // Values extracted from the Profile. // // NOTE: If you add any parameters here, keep it in sync with // ApplyProfileParametersToContext(). bool is_media_; bool is_off_the_record_; std::string accept_language_; std::string accept_charset_; std::string referrer_charset_; ChromeURLRequestContext::ExtensionInfoMap extension_info_; // TODO(aa): I think this can go away now as we no longer support standalone // user scripts. FilePath user_script_dir_path_; scoped_refptr host_content_settings_map_; scoped_refptr database_tracker_; scoped_refptr host_zoom_map_; scoped_refptr transport_security_state_; scoped_refptr ssl_config_service_; scoped_refptr cookie_monster_delegate_; FilePath profile_dir_path_; private: IOThread* const io_thread_; DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory); }; // Creates a proxy configuration from proxy-related preferences fetched // from |pref_service|. The relevant preferences in |pref_service| are // initialized from the process' command line or by applicable proxy policies. net::ProxyConfig* CreateProxyConfig(const PrefService* pref_service); #endif // CHROME_BROWSER_NET_CHROME_URL_REQUEST_CONTEXT_H_