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 "components/cronet/android/cronet_url_request_context_adapter.h"
8 #include "base/files/file_util.h"
9 #include "base/single_thread_task_runner.h"
10 #include "components/cronet/url_request_context_config.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/net_log_logger.h"
13 #include "net/cert/cert_verifier.h"
14 #include "net/http/http_auth_handler_factory.h"
15 #include "net/http/http_network_layer.h"
16 #include "net/http/http_server_properties.h"
17 #include "net/proxy/proxy_config_service_fixed.h"
18 #include "net/proxy/proxy_service.h"
19 #include "net/ssl/ssl_config_service_defaults.h"
20 #include "net/url_request/static_http_user_agent_settings.h"
21 #include "net/url_request/url_request_context.h"
22 #include "net/url_request/url_request_context_builder.h"
23 #include "net/url_request/url_request_context_storage.h"
24 #include "net/url_request/url_request_job_factory_impl.h"
28 class BasicNetworkDelegate
: public net::NetworkDelegate
{
30 BasicNetworkDelegate() {}
31 virtual ~BasicNetworkDelegate() {}
34 // net::NetworkDelegate implementation.
35 int OnBeforeURLRequest(net::URLRequest
* request
,
36 const net::CompletionCallback
& callback
,
37 GURL
* new_url
) override
{
41 int OnBeforeSendHeaders(net::URLRequest
* request
,
42 const net::CompletionCallback
& callback
,
43 net::HttpRequestHeaders
* headers
) override
{
47 void OnSendHeaders(net::URLRequest
* request
,
48 const net::HttpRequestHeaders
& headers
) override
{}
50 int OnHeadersReceived(
51 net::URLRequest
* request
,
52 const net::CompletionCallback
& callback
,
53 const net::HttpResponseHeaders
* original_response_headers
,
54 scoped_refptr
<net::HttpResponseHeaders
>* _response_headers
,
55 GURL
* allowed_unsafe_redirect_url
) override
{
59 void OnBeforeRedirect(net::URLRequest
* request
,
60 const GURL
& new_location
) override
{}
62 void OnResponseStarted(net::URLRequest
* request
) override
{}
64 void OnRawBytesRead(const net::URLRequest
& request
, int bytes_read
) override
{
67 void OnCompleted(net::URLRequest
* request
, bool started
) override
{}
69 void OnURLRequestDestroyed(net::URLRequest
* request
) override
{}
71 void OnPACScriptError(int line_number
, const base::string16
& error
) override
{
74 NetworkDelegate::AuthRequiredResponse
OnAuthRequired(
75 net::URLRequest
* request
,
76 const net::AuthChallengeInfo
& auth_info
,
77 const AuthCallback
& callback
,
78 net::AuthCredentials
* credentials
) override
{
79 return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION
;
82 bool OnCanGetCookies(const net::URLRequest
& request
,
83 const net::CookieList
& cookie_list
) override
{
87 bool OnCanSetCookie(const net::URLRequest
& request
,
88 const std::string
& cookie_line
,
89 net::CookieOptions
* options
) override
{
93 bool OnCanAccessFile(const net::URLRequest
& request
,
94 const base::FilePath
& path
) const override
{
98 bool OnCanThrottleRequest(const net::URLRequest
& request
) const override
{
102 DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate
);
109 CronetURLRequestContextAdapter::CronetURLRequestContextAdapter() {
112 CronetURLRequestContextAdapter::~CronetURLRequestContextAdapter() {
113 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
114 StopNetLogOnNetworkThread();
117 void CronetURLRequestContextAdapter::Initialize(
118 scoped_ptr
<URLRequestContextConfig
> config
,
119 const base::Closure
& java_init_network_thread
) {
120 network_thread_
= new base::Thread("network");
121 base::Thread::Options options
;
122 options
.message_loop_type
= base::MessageLoop::TYPE_IO
;
123 network_thread_
->StartWithOptions(options
);
125 GetNetworkTaskRunner()->PostTask(
127 base::Bind(&CronetURLRequestContextAdapter::InitializeOnNetworkThread
,
128 base::Unretained(this),
130 java_init_network_thread
));
133 void CronetURLRequestContextAdapter::InitializeOnNetworkThread(
134 scoped_ptr
<URLRequestContextConfig
> config
,
135 const base::Closure
& java_init_network_thread
) {
136 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
137 // TODO(mmenke): Add method to have the builder enable SPDY.
138 net::URLRequestContextBuilder context_builder
;
139 context_builder
.set_network_delegate(new BasicNetworkDelegate());
140 context_builder
.set_proxy_config_service(
141 new net::ProxyConfigServiceFixed(net::ProxyConfig()));
142 config
->ConfigureURLRequestContextBuilder(&context_builder
);
144 context_
.reset(context_builder
.Build());
146 // Currently (circa M39) enabling QUIC requires setting probability threshold.
147 if (config
->enable_quic
) {
148 context_
->http_server_properties()
149 ->SetAlternateProtocolProbabilityThreshold(0.0f
);
150 for (auto hint
= config
->quic_hints
.begin();
151 hint
!= config
->quic_hints
.end(); ++hint
) {
152 const URLRequestContextConfig::QuicHint
& quic_hint
= **hint
;
153 if (quic_hint
.host
.empty()) {
154 LOG(ERROR
) << "Empty QUIC hint host: " << quic_hint
.host
;
158 url::CanonHostInfo host_info
;
159 std::string
canon_host(net::CanonicalizeHost(quic_hint
.host
, &host_info
));
160 if (!host_info
.IsIPAddress() &&
161 !net::IsCanonicalizedHostCompliant(canon_host
)) {
162 LOG(ERROR
) << "Invalid QUIC hint host: " << quic_hint
.host
;
166 if (quic_hint
.port
<= std::numeric_limits
<uint16
>::min() ||
167 quic_hint
.port
> std::numeric_limits
<uint16
>::max()) {
168 LOG(ERROR
) << "Invalid QUIC hint port: "
173 if (quic_hint
.alternate_port
<= std::numeric_limits
<uint16
>::min() ||
174 quic_hint
.alternate_port
> std::numeric_limits
<uint16
>::max()) {
175 LOG(ERROR
) << "Invalid QUIC hint alternate port: "
176 << quic_hint
.alternate_port
;
180 net::HostPortPair
quic_hint_host_port_pair(canon_host
,
182 context_
->http_server_properties()->SetAlternateProtocol(
183 quic_hint_host_port_pair
,
184 static_cast<uint16
>(quic_hint
.alternate_port
),
185 net::AlternateProtocol::QUIC
,
190 java_init_network_thread
.Run();
193 void CronetURLRequestContextAdapter::Destroy() {
194 DCHECK(!GetNetworkTaskRunner()->BelongsToCurrentThread());
195 // Stick network_thread_ in a local, as |this| may be destroyed from the
196 // network thread before delete network_thread is called.
197 base::Thread
* network_thread
= network_thread_
;
198 GetNetworkTaskRunner()->DeleteSoon(FROM_HERE
, this);
199 // Deleting thread stops it after all tasks are completed.
200 delete network_thread
;
203 net::URLRequestContext
* CronetURLRequestContextAdapter::GetURLRequestContext() {
205 LOG(ERROR
) << "URLRequestContext is not set up";
207 return context_
.get();
210 scoped_refptr
<base::SingleThreadTaskRunner
>
211 CronetURLRequestContextAdapter::GetNetworkTaskRunner() const {
212 return network_thread_
->task_runner();
215 void CronetURLRequestContextAdapter::StartNetLogToFile(
216 const std::string
& file_name
) {
217 GetNetworkTaskRunner()->PostTask(
220 &CronetURLRequestContextAdapter::StartNetLogToFileOnNetworkThread
,
221 base::Unretained(this),
225 void CronetURLRequestContextAdapter::StopNetLog() {
226 GetNetworkTaskRunner()->PostTask(
228 base::Bind(&CronetURLRequestContextAdapter::StopNetLogOnNetworkThread
,
229 base::Unretained(this)));
232 void CronetURLRequestContextAdapter::StartNetLogToFileOnNetworkThread(
233 const std::string
& file_name
) {
234 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
235 // Do nothing if already logging to a file.
239 base::FilePath
file_path(file_name
);
240 FILE* file
= base::OpenFile(file_path
, "w");
244 scoped_ptr
<base::Value
> constants(net::NetLogLogger::GetConstants());
245 net_log_logger_
.reset(new net::NetLogLogger(file
, *constants
));
246 net_log_logger_
->StartObserving(context_
->net_log());
249 void CronetURLRequestContextAdapter::StopNetLogOnNetworkThread() {
250 DCHECK(GetNetworkTaskRunner()->BelongsToCurrentThread());
251 if (net_log_logger_
) {
252 net_log_logger_
->StopObserving();
253 net_log_logger_
.reset();
257 } // namespace cronet