Add ICU message format support
[chromium-blink-merge.git] / mojo / services / network / network_context.cc
blob4e2bf55cb8aa1fcce79e911857cf6c9148cdf99d
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"
7 #include <algorithm>
8 #include <vector>
10 #include "base/base_paths.h"
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/logging.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "mojo/common/user_agent.h"
17 #include "mojo/services/network/mojo_persistent_cookie_store.h"
18 #include "mojo/services/network/url_loader_impl.h"
19 #include "net/cookies/cookie_monster.h"
20 #include "net/dns/host_resolver.h"
21 #include "net/dns/mapped_host_resolver.h"
22 #include "net/log/net_log_util.h"
23 #include "net/log/write_to_file_net_log_observer.h"
24 #include "net/proxy/proxy_service.h"
25 #include "net/ssl/channel_id_service.h"
26 #include "net/url_request/url_request_context.h"
27 #include "net/url_request/url_request_context_builder.h"
29 namespace mojo {
31 namespace {
32 // Applies the specified mapping rules when resolving hosts. Please see the
33 // comment of net::MappedHostResolver::AddRulesFromString() for rule format.
34 const char kHostResolverRules[] = "host-resolver-rules";
36 // Ignores certificate-related errors.
37 const char kIgnoreCertificateErrors[] = "ignore-certificate-errors";
39 // Logs network information to the specified file.
40 const char kLogNetLog[] = "log-net-log";
42 // Allows for forcing socket connections to HTTP/HTTPS to use fixed ports.
43 const char kTestingFixedHttpPort[] = "testing-fixed-http-port";
44 const char kTestingFixedHttpsPort[] = "testing-fixed-https-port";
46 uint16 GetPortNumber(const base::CommandLine& command_line,
47 const base::StringPiece& switch_name) {
48 std::string port_str = command_line.GetSwitchValueASCII(switch_name);
49 unsigned port;
50 if (!base::StringToUint(port_str, &port) || port > 65535) {
51 LOG(ERROR) << "Invalid value for switch " << switch_name << ": '"
52 << port_str << "' is not a valid port number.";
53 return 0;
55 return static_cast<uint16>(port);
58 } // namespace
60 class NetworkContext::MojoNetLog : public net::NetLog {
61 public:
62 MojoNetLog() {
63 const base::CommandLine* command_line =
64 base::CommandLine::ForCurrentProcess();
65 if (!command_line->HasSwitch(kLogNetLog))
66 return;
68 base::FilePath log_path = command_line->GetSwitchValuePath(kLogNetLog);
69 base::ScopedFILE file;
70 #if defined(OS_WIN)
71 file.reset(_wfopen(log_path.value().c_str(), L"w"));
72 #elif defined(OS_POSIX)
73 file.reset(fopen(log_path.value().c_str(), "w"));
74 #endif
75 if (!file) {
76 LOG(ERROR) << "Could not open file " << log_path.value()
77 << " for net logging";
78 } else {
79 write_to_file_observer_.reset(new net::WriteToFileNetLogObserver());
80 write_to_file_observer_->set_capture_mode(
81 net::NetLogCaptureMode::IncludeCookiesAndCredentials());
82 write_to_file_observer_->StartObserving(this, file.Pass(), nullptr,
83 nullptr);
87 ~MojoNetLog() override {
88 if (write_to_file_observer_)
89 write_to_file_observer_->StopObserving(nullptr);
92 private:
93 scoped_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_;
95 DISALLOW_COPY_AND_ASSIGN(MojoNetLog);
98 NetworkContext::NetworkContext(
99 scoped_ptr<net::URLRequestContext> url_request_context)
100 : net_log_(new MojoNetLog),
101 url_request_context_(url_request_context.Pass()),
102 in_shutdown_(false) {
103 url_request_context_->set_net_log(net_log_.get());
106 NetworkContext::NetworkContext(
107 const base::FilePath& base_path,
108 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
109 NetworkServiceDelegate* delegate)
110 : NetworkContext(MakeURLRequestContext(base_path, background_task_runner,
111 delegate)) {
114 NetworkContext::~NetworkContext() {
115 in_shutdown_ = true;
116 // TODO(darin): Be careful about destruction order of member variables?
118 // Call each URLLoaderImpl and ask it to release its net::URLRequest, as the
119 // corresponding net::URLRequestContext is going away with this
120 // NetworkContext. The loaders can be deregistering themselves in Cleanup(),
121 // so iterate over a copy.
122 for (auto& url_loader : url_loaders_) {
123 url_loader->Cleanup();
127 void NetworkContext::RegisterURLLoader(URLLoaderImpl* url_loader) {
128 DCHECK(url_loaders_.count(url_loader) == 0);
129 url_loaders_.insert(url_loader);
132 void NetworkContext::DeregisterURLLoader(URLLoaderImpl* url_loader) {
133 if (!in_shutdown_) {
134 size_t removed_count = url_loaders_.erase(url_loader);
135 DCHECK(removed_count);
139 size_t NetworkContext::GetURLLoaderCountForTesting() {
140 return url_loaders_.size();
143 // static
144 scoped_ptr<net::URLRequestContext> NetworkContext::MakeURLRequestContext(
145 const base::FilePath& base_path,
146 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
147 NetworkServiceDelegate* delegate) {
148 net::URLRequestContextBuilder builder;
149 net::URLRequestContextBuilder::HttpNetworkSessionParams params;
150 const base::CommandLine* command_line =
151 base::CommandLine::ForCurrentProcess();
152 if (command_line->HasSwitch(kIgnoreCertificateErrors))
153 params.ignore_certificate_errors = true;
154 if (command_line->HasSwitch(kTestingFixedHttpPort)) {
155 params.testing_fixed_http_port =
156 GetPortNumber(*command_line, kTestingFixedHttpPort);
158 if (command_line->HasSwitch(kTestingFixedHttpsPort)) {
159 params.testing_fixed_https_port =
160 GetPortNumber(*command_line, kTestingFixedHttpsPort);
162 builder.set_http_network_session_params(params);
164 if (command_line->HasSwitch(kHostResolverRules)) {
165 scoped_ptr<net::HostResolver> host_resolver(
166 net::HostResolver::CreateDefaultResolver(nullptr));
167 scoped_ptr<net::MappedHostResolver> remapped_host_resolver(
168 new net::MappedHostResolver(host_resolver.Pass()));
169 remapped_host_resolver->SetRulesFromString(
170 command_line->GetSwitchValueASCII(kHostResolverRules));
171 host_resolver.reset(remapped_host_resolver.release());
172 builder.set_host_resolver(host_resolver.release());
175 builder.set_accept_language("en-us,en");
176 builder.set_user_agent(mojo::common::GetUserAgent());
177 builder.set_proxy_service(net::ProxyService::CreateDirect());
178 builder.set_transport_security_persister_path(base_path);
180 net::URLRequestContextBuilder::HttpCacheParams cache_params;
181 #if defined(OS_ANDROID)
182 // On Android, we store the cache on disk becase we can run only a single
183 // instance of the shell at a time.
184 cache_params.type = net::URLRequestContextBuilder::HttpCacheParams::DISK;
185 cache_params.path = base_path.Append(FILE_PATH_LITERAL("Cache"));
186 #else
187 // On desktop, we store the cache in memory so we can run many shells
188 // in parallel when running tests, otherwise the network services in each
189 // shell will corrupt the disk cache.
190 cache_params.type = net::URLRequestContextBuilder::HttpCacheParams::IN_MEMORY;
191 #endif
193 builder.EnableHttpCache(cache_params);
194 builder.set_file_enabled(true);
196 if (background_task_runner) {
197 // TODO(erg): This only gets run on non-android system. Currently, any
198 // attempts from the network_service trying to access the filesystem break
199 // the apptests on android. (And only the apptests on android. Mandoline
200 // shell works fine on android, as does apptests on desktop.)
201 MojoPersistentCookieStore* cookie_store =
202 new MojoPersistentCookieStore(
203 delegate,
204 base::FilePath(FILE_PATH_LITERAL("Cookies")),
205 base::MessageLoop::current()->task_runner(),
206 background_task_runner,
207 false, // TODO(erg): Make RESTORED_SESSION_COOKIES configurable.
208 nullptr);
209 builder.SetCookieAndChannelIdStores(
210 new net::CookieMonster(cookie_store, nullptr), nullptr);
213 return make_scoped_ptr(builder.Build());
216 } // namespace mojo