1 // Copyright (c) 2012 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"
10 #include "base/bind_helpers.h"
11 #include "base/command_line.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/pref_proxy_config_tracker.h"
29 #include "chrome/browser/net/proxy_service_factory.h"
30 #include "chrome/browser/net/sdch_dictionary_fetcher.h"
31 #include "chrome/browser/prefs/pref_service.h"
32 #include "chrome/common/chrome_switches.h"
33 #include "chrome/common/pref_names.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/common/content_client.h"
36 #include "content/public/common/url_fetcher.h"
37 #include "net/base/cert_verifier.h"
38 #include "net/base/default_server_bound_cert_store.h"
39 #include "net/base/host_cache.h"
40 #include "net/base/host_resolver.h"
41 #include "net/base/mapped_host_resolver.h"
42 #include "net/base/net_util.h"
43 #include "net/base/sdch_manager.h"
44 #include "net/base/server_bound_cert_service.h"
45 #include "net/cookies/cookie_monster.h"
46 #include "net/ftp/ftp_network_layer.h"
47 #include "net/http/http_auth_filter.h"
48 #include "net/http/http_auth_handler_factory.h"
49 #include "net/http/http_network_layer.h"
50 #include "net/http/http_network_session.h"
51 #include "net/http/http_server_properties_impl.h"
52 #include "net/proxy/proxy_config_service.h"
53 #include "net/proxy/proxy_script_fetcher_impl.h"
54 #include "net/proxy/proxy_service.h"
57 #include "net/ocsp/nss_ocsp.h"
58 #endif // defined(USE_NSS)
60 #if defined(OS_CHROMEOS)
61 #include "chrome/browser/chromeos/proxy_config_service_impl.h"
62 #endif // defined(OS_CHROMEOS)
64 using content::BrowserThread
;
66 class SafeBrowsingURLRequestContext
;
68 // The IOThread object must outlive any tasks posted to the IO thread before the
69 // Quit task, so base::Bind() calls are not refcounted.
73 // Custom URLRequestContext used by requests which aren't associated with a
74 // particular profile. We need to use a subclass of URLRequestContext in order
75 // to provide the correct User-Agent.
76 class URLRequestContextWithUserAgent
: public net::URLRequestContext
{
78 virtual const std::string
& GetUserAgent(
79 const GURL
& url
) const OVERRIDE
{
80 return content::GetUserAgent(url
);
84 // Used for the "system" URLRequestContext. If this grows more complicated, then
85 // consider inheriting directly from URLRequestContext rather than using
86 // implementation inheritance.
87 class SystemURLRequestContext
: public URLRequestContextWithUserAgent
{
89 SystemURLRequestContext() {
91 net::SetURLRequestContextForNSSHttpIO(this);
92 #endif // defined(USE_NSS)
96 virtual ~SystemURLRequestContext() {
98 net::SetURLRequestContextForNSSHttpIO(NULL
);
99 #endif // defined(USE_NSS)
103 net::HostResolver
* CreateGlobalHostResolver(net::NetLog
* net_log
) {
104 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
106 size_t parallelism
= net::HostResolver::kDefaultParallelism
;
108 // Use the concurrency override from the command-line, if any.
109 if (command_line
.HasSwitch(switches::kHostResolverParallelism
)) {
111 command_line
.GetSwitchValueASCII(switches::kHostResolverParallelism
);
113 // Parse the switch (it should be a positive integer formatted as decimal).
115 if (base::StringToInt(s
, &n
) && n
> 0) {
116 parallelism
= static_cast<size_t>(n
);
118 LOG(ERROR
) << "Invalid switch for host resolver parallelism: " << s
;
122 size_t retry_attempts
= net::HostResolver::kDefaultRetryAttempts
;
124 // Use the retry attempts override from the command-line, if any.
125 if (command_line
.HasSwitch(switches::kHostResolverRetryAttempts
)) {
127 command_line
.GetSwitchValueASCII(switches::kHostResolverRetryAttempts
);
128 // Parse the switch (it should be a non-negative integer).
130 if (base::StringToInt(s
, &n
) && n
>= 0) {
131 retry_attempts
= static_cast<size_t>(n
);
133 LOG(ERROR
) << "Invalid switch for host resolver retry attempts: " << s
;
137 net::HostResolver
* global_host_resolver
= NULL
;
138 if (command_line
.HasSwitch(switches::kEnableAsyncDns
)) {
139 global_host_resolver
=
140 net::CreateAsyncHostResolver(parallelism
, retry_attempts
, net_log
);
143 if (!global_host_resolver
) {
144 global_host_resolver
=
145 net::CreateSystemHostResolver(parallelism
, retry_attempts
, net_log
);
148 // Determine if we should disable IPv6 support.
149 if (!command_line
.HasSwitch(switches::kEnableIPv6
)) {
150 if (command_line
.HasSwitch(switches::kDisableIPv6
)) {
151 global_host_resolver
->SetDefaultAddressFamily(net::ADDRESS_FAMILY_IPV4
);
153 global_host_resolver
->ProbeIPv6Support();
157 // If hostname remappings were specified on the command-line, layer these
158 // rules on top of the real host resolver. This allows forwarding all requests
159 // through a designated test server.
160 if (!command_line
.HasSwitch(switches::kHostResolverRules
))
161 return global_host_resolver
;
163 net::MappedHostResolver
* remapped_resolver
=
164 new net::MappedHostResolver(global_host_resolver
);
165 remapped_resolver
->SetRulesFromString(
166 command_line
.GetSwitchValueASCII(switches::kHostResolverRules
));
167 return remapped_resolver
;
170 class LoggingNetworkChangeObserver
171 : public net::NetworkChangeNotifier::IPAddressObserver
{
173 // |net_log| must remain valid throughout our lifetime.
174 explicit LoggingNetworkChangeObserver(net::NetLog
* net_log
)
175 : net_log_(net_log
) {
176 net::NetworkChangeNotifier::AddIPAddressObserver(this);
179 ~LoggingNetworkChangeObserver() {
180 net::NetworkChangeNotifier::RemoveIPAddressObserver(this);
183 virtual void OnIPAddressChanged() {
184 VLOG(1) << "Observed a change to the network IP addresses";
186 net_log_
->AddGlobalEntry(net::NetLog::TYPE_NETWORK_IP_ADDRESSES_CHANGED
,
191 net::NetLog
* net_log_
;
192 DISALLOW_COPY_AND_ASSIGN(LoggingNetworkChangeObserver
);
195 // Create a separate request context for PAC fetches to avoid reference cycles.
196 // See IOThread::Globals for details.
197 scoped_refptr
<net::URLRequestContext
>
198 ConstructProxyScriptFetcherContext(IOThread::Globals
* globals
,
199 net::NetLog
* net_log
) {
200 scoped_refptr
<net::URLRequestContext
> context(
201 new URLRequestContextWithUserAgent
);
202 context
->set_net_log(net_log
);
203 context
->set_host_resolver(globals
->host_resolver
.get());
204 context
->set_cert_verifier(globals
->cert_verifier
.get());
205 context
->set_transport_security_state(
206 globals
->transport_security_state
.get());
207 context
->set_http_auth_handler_factory(
208 globals
->http_auth_handler_factory
.get());
209 context
->set_proxy_service(globals
->proxy_script_fetcher_proxy_service
.get());
210 context
->set_http_transaction_factory(
211 globals
->proxy_script_fetcher_http_transaction_factory
.get());
212 context
->set_ftp_transaction_factory(
213 globals
->proxy_script_fetcher_ftp_transaction_factory
.get());
214 context
->set_cookie_store(globals
->system_cookie_store
.get());
215 context
->set_server_bound_cert_service(
216 globals
->system_server_bound_cert_service
.get());
217 context
->set_network_delegate(globals
->system_network_delegate
.get());
218 // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the
219 // system URLRequestContext too. There's no reason this should be tied to a
224 scoped_refptr
<net::URLRequestContext
>
225 ConstructSystemRequestContext(IOThread::Globals
* globals
,
226 net::NetLog
* net_log
) {
227 scoped_refptr
<net::URLRequestContext
> context(
228 new SystemURLRequestContext
);
229 context
->set_net_log(net_log
);
230 context
->set_host_resolver(globals
->host_resolver
.get());
231 context
->set_cert_verifier(globals
->cert_verifier
.get());
232 context
->set_transport_security_state(
233 globals
->transport_security_state
.get());
234 context
->set_http_auth_handler_factory(
235 globals
->http_auth_handler_factory
.get());
236 context
->set_proxy_service(globals
->system_proxy_service
.get());
237 context
->set_http_transaction_factory(
238 globals
->system_http_transaction_factory
.get());
239 context
->set_ftp_transaction_factory(
240 globals
->system_ftp_transaction_factory
.get());
241 context
->set_cookie_store(globals
->system_cookie_store
.get());
242 context
->set_server_bound_cert_service(
243 globals
->system_server_bound_cert_service
.get());
249 class SystemURLRequestContextGetter
: public net::URLRequestContextGetter
{
251 explicit SystemURLRequestContextGetter(IOThread
* io_thread
);
252 virtual ~SystemURLRequestContextGetter();
254 // Implementation for net::UrlRequestContextGetter.
255 virtual net::URLRequestContext
* GetURLRequestContext();
256 virtual scoped_refptr
<base::MessageLoopProxy
> GetIOMessageLoopProxy() const;
259 IOThread
* const io_thread_
; // Weak pointer, owned by BrowserProcess.
260 scoped_refptr
<base::MessageLoopProxy
> io_message_loop_proxy_
;
262 base::debug::LeakTracker
<SystemURLRequestContextGetter
> leak_tracker_
;
265 SystemURLRequestContextGetter::SystemURLRequestContextGetter(
267 : io_thread_(io_thread
),
268 io_message_loop_proxy_(
269 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
)) {
272 SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {}
274 net::URLRequestContext
* SystemURLRequestContextGetter::GetURLRequestContext() {
275 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
276 DCHECK(io_thread_
->globals()->system_request_context
);
278 return io_thread_
->globals()->system_request_context
;
281 scoped_refptr
<base::MessageLoopProxy
>
282 SystemURLRequestContextGetter::GetIOMessageLoopProxy() const {
283 return io_message_loop_proxy_
;
286 IOThread::Globals::Globals() {}
288 IOThread::Globals::~Globals() {}
290 IOThread::Globals::MediaGlobals::MediaGlobals() {}
292 IOThread::Globals::MediaGlobals::~MediaGlobals() {}
294 // |local_state| is passed in explicitly in order to (1) reduce implicit
295 // dependencies and (2) make IOThread more flexible for testing.
297 PrefService
* local_state
,
298 ChromeNetLog
* net_log
,
299 ExtensionEventRouterForwarder
* extension_event_router_forwarder
)
301 extension_event_router_forwarder_(extension_event_router_forwarder
),
304 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
305 // We call RegisterPrefs() here (instead of inside browser_prefs.cc) to make
306 // sure that everything is initialized in the right order.
307 RegisterPrefs(local_state
);
308 auth_schemes_
= local_state
->GetString(prefs::kAuthSchemes
);
309 negotiate_disable_cname_lookup_
= local_state
->GetBoolean(
310 prefs::kDisableAuthNegotiateCnameLookup
);
311 negotiate_enable_port_
= local_state
->GetBoolean(
312 prefs::kEnableAuthNegotiatePort
);
313 auth_server_whitelist_
= local_state
->GetString(prefs::kAuthServerWhitelist
);
314 auth_delegate_whitelist_
= local_state
->GetString(
315 prefs::kAuthNegotiateDelegateWhitelist
);
316 gssapi_library_name_
= local_state
->GetString(prefs::kGSSAPILibraryName
);
317 pref_proxy_config_tracker_
.reset(
318 ProxyServiceFactory::CreatePrefProxyConfigTracker(local_state
));
319 ChromeNetworkDelegate::InitializeReferrersEnabled(&system_enable_referrers_
,
321 ssl_config_service_manager_
.reset(
322 SSLConfigServiceManager::CreateDefaultManager(local_state
));
324 BrowserThread::SetDelegate(BrowserThread::IO
, this);
327 IOThread::~IOThread() {
328 // This isn't needed for production code, but in tests, IOThread may
329 // be multiply constructed.
330 BrowserThread::SetDelegate(BrowserThread::IO
, NULL
);
332 if (pref_proxy_config_tracker_
.get())
333 pref_proxy_config_tracker_
->DetachFromPrefService();
337 IOThread::Globals
* IOThread::globals() {
338 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
342 ChromeNetLog
* IOThread::net_log() {
346 void IOThread::ChangedToOnTheRecord() {
347 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
348 BrowserThread::PostTask(
351 base::Bind(&IOThread::ChangedToOnTheRecordOnIOThread
,
352 base::Unretained(this)));
355 net::URLRequestContextGetter
* IOThread::system_url_request_context_getter() {
356 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
357 if (!system_url_request_context_getter_
) {
358 InitSystemRequestContext();
360 return system_url_request_context_getter_
;
363 void IOThread::Init() {
364 // Though this thread is called the "IO" thread, it actually just routes
365 // messages around; it shouldn't be allowed to perform any blocking disk I/O.
366 base::ThreadRestrictions::SetIOAllowed(false);
368 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
371 net::SetMessageLoopForNSSHttpIO();
372 #endif // defined(USE_NSS)
375 globals_
= new Globals
;
377 globals_
->media
.media_internals
.reset(new MediaInternals());
379 // Add an observer that will emit network change events to the ChromeNetLog.
380 // Assuming NetworkChangeNotifier dispatches in FIFO order, we should be
381 // logging the network change before other IO thread consumers respond to it.
382 network_change_observer_
.reset(
383 new LoggingNetworkChangeObserver(net_log_
));
385 globals_
->extension_event_router_forwarder
=
386 extension_event_router_forwarder_
;
387 globals_
->system_network_delegate
.reset(new ChromeNetworkDelegate(
388 extension_event_router_forwarder_
,
393 &system_enable_referrers_
));
394 globals_
->host_resolver
.reset(
395 CreateGlobalHostResolver(net_log_
));
396 globals_
->cert_verifier
.reset(net::CertVerifier::CreateDefault());
397 globals_
->transport_security_state
.reset(new net::TransportSecurityState(""));
398 globals_
->ssl_config_service
= GetSSLConfigService();
399 globals_
->http_auth_handler_factory
.reset(CreateDefaultAuthHandlerFactory(
400 globals_
->host_resolver
.get()));
401 globals_
->http_server_properties
.reset(new net::HttpServerPropertiesImpl
);
402 // For the ProxyScriptFetcher, we use a direct ProxyService.
403 globals_
->proxy_script_fetcher_proxy_service
.reset(
404 net::ProxyService::CreateDirectWithNetLog(net_log_
));
405 // In-memory cookie store.
406 globals_
->system_cookie_store
= new net::CookieMonster(NULL
, NULL
);
407 // In-memory server bound cert store.
408 globals_
->system_server_bound_cert_service
.reset(
409 new net::ServerBoundCertService(
410 new net::DefaultServerBoundCertStore(NULL
)));
411 net::HttpNetworkSession::Params session_params
;
412 session_params
.host_resolver
= globals_
->host_resolver
.get();
413 session_params
.cert_verifier
= globals_
->cert_verifier
.get();
414 session_params
.server_bound_cert_service
=
415 globals_
->system_server_bound_cert_service
.get();
416 session_params
.transport_security_state
=
417 globals_
->transport_security_state
.get();
418 session_params
.proxy_service
=
419 globals_
->proxy_script_fetcher_proxy_service
.get();
420 session_params
.http_auth_handler_factory
=
421 globals_
->http_auth_handler_factory
.get();
422 session_params
.network_delegate
= globals_
->system_network_delegate
.get();
423 // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the
424 // system URLRequestContext too. There's no reason this should be tied to a
426 session_params
.http_server_properties
=
427 globals_
->http_server_properties
.get();
428 session_params
.net_log
= net_log_
;
429 session_params
.ssl_config_service
= globals_
->ssl_config_service
;
430 scoped_refptr
<net::HttpNetworkSession
> network_session(
431 new net::HttpNetworkSession(session_params
));
432 globals_
->proxy_script_fetcher_http_transaction_factory
.reset(
433 new net::HttpNetworkLayer(network_session
));
434 globals_
->proxy_script_fetcher_ftp_transaction_factory
.reset(
435 new net::FtpNetworkLayer(globals_
->host_resolver
.get()));
437 globals_
->proxy_script_fetcher_context
=
438 ConstructProxyScriptFetcherContext(globals_
, net_log_
);
440 sdch_manager_
= new net::SdchManager();
442 // InitSystemRequestContext turns right around and posts a task back
443 // to the IO thread, so we can't let it run until we know the IO
444 // thread has started.
446 // Note that since we are at BrowserThread::Init time, the UI thread
447 // is blocked waiting for the thread to start. Therefore, posting
448 // this task to the main thread's message loop here is guaranteed to
449 // get it onto the message loop while the IOThread object still
450 // exists. However, the message might not be processed on the UI
451 // thread until after IOThread is gone, so use a weak pointer.
452 BrowserThread::PostTask(BrowserThread::UI
,
454 base::Bind(&IOThread::InitSystemRequestContext
,
455 weak_factory_
.GetWeakPtr()));
457 // We constructed the weak pointer on the IO thread but it will be
458 // used on the UI thread. Call this to avoid a thread checker
460 weak_factory_
.DetachFromThread();
463 void IOThread::CleanUp() {
464 base::debug::LeakTracker
<SafeBrowsingURLRequestContext
>::CheckForLeaks();
466 delete sdch_manager_
;
467 sdch_manager_
= NULL
;
470 net::ShutdownNSSHttpIO();
471 #endif // defined(USE_NSS)
473 system_url_request_context_getter_
= NULL
;
475 // Release objects that the net::URLRequestContext could have been pointing
478 // This must be reset before the ChromeNetLog is destroyed.
479 network_change_observer_
.reset();
481 system_proxy_config_service_
.reset();
486 base::debug::LeakTracker
<SystemURLRequestContextGetter
>::CheckForLeaks();
490 void IOThread::RegisterPrefs(PrefService
* local_state
) {
491 local_state
->RegisterStringPref(prefs::kAuthSchemes
,
492 "basic,digest,ntlm,negotiate");
493 local_state
->RegisterBooleanPref(prefs::kDisableAuthNegotiateCnameLookup
,
495 local_state
->RegisterBooleanPref(prefs::kEnableAuthNegotiatePort
, false);
496 local_state
->RegisterStringPref(prefs::kAuthServerWhitelist
, "");
497 local_state
->RegisterStringPref(prefs::kAuthNegotiateDelegateWhitelist
, "");
498 local_state
->RegisterStringPref(prefs::kGSSAPILibraryName
, "");
499 local_state
->RegisterBooleanPref(prefs::kEnableReferrers
, true);
502 net::HttpAuthHandlerFactory
* IOThread::CreateDefaultAuthHandlerFactory(
503 net::HostResolver
* resolver
) {
504 net::HttpAuthFilterWhitelist
* auth_filter_default_credentials
= NULL
;
505 if (!auth_server_whitelist_
.empty()) {
506 auth_filter_default_credentials
=
507 new net::HttpAuthFilterWhitelist(auth_server_whitelist_
);
509 net::HttpAuthFilterWhitelist
* auth_filter_delegate
= NULL
;
510 if (!auth_delegate_whitelist_
.empty()) {
511 auth_filter_delegate
=
512 new net::HttpAuthFilterWhitelist(auth_delegate_whitelist_
);
514 globals_
->url_security_manager
.reset(
515 net::URLSecurityManager::Create(auth_filter_default_credentials
,
516 auth_filter_delegate
));
517 std::vector
<std::string
> supported_schemes
;
518 base::SplitString(auth_schemes_
, ',', &supported_schemes
);
520 return net::HttpAuthHandlerRegistryFactory::Create(
522 globals_
->url_security_manager
.get(),
524 gssapi_library_name_
,
525 negotiate_disable_cname_lookup_
,
526 negotiate_enable_port_
);
529 void IOThread::ClearHostCache() {
530 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
532 net::HostCache
* host_cache
= globals_
->host_resolver
->GetHostCache();
537 net::SSLConfigService
* IOThread::GetSSLConfigService() {
538 return ssl_config_service_manager_
->Get();
541 void IOThread::ChangedToOnTheRecordOnIOThread() {
542 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
544 // Clear the host cache to avoid showing entries from the OTR session
545 // in about:net-internals.
549 void IOThread::InitSystemRequestContext() {
550 if (system_url_request_context_getter_
)
552 // If we're in unit_tests, IOThread may not be run.
553 if (!BrowserThread::IsMessageLoopValid(BrowserThread::IO
))
555 bool wait_for_first_update
= (pref_proxy_config_tracker_
.get() != NULL
);
556 ChromeProxyConfigService
* proxy_config_service
=
557 ProxyServiceFactory::CreateProxyConfigService(wait_for_first_update
);
558 system_proxy_config_service_
.reset(proxy_config_service
);
559 if (pref_proxy_config_tracker_
.get()) {
560 pref_proxy_config_tracker_
->SetChromeProxyConfigService(
561 proxy_config_service
);
563 system_url_request_context_getter_
=
564 new SystemURLRequestContextGetter(this);
565 // Safe to post an unretained this pointer, since IOThread is
566 // guaranteed to outlive the IO BrowserThread.
567 BrowserThread::PostTask(
570 base::Bind(&IOThread::InitSystemRequestContextOnIOThread
,
571 base::Unretained(this)));
574 void IOThread::InitSystemRequestContextOnIOThread() {
575 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
576 DCHECK(!globals_
->system_proxy_service
.get());
577 DCHECK(system_proxy_config_service_
.get());
579 const CommandLine
& command_line
= *CommandLine::ForCurrentProcess();
580 globals_
->system_proxy_service
.reset(
581 ProxyServiceFactory::CreateProxyService(
583 globals_
->proxy_script_fetcher_context
,
584 system_proxy_config_service_
.release(),
586 net::HttpNetworkSession::Params system_params
;
587 system_params
.host_resolver
= globals_
->host_resolver
.get();
588 system_params
.cert_verifier
= globals_
->cert_verifier
.get();
589 system_params
.server_bound_cert_service
=
590 globals_
->system_server_bound_cert_service
.get();
591 system_params
.transport_security_state
=
592 globals_
->transport_security_state
.get();
593 system_params
.ssl_host_info_factory
= NULL
;
594 system_params
.proxy_service
= globals_
->system_proxy_service
.get();
595 system_params
.ssl_config_service
= globals_
->ssl_config_service
.get();
596 system_params
.http_auth_handler_factory
=
597 globals_
->http_auth_handler_factory
.get();
598 system_params
.http_server_properties
= globals_
->http_server_properties
.get();
599 system_params
.network_delegate
= globals_
->system_network_delegate
.get();
600 system_params
.net_log
= net_log_
;
601 globals_
->system_http_transaction_factory
.reset(
602 new net::HttpNetworkLayer(
603 new net::HttpNetworkSession(system_params
)));
604 globals_
->system_ftp_transaction_factory
.reset(
605 new net::FtpNetworkLayer(globals_
->host_resolver
.get()));
606 globals_
->system_request_context
=
607 ConstructSystemRequestContext(globals_
, net_log_
);
609 sdch_manager_
->set_sdch_fetcher(
610 new SdchDictionaryFetcher(system_url_request_context_getter_
.get()));