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