• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "components/cronet/android/url_request_context_adapter.h"
6 
7 #include "base/bind.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_builder.h"
22 #include "net/url_request/url_request_context_storage.h"
23 #include "net/url_request/url_request_job_factory_impl.h"
24 
25 namespace {
26 
27 class BasicNetworkDelegate : public net::NetworkDelegate {
28  public:
BasicNetworkDelegate()29   BasicNetworkDelegate() {}
~BasicNetworkDelegate()30   virtual ~BasicNetworkDelegate() {}
31 
32  private:
33   // net::NetworkDelegate implementation.
OnBeforeURLRequest(net::URLRequest * request,const net::CompletionCallback & callback,GURL * new_url)34   virtual int OnBeforeURLRequest(net::URLRequest* request,
35                                  const net::CompletionCallback& callback,
36                                  GURL* new_url) OVERRIDE {
37     return net::OK;
38   }
39 
OnBeforeSendHeaders(net::URLRequest * request,const net::CompletionCallback & callback,net::HttpRequestHeaders * headers)40   virtual int OnBeforeSendHeaders(net::URLRequest* request,
41                                   const net::CompletionCallback& callback,
42                                   net::HttpRequestHeaders* headers) OVERRIDE {
43     return net::OK;
44   }
45 
OnSendHeaders(net::URLRequest * request,const net::HttpRequestHeaders & headers)46   virtual void OnSendHeaders(net::URLRequest* request,
47                              const net::HttpRequestHeaders& headers) OVERRIDE {}
48 
OnHeadersReceived(net::URLRequest * request,const net::CompletionCallback & callback,const net::HttpResponseHeaders * original_response_headers,scoped_refptr<net::HttpResponseHeaders> * _response_headers,GURL * allowed_unsafe_redirect_url)49   virtual int OnHeadersReceived(
50       net::URLRequest* request,
51       const net::CompletionCallback& callback,
52       const net::HttpResponseHeaders* original_response_headers,
53       scoped_refptr<net::HttpResponseHeaders>* _response_headers,
54       GURL* allowed_unsafe_redirect_url) OVERRIDE {
55     return net::OK;
56   }
57 
OnBeforeRedirect(net::URLRequest * request,const GURL & new_location)58   virtual void OnBeforeRedirect(net::URLRequest* request,
59                                 const GURL& new_location) OVERRIDE {}
60 
OnResponseStarted(net::URLRequest * request)61   virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE {}
62 
OnRawBytesRead(const net::URLRequest & request,int bytes_read)63   virtual void OnRawBytesRead(const net::URLRequest& request,
64                               int bytes_read) OVERRIDE {}
65 
OnCompleted(net::URLRequest * request,bool started)66   virtual void OnCompleted(net::URLRequest* request, bool started) OVERRIDE {}
67 
OnURLRequestDestroyed(net::URLRequest * request)68   virtual void OnURLRequestDestroyed(net::URLRequest* request) OVERRIDE {}
69 
OnPACScriptError(int line_number,const base::string16 & error)70   virtual void OnPACScriptError(int line_number,
71                                 const base::string16& error) OVERRIDE {}
72 
OnAuthRequired(net::URLRequest * request,const net::AuthChallengeInfo & auth_info,const AuthCallback & callback,net::AuthCredentials * credentials)73   virtual NetworkDelegate::AuthRequiredResponse OnAuthRequired(
74       net::URLRequest* request,
75       const net::AuthChallengeInfo& auth_info,
76       const AuthCallback& callback,
77       net::AuthCredentials* credentials) OVERRIDE {
78     return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
79   }
80 
OnCanGetCookies(const net::URLRequest & request,const net::CookieList & cookie_list)81   virtual bool OnCanGetCookies(const net::URLRequest& request,
82                                const net::CookieList& cookie_list) OVERRIDE {
83     return false;
84   }
85 
OnCanSetCookie(const net::URLRequest & request,const std::string & cookie_line,net::CookieOptions * options)86   virtual bool OnCanSetCookie(const net::URLRequest& request,
87                               const std::string& cookie_line,
88                               net::CookieOptions* options) OVERRIDE {
89     return false;
90   }
91 
OnCanAccessFile(const net::URLRequest & request,const base::FilePath & path) const92   virtual bool OnCanAccessFile(const net::URLRequest& request,
93                                const base::FilePath& path) const OVERRIDE {
94     return false;
95   }
96 
OnCanThrottleRequest(const net::URLRequest & request) const97   virtual bool OnCanThrottleRequest(
98       const net::URLRequest& request) const OVERRIDE {
99     return false;
100   }
101 
OnBeforeSocketStreamConnect(net::SocketStream * stream,const net::CompletionCallback & callback)102   virtual int OnBeforeSocketStreamConnect(
103       net::SocketStream* stream,
104       const net::CompletionCallback& callback) OVERRIDE {
105     return net::OK;
106   }
107 
108   DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate);
109 };
110 
111 }  // namespace
112 
113 namespace cronet {
114 
URLRequestContextAdapter(URLRequestContextAdapterDelegate * delegate,std::string user_agent)115 URLRequestContextAdapter::URLRequestContextAdapter(
116     URLRequestContextAdapterDelegate* delegate,
117     std::string user_agent) {
118   delegate_ = delegate;
119   user_agent_ = user_agent;
120 }
121 
Initialize(scoped_ptr<URLRequestContextConfig> config)122 void URLRequestContextAdapter::Initialize(
123     scoped_ptr<URLRequestContextConfig> config) {
124   network_thread_ = new base::Thread("network");
125   base::Thread::Options options;
126   options.message_loop_type = base::MessageLoop::TYPE_IO;
127   network_thread_->StartWithOptions(options);
128 
129   GetNetworkTaskRunner()->PostTask(
130       FROM_HERE,
131       base::Bind(&URLRequestContextAdapter::InitializeURLRequestContext,
132                  this,
133                  Passed(&config)));
134 }
135 
InitializeURLRequestContext(scoped_ptr<URLRequestContextConfig> config)136 void URLRequestContextAdapter::InitializeURLRequestContext(
137     scoped_ptr<URLRequestContextConfig> config) {
138   // TODO(mmenke):  Add method to have the builder enable SPDY.
139   net::URLRequestContextBuilder context_builder;
140   context_builder.set_network_delegate(new BasicNetworkDelegate());
141   context_builder.set_proxy_config_service(
142       new net::ProxyConfigServiceFixed(net::ProxyConfig()));
143   config->ConfigureURLRequestContextBuilder(&context_builder);
144 
145   context_.reset(context_builder.Build());
146 
147   // Currently (circa M39) enabling QUIC requires setting probability threshold.
148   if (config->enable_quic) {
149     context_->http_server_properties()
150         ->SetAlternateProtocolProbabilityThreshold(0.0f);
151     for (size_t hint = 0; hint < config->quic_hints.size(); ++hint) {
152       const URLRequestContextConfig::QuicHint& quic_hint =
153           *config->quic_hints[hint];
154       if (quic_hint.host.empty()) {
155         LOG(ERROR) << "Empty QUIC hint host: " << quic_hint.host;
156         continue;
157       }
158 
159       if (quic_hint.port <= std::numeric_limits<uint16>::min() ||
160           quic_hint.port > std::numeric_limits<uint16>::max()) {
161         LOG(ERROR) << "Invalid QUIC hint port: "
162                    << quic_hint.port;
163         continue;
164       }
165 
166       if (quic_hint.alternate_port <= std::numeric_limits<uint16>::min() ||
167           quic_hint.alternate_port > std::numeric_limits<uint16>::max()) {
168         LOG(ERROR) << "Invalid QUIC hint alternate port: "
169                    << quic_hint.alternate_port;
170         continue;
171       }
172 
173       net::HostPortPair quic_hint_host_port_pair(quic_hint.host,
174                                                  quic_hint.port);
175       context_->http_server_properties()->SetAlternateProtocol(
176           quic_hint_host_port_pair,
177           static_cast<uint16>(quic_hint.alternate_port),
178           net::AlternateProtocol::QUIC,
179           1.0f);
180     }
181   }
182 
183   if (VLOG_IS_ON(2)) {
184     net_log_observer_.reset(new NetLogObserver());
185     context_->net_log()->AddThreadSafeObserver(net_log_observer_.get(),
186                                                net::NetLog::LOG_ALL_BUT_BYTES);
187   }
188 
189   delegate_->OnContextInitialized(this);
190 }
191 
~URLRequestContextAdapter()192 URLRequestContextAdapter::~URLRequestContextAdapter() {
193   if (net_log_observer_) {
194     context_->net_log()->RemoveThreadSafeObserver(net_log_observer_.get());
195     net_log_observer_.reset();
196   }
197   StopNetLog();
198   // TODO(mef): Ensure that |network_thread_| is destroyed properly.
199 }
200 
GetUserAgent(const GURL & url) const201 const std::string& URLRequestContextAdapter::GetUserAgent(
202     const GURL& url) const {
203   return user_agent_;
204 }
205 
GetURLRequestContext()206 net::URLRequestContext* URLRequestContextAdapter::GetURLRequestContext() {
207   if (!context_) {
208     LOG(ERROR) << "URLRequestContext is not set up";
209   }
210   return context_.get();
211 }
212 
213 scoped_refptr<base::SingleThreadTaskRunner>
GetNetworkTaskRunner() const214 URLRequestContextAdapter::GetNetworkTaskRunner() const {
215   return network_thread_->message_loop_proxy();
216 }
217 
StartNetLogToFile(const std::string & file_name)218 void URLRequestContextAdapter::StartNetLogToFile(const std::string& file_name) {
219   // Do nothing if already logging to a file.
220   if (net_log_logger_)
221     return;
222 
223   base::FilePath file_path(file_name);
224   FILE* file = base::OpenFile(file_path, "w");
225   if (!file)
226     return;
227 
228   scoped_ptr<base::Value> constants(net::NetLogLogger::GetConstants());
229   net_log_logger_.reset(new net::NetLogLogger(file, *constants));
230   net_log_logger_->StartObserving(context_->net_log());
231 }
232 
StopNetLog()233 void URLRequestContextAdapter::StopNetLog() {
234   if (net_log_logger_) {
235     net_log_logger_->StopObserving();
236     net_log_logger_.reset();
237   }
238 }
239 
OnAddEntry(const net::NetLog::Entry & entry)240 void NetLogObserver::OnAddEntry(const net::NetLog::Entry& entry) {
241   VLOG(2) << "Net log entry: type=" << entry.type()
242           << ", source=" << entry.source().type << ", phase=" << entry.phase();
243 }
244 
245 }  // namespace cronet
246