1 // Copyright (c) 2011 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.
5 #include "chrome/browser/io_thread.h"
9 #include "base/command_line.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/debug/leak_tracker.h"
13 #include "base/logging.h"
14 #include "base/stl_util.h"
15 #include "base/string_number_conversions.h"
16 #include "base/string_split.h"
17 #include "base/string_util.h"
18 #include "base/threading/thread.h"
19 #include "base/threading/thread_restrictions.h"
20 #include "build/build_config.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/extensions/extension_event_router_forwarder.h"
23 #include "chrome/browser/media/media_internals.h"
24 #include "chrome/browser/net/chrome_net_log.h"
25 #include "chrome/browser/net/chrome_network_delegate.h"
26 #include "chrome/browser/net/chrome_url_request_context.h"
27 #include "chrome/browser/net/connect_interceptor.h"
28 #include "chrome/browser/net/passive_log_collector.h"
29 #include "chrome/browser/net/pref_proxy_config_tracker.h"
30 #include "chrome/browser/net/proxy_service_factory.h"
31 #include "chrome/browser/net/sdch_dictionary_fetcher.h"
32 #include "chrome/browser/prefs/pref_service.h"
33 #include "chrome/common/chrome_switches.h"
34 #include "chrome/common/pref_names.h"
35 #include "content/public/browser/browser_thread.h"
36 #include "content/public/common/content_client.h"
37 #include "content/public/common/url_fetcher.h"
38 #include "net/base/cert_verifier.h"
39 #include "net/base/cookie_monster.h"
40 #include "net/base/default_origin_bound_cert_store.h"
41 #include "net/base/host_cache.h"
42 #include "net/base/host_resolver.h"
43 #include "net/base/host_resolver_impl.h"
44 #include "net/base/mapped_host_resolver.h"
45 #include "net/base/net_util.h"
46 #include "net/base/origin_bound_cert_service.h"
47 #include "net/base/sdch_manager.h"
48 #include "net/dns/async_host_resolver.h"
49 #include "net/ftp/ftp_network_layer.h"
50 #include "net/http/http_auth_filter.h"
51 #include "net/http/http_auth_handler_factory.h"
52 #include "net/http/http_network_layer.h"
53 #include "net/http/http_network_session.h"
54 #include "net/http/http_server_properties_impl.h"
55 #include "net/proxy/proxy_config_service.h"
56 #include "net/proxy/proxy_script_fetcher_impl.h"
57 #include "net/proxy/proxy_service.h"
60 #include "net/ocsp/nss_ocsp.h"
61 #endif // defined(USE_NSS)
63 #if defined(OS_CHROMEOS)
64 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
65 #endif // defined(OS_CHROMEOS)
67 using content::BrowserThread
;
69 // The IOThread object must outlive any tasks posted to the IO thread before the
70 // Quit task, so base::Bind() calls are not refcounted.
74 // Custom URLRequestContext used by requests which aren't associated with a
75 // particular profile. We need to use a subclass of URLRequestContext in order
76 // to provide the correct User-Agent.
77 class URLRequestContextWithUserAgent
: public net::URLRequestContext
{
79 virtual const std::string
& GetUserAgent(
80 const GURL
& url
) const OVERRIDE
{
81 return content::GetUserAgent(url
);
85 // Used for the "system" URLRequestContext. If this grows more complicated, then
86 // consider inheriting directly from URLRequestContext rather than using
87 // implementation inheritance.
88 class SystemURLRequestContext
: public URLRequestContextWithUserAgent
{
90 SystemURLRequestContext() {
92 net::SetURLRequestContextForOCSP(this);
93 #endif // defined(USE_NSS)
97 virtual ~SystemURLRequestContext() {
99 net::SetURLRequestContextForOCSP(NULL
);
100 #endif // defined(USE_NSS)
104 net::HostResolver
* CreateGlobalHostResolver(net::NetLog
* net_log
) {
105 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
107 size_t parallelism
= net::HostResolver::kDefaultParallelism
;
109 // Use the concurrency override from the command-line, if any.
110 if (command_line
.HasSwitch(switches::kHostResolverParallelism
)) {
112 command_line
.GetSwitchValueASCII(switches::kHostResolverParallelism
);
114 // Parse the switch (it should be a positive integer formatted as decimal).
116 if (base::StringToInt(s
, &n
) && n
> 0) {
117 parallelism
= static_cast<size_t>(n
);
119 LOG(ERROR
) << "Invalid switch for host resolver parallelism: " << s
;
123 size_t retry_attempts
= net::HostResolver::kDefaultRetryAttempts
;
125 // Use the retry attempts override from the command-line, if any.
126 if (command_line
.HasSwitch(switches::kHostResolverRetryAttempts
)) {
128 command_line
.GetSwitchValueASCII(switches::kHostResolverRetryAttempts
);
129 // Parse the switch (it should be a non-negative integer).
131 if (base::StringToInt(s
, &n
) && n
>= 0) {
132 retry_attempts
= static_cast<size_t>(n
);
134 LOG(ERROR
) << "Invalid switch for host resolver retry attempts: " << s
;
138 net::HostResolver
* global_host_resolver
= NULL
;
139 if (command_line
.HasSwitch(switches::kDnsServer
)) {
140 std::string dns_ip_string
=
141 command_line
.GetSwitchValueASCII(switches::kDnsServer
);
142 net::IPAddressNumber dns_ip_number
;
143 if (net::ParseIPLiteralToNumber(dns_ip_string
, &dns_ip_number
)) {
144 global_host_resolver
=
145 net::CreateAsyncHostResolver(parallelism
, dns_ip_number
, net_log
);
147 LOG(ERROR
) << "Invalid IP address specified for --dns-server: "
152 if (!global_host_resolver
) {
153 global_host_resolver
=
154 net::CreateSystemHostResolver(parallelism
, retry_attempts
, net_log
);
157 // Determine if we should disable IPv6 support.
158 if (!command_line
.HasSwitch(switches::kEnableIPv6
)) {
159 if (command_line
.HasSwitch(switches::kDisableIPv6
)) {
160 global_host_resolver
->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4
);
162 global_host_resolver
->ProbeIPv6Support();
166 // If hostname remappings were specified on the command-line, layer these
167 // rules on top of the real host resolver. This allows forwarding all requests
168 // through a designated test server.
169 if (!command_line
.HasSwitch(switches::kHostResolverRules
))
170 return global_host_resolver
;
172 net::MappedHostResolver
* remapped_resolver
=
173 new net::MappedHostResolver(global_host_resolver
);
174 remapped_resolver
->SetRulesFromString(
175 command_line
.GetSwitchValueASCII(switches::kHostResolverRules
));
176 return remapped_resolver
;
179 class LoggingNetworkChangeObserver
180 : public net::NetworkChangeNotifier::IPAddressObserver
{
182 // |net_log| must remain valid throughout our lifetime.
183 explicit LoggingNetworkChangeObserver(net::NetLog
* net_log
)
184 : net_log_(net_log
) {
185 net::NetworkChangeNotifier::AddIPAddressObserver(this);
188 ~LoggingNetworkChangeObserver() {
189 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
192 virtual void OnIPAddressChanged() {
193 VLOG(1) << "Observed a change to the network IP addresses";
195 net_log_
->AddEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED
,
196 base::TimeTicks::Now(),
197 net::NetLog::Source(),
198 net::NetLog::PHASE_NONE
,
203 net::NetLog
* net_log_
;
204 DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver
);
207 // Create a separate request context for PAC fetches to avoid reference cycles.
208 // See IOThread::Globals for details.
209 scoped_refptr
<net::URLRequestContext
>
210 ConstructProxyScriptFetcherContext(IOThread::Globals
* globals
,
211 net::NetLog
* net_log
) {
212 scoped_refptr
<net::URLRequestContext
> context(
213 new URLRequestContextWithUserAgent
);
214 context
->set_net_log(net_log
);
215 context
->set_host_resolver(globals
->host_resolver
.get());
216 context
->set_cert_verifier(globals
->cert_verifier
.get());
217 context
->set_transport_security_state(
218 globals
->transport_security_state
.get());
219 context
->set_http_auth_handler_factory(
220 globals
->http_auth_handler_factory
.get());
221 context
->set_proxy_service(globals
->proxy_script_fetcher_proxy_service
.get());
222 context
->set_http_transaction_factory(
223 globals
->proxy_script_fetcher_http_transaction_factory
.get());
224 context
->set_ftp_transaction_factory(
225 globals
->proxy_script_fetcher_ftp_transaction_factory
.get());
226 context
->set_cookie_store(globals
->system_cookie_store
.get());
227 context
->set_origin_bound_cert_service(
228 globals
->system_origin_bound_cert_service
.get());
229 context
->set_network_delegate(globals
->system_network_delegate
.get());
230 // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the
231 // system URLRequestContext too. There's no reason this should be tied to a
236 scoped_refptr
<net::URLRequestContext
>
237 ConstructSystemRequestContext(IOThread::Globals
* globals
,
238 net::NetLog
* net_log
) {
239 scoped_refptr
<net::URLRequestContext
> context(
240 new SystemURLRequestContext
);
241 context
->set_net_log(net_log
);
242 context
->set_host_resolver(globals
->host_resolver
.get());
243 context
->set_cert_verifier(globals
->cert_verifier
.get());
244 context
->set_transport_security_state(
245 globals
->transport_security_state
.get());
246 context
->set_http_auth_handler_factory(
247 globals
->http_auth_handler_factory
.get());
248 context
->set_proxy_service(globals
->system_proxy_service
.get());
249 context
->set_http_transaction_factory(
250 globals
->system_http_transaction_factory
.get());
251 context
->set_ftp_transaction_factory(
252 globals
->system_ftp_transaction_factory
.get());
253 context
->set_cookie_store(globals
->system_cookie_store
.get());
254 context
->set_origin_bound_cert_service(
255 globals
->system_origin_bound_cert_service
.get());
261 class SystemURLRequestContextGetter
: public net::URLRequestContextGetter
{
263 explicit SystemURLRequestContextGetter(IOThread
* io_thread
);
264 virtual ~SystemURLRequestContextGetter();
266 // Implementation for net::UrlRequestContextGetter.
267 virtual net::URLRequestContext
* GetURLRequestContext();
268 virtual scoped_refptr
<base::MessageLoopProxy
> GetIOMessageLoopProxy() const;
271 IOThread
* const io_thread_
; // Weak pointer, owned by BrowserProcess.
272 scoped_refptr
<base::MessageLoopProxy
> io_message_loop_proxy_
;
274 base::debug::LeakTracker
<SystemURLRequestContextGetter
> leak_tracker_
;
277 SystemURLRequestContextGetter::SystemURLRequestContextGetter(
279 : io_thread_(io_thread
),
280 io_message_loop_proxy_(
281 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
)) {
284 SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {}
286 net::URLRequestContext
* SystemURLRequestContextGetter::GetURLRequestContext() {
287 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
288 DCHECK(io_thread_
->globals()->system_request_context
);
290 return io_thread_
->globals()->system_request_context
;
293 scoped_refptr
<base::MessageLoopProxy
>
294 SystemURLRequestContextGetter::GetIOMessageLoopProxy() const {
295 return io_message_loop_proxy_
;
298 IOThread::Globals::Globals() {}
300 IOThread::Globals::~Globals() {}
302 IOThread::Globals::MediaGlobals::MediaGlobals() {}
304 IOThread::Globals::MediaGlobals::~MediaGlobals() {}
306 // |local_state| is passed in explicitly in order to (1) reduce implicit
307 // dependencies and (2) make IOThread more flexible for testing.
309 PrefService
* local_state
,
310 ChromeNetLog
* net_log
,
311 ExtensionEventRouterForwarder
* extension_event_router_forwarder
)
313 extension_event_router_forwarder_(extension_event_router_forwarder
),
316 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
317 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
318 // sure that everything is initialized in the right order.
319 RegisterPrefs(local_state
);
320 auth_schemes_
= local_state
->GetString(prefs::kAuthSchemes
);
321 negotiate_disable_cname_lookup_
= local_state
->GetBoolean(
322 prefs::kDisableAuthNegotiateCnameLookup
);
323 negotiate_enable_port_
= local_state
->GetBoolean(
324 prefs::kEnableAuthNegotiatePort
);
325 auth_server_whitelist_
= local_state
->GetString(prefs::kAuthServerWhitelist
);
326 auth_delegate_whitelist_
= local_state
->GetString(
327 prefs::kAuthNegotiateDelegateWhitelist
);
328 gssapi_library_name_
= local_state
->GetString(prefs::kGSSAPILibraryName
);
329 pref_proxy_config_tracker_
.reset(
330 ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state
));
331 ChromeNetworkDelegate::InitializeReferrersEnabled(&system_enable_referrers_
,
333 ssl_config_service_manager_
.reset(
334 SSLConfigServiceManager::CreateDefaultManager(local_state
));
336 BrowserThread::SetDelegate(BrowserThread::IO
, this);
339 IOThread::~IOThread() {
340 // This isn't needed for production code, but in tests, IOThread may
341 // be multiply constructed.
342 BrowserThread::SetDelegate(BrowserThread::IO
, NULL
);
344 if (pref_proxy_config_tracker_
.get())
345 pref_proxy_config_tracker_
->DetachFromPrefService();
349 IOThread::Globals
* IOThread::globals() {
350 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
354 ChromeNetLog
* IOThread::net_log() {
358 void IOThread::ChangedToOnTheRecord() {
359 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
360 BrowserThread::PostTask(
363 base::Bind(&IOThread::ChangedToOnTheRecordOnIOThread
,
364 base::Unretained(this)));
367 net::URLRequestContextGetter
* IOThread::system_url_request_context_getter() {
368 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
369 if (!system_url_request_context_getter_
) {
370 InitSystemRequestContext();
372 return system_url_request_context_getter_
;
375 void IOThread::Init() {
376 // Though this thread is called the "IO" thread, it actually just routes
377 // messages around; it shouldn't be allowed to perform any blocking disk I/O.
378 base::ThreadRestrictions::SetIOAllowed(false);
380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
383 net::SetMessageLoopForOCSP();
384 #endif // defined(USE_NSS)
387 globals_
= new Globals
;
389 globals_
->media
.media_internals
.reset(new MediaInternals());
391 // Add an observer that will emit network change events to the ChromeNetLog.
392 // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
393 // logging the network change before other IO thread consumers respond to it.
394 network_change_observer_
.reset(
395 new LoggingNetworkChangeObserver(net_log_
));
397 globals_
->extension_event_router_forwarder
=
398 extension_event_router_forwarder_
;
399 globals_
->system_network_delegate
.reset(new ChromeNetworkDelegate(
400 extension_event_router_forwarder_
,
404 &system_enable_referrers_
));
405 globals_
->host_resolver
.reset(
406 CreateGlobalHostResolver(net_log_
));
407 globals_
->cert_verifier
.reset(new net::CertVerifier
);
408 globals_
->transport_security_state
.reset(new net::TransportSecurityState(""));
409 globals_
->ssl_config_service
= GetSSLConfigService();
410 globals_
->http_auth_handler_factory
.reset(CreateDefaultAuthHandlerFactory(
411 globals_
->host_resolver
.get()));
412 globals_
->http_server_properties
.reset(new net::HttpServerPropertiesImpl
);
413 // For the ProxyScriptFetcher, we use a direct ProxyService.
414 globals_
->proxy_script_fetcher_proxy_service
.reset(
415 net::ProxyService::CreateDirectWithNetLog(net_log_
));
416 // In-memory cookie store.
417 globals_
->system_cookie_store
= new net::CookieMonster(NULL
, NULL
);
418 // In-memory origin-bound cert store.
419 globals_
->system_origin_bound_cert_service
.reset(
420 new net::OriginBoundCertService(
421 new net::DefaultOriginBoundCertStore(NULL
)));
422 net::HttpNetworkSession::Params session_params
;
423 session_params
.host_resolver
= globals_
->host_resolver
.get();
424 session_params
.cert_verifier
= globals_
->cert_verifier
.get();
425 session_params
.origin_bound_cert_service
=
426 globals_
->system_origin_bound_cert_service
.get();
427 session_params
.transport_security_state
=
428 globals_
->transport_security_state
.get();
429 session_params
.proxy_service
=
430 globals_
->proxy_script_fetcher_proxy_service
.get();
431 session_params
.http_auth_handler_factory
=
432 globals_
->http_auth_handler_factory
.get();
433 session_params
.network_delegate
= globals_
->system_network_delegate
.get();
434 // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the
435 // system URLRequestContext too. There's no reason this should be tied to a
437 session_params
.http_server_properties
=
438 globals_
->http_server_properties
.get();
439 session_params
.net_log
= net_log_
;
440 session_params
.ssl_config_service
= globals_
->ssl_config_service
;
441 scoped_refptr
<net::HttpNetworkSession
> network_session(
442 new net::HttpNetworkSession(session_params
));
443 globals_
->proxy_script_fetcher_http_transaction_factory
.reset(
444 new net::HttpNetworkLayer(network_session
));
445 globals_
->proxy_script_fetcher_ftp_transaction_factory
.reset(
446 new net::FtpNetworkLayer(globals_
->host_resolver
.get()));
448 globals_
->proxy_script_fetcher_context
=
449 ConstructProxyScriptFetcherContext(globals_
, net_log_
);
451 sdch_manager_
= new net::SdchManager();
452 sdch_manager_
->set_sdch_fetcher(new SdchDictionaryFetcher
);
454 // InitSystemRequestContext turns right around and posts a task back
455 // to the IO thread, so we can't let it run until we know the IO
456 // thread has started.
458 // Note that since we are at BrowserThread::Init time, the UI thread
459 // is blocked waiting for the thread to start. Therefore, posting
460 // this task to the main thread's message loop here is guaranteed to
461 // get it onto the message loop while the IOThread object still
462 // exists. However, the message might not be processed on the UI
463 // thread until after IOThread is gone, so use a weak pointer.
464 BrowserThread::PostTask(BrowserThread::UI
,
466 base::Bind(&IOThread::InitSystemRequestContext
,
467 weak_factory_
.GetWeakPtr()));
469 // We constructed the weak pointer on the IO thread but it will be
470 // used on the UI thread. Call this to avoid a thread checker
472 weak_factory_
.DetachFromThread();
475 void IOThread::CleanUp() {
476 delete sdch_manager_
;
477 sdch_manager_
= NULL
;
481 #endif // defined(USE_NSS)
483 system_url_request_context_getter_
= NULL
;
485 // Release objects that the net::URLRequestContext could have been pointing
488 // This must be reset before the ChromeNetLog is destroyed.
489 network_change_observer_
.reset();
491 system_proxy_config_service_
.reset();
496 base::debug::LeakTracker
<SystemURLRequestContextGetter
>::CheckForLeaks();
500 void IOThread::RegisterPrefs(PrefService
* local_state
) {
501 local_state
->RegisterStringPref(prefs::kAuthSchemes
,
502 "basic,digest,ntlm,negotiate");
503 local_state
->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup
,
505 local_state
->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort
, false);
506 local_state
->RegisterStringPref(prefs::kAuthServerWhitelist
, "");
507 local_state
->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist
, "");
508 local_state
->RegisterStringPref(prefs::kGSSAPILibraryName
, "");
509 local_state
->RegisterBooleanPref(prefs::kEnableReferrers
, true);
512 net::HttpAuthHandlerFactory
* IOThread::CreateDefaultAuthHandlerFactory(
513 net::HostResolver
* resolver
) {
514 net::HttpAuthFilterWhitelist
* auth_filter_default_credentials
= NULL
;
515 if (!auth_server_whitelist_
.empty()) {
516 auth_filter_default_credentials
=
517 new net::HttpAuthFilterWhitelist(auth_server_whitelist_
);
519 net::HttpAuthFilterWhitelist
* auth_filter_delegate
= NULL
;
520 if (!auth_delegate_whitelist_
.empty()) {
521 auth_filter_delegate
=
522 new net::HttpAuthFilterWhitelist(auth_delegate_whitelist_
);
524 globals_
->url_security_manager
.reset(
525 net::URLSecurityManager::Create(auth_filter_default_credentials
,
526 auth_filter_delegate
));
527 std::vector
<std::string
> supported_schemes
;
528 base::SplitString(auth_schemes_
, ',', &supported_schemes
);
530 return net::HttpAuthHandlerRegistryFactory::Create(
532 globals_
->url_security_manager
.get(),
534 gssapi_library_name_
,
535 negotiate_disable_cname_lookup_
,
536 negotiate_enable_port_
);
539 void IOThread::ClearHostCache() {
540 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
542 net::HostCache
* host_cache
= globals_
->host_resolver
->GetHostCache();
547 net::SSLConfigService
* IOThread::GetSSLConfigService() {
548 return ssl_config_service_manager_
->Get();
551 void IOThread::ChangedToOnTheRecordOnIOThread() {
552 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
554 // Clear the host cache to avoid showing entries from the OTR session
555 // in about:net-internals.
558 // Clear all of the passively logged data.
559 // TODO(eroman): this is a bit heavy handed, really all we need to do is
560 // clear the data pertaining to incognito context.
561 net_log_
->ClearAllPassivelyCapturedEvents();
564 void IOThread::InitSystemRequestContext() {
565 if (system_url_request_context_getter_
)
567 // If we're in unit_tests, IOThread may not be run.
568 if (!BrowserThread::IsMessageLoopValid(BrowserThread::IO
))
570 bool wait_for_first_update
= (pref_proxy_config_tracker_
.get() != NULL
);
571 ChromeProxyConfigService
* proxy_config_service
=
572 ProxyServiceFactory::CreateProxyConfigService(wait_for_first_update
);
573 system_proxy_config_service_
.reset(proxy_config_service
);
574 if (pref_proxy_config_tracker_
.get()) {
575 pref_proxy_config_tracker_
->SetChromeProxyConfigService(
576 proxy_config_service
);
578 system_url_request_context_getter_
=
579 new SystemURLRequestContextGetter(this);
580 // Safe to post an unretained this pointer, since IOThread is
581 // guaranteed to outlive the IO BrowserThread.
582 BrowserThread::PostTask(
585 base::Bind(&IOThread::InitSystemRequestContextOnIOThread
,
586 base::Unretained(this)));
589 void IOThread::InitSystemRequestContextOnIOThread() {
590 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
591 DCHECK(!globals_
->system_proxy_service
.get());
592 DCHECK(system_proxy_config_service_
.get());
594 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
595 globals_
->system_proxy_service
.reset(
596 ProxyServiceFactory::CreateProxyService(
598 globals_
->proxy_script_fetcher_context
,
599 system_proxy_config_service_
.release(),
601 net::HttpNetworkSession::Params system_params
;
602 system_params
.host_resolver
= globals_
->host_resolver
.get();
603 system_params
.cert_verifier
= globals_
->cert_verifier
.get();
604 system_params
.origin_bound_cert_service
=
605 globals_
->system_origin_bound_cert_service
.get();
606 system_params
.transport_security_state
=
607 globals_
->transport_security_state
.get();
608 system_params
.ssl_host_info_factory
= NULL
;
609 system_params
.proxy_service
= globals_
->system_proxy_service
.get();
610 system_params
.ssl_config_service
= globals_
->ssl_config_service
.get();
611 system_params
.http_auth_handler_factory
=
612 globals_
->http_auth_handler_factory
.get();
613 system_params
.http_server_properties
= globals_
->http_server_properties
.get();
614 system_params
.network_delegate
= globals_
->system_network_delegate
.get();
615 system_params
.net_log
= net_log_
;
616 globals_
->system_http_transaction_factory
.reset(
617 new net::HttpNetworkLayer(
618 new net::HttpNetworkSession(system_params
)));
619 globals_
->system_ftp_transaction_factory
.reset(
620 new net::FtpNetworkLayer(globals_
->host_resolver
.get()));
621 globals_
->system_request_context
=
622 ConstructSystemRequestContext(globals_
, net_log_
);