chrome_url_request_context.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_NET_CHROME_URL_REQUEST_CONTEXT_H_
6#define CHROME_BROWSER_NET_CHROME_URL_REQUEST_CONTEXT_H_
7#pragma once
8
9#include <map>
10#include <string>
11#include <vector>
12
13#include "base/file_path.h"
14#include "base/linked_ptr.h"
15#include "chrome/browser/appcache/chrome_appcache_service.h"
16#include "chrome/browser/chrome_blob_storage_context.h"
17#include "chrome/browser/file_system/file_system_host_context.h"
18#include "chrome/browser/host_content_settings_map.h"
19#include "chrome/browser/host_zoom_map.h"
20#include "chrome/browser/io_thread.h"
21#include "chrome/browser/net/chrome_cookie_policy.h"
22#include "chrome/browser/prefs/pref_change_registrar.h"
23#include "chrome/browser/prefs/pref_service.h"
24#include "chrome/common/extensions/extension.h"
25#include "chrome/common/extensions/extension_icon_set.h"
26#include "chrome/common/net/url_request_context_getter.h"
27#include "chrome/common/notification_registrar.h"
28#include "net/base/cookie_monster.h"
29#include "net/base/cookie_policy.h"
30#include "net/url_request/url_request_context.h"
31#include "webkit/database/database_tracker.h"
32
33class CommandLine;
34class PrefService;
35class Profile;
36
37namespace net {
38class NetworkDelegate;
39class ProxyConfig;
40}
41
42class ChromeURLRequestContext;
43class ChromeURLRequestContextFactory;
44
45// Subclass of URLRequestContext which can be used to store extra information
46// for requests.
47//
48// All methods of this class must be called from the IO thread,
49// including the constructor and destructor.
50class ChromeURLRequestContext : public URLRequestContext {
51 public:
52  // Maintains some extension-related state we need on the IO thread.
53  // TODO(aa): It would be cool if the Extension objects in ExtensionsService
54  // could be immutable and ref-counted so that we could use them directly from
55  // both threads. There is only a small amount of mutable state in Extension.
56  struct ExtensionInfo {
57    ExtensionInfo(const std::string& name,
58                  const FilePath& path,
59                  const std::string& default_locale,
60                  bool incognito_split_mode,
61                  const ExtensionExtent& extent,
62                  const ExtensionExtent& effective_host_permissions,
63                  const std::set<std::string>& api_permissions,
64                  const ExtensionIconSet& icons)
65        : name(name),
66          path(path),
67          default_locale(default_locale),
68          incognito_split_mode(incognito_split_mode),
69          extent(extent),
70          effective_host_permissions(effective_host_permissions),
71          api_permissions(api_permissions),
72          icons(icons) {
73    }
74    const std::string name;
75    const FilePath path;
76    const std::string default_locale;
77    const bool incognito_split_mode;
78    const ExtensionExtent extent;
79    const ExtensionExtent effective_host_permissions;
80    std::set<std::string> api_permissions;
81    ExtensionIconSet icons;
82  };
83
84  // Map of extension info by extension id.
85  typedef std::map<std::string, linked_ptr<ExtensionInfo> > ExtensionInfoMap;
86
87  ChromeURLRequestContext();
88
89  // Gets the name for the specified extension.
90  std::string GetNameForExtension(const std::string& id);
91
92  // Gets the path to the directory for the specified extension.
93  FilePath GetPathForExtension(const std::string& id);
94
95  // Returns true if the specified extension exists and has a non-empty web
96  // extent.
97  bool ExtensionHasWebExtent(const std::string& id);
98
99  // Returns true if the specified extension exists and can load in incognito
100  // contexts.
101  bool ExtensionCanLoadInIncognito(const std::string& id);
102
103  // Returns an empty string if the extension with |id| doesn't have a default
104  // locale.
105  std::string GetDefaultLocaleForExtension(const std::string& id);
106
107  // Gets the effective host permissions for the extension with |id|.
108  ExtensionExtent
109      GetEffectiveHostPermissionsForExtension(const std::string& id);
110
111  // Determine whether a URL has access to the specified extension permission.
112  bool CheckURLAccessToExtensionPermission(const GURL& url,
113                                           const char* permission_name);
114
115  // Returns true if the specified URL references the icon for an extension.
116  bool URLIsForExtensionIcon(const GURL& url);
117
118  // Gets the path to the directory user scripts are stored in.
119  FilePath user_script_dir_path() const {
120    return user_script_dir_path_;
121  }
122
123  // Gets the appcache service to be used for requests in this context.
124  // May be NULL if requests for this context aren't subject to appcaching.
125  ChromeAppCacheService* appcache_service() const {
126    return appcache_service_.get();
127  }
128
129  // Gets the database tracker associated with this context's profile.
130  webkit_database::DatabaseTracker* database_tracker() const {
131    return database_tracker_.get();
132  }
133
134  // Gets the blob storage context associated with this context's profile.
135  ChromeBlobStorageContext* blob_storage_context() const {
136    return blob_storage_context_.get();
137  }
138
139  // Gets the file system host context with this context's profile.
140  FileSystemHostContext* file_system_host_context() const {
141    return file_system_host_context_.get();
142  }
143
144  bool is_off_the_record() const {
145    return is_off_the_record_;
146  }
147  bool is_media() const {
148    return is_media_;
149  }
150
151  virtual const std::string& GetUserAgent(const GURL& url) const;
152
153  HostContentSettingsMap* host_content_settings_map() {
154    return host_content_settings_map_;
155  }
156
157  const HostZoomMap* host_zoom_map() const { return host_zoom_map_; }
158
159  // Callback for when new extensions are loaded. Takes ownership of
160  // |extension_info|.
161  void OnNewExtensions(const std::string& id, ExtensionInfo* extension_info);
162
163  // Callback for when an extension is unloaded.
164  void OnUnloadedExtension(const std::string& id);
165
166  // Returns true if this context is an external request context, like
167  // ChromeFrame.
168  virtual bool IsExternal() const;
169
170 protected:
171  // Copies the dependencies from |other| into |this|. If you use this
172  // constructor, then you should hold a reference to |other|, as we
173  // depend on |other| being alive.
174  explicit ChromeURLRequestContext(ChromeURLRequestContext* other);
175  virtual ~ChromeURLRequestContext();
176
177 public:
178  // Setters to simplify initializing from factory objects.
179
180  void set_accept_language(const std::string& accept_language) {
181    accept_language_ = accept_language;
182  }
183  void set_accept_charset(const std::string& accept_charset) {
184    accept_charset_ = accept_charset;
185  }
186  void set_referrer_charset(const std::string& referrer_charset) {
187    referrer_charset_ = referrer_charset;
188  }
189  void set_extension_info(
190      const ChromeURLRequestContext::ExtensionInfoMap& info) {
191    extension_info_ = info;
192  }
193  void set_transport_security_state(
194      net::TransportSecurityState* state) {
195    transport_security_state_ = state;
196  }
197  void set_ssl_config_service(net::SSLConfigService* service) {
198    ssl_config_service_ = service;
199  }
200  void set_host_resolver(net::HostResolver* resolver) {
201    host_resolver_ = resolver;
202  }
203  void set_http_transaction_factory(net::HttpTransactionFactory* factory) {
204    http_transaction_factory_ = factory;
205  }
206  void set_ftp_transaction_factory(net::FtpTransactionFactory* factory) {
207    ftp_transaction_factory_ = factory;
208  }
209  void set_http_auth_handler_factory(net::HttpAuthHandlerFactory* factory) {
210    http_auth_handler_factory_ = factory;
211  }
212  void set_cookie_store(net::CookieStore* cookie_store) {
213    cookie_store_ = cookie_store;
214  }
215  void set_cookie_policy(ChromeCookiePolicy* cookie_policy) {
216    chrome_cookie_policy_ = cookie_policy;  // Take a strong reference.
217    cookie_policy_ = cookie_policy;
218  }
219  void set_proxy_service(net::ProxyService* service) {
220    proxy_service_ = service;
221  }
222  void set_user_script_dir_path(const FilePath& path) {
223    user_script_dir_path_ = path;
224  }
225  void set_is_off_the_record(bool is_off_the_record) {
226    is_off_the_record_ = is_off_the_record;
227  }
228  void set_is_media(bool is_media) {
229    is_media_ = is_media;
230  }
231  void set_host_content_settings_map(
232      HostContentSettingsMap* host_content_settings_map) {
233    host_content_settings_map_ = host_content_settings_map;
234  }
235  void set_host_zoom_map(HostZoomMap* host_zoom_map) {
236    host_zoom_map_ = host_zoom_map;
237  }
238  void set_appcache_service(ChromeAppCacheService* service) {
239    appcache_service_ = service;
240  }
241  void set_database_tracker(webkit_database::DatabaseTracker* tracker) {
242    database_tracker_ = tracker;
243  }
244  void set_blob_storage_context(ChromeBlobStorageContext* context) {
245    blob_storage_context_ = context;
246  }
247  void set_file_system_host_context(FileSystemHostContext* context) {
248    file_system_host_context_ = context;
249  }
250  void set_net_log(net::NetLog* net_log) {
251    net_log_ = net_log;
252  }
253  void set_network_delegate(
254      net::HttpNetworkDelegate* network_delegate) {
255    network_delegate_ = network_delegate;
256  }
257
258  // Callback for when the accept language changes.
259  void OnAcceptLanguageChange(const std::string& accept_language);
260
261  // Callback for when the default charset changes.
262  void OnDefaultCharsetChange(const std::string& default_charset);
263
264 protected:
265  ExtensionInfoMap extension_info_;
266
267  // Path to the directory user scripts are stored in.
268  FilePath user_script_dir_path_;
269
270  scoped_refptr<ChromeAppCacheService> appcache_service_;
271  scoped_refptr<webkit_database::DatabaseTracker> database_tracker_;
272  scoped_refptr<ChromeCookiePolicy> chrome_cookie_policy_;
273  scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
274  scoped_refptr<HostZoomMap> host_zoom_map_;
275  scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
276  scoped_refptr<FileSystemHostContext> file_system_host_context_;
277
278  bool is_media_;
279  bool is_off_the_record_;
280
281 private:
282
283  DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContext);
284};
285
286// A URLRequestContextGetter subclass used by the browser. This returns a
287// subclass of URLRequestContext which can be used to store extra information
288// about requests.
289//
290// Most methods are expected to be called on the UI thread, except for
291// the destructor and GetURLRequestContext().
292class ChromeURLRequestContextGetter : public URLRequestContextGetter,
293                                      public NotificationObserver {
294 public:
295  // Constructs a ChromeURLRequestContextGetter that will use |factory| to
296  // create the ChromeURLRequestContext. If |profile| is non-NULL, then the
297  // ChromeURLRequestContextGetter will additionally watch the preferences for
298  // changes to charset/language and CleanupOnUIThread() will need to be
299  // called to unregister.
300  ChromeURLRequestContextGetter(Profile* profile,
301                                ChromeURLRequestContextFactory* factory);
302
303  static void RegisterUserPrefs(PrefService* user_prefs);
304
305  // Note that GetURLRequestContext() can only be called from the IO
306  // thread (it will assert otherwise). GetCookieStore() and
307  // GetIOMessageLoopProxy however can be called from any thread.
308  //
309  // URLRequestContextGetter implementation.
310  virtual URLRequestContext* GetURLRequestContext();
311  virtual net::CookieStore* GetCookieStore();
312  virtual scoped_refptr<base::MessageLoopProxy> GetIOMessageLoopProxy();
313
314  // Convenience overload of GetURLRequestContext() that returns a
315  // ChromeURLRequestContext* rather than a URLRequestContext*.
316  ChromeURLRequestContext* GetIOContext() {
317    return reinterpret_cast<ChromeURLRequestContext*>(GetURLRequestContext());
318  }
319
320  // Create an instance for use with an 'original' (non-OTR) profile. This is
321  // expected to get called on the UI thread.
322  static ChromeURLRequestContextGetter* CreateOriginal(
323      Profile* profile, const FilePath& cookie_store_path,
324      const FilePath& disk_cache_path, int cache_size);
325
326  // Create an instance for an original profile for media. This is expected to
327  // get called on UI thread. This method takes a profile and reuses the
328  // 'original' URLRequestContext for common files.
329  static ChromeURLRequestContextGetter* CreateOriginalForMedia(
330      Profile* profile, const FilePath& disk_cache_path, int cache_size);
331
332  // Create an instance for an original profile for extensions. This is expected
333  // to get called on UI thread.
334  static ChromeURLRequestContextGetter* CreateOriginalForExtensions(
335      Profile* profile, const FilePath& cookie_store_path);
336
337  // Create an instance for use with an OTR profile. This is expected to get
338  // called on the UI thread.
339  static ChromeURLRequestContextGetter* CreateOffTheRecord(Profile* profile);
340
341  // Create an instance for an OTR profile for extensions. This is expected
342  // to get called on UI thread.
343  static ChromeURLRequestContextGetter* CreateOffTheRecordForExtensions(
344      Profile* profile);
345
346  // Clean up UI thread resources. This is expected to get called on the UI
347  // thread before the instance is deleted on the IO thread.
348  void CleanupOnUIThread();
349
350  // These methods simply forward to the corresponding methods on
351  // ChromeURLRequestContext. Takes ownership of |extension_info|.
352  void OnNewExtensions(
353      const std::string& extension_id,
354      ChromeURLRequestContext::ExtensionInfo* extension_info);
355  void OnUnloadedExtension(const std::string& id);
356
357  // NotificationObserver implementation.
358  virtual void Observe(NotificationType type,
359                       const NotificationSource& source,
360                       const NotificationDetails& details);
361
362 private:
363  // Must be called on the IO thread.
364  virtual ~ChromeURLRequestContextGetter();
365
366  // Registers an observer on |profile|'s preferences which will be used
367  // to update the context when the default language and charset change.
368  void RegisterPrefsObserver(Profile* profile);
369
370  // Creates a request context for media resources from a regular request
371  // context. This helper method is called from CreateOriginalForMedia and
372  // CreateOffTheRecordForMedia.
373  static ChromeURLRequestContextGetter* CreateRequestContextForMedia(
374      Profile* profile, const FilePath& disk_cache_path, int cache_size,
375      bool off_the_record);
376
377  // These methods simply forward to the corresponding method on
378  // ChromeURLRequestContext.
379  void OnAcceptLanguageChange(const std::string& accept_language);
380  void OnDefaultCharsetChange(const std::string& default_charset);
381
382  // Saves the cookie store to |result| and signals |completion|.
383  void GetCookieStoreAsyncHelper(base::WaitableEvent* completion,
384                                 net::CookieStore** result);
385
386  PrefChangeRegistrar registrar_;
387
388  // Deferred logic for creating a ChromeURLRequestContext.
389  // Access only from the IO thread.
390  scoped_ptr<ChromeURLRequestContextFactory> factory_;
391
392  // NULL if not yet initialized. Otherwise, it is the URLRequestContext
393  // instance that was lazilly created by GetURLRequestContext.
394  // Access only from the IO thread.
395  scoped_refptr<URLRequestContext> url_request_context_;
396
397  DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextGetter);
398};
399
400// Base class for a ChromeURLRequestContext factory. This includes
401// the shared functionality like extracting the default language/charset
402// from a profile.
403//
404// Except for the constructor, all methods of this class must be called from
405// the IO thread.
406class ChromeURLRequestContextFactory {
407 public:
408  // Extract properties of interested from |profile|, for setting later into
409  // a ChromeURLRequestContext using ApplyProfileParametersToContext().
410  explicit ChromeURLRequestContextFactory(Profile* profile);
411
412  virtual ~ChromeURLRequestContextFactory();
413
414  // Called to create a new instance (will only be called once).
415  virtual ChromeURLRequestContext* Create() = 0;
416
417 protected:
418  IOThread* io_thread() { return io_thread_; }
419
420  // Assigns this factory's properties to |context|.
421  void ApplyProfileParametersToContext(ChromeURLRequestContext* context);
422
423  // Values extracted from the Profile.
424  //
425  // NOTE: If you add any parameters here, keep it in sync with
426  // ApplyProfileParametersToContext().
427  bool is_media_;
428  bool is_off_the_record_;
429  std::string accept_language_;
430  std::string accept_charset_;
431  std::string referrer_charset_;
432  ChromeURLRequestContext::ExtensionInfoMap extension_info_;
433  // TODO(aa): I think this can go away now as we no longer support standalone
434  // user scripts.
435  FilePath user_script_dir_path_;
436  scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
437  scoped_refptr<ChromeAppCacheService> appcache_service_;
438  scoped_refptr<webkit_database::DatabaseTracker> database_tracker_;
439  scoped_refptr<HostZoomMap> host_zoom_map_;
440  scoped_refptr<net::TransportSecurityState> transport_security_state_;
441  scoped_refptr<net::SSLConfigService> ssl_config_service_;
442  scoped_refptr<net::CookieMonster::Delegate> cookie_monster_delegate_;
443  scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
444  scoped_refptr<FileSystemHostContext> file_system_host_context_;
445
446  FilePath profile_dir_path_;
447
448 private:
449  IOThread* const io_thread_;
450
451  DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory);
452};
453
454// Creates a proxy configuration from proxy-related preferences fetched
455// from |pref_service|. The relevant preferences in |pref_service| are
456// initialized from the process' command line or by applicable proxy policies.
457net::ProxyConfig* CreateProxyConfig(const PrefService* pref_service);
458
459#endif  // CHROME_BROWSER_NET_CHROME_URL_REQUEST_CONTEXT_H_
460