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: 29 BasicNetworkDelegate() {} 30 virtual ~BasicNetworkDelegate() {} 31 32 private: 33 // net::NetworkDelegate implementation. 34 virtual int OnBeforeURLRequest(net::URLRequest* request, 35 const net::CompletionCallback& callback, 36 GURL* new_url) OVERRIDE { 37 return net::OK; 38 } 39 40 virtual int OnBeforeSendHeaders(net::URLRequest* request, 41 const net::CompletionCallback& callback, 42 net::HttpRequestHeaders* headers) OVERRIDE { 43 return net::OK; 44 } 45 46 virtual void OnSendHeaders(net::URLRequest* request, 47 const net::HttpRequestHeaders& headers) OVERRIDE {} 48 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 58 virtual void OnBeforeRedirect(net::URLRequest* request, 59 const GURL& new_location) OVERRIDE {} 60 61 virtual void OnResponseStarted(net::URLRequest* request) OVERRIDE {} 62 63 virtual void OnRawBytesRead(const net::URLRequest& request, 64 int bytes_read) OVERRIDE {} 65 66 virtual void OnCompleted(net::URLRequest* request, bool started) OVERRIDE {} 67 68 virtual void OnURLRequestDestroyed(net::URLRequest* request) OVERRIDE {} 69 70 virtual void OnPACScriptError(int line_number, 71 const base::string16& error) OVERRIDE {} 72 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 81 virtual bool OnCanGetCookies(const net::URLRequest& request, 82 const net::CookieList& cookie_list) OVERRIDE { 83 return false; 84 } 85 86 virtual bool OnCanSetCookie(const net::URLRequest& request, 87 const std::string& cookie_line, 88 net::CookieOptions* options) OVERRIDE { 89 return false; 90 } 91 92 virtual bool OnCanAccessFile(const net::URLRequest& request, 93 const base::FilePath& path) const OVERRIDE { 94 return false; 95 } 96 97 virtual bool OnCanThrottleRequest( 98 const net::URLRequest& request) const OVERRIDE { 99 return false; 100 } 101 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 115 URLRequestContextAdapter::URLRequestContextAdapter( 116 URLRequestContextAdapterDelegate* delegate, 117 std::string user_agent) { 118 delegate_ = delegate; 119 user_agent_ = user_agent; 120 } 121 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 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 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 201 const std::string& URLRequestContextAdapter::GetUserAgent( 202 const GURL& url) const { 203 return user_agent_; 204 } 205 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> 214 URLRequestContextAdapter::GetNetworkTaskRunner() const { 215 return network_thread_->message_loop_proxy(); 216 } 217 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 233 void URLRequestContextAdapter::StopNetLog() { 234 if (net_log_logger_) { 235 net_log_logger_->StopObserving(); 236 net_log_logger_.reset(); 237 } 238 } 239 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