blob: 5637a659ce49c9314ce8a68feac7dd54d7059441 [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"
9#include "content/network/url_loader_impl.h"
10#include "content/public/common/content_client.h"
11#include "net/dns/host_resolver.h"
12#include "net/dns/mapped_host_resolver.h"
13#include "net/log/net_log_util.h"
14#include "net/log/write_to_file_net_log_observer.h"
15#include "net/proxy/proxy_service.h"
16#include "net/url_request/url_request_context.h"
17#include "net/url_request/url_request_context_builder.h"
18
19namespace content {
20
21namespace {
22// Logs network information to the specified file.
23const char kLogNetLog[] = "log-net-log";
24
25// Applies the specified mapping rules when resolving hosts. Please see the
26// comment of net::MappedHostResolver::AddRulesFromString() for rule format.
27const char kHostResolverRules[] = "host-resolver-rules";
28
29// Ignores certificate-related errors.
30const char kIgnoreCertificateErrors[] = "ignore-certificate-errors";
31
32std::unique_ptr<net::URLRequestContext> MakeURLRequestContext() {
33 net::URLRequestContextBuilder builder;
34 net::URLRequestContextBuilder::HttpNetworkSessionParams params;
35 const base::CommandLine* command_line =
36 base::CommandLine::ForCurrentProcess();
37 if (command_line->HasSwitch(kIgnoreCertificateErrors))
38 params.ignore_certificate_errors = true;
39 builder.set_http_network_session_params(params);
40 if (command_line->HasSwitch(kHostResolverRules)) {
41 std::unique_ptr<net::HostResolver> host_resolver(
42 net::HostResolver::CreateDefaultResolver(nullptr));
43 std::unique_ptr<net::MappedHostResolver> remapped_host_resolver(
44 new net::MappedHostResolver(std::move(host_resolver)));
45 remapped_host_resolver->SetRulesFromString(
46 command_line->GetSwitchValueASCII(kHostResolverRules));
47 builder.set_host_resolver(std::move(remapped_host_resolver));
48 }
49 builder.set_accept_language("en-us,en");
50 builder.set_user_agent(GetContentClient()->GetUserAgent());
51 builder.set_proxy_service(net::ProxyService::CreateDirect());
52 net::URLRequestContextBuilder::HttpCacheParams cache_params;
53
54 // We store the cache in memory so we can run many shells in parallel when
55 // running tests, otherwise the network services in each shell will corrupt
56 // the disk cache.
57 cache_params.type = net::URLRequestContextBuilder::HttpCacheParams::IN_MEMORY;
58
59 builder.EnableHttpCache(cache_params);
60 builder.set_file_enabled(true);
61 return builder.Build();
62}
63
64} // namespace
65
66class NetworkContext::MojoNetLog : public net::NetLog {
67 public:
68 MojoNetLog() {
69 const base::CommandLine* command_line =
70 base::CommandLine::ForCurrentProcess();
71 if (!command_line->HasSwitch(kLogNetLog))
72 return;
73 base::FilePath log_path = command_line->GetSwitchValuePath(kLogNetLog);
74 base::ScopedFILE file;
75#if defined(OS_WIN)
76 file.reset(_wfopen(log_path.value().c_str(), L"w"));
77#elif defined(OS_POSIX)
78 file.reset(fopen(log_path.value().c_str(), "w"));
79#endif
80 if (!file) {
81 LOG(ERROR) << "Could not open file " << log_path.value()
82 << " for net logging";
83 } else {
84 write_to_file_observer_.reset(new net::WriteToFileNetLogObserver());
85 write_to_file_observer_->set_capture_mode(
86 net::NetLogCaptureMode::IncludeCookiesAndCredentials());
87 write_to_file_observer_->StartObserving(this, std::move(file), nullptr,
88 nullptr);
89 }
90 }
91 ~MojoNetLog() override {
92 if (write_to_file_observer_)
93 write_to_file_observer_->StopObserving(nullptr);
94 }
95
96 private:
97 std::unique_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_;
98 DISALLOW_COPY_AND_ASSIGN(MojoNetLog);
99};
100
101NetworkContext::NetworkContext()
102 : net_log_(new MojoNetLog),
103 url_request_context_(MakeURLRequestContext()),
104 in_shutdown_(false) {}
105
106NetworkContext::~NetworkContext() {
107 in_shutdown_ = true;
108 // Call each URLLoaderImpl and ask it to release its net::URLRequest, as the
109 // corresponding net::URLRequestContext is going away with this
110 // NetworkContext. The loaders can be deregistering themselves in Cleanup(),
111 // so iterate over a copy.
112 for (auto* url_loader : url_loaders_)
113 url_loader->Cleanup();
114}
115
116void NetworkContext::RegisterURLLoader(URLLoaderImpl* url_loader) {
117 DCHECK(url_loaders_.count(url_loader) == 0);
118 url_loaders_.insert(url_loader);
119}
120
121void NetworkContext::DeregisterURLLoader(URLLoaderImpl* url_loader) {
122 if (!in_shutdown_) {
123 size_t removed_count = url_loaders_.erase(url_loader);
124 DCHECK(removed_count);
125 }
126}
127
128} // namespace content