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_switches.h" 16 #include "android_webview/native/cookie_manager.h" 17 #include "base/command_line.h" 18 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/content_browser_client.h" 20 #include "content/public/common/content_client.h" 21 #include "content/public/common/url_constants.h" 22 #include "net/base/cache_type.h" 23 #include "net/cookies/cookie_store.h" 24 #include "net/http/http_cache.h" 25 #include "net/proxy/proxy_service.h" 26 #include "net/url_request/data_protocol_handler.h" 27 #include "net/url_request/file_protocol_handler.h" 28 #include "net/url_request/protocol_intercept_job_factory.h" 29 #include "net/url_request/url_request_context_builder.h" 30 #include "net/url_request/url_request_context.h" 31 32 using base::FilePath; 33 using content::BrowserThread; 34 35 namespace android_webview { 36 37 AwURLRequestContextGetter::AwURLRequestContextGetter( 38 AwBrowserContext* browser_context) 39 : browser_context_(browser_context), 40 proxy_config_service_(net::ProxyService::CreateSystemProxyConfigService( 41 GetNetworkTaskRunner(), 42 NULL /* Ignored on Android */)) { 43 // CreateSystemProxyConfigService for Android must be called on main thread. 44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 45 46 // All network stack initialization is done on the synchronous Init call when 47 // the IO thread is created. 48 BrowserThread::SetDelegate(BrowserThread::IO, this); 49 } 50 51 AwURLRequestContextGetter::~AwURLRequestContextGetter() { 52 BrowserThread::SetDelegate(BrowserThread::IO, NULL); 53 } 54 55 void AwURLRequestContextGetter::Init() { 56 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 57 58 cookie_store_ = CreateCookieStore(browser_context_); 59 } 60 61 void AwURLRequestContextGetter::InitAsync() { 62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 63 64 net::URLRequestContextBuilder builder; 65 builder.set_user_agent(content::GetUserAgent(GURL())); 66 builder.set_network_delegate(new AwNetworkDelegate()); 67 #if !defined(DISABLE_FTP_SUPPORT) 68 builder.set_ftp_enabled(false); // Android WebView does not support ftp yet. 69 #endif 70 builder.set_proxy_config_service(proxy_config_service_.release()); 71 builder.set_accept_language(net::HttpUtil::GenerateAcceptLanguageHeader( 72 AwContentBrowserClient::GetAcceptLangsImpl())); 73 74 url_request_context_.reset(builder.Build()); 75 // TODO(mnaganov): Fix URLRequestContextBuilder to use proper threads. 76 net::HttpNetworkSession::Params network_session_params; 77 78 net::BackendType cache_type = net::CACHE_BACKEND_SIMPLE; 79 if (CommandLine::ForCurrentProcess()->HasSwitch( 80 switches::kDisableSimpleCache)) { 81 cache_type = net::CACHE_BACKEND_BLOCKFILE; 82 } 83 PopulateNetworkSessionParams(&network_session_params); 84 net::HttpCache* main_cache = new net::HttpCache( 85 network_session_params, 86 new net::HttpCache::DefaultBackend( 87 net::DISK_CACHE, 88 cache_type, 89 browser_context_->GetPath().Append(FILE_PATH_LITERAL("Cache")), 90 10 * 1024 * 1024, // 10M 91 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE))); 92 main_http_factory_.reset(main_cache); 93 url_request_context_->set_http_transaction_factory(main_cache); 94 url_request_context_->set_cookie_store(cookie_store_.get()); 95 } 96 97 void AwURLRequestContextGetter::PopulateNetworkSessionParams( 98 net::HttpNetworkSession::Params* params) { 99 net::URLRequestContext* context = url_request_context_.get(); 100 params->host_resolver = context->host_resolver(); 101 params->cert_verifier = context->cert_verifier(); 102 params->server_bound_cert_service = context->server_bound_cert_service(); 103 params->transport_security_state = context->transport_security_state(); 104 params->proxy_service = context->proxy_service(); 105 params->ssl_config_service = context->ssl_config_service(); 106 params->http_auth_handler_factory = context->http_auth_handler_factory(); 107 params->network_delegate = context->network_delegate(); 108 params->http_server_properties = context->http_server_properties(); 109 params->net_log = context->net_log(); 110 } 111 112 net::URLRequestContext* AwURLRequestContextGetter::GetURLRequestContext() { 113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 114 if (!job_factory_) { 115 scoped_ptr<AwURLRequestJobFactory> job_factory(new AwURLRequestJobFactory); 116 bool set_protocol = job_factory->SetProtocolHandler( 117 chrome::kFileScheme, new net::FileProtocolHandler()); 118 DCHECK(set_protocol); 119 set_protocol = job_factory->SetProtocolHandler( 120 chrome::kDataScheme, new net::DataProtocolHandler()); 121 DCHECK(set_protocol); 122 set_protocol = job_factory->SetProtocolHandler( 123 chrome::kBlobScheme, protocol_handlers_[chrome::kBlobScheme].release()); 124 DCHECK(set_protocol); 125 set_protocol = job_factory->SetProtocolHandler( 126 chrome::kFileSystemScheme, 127 protocol_handlers_[chrome::kFileSystemScheme].release()); 128 DCHECK(set_protocol); 129 set_protocol = job_factory->SetProtocolHandler( 130 chrome::kChromeUIScheme, 131 protocol_handlers_[chrome::kChromeUIScheme].release()); 132 DCHECK(set_protocol); 133 set_protocol = job_factory->SetProtocolHandler( 134 chrome::kChromeDevToolsScheme, 135 protocol_handlers_[chrome::kChromeDevToolsScheme].release()); 136 DCHECK(set_protocol); 137 protocol_handlers_.clear(); 138 139 // Create a chain of URLRequestJobFactories. The handlers will be invoked 140 // in the order in which they appear in the protocol_handlers vector. 141 typedef std::vector<net::URLRequestJobFactory::ProtocolHandler*> 142 ProtocolHandlerVector; 143 ProtocolHandlerVector protocol_interceptors; 144 145 // Note that even though the content:// scheme handler is created here, 146 // it cannot be used by child processes until access to it is granted via 147 // ChildProcessSecurityPolicy::GrantScheme(). This is done in 148 // AwContentBrowserClient. 149 protocol_interceptors.push_back( 150 CreateAndroidContentProtocolHandler().release()); 151 protocol_interceptors.push_back( 152 CreateAndroidAssetFileProtocolHandler().release()); 153 // The AwRequestInterceptor must come after the content and asset file job 154 // factories. This for WebViewClassic compatibility where it was not 155 // possible to intercept resource loads to resolvable content:// and 156 // file:// URIs. 157 // This logical dependency is also the reason why the Content 158 // ProtocolHandler has to be added as a ProtocolInterceptJobFactory rather 159 // than via SetProtocolHandler. 160 protocol_interceptors.push_back(new AwRequestInterceptor()); 161 162 // The chain of responsibility will execute the handlers in reverse to the 163 // order in which the elements of the chain are created. 164 job_factory_ = job_factory.PassAs<net::URLRequestJobFactory>(); 165 for (ProtocolHandlerVector::reverse_iterator 166 i = protocol_interceptors.rbegin(); 167 i != protocol_interceptors.rend(); 168 ++i) { 169 job_factory_.reset(new net::ProtocolInterceptJobFactory( 170 job_factory_.Pass(), make_scoped_ptr(*i))); 171 } 172 173 url_request_context_->set_job_factory(job_factory_.get()); 174 } 175 176 return url_request_context_.get(); 177 } 178 179 scoped_refptr<base::SingleThreadTaskRunner> 180 AwURLRequestContextGetter::GetNetworkTaskRunner() const { 181 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 182 } 183 184 void AwURLRequestContextGetter::SetProtocolHandlers( 185 content::ProtocolHandlerMap* protocol_handlers) { 186 std::swap(protocol_handlers_, *protocol_handlers); 187 } 188 189 } // namespace android_webview 190