blob: c88917613bd114545c889d2f1352bc03b2da6ef7 [file] [log] [blame]
jam6f02ddc2017-04-12 01:43:501// Copyright 2017 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.
4
5#include "content/network/network_context.h"
6
7#include "base/command_line.h"
8#include "base/logging.h"
scottmgfd5066f2017-04-14 00:49:179#include "base/memory/ptr_util.h"
yzshen6da6865f2017-04-18 17:49:1310#include "base/strings/string_number_conversions.h"
jam6f02ddc2017-04-12 01:43:5011#include "content/network/url_loader_impl.h"
12#include "content/public/common/content_client.h"
yzshen6da6865f2017-04-18 17:49:1313#include "content/public/common/content_switches.h"
jam6f02ddc2017-04-12 01:43:5014#include "net/dns/host_resolver.h"
15#include "net/dns/mapped_host_resolver.h"
16#include "net/log/net_log_util.h"
17#include "net/log/write_to_file_net_log_observer.h"
yzshena90291c2017-04-26 16:22:5218#include "net/proxy/proxy_config.h"
19#include "net/proxy/proxy_config_service_fixed.h"
scottmgfd5066f2017-04-14 00:49:1720#include "net/url_request/data_protocol_handler.h"
jam6f02ddc2017-04-12 01:43:5021#include "net/url_request/url_request_context.h"
22#include "net/url_request/url_request_context_builder.h"
23
24namespace content {
25
26namespace {
jam6f02ddc2017-04-12 01:43:5027
28std::unique_ptr<net::URLRequestContext> MakeURLRequestContext() {
29 net::URLRequestContextBuilder builder;
30 net::URLRequestContextBuilder::HttpNetworkSessionParams params;
31 const base::CommandLine* command_line =
32 base::CommandLine::ForCurrentProcess();
yzshen6da6865f2017-04-18 17:49:1333 if (command_line->HasSwitch(switches::kIgnoreCertificateErrors))
jam6f02ddc2017-04-12 01:43:5034 params.ignore_certificate_errors = true;
yzshen6da6865f2017-04-18 17:49:1335
36 if (command_line->HasSwitch(switches::kTestingFixedHttpPort)) {
37 int value;
38 base::StringToInt(
39 command_line->GetSwitchValueASCII(switches::kTestingFixedHttpPort),
40 &value);
41 params.testing_fixed_http_port = value;
42 }
43 if (command_line->HasSwitch(switches::kTestingFixedHttpsPort)) {
44 int value;
45 base::StringToInt(
46 command_line->GetSwitchValueASCII(switches::kTestingFixedHttpsPort),
47 &value);
48 params.testing_fixed_https_port = value;
49 }
jam6f02ddc2017-04-12 01:43:5050 builder.set_http_network_session_params(params);
yzshen6da6865f2017-04-18 17:49:1351 if (command_line->HasSwitch(switches::kHostResolverRules)) {
jam6f02ddc2017-04-12 01:43:5052 std::unique_ptr<net::HostResolver> host_resolver(
53 net::HostResolver::CreateDefaultResolver(nullptr));
54 std::unique_ptr<net::MappedHostResolver> remapped_host_resolver(
55 new net::MappedHostResolver(std::move(host_resolver)));
56 remapped_host_resolver->SetRulesFromString(
yzshen6da6865f2017-04-18 17:49:1357 command_line->GetSwitchValueASCII(switches::kHostResolverRules));
jam6f02ddc2017-04-12 01:43:5058 builder.set_host_resolver(std::move(remapped_host_resolver));
59 }
60 builder.set_accept_language("en-us,en");
61 builder.set_user_agent(GetContentClient()->GetUserAgent());
jam6f02ddc2017-04-12 01:43:5062 net::URLRequestContextBuilder::HttpCacheParams cache_params;
63
64 // We store the cache in memory so we can run many shells in parallel when
65 // running tests, otherwise the network services in each shell will corrupt
66 // the disk cache.
67 cache_params.type = net::URLRequestContextBuilder::HttpCacheParams::IN_MEMORY;
68
69 builder.EnableHttpCache(cache_params);
70 builder.set_file_enabled(true);
scottmgfd5066f2017-04-14 00:49:1771
72 builder.SetProtocolHandler(url::kDataScheme,
73 base::MakeUnique<net::DataProtocolHandler>());
74
yzshena90291c2017-04-26 16:22:5275 if (command_line->HasSwitch(switches::kProxyServer)) {
76 net::ProxyConfig config;
77 config.proxy_rules().ParseFromString(
78 command_line->GetSwitchValueASCII(switches::kProxyServer));
79 std::unique_ptr<net::ProxyConfigService> fixed_config_service =
80 base::MakeUnique<net::ProxyConfigServiceFixed>(config);
81 builder.set_proxy_config_service(std::move(fixed_config_service));
82 } else {
83 builder.set_proxy_service(net::ProxyService::CreateDirect());
84 }
85
jam6f02ddc2017-04-12 01:43:5086 return builder.Build();
87}
88
89} // namespace
90
91class NetworkContext::MojoNetLog : public net::NetLog {
92 public:
93 MojoNetLog() {
94 const base::CommandLine* command_line =
95 base::CommandLine::ForCurrentProcess();
yzshen6da6865f2017-04-18 17:49:1396 if (!command_line->HasSwitch(switches::kLogNetLog))
jam6f02ddc2017-04-12 01:43:5097 return;
yzshen6da6865f2017-04-18 17:49:1398 base::FilePath log_path =
99 command_line->GetSwitchValuePath(switches::kLogNetLog);
jam6f02ddc2017-04-12 01:43:50100 base::ScopedFILE file;
101#if defined(OS_WIN)
102 file.reset(_wfopen(log_path.value().c_str(), L"w"));
103#elif defined(OS_POSIX)
104 file.reset(fopen(log_path.value().c_str(), "w"));
105#endif
106 if (!file) {
107 LOG(ERROR) << "Could not open file " << log_path.value()
108 << " for net logging";
109 } else {
110 write_to_file_observer_.reset(new net::WriteToFileNetLogObserver());
111 write_to_file_observer_->set_capture_mode(
112 net::NetLogCaptureMode::IncludeCookiesAndCredentials());
113 write_to_file_observer_->StartObserving(this, std::move(file), nullptr,
114 nullptr);
115 }
116 }
117 ~MojoNetLog() override {
118 if (write_to_file_observer_)
119 write_to_file_observer_->StopObserving(nullptr);
120 }
121
122 private:
123 std::unique_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_;
124 DISALLOW_COPY_AND_ASSIGN(MojoNetLog);
125};
126
127NetworkContext::NetworkContext()
128 : net_log_(new MojoNetLog),
129 url_request_context_(MakeURLRequestContext()),
130 in_shutdown_(false) {}
131
132NetworkContext::~NetworkContext() {
133 in_shutdown_ = true;
134 // Call each URLLoaderImpl and ask it to release its net::URLRequest, as the
135 // corresponding net::URLRequestContext is going away with this
136 // NetworkContext. The loaders can be deregistering themselves in Cleanup(),
137 // so iterate over a copy.
138 for (auto* url_loader : url_loaders_)
139 url_loader->Cleanup();
140}
141
142void NetworkContext::RegisterURLLoader(URLLoaderImpl* url_loader) {
143 DCHECK(url_loaders_.count(url_loader) == 0);
144 url_loaders_.insert(url_loader);
145}
146
147void NetworkContext::DeregisterURLLoader(URLLoaderImpl* url_loader) {
148 if (!in_shutdown_) {
149 size_t removed_count = url_loaders_.erase(url_loader);
150 DCHECK(removed_count);
151 }
152}
153
154} // namespace content