1 // Copyright (c) 2012 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 "net/url_request/url_request_context_builder.h" 6 7 #include <string> 8 9 #include "base/basictypes.h" 10 #include "base/compiler_specific.h" 11 #include "base/logging.h" 12 #include "base/strings/string_util.h" 13 #include "base/thread_task_runner_handle.h" 14 #include "base/threading/thread.h" 15 #include "net/base/cache_type.h" 16 #include "net/base/net_errors.h" 17 #include "net/base/network_delegate.h" 18 #include "net/cert/cert_verifier.h" 19 #include "net/cookies/cookie_monster.h" 20 #include "net/dns/host_resolver.h" 21 #include "net/ftp/ftp_network_layer.h" 22 #include "net/http/http_auth_handler_factory.h" 23 #include "net/http/http_cache.h" 24 #include "net/http/http_network_layer.h" 25 #include "net/http/http_network_session.h" 26 #include "net/http/http_server_properties_impl.h" 27 #include "net/http/transport_security_state.h" 28 #include "net/proxy/proxy_service.h" 29 #include "net/ssl/ssl_config_service_defaults.h" 30 #include "net/url_request/data_protocol_handler.h" 31 #include "net/url_request/file_protocol_handler.h" 32 #include "net/url_request/ftp_protocol_handler.h" 33 #include "net/url_request/static_http_user_agent_settings.h" 34 #include "net/url_request/url_request_context.h" 35 #include "net/url_request/url_request_context_storage.h" 36 #include "net/url_request/url_request_job_factory_impl.h" 37 38 namespace net { 39 40 namespace { 41 42 class BasicNetworkDelegate : public NetworkDelegate { 43 public: 44 BasicNetworkDelegate() {} 45 virtual ~BasicNetworkDelegate() {} 46 47 private: 48 virtual int OnBeforeURLRequest(URLRequest* request, 49 const CompletionCallback& callback, 50 GURL* new_url) OVERRIDE { 51 return OK; 52 } 53 54 virtual int OnBeforeSendHeaders(URLRequest* request, 55 const CompletionCallback& callback, 56 HttpRequestHeaders* headers) OVERRIDE { 57 return OK; 58 } 59 60 virtual void OnSendHeaders(URLRequest* request, 61 const HttpRequestHeaders& headers) OVERRIDE {} 62 63 virtual int OnHeadersReceived( 64 URLRequest* request, 65 const CompletionCallback& callback, 66 const HttpResponseHeaders* original_response_headers, 67 scoped_refptr<HttpResponseHeaders>* override_response_headers) 68 OVERRIDE { 69 return OK; 70 } 71 72 virtual void OnBeforeRedirect(URLRequest* request, 73 const GURL& new_location) OVERRIDE {} 74 75 virtual void OnResponseStarted(URLRequest* request) OVERRIDE {} 76 77 virtual void OnRawBytesRead(const URLRequest& request, 78 int bytes_read) OVERRIDE {} 79 80 virtual void OnCompleted(URLRequest* request, bool started) OVERRIDE {} 81 82 virtual void OnURLRequestDestroyed(URLRequest* request) OVERRIDE {} 83 84 virtual void OnPACScriptError(int line_number, 85 const base::string16& error) OVERRIDE {} 86 87 virtual NetworkDelegate::AuthRequiredResponse OnAuthRequired( 88 URLRequest* request, 89 const AuthChallengeInfo& auth_info, 90 const AuthCallback& callback, 91 AuthCredentials* credentials) OVERRIDE { 92 return NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION; 93 } 94 95 virtual bool OnCanGetCookies(const URLRequest& request, 96 const CookieList& cookie_list) OVERRIDE { 97 return true; 98 } 99 100 virtual bool OnCanSetCookie(const URLRequest& request, 101 const std::string& cookie_line, 102 CookieOptions* options) OVERRIDE { 103 return true; 104 } 105 106 virtual bool OnCanAccessFile(const net::URLRequest& request, 107 const base::FilePath& path) const OVERRIDE { 108 return true; 109 } 110 111 virtual bool OnCanThrottleRequest(const URLRequest& request) const OVERRIDE { 112 return false; 113 } 114 115 virtual int OnBeforeSocketStreamConnect( 116 SocketStream* stream, 117 const CompletionCallback& callback) OVERRIDE { 118 return OK; 119 } 120 121 virtual void OnRequestWaitStateChange(const URLRequest& request, 122 RequestWaitState state) OVERRIDE { 123 } 124 125 DISALLOW_COPY_AND_ASSIGN(BasicNetworkDelegate); 126 }; 127 128 class BasicURLRequestContext : public URLRequestContext { 129 public: 130 BasicURLRequestContext() 131 : cache_thread_("Cache Thread"), 132 file_thread_("File Thread"), 133 storage_(this) {} 134 135 URLRequestContextStorage* storage() { 136 return &storage_; 137 } 138 139 void StartCacheThread() { 140 cache_thread_.StartWithOptions( 141 base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); 142 } 143 144 scoped_refptr<base::MessageLoopProxy> cache_message_loop_proxy() { 145 DCHECK(cache_thread_.IsRunning()); 146 return cache_thread_.message_loop_proxy(); 147 } 148 149 void StartFileThread() { 150 file_thread_.StartWithOptions( 151 base::Thread::Options(base::MessageLoop::TYPE_DEFAULT, 0)); 152 } 153 154 base::MessageLoop* file_message_loop() { 155 DCHECK(file_thread_.IsRunning()); 156 return file_thread_.message_loop(); 157 } 158 159 scoped_refptr<base::MessageLoopProxy> file_message_loop_proxy() { 160 DCHECK(file_thread_.IsRunning()); 161 return file_thread_.message_loop_proxy(); 162 } 163 164 protected: 165 virtual ~BasicURLRequestContext() {} 166 167 private: 168 base::Thread cache_thread_; 169 base::Thread file_thread_; 170 URLRequestContextStorage storage_; 171 DISALLOW_COPY_AND_ASSIGN(BasicURLRequestContext); 172 }; 173 174 } // namespace 175 176 URLRequestContextBuilder::HttpCacheParams::HttpCacheParams() 177 : type(IN_MEMORY), 178 max_size(0) {} 179 URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() {} 180 181 URLRequestContextBuilder::HttpNetworkSessionParams::HttpNetworkSessionParams() 182 : ignore_certificate_errors(false), 183 host_mapping_rules(NULL), 184 http_pipelining_enabled(false), 185 testing_fixed_http_port(0), 186 testing_fixed_https_port(0), 187 trusted_spdy_proxy() {} 188 189 URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams() 190 {} 191 192 URLRequestContextBuilder::URLRequestContextBuilder() 193 : data_enabled_(false), 194 file_enabled_(false), 195 #if !defined(DISABLE_FTP_SUPPORT) 196 ftp_enabled_(false), 197 #endif 198 http_cache_enabled_(true) { 199 } 200 201 URLRequestContextBuilder::~URLRequestContextBuilder() {} 202 203 void URLRequestContextBuilder::set_proxy_config_service( 204 ProxyConfigService* proxy_config_service) { 205 proxy_config_service_.reset(proxy_config_service); 206 } 207 208 URLRequestContext* URLRequestContextBuilder::Build() { 209 BasicURLRequestContext* context = new BasicURLRequestContext; 210 URLRequestContextStorage* storage = context->storage(); 211 212 storage->set_http_user_agent_settings(new StaticHttpUserAgentSettings( 213 accept_language_, user_agent_)); 214 215 if (!network_delegate_) 216 network_delegate_.reset(new BasicNetworkDelegate); 217 NetworkDelegate* network_delegate = network_delegate_.release(); 218 storage->set_network_delegate(network_delegate); 219 220 if (!host_resolver_) 221 host_resolver_ = net::HostResolver::CreateDefaultResolver(NULL); 222 storage->set_host_resolver(host_resolver_.Pass()); 223 224 context->StartFileThread(); 225 226 // TODO(willchan): Switch to using this code when 227 // ProxyService::CreateSystemProxyConfigService()'s signature doesn't suck. 228 #if defined(OS_LINUX) || defined(OS_ANDROID) 229 ProxyConfigService* proxy_config_service = proxy_config_service_.release(); 230 #else 231 ProxyConfigService* proxy_config_service = NULL; 232 if (proxy_config_service_) { 233 proxy_config_service = proxy_config_service_.release(); 234 } else { 235 proxy_config_service = 236 ProxyService::CreateSystemProxyConfigService( 237 base::ThreadTaskRunnerHandle::Get().get(), 238 context->file_message_loop()); 239 } 240 #endif // defined(OS_LINUX) || defined(OS_ANDROID) 241 storage->set_proxy_service( 242 ProxyService::CreateUsingSystemProxyResolver( 243 proxy_config_service, 244 4, // TODO(willchan): Find a better constant somewhere. 245 context->net_log())); 246 storage->set_ssl_config_service(new net::SSLConfigServiceDefaults); 247 storage->set_http_auth_handler_factory( 248 net::HttpAuthHandlerRegistryFactory::CreateDefault( 249 context->host_resolver())); 250 storage->set_cookie_store(new CookieMonster(NULL, NULL)); 251 storage->set_transport_security_state(new net::TransportSecurityState()); 252 storage->set_http_server_properties( 253 scoped_ptr<net::HttpServerProperties>( 254 new net::HttpServerPropertiesImpl())); 255 storage->set_cert_verifier(CertVerifier::CreateDefault()); 256 257 net::HttpNetworkSession::Params network_session_params; 258 network_session_params.host_resolver = context->host_resolver(); 259 network_session_params.cert_verifier = context->cert_verifier(); 260 network_session_params.transport_security_state = 261 context->transport_security_state(); 262 network_session_params.proxy_service = context->proxy_service(); 263 network_session_params.ssl_config_service = 264 context->ssl_config_service(); 265 network_session_params.http_auth_handler_factory = 266 context->http_auth_handler_factory(); 267 network_session_params.network_delegate = network_delegate; 268 network_session_params.http_server_properties = 269 context->http_server_properties(); 270 network_session_params.net_log = context->net_log(); 271 network_session_params.ignore_certificate_errors = 272 http_network_session_params_.ignore_certificate_errors; 273 network_session_params.host_mapping_rules = 274 http_network_session_params_.host_mapping_rules; 275 network_session_params.http_pipelining_enabled = 276 http_network_session_params_.http_pipelining_enabled; 277 network_session_params.testing_fixed_http_port = 278 http_network_session_params_.testing_fixed_http_port; 279 network_session_params.testing_fixed_https_port = 280 http_network_session_params_.testing_fixed_https_port; 281 network_session_params.trusted_spdy_proxy = 282 http_network_session_params_.trusted_spdy_proxy; 283 284 HttpTransactionFactory* http_transaction_factory = NULL; 285 if (http_cache_enabled_) { 286 network_session_params.server_bound_cert_service = 287 context->server_bound_cert_service(); 288 HttpCache::BackendFactory* http_cache_backend = NULL; 289 if (http_cache_params_.type == HttpCacheParams::DISK) { 290 context->StartCacheThread(); 291 http_cache_backend = new HttpCache::DefaultBackend( 292 DISK_CACHE, 293 net::CACHE_BACKEND_DEFAULT, 294 http_cache_params_.path, 295 http_cache_params_.max_size, 296 context->cache_message_loop_proxy().get()); 297 } else { 298 http_cache_backend = 299 HttpCache::DefaultBackend::InMemory(http_cache_params_.max_size); 300 } 301 302 http_transaction_factory = new HttpCache( 303 network_session_params, http_cache_backend); 304 } else { 305 scoped_refptr<net::HttpNetworkSession> network_session( 306 new net::HttpNetworkSession(network_session_params)); 307 308 http_transaction_factory = new HttpNetworkLayer(network_session.get()); 309 } 310 storage->set_http_transaction_factory(http_transaction_factory); 311 312 URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl; 313 if (data_enabled_) 314 job_factory->SetProtocolHandler("data", new DataProtocolHandler); 315 if (file_enabled_) 316 job_factory->SetProtocolHandler( 317 "file", new FileProtocolHandler(context->file_message_loop_proxy())); 318 #if !defined(DISABLE_FTP_SUPPORT) 319 if (ftp_enabled_) { 320 ftp_transaction_factory_.reset( 321 new FtpNetworkLayer(context->host_resolver())); 322 job_factory->SetProtocolHandler("ftp", 323 new FtpProtocolHandler(ftp_transaction_factory_.get())); 324 } 325 #endif 326 storage->set_job_factory(job_factory); 327 328 // TODO(willchan): Support sdch. 329 330 return context; 331 } 332 333 } // namespace net 334