blob: cb24f8d0cb066b1db5b19dd29f4da1a13dd11631 [file] [log] [blame]
[email protected]9105e262014-03-14 16:45:321// 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
[email protected]fa5f4742014-08-08 21:36:195#include "components/cronet/android/url_request_context_adapter.h"
[email protected]9105e262014-03-14 16:45:326
xunjieli926338d2014-10-15 15:38:407#include <limits>
8
[email protected]94de3e02014-06-17 00:09:519#include "base/bind.h"
thestig819adcc82014-09-10 22:24:5310#include "base/files/file_util.h"
mmenke853ed15d2015-03-16 17:38:4911#include "base/files/scoped_file.h"
xunjieli0b21f8f2014-10-17 12:58:2812#include "base/message_loop/message_loop.h"
[email protected]94de3e02014-06-17 00:09:5113#include "base/single_thread_task_runner.h"
14#include "components/cronet/url_request_context_config.h"
xunjieli071779c2014-10-28 20:07:5115#include "net/android/network_change_notifier_factory_android.h"
[email protected]9105e262014-03-14 16:45:3216#include "net/base/net_errors.h"
meff9376042014-10-20 22:42:1217#include "net/base/net_util.h"
xunjieli071779c2014-10-28 20:07:5118#include "net/base/network_change_notifier.h"
megjablonc1751452014-12-09 19:46:4719#include "net/base/network_delegate_impl.h"
[email protected]9105e262014-03-14 16:45:3220#include "net/cert/cert_verifier.h"
21#include "net/http/http_auth_handler_factory.h"
22#include "net/http/http_network_layer.h"
mefc71361c2014-09-16 14:48:5623#include "net/http/http_server_properties.h"
vishal.b62985ca92015-04-17 08:45:5124#include "net/log/write_to_file_net_log_observer.h"
[email protected]9105e262014-03-14 16:45:3225#include "net/proxy/proxy_service.h"
xunjielib8a6d56f2015-04-29 17:36:1426#include "net/sdch/sdch_owner.h"
[email protected]9105e262014-03-14 16:45:3227#include "net/ssl/ssl_config_service_defaults.h"
28#include "net/url_request/static_http_user_agent_settings.h"
[email protected]c7b1ddc72014-04-18 19:09:4329#include "net/url_request/url_request_context_builder.h"
[email protected]9105e262014-03-14 16:45:3230#include "net/url_request/url_request_context_storage.h"
31#include "net/url_request/url_request_job_factory_impl.h"
32
33namespace {
34
megjablonc1751452014-12-09 19:46:4735class BasicNetworkDelegate : public net::NetworkDelegateImpl {
[email protected]9105e262014-03-14 16:45:3236 public:
37 BasicNetworkDelegate() {}
dchenge27b1ef2015-02-04 23:34:1138 ~BasicNetworkDelegate() override {}
[email protected]9105e262014-03-14 16:45:3239
40 private:
41 // net::NetworkDelegate implementation.
xunjieli926338d2014-10-15 15:38:4042 int OnBeforeURLRequest(net::URLRequest* request,
43 const net::CompletionCallback& callback,
44 GURL* new_url) override {
[email protected]9105e262014-03-14 16:45:3245 return net::OK;
46 }
47
xunjieli926338d2014-10-15 15:38:4048 int OnBeforeSendHeaders(net::URLRequest* request,
49 const net::CompletionCallback& callback,
50 net::HttpRequestHeaders* headers) override {
[email protected]9105e262014-03-14 16:45:3251 return net::OK;
52 }
53
xunjieli926338d2014-10-15 15:38:4054 void OnSendHeaders(net::URLRequest* request,
55 const net::HttpRequestHeaders& headers) override {}
[email protected]9105e262014-03-14 16:45:3256
xunjieli926338d2014-10-15 15:38:4057 int OnHeadersReceived(
[email protected]9105e262014-03-14 16:45:3258 net::URLRequest* request,
59 const net::CompletionCallback& callback,
60 const net::HttpResponseHeaders* original_response_headers,
[email protected]5f714132014-03-26 10:41:1661 scoped_refptr<net::HttpResponseHeaders>* _response_headers,
mostynbfe59f482014-10-06 15:04:4662 GURL* allowed_unsafe_redirect_url) override {
[email protected]9105e262014-03-14 16:45:3263 return net::OK;
64 }
65
xunjieli926338d2014-10-15 15:38:4066 void OnBeforeRedirect(net::URLRequest* request,
67 const GURL& new_location) override {}
[email protected]9105e262014-03-14 16:45:3268
xunjieli926338d2014-10-15 15:38:4069 void OnResponseStarted(net::URLRequest* request) override {}
[email protected]9105e262014-03-14 16:45:3270
xunjieli926338d2014-10-15 15:38:4071 void OnRawBytesRead(const net::URLRequest& request,
72 int bytes_read) override {}
[email protected]9105e262014-03-14 16:45:3273
xunjieli926338d2014-10-15 15:38:4074 void OnCompleted(net::URLRequest* request, bool started) override {}
[email protected]9105e262014-03-14 16:45:3275
xunjieli926338d2014-10-15 15:38:4076 void OnURLRequestDestroyed(net::URLRequest* request) override {}
[email protected]9105e262014-03-14 16:45:3277
xunjieli926338d2014-10-15 15:38:4078 void OnPACScriptError(int line_number,
79 const base::string16& error) override {}
[email protected]9105e262014-03-14 16:45:3280
xunjieli926338d2014-10-15 15:38:4081 NetworkDelegate::AuthRequiredResponse OnAuthRequired(
[email protected]9105e262014-03-14 16:45:3282 net::URLRequest* request,
83 const net::AuthChallengeInfo& auth_info,
84 const AuthCallback& callback,
mostynbfe59f482014-10-06 15:04:4685 net::AuthCredentials* credentials) override {
[email protected]9105e262014-03-14 16:45:3286 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
87 }
88
xunjieli926338d2014-10-15 15:38:4089 bool OnCanGetCookies(const net::URLRequest& request,
90 const net::CookieList& cookie_list) override {
[email protected]9105e262014-03-14 16:45:3291 return false;
92 }
93
xunjieli926338d2014-10-15 15:38:4094 bool OnCanSetCookie(const net::URLRequest& request,
95 const std::string& cookie_line,
96 net::CookieOptions* options) override {
[email protected]9105e262014-03-14 16:45:3297 return false;
98 }
99
xunjieli926338d2014-10-15 15:38:40100 bool OnCanAccessFile(const net::URLRequest& request,
101 const base::FilePath& path) const override {
[email protected]9105e262014-03-14 16:45:32102 return false;
103 }
104
xunjieli926338d2014-10-15 15:38:40105 bool OnCanThrottleRequest(
mostynbfe59f482014-10-06 15:04:46106 const net::URLRequest& request) const override {
[email protected]9105e262014-03-14 16:45:32107 return false;
108 }
109
[email protected]9105e262014-03-14 16:45:32110 DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
111};
112
[email protected]9105e262014-03-14 16:45:32113} // namespace
114
[email protected]f478a9602014-04-23 01:48:08115namespace cronet {
116
[email protected]fa5f4742014-08-08 21:36:19117URLRequestContextAdapter::URLRequestContextAdapter(
118 URLRequestContextAdapterDelegate* delegate,
mefbb4f45c2015-01-12 18:03:25119 std::string user_agent)
120 : load_disable_cache_(true),
121 is_context_initialized_(false) {
[email protected]9105e262014-03-14 16:45:32122 delegate_ = delegate;
123 user_agent_ = user_agent;
[email protected]9105e262014-03-14 16:45:32124}
125
[email protected]fa5f4742014-08-08 21:36:19126void URLRequestContextAdapter::Initialize(
[email protected]94de3e02014-06-17 00:09:51127 scoped_ptr<URLRequestContextConfig> config) {
[email protected]9105e262014-03-14 16:45:32128 network_thread_ = new base::Thread("network");
129 base::Thread::Options options;
130 options.message_loop_type = base::MessageLoop::TYPE_IO;
131 network_thread_->StartWithOptions(options);
xunjieli0b21f8f2014-10-17 12:58:28132 config_ = config.Pass();
[email protected]9105e262014-03-14 16:45:32133}
134
xunjieli0b21f8f2014-10-17 12:58:28135void URLRequestContextAdapter::InitRequestContextOnMainThread() {
xunjieli0b21f8f2014-10-17 12:58:28136 proxy_config_service_.reset(net::ProxyService::CreateSystemProxyConfigService(
137 GetNetworkTaskRunner(), NULL));
138 GetNetworkTaskRunner()->PostTask(
139 FROM_HERE,
140 base::Bind(&URLRequestContextAdapter::InitRequestContextOnNetworkThread,
141 this));
142}
143
144void URLRequestContextAdapter::InitRequestContextOnNetworkThread() {
xunjielibe3c72f2014-10-10 18:29:07145 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
xunjieli0b21f8f2014-10-17 12:58:28146 DCHECK(config_);
[email protected]d7599122014-05-24 03:37:23147 // TODO(mmenke): Add method to have the builder enable SPDY.
[email protected]c7b1ddc72014-04-18 19:09:43148 net::URLRequestContextBuilder context_builder;
149 context_builder.set_network_delegate(new BasicNetworkDelegate());
xunjieli0b21f8f2014-10-17 12:58:28150 context_builder.set_proxy_config_service(proxy_config_service_.get());
151 config_->ConfigureURLRequestContextBuilder(&context_builder);
[email protected]9105e262014-03-14 16:45:32152
[email protected]c7b1ddc72014-04-18 19:09:43153 context_.reset(context_builder.Build());
[email protected]9105e262014-03-14 16:45:32154
xunjielib8a6d56f2015-04-29 17:36:14155 if (config_->enable_sdch) {
156 DCHECK(context_->sdch_manager());
157 sdch_owner_.reset(
158 new net::SdchOwner(context_->sdch_manager(), context_.get()));
159 }
160
mefc71361c2014-09-16 14:48:56161 // Currently (circa M39) enabling QUIC requires setting probability threshold.
xunjieli0b21f8f2014-10-17 12:58:28162 if (config_->enable_quic) {
mefc71361c2014-09-16 14:48:56163 context_->http_server_properties()
bnc62891a52015-04-27 14:14:12164 ->SetAlternativeServiceProbabilityThreshold(0.0f);
xunjieli0b21f8f2014-10-17 12:58:28165 for (size_t hint = 0; hint < config_->quic_hints.size(); ++hint) {
mefc71361c2014-09-16 14:48:56166 const URLRequestContextConfig::QuicHint& quic_hint =
xunjieli0b21f8f2014-10-17 12:58:28167 *config_->quic_hints[hint];
mefc71361c2014-09-16 14:48:56168 if (quic_hint.host.empty()) {
169 LOG(ERROR) << "Empty QUIC hint host: " << quic_hint.host;
170 continue;
171 }
172
meff9376042014-10-20 22:42:12173 url::CanonHostInfo host_info;
174 std::string canon_host(net::CanonicalizeHost(quic_hint.host, &host_info));
175 if (!host_info.IsIPAddress() &&
176 !net::IsCanonicalizedHostCompliant(canon_host)) {
177 LOG(ERROR) << "Invalid QUIC hint host: " << quic_hint.host;
178 continue;
179 }
180
mefc71361c2014-09-16 14:48:56181 if (quic_hint.port <= std::numeric_limits<uint16>::min() ||
182 quic_hint.port > std::numeric_limits<uint16>::max()) {
183 LOG(ERROR) << "Invalid QUIC hint port: "
184 << quic_hint.port;
185 continue;
186 }
187
188 if (quic_hint.alternate_port <= std::numeric_limits<uint16>::min() ||
189 quic_hint.alternate_port > std::numeric_limits<uint16>::max()) {
190 LOG(ERROR) << "Invalid QUIC hint alternate port: "
191 << quic_hint.alternate_port;
192 continue;
193 }
194
meff9376042014-10-20 22:42:12195 net::HostPortPair quic_hint_host_port_pair(canon_host,
mefc71361c2014-09-16 14:48:56196 quic_hint.port);
bnccacc0992015-03-20 20:22:22197 net::AlternativeService alternative_service(
198 net::AlternateProtocol::QUIC, "",
199 static_cast<uint16>(quic_hint.alternate_port));
200 context_->http_server_properties()->SetAlternativeService(
201 quic_hint_host_port_pair, alternative_service, 1.0f);
mefc71361c2014-09-16 14:48:56202 }
203 }
mefbb4f45c2015-01-12 18:03:25204 load_disable_cache_ = config_->load_disable_cache;
xunjieli0b21f8f2014-10-17 12:58:28205 config_.reset(NULL);
mefc71361c2014-09-16 14:48:56206
[email protected]9105e262014-03-14 16:45:32207 if (VLOG_IS_ON(2)) {
[email protected]f3b1c762014-08-07 17:07:20208 net_log_observer_.reset(new NetLogObserver());
eroman001c3742015-04-23 03:11:17209 context_->net_log()->DeprecatedAddObserver(
210 net_log_observer_.get(),
211 net::NetLogCaptureMode::IncludeCookiesAndCredentials());
[email protected]9105e262014-03-14 16:45:32212 }
213
xunjieli0b21f8f2014-10-17 12:58:28214 is_context_initialized_ = true;
215 while (!tasks_waiting_for_context_.empty()) {
216 tasks_waiting_for_context_.front().Run();
217 tasks_waiting_for_context_.pop();
218 }
219
[email protected]9105e262014-03-14 16:45:32220 delegate_->OnContextInitialized(this);
221}
222
xunjielibe3c72f2014-10-10 18:29:07223void URLRequestContextAdapter::PostTaskToNetworkThread(
224 const tracked_objects::Location& posted_from,
225 const RunAfterContextInitTask& callback) {
226 GetNetworkTaskRunner()->PostTask(
227 posted_from,
228 base::Bind(
229 &URLRequestContextAdapter::RunTaskAfterContextInitOnNetworkThread,
230 this,
231 callback));
232}
233
234void URLRequestContextAdapter::RunTaskAfterContextInitOnNetworkThread(
235 const RunAfterContextInitTask& callback) {
236 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
237 if (is_context_initialized_) {
238 callback.Run();
239 return;
240 }
241 tasks_waiting_for_context_.push(callback);
242}
243
[email protected]fa5f4742014-08-08 21:36:19244URLRequestContextAdapter::~URLRequestContextAdapter() {
xunjielibe3c72f2014-10-10 18:29:07245 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
[email protected]9afe8912014-04-09 16:57:25246 if (net_log_observer_) {
eromanbc4e5fe2015-04-03 17:41:34247 context_->net_log()->DeprecatedRemoveObserver(net_log_observer_.get());
[email protected]9afe8912014-04-09 16:57:25248 net_log_observer_.reset();
249 }
xunjielibe3c72f2014-10-10 18:29:07250 StopNetLogHelper();
[email protected]94de3e02014-06-17 00:09:51251 // TODO(mef): Ensure that |network_thread_| is destroyed properly.
[email protected]9afe8912014-04-09 16:57:25252}
[email protected]9105e262014-03-14 16:45:32253
[email protected]fa5f4742014-08-08 21:36:19254const std::string& URLRequestContextAdapter::GetUserAgent(
255 const GURL& url) const {
[email protected]9105e262014-03-14 16:45:32256 return user_agent_;
257}
258
[email protected]fa5f4742014-08-08 21:36:19259net::URLRequestContext* URLRequestContextAdapter::GetURLRequestContext() {
xunjielibe3c72f2014-10-10 18:29:07260 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
[email protected]9105e262014-03-14 16:45:32261 if (!context_) {
262 LOG(ERROR) << "URLRequestContext is not set up";
263 }
264 return context_.get();
265}
266
267scoped_refptr<base::SingleThreadTaskRunner>
[email protected]fa5f4742014-08-08 21:36:19268URLRequestContextAdapter::GetNetworkTaskRunner() const {
skyostilb0daa012015-06-02 19:03:48269 return network_thread_->task_runner();
[email protected]9105e262014-03-14 16:45:32270}
271
kallasjoki9f27db62015-05-07 16:06:00272void URLRequestContextAdapter::StartNetLogToFile(const std::string& file_name,
273 bool log_all) {
xunjielibe3c72f2014-10-10 18:29:07274 PostTaskToNetworkThread(
275 FROM_HERE,
kallasjoki9f27db62015-05-07 16:06:00276 base::Bind(&URLRequestContextAdapter::StartNetLogToFileHelper, this,
277 file_name, log_all));
xunjielibe3c72f2014-10-10 18:29:07278}
279
280void URLRequestContextAdapter::StopNetLog() {
281 PostTaskToNetworkThread(
282 FROM_HERE, base::Bind(&URLRequestContextAdapter::StopNetLogHelper, this));
283}
284
285void URLRequestContextAdapter::StartNetLogToFileHelper(
kallasjoki9f27db62015-05-07 16:06:00286 const std::string& file_name, bool log_all) {
xunjielibe3c72f2014-10-10 18:29:07287 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
[email protected]9afe8912014-04-09 16:57:25288 // Do nothing if already logging to a file.
vishal.b94fed102015-04-23 13:10:41289 if (write_to_file_observer_)
[email protected]9afe8912014-04-09 16:57:25290 return;
291
292 base::FilePath file_path(file_name);
mmenke853ed15d2015-03-16 17:38:49293 base::ScopedFILE file(base::OpenFile(file_path, "w"));
[email protected]9afe8912014-04-09 16:57:25294 if (!file)
295 return;
296
vishal.b94fed102015-04-23 13:10:41297 write_to_file_observer_.reset(new net::WriteToFileNetLogObserver());
kallasjoki9f27db62015-05-07 16:06:00298 if (log_all) {
299 write_to_file_observer_->set_capture_mode(
300 net::NetLogCaptureMode::IncludeSocketBytes());
301 }
vishal.b94fed102015-04-23 13:10:41302 write_to_file_observer_->StartObserving(context_->net_log(), file.Pass(),
303 nullptr, context_.get());
[email protected]9afe8912014-04-09 16:57:25304}
305
xunjielibe3c72f2014-10-10 18:29:07306void URLRequestContextAdapter::StopNetLogHelper() {
307 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
vishal.b94fed102015-04-23 13:10:41308 if (write_to_file_observer_) {
309 write_to_file_observer_->StopObserving(context_.get());
310 write_to_file_observer_.reset();
[email protected]9afe8912014-04-09 16:57:25311 }
312}
313
[email protected]9105e262014-03-14 16:45:32314void NetLogObserver::OnAddEntry(const net::NetLog::Entry& entry) {
[email protected]f3b1c762014-08-07 17:07:20315 VLOG(2) << "Net log entry: type=" << entry.type()
[email protected]fa5f4742014-08-08 21:36:19316 << ", source=" << entry.source().type << ", phase=" << entry.phase();
[email protected]9105e262014-03-14 16:45:32317}
[email protected]f478a9602014-04-23 01:48:08318
319} // namespace cronet