1 // Copyright 2014 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 "mojo/services/network/network_context.h"
10 #include "base/base_paths.h"
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/path_service.h"
14 #include "mojo/common/user_agent.h"
15 #include "mojo/services/network/mojo_persistent_cookie_store.h"
16 #include "mojo/services/network/url_loader_impl.h"
17 #include "net/cookies/cookie_monster.h"
18 #include "net/log/net_log_util.h"
19 #include "net/log/write_to_file_net_log_observer.h"
20 #include "net/proxy/proxy_service.h"
21 #include "net/ssl/channel_id_service.h"
22 #include "net/url_request/url_request_context.h"
23 #include "net/url_request/url_request_context_builder.h"
28 // Logs network information to the specified file.
29 const char kLogNetLog
[] = "log-net-log";
32 class NetworkContext::MojoNetLog
: public net::NetLog
{
35 const base::CommandLine
* command_line
=
36 base::CommandLine::ForCurrentProcess();
37 if (!command_line
->HasSwitch(kLogNetLog
))
40 base::FilePath log_path
= command_line
->GetSwitchValuePath(kLogNetLog
);
41 base::ScopedFILE file
;
43 file
.reset(_wfopen(log_path
.value().c_str(), L
"w"));
44 #elif defined(OS_POSIX)
45 file
.reset(fopen(log_path
.value().c_str(), "w"));
48 LOG(ERROR
) << "Could not open file " << log_path
.value()
49 << " for net logging";
51 write_to_file_observer_
.reset(new net::WriteToFileNetLogObserver());
52 write_to_file_observer_
->set_capture_mode(
53 net::NetLogCaptureMode::IncludeCookiesAndCredentials());
54 write_to_file_observer_
->StartObserving(this, file
.Pass(), nullptr,
59 ~MojoNetLog() override
{
60 if (write_to_file_observer_
)
61 write_to_file_observer_
->StopObserving(nullptr);
65 scoped_ptr
<net::WriteToFileNetLogObserver
> write_to_file_observer_
;
67 DISALLOW_COPY_AND_ASSIGN(MojoNetLog
);
70 NetworkContext::NetworkContext(
71 scoped_ptr
<net::URLRequestContext
> url_request_context
)
72 : net_log_(new MojoNetLog
),
73 url_request_context_(url_request_context
.Pass()),
75 url_request_context_
->set_net_log(net_log_
.get());
78 NetworkContext::NetworkContext(
79 const base::FilePath
& base_path
,
80 const scoped_refptr
<base::SequencedTaskRunner
>& background_task_runner
,
81 NetworkServiceDelegate
* delegate
)
82 : NetworkContext(MakeURLRequestContext(base_path
, background_task_runner
,
86 NetworkContext::~NetworkContext() {
88 // TODO(darin): Be careful about destruction order of member variables?
90 // Call each URLLoaderImpl and ask it to release its net::URLRequest, as the
91 // corresponding net::URLRequestContext is going away with this
92 // NetworkContext. The loaders can be deregistering themselves in Cleanup(),
93 // so iterate over a copy.
94 for (auto& url_loader
: url_loaders_
) {
95 url_loader
->Cleanup();
99 void NetworkContext::RegisterURLLoader(URLLoaderImpl
* url_loader
) {
100 DCHECK(url_loaders_
.count(url_loader
) == 0);
101 url_loaders_
.insert(url_loader
);
104 void NetworkContext::DeregisterURLLoader(URLLoaderImpl
* url_loader
) {
106 size_t removed_count
= url_loaders_
.erase(url_loader
);
107 DCHECK(removed_count
);
111 size_t NetworkContext::GetURLLoaderCountForTesting() {
112 return url_loaders_
.size();
116 scoped_ptr
<net::URLRequestContext
> NetworkContext::MakeURLRequestContext(
117 const base::FilePath
& base_path
,
118 const scoped_refptr
<base::SequencedTaskRunner
>& background_task_runner
,
119 NetworkServiceDelegate
* delegate
) {
120 net::URLRequestContextBuilder builder
;
121 builder
.set_accept_language("en-us,en");
122 builder
.set_user_agent(mojo::common::GetUserAgent());
123 builder
.set_proxy_service(net::ProxyService::CreateDirect());
124 builder
.set_transport_security_persister_path(base_path
);
126 net::URLRequestContextBuilder::HttpCacheParams cache_params
;
127 #if defined(OS_ANDROID)
128 // On Android, we store the cache on disk becase we can run only a single
129 // instance of the shell at a time.
130 cache_params
.type
= net::URLRequestContextBuilder::HttpCacheParams::DISK
;
131 cache_params
.path
= base_path
.Append(FILE_PATH_LITERAL("Cache"));
133 // On desktop, we store the cache in memory so we can run many shells
134 // in parallel when running tests, otherwise the network services in each
135 // shell will corrupt the disk cache.
136 cache_params
.type
= net::URLRequestContextBuilder::HttpCacheParams::IN_MEMORY
;
139 builder
.EnableHttpCache(cache_params
);
140 builder
.set_file_enabled(true);
142 if (background_task_runner
) {
143 // TODO(erg): This only gets run on non-android system. Currently, any
144 // attempts from the network_service trying to access the filesystem break
145 // the apptests on android. (And only the apptests on android. Mandoline
146 // shell works fine on android, as does apptests on desktop.)
147 MojoPersistentCookieStore
* cookie_store
=
148 new MojoPersistentCookieStore(
150 base::FilePath(FILE_PATH_LITERAL("Cookies")),
151 base::MessageLoop::current()->task_runner(),
152 background_task_runner
,
153 false, // TODO(erg): Make RESTORED_SESSION_COOKIES configurable.
155 builder
.SetCookieAndChannelIdStores(
156 new net::CookieMonster(cookie_store
, nullptr), nullptr);
159 return make_scoped_ptr(builder
.Build());