| OLD | NEW |
| (Empty) |
| 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. | |
| 4 | |
| 5 #include "mojo/services/network/network_context.h" | |
| 6 | |
| 7 #include <stddef.h> | |
| 8 #include <stdint.h> | |
| 9 | |
| 10 #include <algorithm> | |
| 11 #include <utility> | |
| 12 #include <vector> | |
| 13 | |
| 14 #include "base/base_paths.h" | |
| 15 #include "base/bind.h" | |
| 16 #include "base/command_line.h" | |
| 17 #include "base/logging.h" | |
| 18 #include "base/macros.h" | |
| 19 #include "base/path_service.h" | |
| 20 #include "base/strings/string_number_conversions.h" | |
| 21 #include "mojo/common/user_agent.h" | |
| 22 #include "mojo/services/network/url_loader_impl.h" | |
| 23 #include "net/cookies/cookie_monster.h" | |
| 24 #include "net/dns/host_resolver.h" | |
| 25 #include "net/dns/mapped_host_resolver.h" | |
| 26 #include "net/log/net_log_util.h" | |
| 27 #include "net/log/write_to_file_net_log_observer.h" | |
| 28 #include "net/proxy/proxy_service.h" | |
| 29 #include "net/ssl/channel_id_service.h" | |
| 30 #include "net/url_request/url_request_context.h" | |
| 31 #include "net/url_request/url_request_context_builder.h" | |
| 32 | |
| 33 namespace mojo { | |
| 34 | |
| 35 namespace { | |
| 36 // Applies the specified mapping rules when resolving hosts. Please see the | |
| 37 // comment of net::MappedHostResolver::AddRulesFromString() for rule format. | |
| 38 const char kHostResolverRules[] = "host-resolver-rules"; | |
| 39 | |
| 40 // Ignores certificate-related errors. | |
| 41 const char kIgnoreCertificateErrors[] = "ignore-certificate-errors"; | |
| 42 | |
| 43 // Logs network information to the specified file. | |
| 44 const char kLogNetLog[] = "log-net-log"; | |
| 45 | |
| 46 // Allows for forcing socket connections to HTTP/HTTPS to use fixed ports. | |
| 47 const char kTestingFixedHttpPort[] = "testing-fixed-http-port"; | |
| 48 const char kTestingFixedHttpsPort[] = "testing-fixed-https-port"; | |
| 49 | |
| 50 uint16_t GetPortNumber(const base::CommandLine& command_line, | |
| 51 const base::StringPiece& switch_name) { | |
| 52 std::string port_str = command_line.GetSwitchValueASCII(switch_name); | |
| 53 unsigned port; | |
| 54 if (!base::StringToUint(port_str, &port) || port > 65535) { | |
| 55 LOG(ERROR) << "Invalid value for switch " << switch_name << ": '" | |
| 56 << port_str << "' is not a valid port number."; | |
| 57 return 0; | |
| 58 } | |
| 59 return static_cast<uint16_t>(port); | |
| 60 } | |
| 61 | |
| 62 } // namespace | |
| 63 | |
| 64 class NetworkContext::MojoNetLog : public net::NetLog { | |
| 65 public: | |
| 66 MojoNetLog() { | |
| 67 const base::CommandLine* command_line = | |
| 68 base::CommandLine::ForCurrentProcess(); | |
| 69 if (!command_line->HasSwitch(kLogNetLog)) | |
| 70 return; | |
| 71 | |
| 72 base::FilePath log_path = command_line->GetSwitchValuePath(kLogNetLog); | |
| 73 base::ScopedFILE file; | |
| 74 #if defined(OS_WIN) | |
| 75 file.reset(_wfopen(log_path.value().c_str(), L"w")); | |
| 76 #elif defined(OS_POSIX) | |
| 77 file.reset(fopen(log_path.value().c_str(), "w")); | |
| 78 #endif | |
| 79 if (!file) { | |
| 80 LOG(ERROR) << "Could not open file " << log_path.value() | |
| 81 << " for net logging"; | |
| 82 } else { | |
| 83 write_to_file_observer_.reset(new net::WriteToFileNetLogObserver()); | |
| 84 write_to_file_observer_->set_capture_mode( | |
| 85 net::NetLogCaptureMode::IncludeCookiesAndCredentials()); | |
| 86 write_to_file_observer_->StartObserving(this, std::move(file), nullptr, | |
| 87 nullptr); | |
| 88 } | |
| 89 } | |
| 90 | |
| 91 ~MojoNetLog() override { | |
| 92 if (write_to_file_observer_) | |
| 93 write_to_file_observer_->StopObserving(nullptr); | |
| 94 } | |
| 95 | |
| 96 private: | |
| 97 scoped_ptr<net::WriteToFileNetLogObserver> write_to_file_observer_; | |
| 98 | |
| 99 DISALLOW_COPY_AND_ASSIGN(MojoNetLog); | |
| 100 }; | |
| 101 | |
| 102 NetworkContext::NetworkContext( | |
| 103 scoped_ptr<net::URLRequestContext> url_request_context) | |
| 104 : net_log_(new MojoNetLog), | |
| 105 url_request_context_(std::move(url_request_context)), | |
| 106 in_shutdown_(false) { | |
| 107 url_request_context_->set_net_log(net_log_.get()); | |
| 108 } | |
| 109 | |
| 110 NetworkContext::NetworkContext( | |
| 111 const base::FilePath& base_path, | |
| 112 NetworkServiceDelegate* delegate) | |
| 113 : NetworkContext(MakeURLRequestContext(base_path, delegate)) { | |
| 114 } | |
| 115 | |
| 116 NetworkContext::~NetworkContext() { | |
| 117 in_shutdown_ = true; | |
| 118 // TODO(darin): Be careful about destruction order of member variables? | |
| 119 | |
| 120 // Call each URLLoaderImpl and ask it to release its net::URLRequest, as the | |
| 121 // corresponding net::URLRequestContext is going away with this | |
| 122 // NetworkContext. The loaders can be deregistering themselves in Cleanup(), | |
| 123 // so iterate over a copy. | |
| 124 for (auto& url_loader : url_loaders_) { | |
| 125 url_loader->Cleanup(); | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 void NetworkContext::RegisterURLLoader(URLLoaderImpl* url_loader) { | |
| 130 DCHECK(url_loaders_.count(url_loader) == 0); | |
| 131 url_loaders_.insert(url_loader); | |
| 132 } | |
| 133 | |
| 134 void NetworkContext::DeregisterURLLoader(URLLoaderImpl* url_loader) { | |
| 135 if (!in_shutdown_) { | |
| 136 size_t removed_count = url_loaders_.erase(url_loader); | |
| 137 DCHECK(removed_count); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 size_t NetworkContext::GetURLLoaderCountForTesting() { | |
| 142 return url_loaders_.size(); | |
| 143 } | |
| 144 | |
| 145 // static | |
| 146 scoped_ptr<net::URLRequestContext> NetworkContext::MakeURLRequestContext( | |
| 147 const base::FilePath& base_path, | |
| 148 NetworkServiceDelegate* delegate) { | |
| 149 net::URLRequestContextBuilder builder; | |
| 150 net::URLRequestContextBuilder::HttpNetworkSessionParams params; | |
| 151 const base::CommandLine* command_line = | |
| 152 base::CommandLine::ForCurrentProcess(); | |
| 153 if (command_line->HasSwitch(kIgnoreCertificateErrors)) | |
| 154 params.ignore_certificate_errors = true; | |
| 155 if (command_line->HasSwitch(kTestingFixedHttpPort)) { | |
| 156 params.testing_fixed_http_port = | |
| 157 GetPortNumber(*command_line, kTestingFixedHttpPort); | |
| 158 } | |
| 159 if (command_line->HasSwitch(kTestingFixedHttpsPort)) { | |
| 160 params.testing_fixed_https_port = | |
| 161 GetPortNumber(*command_line, kTestingFixedHttpsPort); | |
| 162 } | |
| 163 builder.set_http_network_session_params(params); | |
| 164 | |
| 165 if (command_line->HasSwitch(kHostResolverRules)) { | |
| 166 scoped_ptr<net::HostResolver> host_resolver( | |
| 167 net::HostResolver::CreateDefaultResolver(nullptr)); | |
| 168 scoped_ptr<net::MappedHostResolver> remapped_host_resolver( | |
| 169 new net::MappedHostResolver(std::move(host_resolver))); | |
| 170 remapped_host_resolver->SetRulesFromString( | |
| 171 command_line->GetSwitchValueASCII(kHostResolverRules)); | |
| 172 builder.set_host_resolver(std::move(remapped_host_resolver)); | |
| 173 } | |
| 174 | |
| 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); | |
| 179 | |
| 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 | |
| 192 | |
| 193 builder.EnableHttpCache(cache_params); | |
| 194 builder.set_file_enabled(true); | |
| 195 | |
| 196 return builder.Build(); | |
| 197 } | |
| 198 | |
| 199 } // namespace mojo | |
| OLD | NEW |