// Copyright (c) 2012 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_IO_THREAD_H_
#define CHROME_BROWSER_IO_THREAD_H_
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/prefs/pref_member.h"
#include "base/time/time.h"
#include "chrome/browser/net/ssl_config_service_manager.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browser_thread_delegate.h"
#include "net/base/network_change_notifier.h"
#include "net/http/http_network_session.h"
#include "net/socket/next_proto.h"
class ChromeNetLog;
class PrefProxyConfigTracker;
class PrefService;
class PrefRegistrySimple;
class SystemURLRequestContextGetter;
namespace base {
class CommandLine;
}
namespace chrome_browser_net {
class DnsProbeService;
}
namespace extensions {
class EventRouterForwarder;
}
namespace net {
class CertVerifier;
class CookieStore;
class CTVerifier;
class FtpTransactionFactory;
class HostMappingRules;
class HostResolver;
class HttpAuthHandlerFactory;
class HttpServerProperties;
class HttpTransactionFactory;
class HttpUserAgentSettings;
class NetworkDelegate;
class ServerBoundCertService;
class ProxyConfigService;
class ProxyService;
class SSLConfigService;
class TransportSecurityState;
class URLRequestContext;
class URLRequestContextGetter;
class URLRequestJobFactory;
class URLRequestThrottlerManager;
class URLSecurityManager;
} // namespace net
namespace policy {
class PolicyService;
} // namespace policy
// Contains state associated with, initialized and cleaned up on, and
// primarily used on, the IO thread.
//
// If you are looking to interact with the IO thread (e.g. post tasks
// to it or check if it is the current thread), see
// content::BrowserThread.
class IOThread : public content::BrowserThreadDelegate {
public:
struct Globals {
template <typename T>
class Optional {
public:
Optional() : set_(false) {}
void set(T value) {
set_ = true;
value_ = value;
}
void CopyToIfSet(T* value) {
if (set_) {
*value = value_;
}
}
private:
bool set_;
T value_;
};
class SystemRequestContextLeakChecker {
public:
explicit SystemRequestContextLeakChecker(Globals* globals);
~SystemRequestContextLeakChecker();
private:
Globals* const globals_;
};
Globals();
~Globals();
// The "system" NetworkDelegate, used for Profile-agnostic network events.
scoped_ptr<net::NetworkDelegate> system_network_delegate;
scoped_ptr<net::HostResolver> host_resolver;
scoped_ptr<net::CertVerifier> cert_verifier;
// The ServerBoundCertService must outlive the HttpTransactionFactory.
scoped_ptr<net::ServerBoundCertService> system_server_bound_cert_service;
// This TransportSecurityState doesn't load or save any state. It's only
// used to enforce pinning for system requests and will only use built-in
// pins.
scoped_ptr<net::TransportSecurityState> transport_security_state;
scoped_ptr<net::CTVerifier> cert_transparency_verifier;
scoped_refptr<net::SSLConfigService> ssl_config_service;
scoped_ptr<net::HttpAuthHandlerFactory> http_auth_handler_factory;
scoped_ptr<net::HttpServerProperties> http_server_properties;
scoped_ptr<net::ProxyService> proxy_script_fetcher_proxy_service;
scoped_ptr<net::HttpTransactionFactory>
proxy_script_fetcher_http_transaction_factory;
scoped_ptr<net::FtpTransactionFactory>
proxy_script_fetcher_ftp_transaction_factory;
scoped_ptr<net::URLRequestJobFactory>
proxy_script_fetcher_url_request_job_factory;
scoped_ptr<net::URLRequestThrottlerManager> throttler_manager;
scoped_ptr<net::URLSecurityManager> url_security_manager;
// TODO(willchan): Remove proxy script fetcher context since it's not
// necessary now that I got rid of refcounting URLRequestContexts.
//
// The first URLRequestContext is |system_url_request_context|. We introduce
// |proxy_script_fetcher_context| for the second context. It has a direct
// ProxyService, since we always directly connect to fetch the PAC script.
scoped_ptr<net::URLRequestContext> proxy_script_fetcher_context;
scoped_ptr<net::ProxyService> system_proxy_service;
scoped_ptr<net::HttpTransactionFactory> system_http_transaction_factory;
scoped_ptr<net::URLRequestJobFactory> system_url_request_job_factory;
scoped_ptr<net::URLRequestContext> system_request_context;
SystemRequestContextLeakChecker system_request_context_leak_checker;
// |system_cookie_store| and |system_server_bound_cert_service| are shared
// between |proxy_script_fetcher_context| and |system_request_context|.
scoped_refptr<net::CookieStore> system_cookie_store;
scoped_refptr<extensions::EventRouterForwarder>
extension_event_router_forwarder;
scoped_ptr<net::HostMappingRules> host_mapping_rules;
scoped_ptr<net::HttpUserAgentSettings> http_user_agent_settings;
bool ignore_certificate_errors;
uint16 testing_fixed_http_port;
uint16 testing_fixed_https_port;
Optional<size_t> initial_max_spdy_concurrent_streams;
Optional<bool> force_spdy_single_domain;
Optional<bool> enable_spdy_compression;
Optional<bool> enable_spdy_ping_based_connection_checking;
Optional<net::NextProto> spdy_default_protocol;
net::NextProtoVector next_protos;
Optional<string> trusted_spdy_proxy;
Optional<bool> force_spdy_over_ssl;
Optional<bool> force_spdy_always;
std::set<net::HostPortPair> forced_spdy_exclusions;
Optional<bool> use_alternate_protocols;
Optional<bool> enable_websocket_over_spdy;
Optional<bool> enable_quic;
Optional<bool> enable_quic_https;
Optional<bool> enable_quic_pacing;
Optional<bool> enable_quic_time_based_loss_detection;
Optional<bool> enable_quic_persist_server_info;
Optional<bool> enable_quic_port_selection;
Optional<size_t> quic_max_packet_length;
Optional<std::string> quic_user_agent_id;
Optional<net::QuicVersionVector> quic_supported_versions;
Optional<net::HostPortPair> origin_to_force_quic_on;
bool enable_user_alternate_protocol_ports;
// NetErrorTabHelper uses |dns_probe_service| to send DNS probes when a
// main frame load fails with a DNS error in order to provide more useful
// information to the renderer so it can show a more specific error page.
scoped_ptr<chrome_browser_net::DnsProbeService> dns_probe_service;
scoped_ptr<data_reduction_proxy::DataReductionProxyParams>
data_reduction_proxy_params;
};
// |net_log| must either outlive the IOThread or be NULL.
IOThread(PrefService* local_state,
policy::PolicyService* policy_service,
ChromeNetLog* net_log,
extensions::EventRouterForwarder* extension_event_router_forwarder);
virtual ~IOThread();
static void RegisterPrefs(PrefRegistrySimple* registry);
// Can only be called on the IO thread.
Globals* globals();
// Allows overriding Globals in tests where IOThread::Init() and
// IOThread::CleanUp() are not called. This allows for injecting mocks into
// IOThread global objects.
void SetGlobalsForTesting(Globals* globals);
ChromeNetLog* net_log();
// Handles changing to On The Record mode, discarding confidential data.
void ChangedToOnTheRecord();
// Returns a getter for the URLRequestContext. Only called on the UI thread.
net::URLRequestContextGetter* system_url_request_context_getter();
// Clears the host cache. Intended to be used to prevent exposing recently
// visited sites on about:net-internals/#dns and about:dns pages. Must be
// called on the IO thread.
void ClearHostCache();
void InitializeNetworkSessionParams(net::HttpNetworkSession::Params* params);
base::TimeTicks creation_time() const;
private:
// Provide SystemURLRequestContextGetter with access to
// InitSystemRequestContext().
friend class SystemURLRequestContextGetter;
// BrowserThreadDelegate implementation, runs on the IO thread.
// This handles initialization and destruction of state that must
// live on the IO thread.
virtual void Init() OVERRIDE;
virtual void InitAsync() OVERRIDE;
virtual void CleanUp() OVERRIDE;
void InitializeNetworkOptions(const base::CommandLine& parsed_command_line);
// Enable SPDY with the given mode, which may contain the following:
//
// "off" : Disables SPDY support entirely.
// "ssl" : Forces SPDY for all HTTPS requests.
// "no-ssl" : Forces SPDY for all HTTP requests.
// "no-ping" : Disables SPDY ping connection testing.
// "exclude=<host>" : Disables SPDY support for the host <host>.
// "no-compress" : Disables SPDY header compression.
// "no-alt-protocols : Disables alternate protocol support.
// "force-alt-protocols : Forces an alternate protocol of SPDY/3
// on port 443.
// "single-domain" : Forces all spdy traffic to a single domain.
// "init-max-streams=<limit>" : Specifies the maximum number of concurrent
// streams for a SPDY session, unless the
// specifies a different value via SETTINGS.
void EnableSpdy(const std::string& mode);
// Global state must be initialized on the IO thread, then this
// method must be invoked on the UI thread.
void InitSystemRequestContext();
// Lazy initialization of system request context for
// SystemURLRequestContextGetter. To be called on IO thread only
// after global state has been initialized on the IO thread, and
// SystemRequestContext state has been initialized on the UI thread.
void InitSystemRequestContextOnIOThread();
net::HttpAuthHandlerFactory* CreateDefaultAuthHandlerFactory(
net::HostResolver* resolver);
// Returns an SSLConfigService instance.
net::SSLConfigService* GetSSLConfigService();
void ChangedToOnTheRecordOnIOThread();
void UpdateDnsClientEnabled();
// Configures QUIC options based on the flags in |command_line| as
// well as the QUIC field trial group.
void ConfigureQuic(const base::CommandLine& command_line);
// Returns true if QUIC should be enabled, either as a result
// of a field trial or a command line flag.
bool ShouldEnableQuic(const base::CommandLine& command_line,
base::StringPiece quic_trial_group);
// Returns true if HTTPS over QUIC should be enabled, either as a result
// of a field trial or a command line flag.
bool ShouldEnableQuicHttps(const base::CommandLine& command_line,
base::StringPiece quic_trial_group);
// Returns true if the selection of the ephemeral port in bind() should be
// performed by Chromium, and false if the OS should select the port. The OS
// option is used to prevent Windows from posting a security security warning
// dialog.
bool ShouldEnableQuicPortSelection(const base::CommandLine& command_line);
// Returns true if QUIC packet pacing should be negotiated during the
// QUIC handshake.
bool ShouldEnableQuicPacing(const base::CommandLine& command_line,
base::StringPiece quic_trial_group);
// Returns true if QUIC time-base loss detection should be negotiated during
// the QUIC handshake.
bool ShouldEnableQuicTimeBasedLossDetection(
const base::CommandLine& command_line,
base::StringPiece quic_trial_group);
// Returns true if Chromium should persist QUIC server config information to
// disk cache.
bool ShouldEnableQuicPersistServerInfo(const base::CommandLine& command_line);
// Returns the maximum length for QUIC packets, based on any flags in
// |command_line| or the field trial. Returns 0 if there is an error
// parsing any of the options, or if the default value should be used.
size_t GetQuicMaxPacketLength(const base::CommandLine& command_line,
base::StringPiece quic_trial_group);
// Returns the quic versions specified by any flags in |command_line|.
net::QuicVersion GetQuicVersion(const base::CommandLine& command_line);
// The NetLog is owned by the browser process, to allow logging from other
// threads during shutdown, but is used most frequently on the IOThread.
ChromeNetLog* net_log_;
// The extensions::EventRouterForwarder allows for sending events to
// extensions from the IOThread.
extensions::EventRouterForwarder* extension_event_router_forwarder_;
// These member variables are basically global, but their lifetimes are tied
// to the IOThread. IOThread owns them all, despite not using scoped_ptr.
// This is because the destructor of IOThread runs on the wrong thread. All
// member variables should be deleted in CleanUp().
// These member variables are initialized in Init() and do not change for the
// lifetime of the IO thread.
Globals* globals_;
// Observer that logs network changes to the ChromeNetLog.
class LoggingNetworkChangeObserver;
scoped_ptr<LoggingNetworkChangeObserver> network_change_observer_;
BooleanPrefMember system_enable_referrers_;
BooleanPrefMember dns_client_enabled_;
BooleanPrefMember quick_check_enabled_;
// Store HTTP Auth-related policies in this thread.
std::string auth_schemes_;
bool negotiate_disable_cname_lookup_;
bool negotiate_enable_port_;
std::string auth_server_whitelist_;
std::string auth_delegate_whitelist_;
std::string gssapi_library_name_;
// This is an instance of the default SSLConfigServiceManager for the current
// platform and it gets SSL preferences from local_state object.
scoped_ptr<SSLConfigServiceManager> ssl_config_service_manager_;
// These member variables are initialized by a task posted to the IO thread,
// which gets posted by calling certain member functions of IOThread.
scoped_ptr<net::ProxyConfigService> system_proxy_config_service_;
scoped_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_;
scoped_refptr<net::URLRequestContextGetter>
system_url_request_context_getter_;
// True if SPDY is disabled by policy.
bool is_spdy_disabled_by_policy_;
base::WeakPtrFactory<IOThread> weak_factory_;
const base::TimeTicks creation_time_;
DISALLOW_COPY_AND_ASSIGN(IOThread);
};
#endif // CHROME_BROWSER_IO_THREAD_H_