aw_url_request_context_getter.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 "android_webview/browser/net/aw_url_request_context_getter.h" 6 7#include <vector> 8 9#include "android_webview/browser/aw_browser_context.h" 10#include "android_webview/browser/aw_content_browser_client.h" 11#include "android_webview/browser/aw_request_interceptor.h" 12#include "android_webview/browser/net/aw_network_delegate.h" 13#include "android_webview/browser/net/aw_url_request_job_factory.h" 14#include "android_webview/browser/net/init_native_callback.h" 15#include "android_webview/common/aw_content_client.h" 16#include "base/command_line.h" 17#include "base/strings/string_number_conversions.h" 18#include "base/threading/sequenced_worker_pool.h" 19#include "components/data_reduction_proxy/browser/data_reduction_proxy_config_service.h" 20#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h" 21#include "components/data_reduction_proxy/browser/http_auth_handler_data_reduction_proxy.h" 22#include "content/public/browser/browser_thread.h" 23#include "content/public/browser/content_browser_client.h" 24#include "content/public/browser/cookie_store_factory.h" 25#include "content/public/common/content_client.h" 26#include "content/public/common/content_switches.h" 27#include "content/public/common/url_constants.h" 28#include "net/base/cache_type.h" 29#include "net/cookies/cookie_store.h" 30#include "net/dns/mapped_host_resolver.h" 31#include "net/http/http_cache.h" 32#include "net/http/http_stream_factory.h" 33#include "net/proxy/proxy_service.h" 34#include "net/socket/next_proto.h" 35#include "net/url_request/data_protocol_handler.h" 36#include "net/url_request/file_protocol_handler.h" 37#include "net/url_request/url_request_context_builder.h" 38#include "net/url_request/url_request_context.h" 39#include "net/url_request/url_request_intercepting_job_factory.h" 40#include "net/url_request/url_request_interceptor.h" 41 42using content::BrowserThread; 43using data_reduction_proxy::DataReductionProxySettings; 44 45namespace android_webview { 46 47 48namespace { 49 50void ApplyCmdlineOverridesToURLRequestContextBuilder( 51 net::URLRequestContextBuilder* builder) { 52 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 53 if (command_line.HasSwitch(switches::kHostResolverRules)) { 54 // If hostname remappings were specified on the command-line, layer these 55 // rules on top of the real host resolver. This allows forwarding all 56 // requests through a designated test server. 57 scoped_ptr<net::MappedHostResolver> host_resolver( 58 new net::MappedHostResolver( 59 net::HostResolver::CreateDefaultResolver(NULL))); 60 host_resolver->SetRulesFromString( 61 command_line.GetSwitchValueASCII(switches::kHostResolverRules)); 62 builder->set_host_resolver(host_resolver.release()); 63 } 64} 65 66void ApplyCmdlineOverridesToNetworkSessionParams( 67 net::HttpNetworkSession::Params* params) { 68 int value; 69 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 70 if (command_line.HasSwitch(switches::kTestingFixedHttpPort)) { 71 base::StringToInt(command_line.GetSwitchValueASCII( 72 switches::kTestingFixedHttpPort), &value); 73 params->testing_fixed_http_port = value; 74 } 75 if (command_line.HasSwitch(switches::kTestingFixedHttpsPort)) { 76 base::StringToInt(command_line.GetSwitchValueASCII( 77 switches::kTestingFixedHttpsPort), &value); 78 params->testing_fixed_https_port = value; 79 } 80} 81 82void PopulateNetworkSessionParams( 83 net::URLRequestContext* context, 84 net::HttpNetworkSession::Params* params) { 85 params->host_resolver = context->host_resolver(); 86 params->cert_verifier = context->cert_verifier(); 87 params->server_bound_cert_service = context->server_bound_cert_service(); 88 params->transport_security_state = context->transport_security_state(); 89 params->proxy_service = context->proxy_service(); 90 params->ssl_config_service = context->ssl_config_service(); 91 params->http_auth_handler_factory = context->http_auth_handler_factory(); 92 params->network_delegate = context->network_delegate(); 93 params->http_server_properties = context->http_server_properties(); 94 params->net_log = context->net_log(); 95 96 // TODO(sgurun) remove once crbug.com/329681 is fixed. 97 params->next_protos = net::NextProtosSpdy31(); 98 params->use_alternate_protocols = true; 99 100 ApplyCmdlineOverridesToNetworkSessionParams(params); 101} 102 103scoped_ptr<net::URLRequestJobFactory> CreateJobFactory( 104 content::ProtocolHandlerMap* protocol_handlers) { 105 scoped_ptr<AwURLRequestJobFactory> aw_job_factory(new AwURLRequestJobFactory); 106 bool set_protocol = aw_job_factory->SetProtocolHandler( 107 url::kFileScheme, 108 new net::FileProtocolHandler( 109 content::BrowserThread::GetBlockingPool()-> 110 GetTaskRunnerWithShutdownBehavior( 111 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))); 112 DCHECK(set_protocol); 113 set_protocol = aw_job_factory->SetProtocolHandler( 114 url::kDataScheme, new net::DataProtocolHandler()); 115 DCHECK(set_protocol); 116 set_protocol = aw_job_factory->SetProtocolHandler( 117 url::kBlobScheme, 118 (*protocol_handlers)[url::kBlobScheme].release()); 119 DCHECK(set_protocol); 120 set_protocol = aw_job_factory->SetProtocolHandler( 121 url::kFileSystemScheme, 122 (*protocol_handlers)[url::kFileSystemScheme].release()); 123 DCHECK(set_protocol); 124 set_protocol = aw_job_factory->SetProtocolHandler( 125 content::kChromeUIScheme, 126 (*protocol_handlers)[content::kChromeUIScheme].release()); 127 DCHECK(set_protocol); 128 set_protocol = aw_job_factory->SetProtocolHandler( 129 content::kChromeDevToolsScheme, 130 (*protocol_handlers)[content::kChromeDevToolsScheme].release()); 131 DCHECK(set_protocol); 132 protocol_handlers->clear(); 133 134 // Create a chain of URLRequestJobFactories. The handlers will be invoked 135 // in the order in which they appear in the |request_interceptors| vector. 136 typedef std::vector<net::URLRequestInterceptor*> 137 URLRequestInterceptorVector; 138 URLRequestInterceptorVector request_interceptors; 139 140 // Note that even though the content:// scheme handler is created here, 141 // it cannot be used by child processes until access to it is granted via 142 // ChildProcessSecurityPolicy::GrantScheme(). This is done in 143 // AwContentBrowserClient. 144 request_interceptors.push_back( 145 CreateAndroidContentRequestInterceptor().release()); 146 request_interceptors.push_back( 147 CreateAndroidAssetFileRequestInterceptor().release()); 148 // The AwRequestInterceptor must come after the content and asset file job 149 // factories. This for WebViewClassic compatibility where it was not 150 // possible to intercept resource loads to resolvable content:// and 151 // file:// URIs. 152 // This logical dependency is also the reason why the Content 153 // URLRequestInterceptor has to be added as an interceptor rather than as a 154 // ProtocolHandler. 155 request_interceptors.push_back(new AwRequestInterceptor()); 156 157 // The chain of responsibility will execute the handlers in reverse to the 158 // order in which the elements of the chain are created. 159 scoped_ptr<net::URLRequestJobFactory> job_factory(aw_job_factory.Pass()); 160 for (URLRequestInterceptorVector::reverse_iterator 161 i = request_interceptors.rbegin(); 162 i != request_interceptors.rend(); 163 ++i) { 164 job_factory.reset(new net::URLRequestInterceptingJobFactory( 165 job_factory.Pass(), make_scoped_ptr(*i))); 166 } 167 168 return job_factory.Pass(); 169} 170 171} // namespace 172 173AwURLRequestContextGetter::AwURLRequestContextGetter( 174 const base::FilePath& partition_path, net::CookieStore* cookie_store) 175 : partition_path_(partition_path), 176 cookie_store_(cookie_store), 177 proxy_config_service_(new DataReductionProxyConfigService( 178 scoped_ptr<net::ProxyConfigService>( 179 net::ProxyService::CreateSystemProxyConfigService( 180 GetNetworkTaskRunner(), 181 NULL /* Ignored on Android */)).Pass())) { 182 // CreateSystemProxyConfigService for Android must be called on main thread. 183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 184} 185 186AwURLRequestContextGetter::~AwURLRequestContextGetter() { 187} 188 189void AwURLRequestContextGetter::InitializeURLRequestContext() { 190 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 191 DCHECK(!url_request_context_); 192 193 net::URLRequestContextBuilder builder; 194 builder.set_user_agent(GetUserAgent()); 195 builder.set_network_delegate(new AwNetworkDelegate()); 196#if !defined(DISABLE_FTP_SUPPORT) 197 builder.set_ftp_enabled(false); // Android WebView does not support ftp yet. 198#endif 199 builder.set_proxy_config_service(proxy_config_service_.release()); 200 builder.set_accept_language(net::HttpUtil::GenerateAcceptLanguageHeader( 201 AwContentBrowserClient::GetAcceptLangsImpl())); 202 ApplyCmdlineOverridesToURLRequestContextBuilder(&builder); 203 204 205 builder.add_http_auth_handler_factory( 206 data_reduction_proxy::HttpAuthHandlerDataReductionProxy::Scheme(), 207 new data_reduction_proxy::HttpAuthHandlerDataReductionProxy::Factory( 208 DataReductionProxySettings::GetDataReductionProxies())); 209 210 url_request_context_.reset(builder.Build()); 211 // TODO(mnaganov): Fix URLRequestContextBuilder to use proper threads. 212 net::HttpNetworkSession::Params network_session_params; 213 214 PopulateNetworkSessionParams(url_request_context_.get(), 215 &network_session_params); 216 217 net::HttpCache* main_cache = new net::HttpCache( 218 network_session_params, 219 new net::HttpCache::DefaultBackend( 220 net::DISK_CACHE, 221 net::CACHE_BACKEND_SIMPLE, 222 partition_path_.Append(FILE_PATH_LITERAL("Cache")), 223 20 * 1024 * 1024, // 20M 224 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE))); 225 226 AwBrowserContext* browser_context = AwBrowserContext::GetDefault(); 227 DCHECK(browser_context); 228 DataReductionProxySettings* drp_settings = 229 browser_context->GetDataReductionProxySettings(); 230 DCHECK(drp_settings); 231 std::string drp_key = drp_settings->key(); 232 // Only precache credentials if a key is available at URLRequestContext 233 // initialization. 234 if (!drp_key.empty()) { 235 DataReductionProxySettings::InitDataReductionProxySession( 236 main_cache->GetSession(), drp_settings->key()); 237 } 238 239 main_http_factory_.reset(main_cache); 240 url_request_context_->set_http_transaction_factory(main_cache); 241 url_request_context_->set_cookie_store(cookie_store_); 242 243 job_factory_ = CreateJobFactory(&protocol_handlers_); 244 url_request_context_->set_job_factory(job_factory_.get()); 245} 246 247net::URLRequestContext* AwURLRequestContextGetter::GetURLRequestContext() { 248 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 249 if (!url_request_context_) 250 InitializeURLRequestContext(); 251 252 return url_request_context_.get(); 253} 254 255scoped_refptr<base::SingleThreadTaskRunner> 256AwURLRequestContextGetter::GetNetworkTaskRunner() const { 257 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 258} 259 260void AwURLRequestContextGetter::SetProtocolHandlers( 261 content::ProtocolHandlerMap* protocol_handlers) { 262 std::swap(protocol_handlers_, *protocol_handlers); 263} 264 265DataReductionProxyConfigService* 266AwURLRequestContextGetter::proxy_config_service() { 267 // TODO(bengr): return system config if data reduction proxy is disabled. 268 return proxy_config_service_.get(); 269} 270 271} // namespace android_webview 272