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 "content/shell/shell_url_request_context_getter.h" 6 7 #include "base/command_line.h" 8 #include "base/logging.h" 9 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_split.h" 11 #include "base/strings/string_util.h" 12 #include "base/threading/worker_pool.h" 13 #include "content/public/browser/browser_thread.h" 14 #include "content/public/common/content_switches.h" 15 #include "content/public/common/url_constants.h" 16 #include "content/shell/common/shell_switches.h" 17 #include "content/shell/shell_network_delegate.h" 18 #include "net/base/cache_type.h" 19 #include "net/cert/cert_verifier.h" 20 #include "net/cookies/cookie_monster.h" 21 #include "net/dns/host_resolver.h" 22 #include "net/dns/mapped_host_resolver.h" 23 #include "net/http/http_auth_handler_factory.h" 24 #include "net/http/http_cache.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/default_server_bound_cert_store.h" 30 #include "net/ssl/server_bound_cert_service.h" 31 #include "net/ssl/ssl_config_service_defaults.h" 32 #include "net/url_request/data_protocol_handler.h" 33 #include "net/url_request/file_protocol_handler.h" 34 #include "net/url_request/protocol_intercept_job_factory.h" 35 #include "net/url_request/static_http_user_agent_settings.h" 36 #include "net/url_request/url_request_context.h" 37 #include "net/url_request/url_request_context_storage.h" 38 #include "net/url_request/url_request_job_factory_impl.h" 39 40 namespace content { 41 42 namespace { 43 44 void InstallProtocolHandlers(net::URLRequestJobFactoryImpl* job_factory, 45 ProtocolHandlerMap* protocol_handlers) { 46 for (ProtocolHandlerMap::iterator it = 47 protocol_handlers->begin(); 48 it != protocol_handlers->end(); 49 ++it) { 50 bool set_protocol = job_factory->SetProtocolHandler( 51 it->first, it->second.release()); 52 DCHECK(set_protocol); 53 } 54 protocol_handlers->clear(); 55 } 56 57 } // namespace 58 59 ShellURLRequestContextGetter::ShellURLRequestContextGetter( 60 bool ignore_certificate_errors, 61 const base::FilePath& base_path, 62 base::MessageLoop* io_loop, 63 base::MessageLoop* file_loop, 64 ProtocolHandlerMap* protocol_handlers, 65 net::NetLog* net_log) 66 : ignore_certificate_errors_(ignore_certificate_errors), 67 base_path_(base_path), 68 io_loop_(io_loop), 69 file_loop_(file_loop), 70 net_log_(net_log) { 71 // Must first be created on the UI thread. 72 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 73 74 std::swap(protocol_handlers_, *protocol_handlers); 75 76 // We must create the proxy config service on the UI loop on Linux because it 77 // must synchronously run on the glib message loop. This will be passed to 78 // the URLRequestContextStorage on the IO thread in GetURLRequestContext(). 79 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) { 80 proxy_config_service_.reset( 81 net::ProxyService::CreateSystemProxyConfigService( 82 io_loop_->message_loop_proxy().get(), file_loop_)); 83 } 84 } 85 86 ShellURLRequestContextGetter::~ShellURLRequestContextGetter() { 87 } 88 89 net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() { 90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 91 92 if (!url_request_context_) { 93 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 94 95 url_request_context_.reset(new net::URLRequestContext()); 96 url_request_context_->set_net_log(net_log_); 97 network_delegate_.reset(new ShellNetworkDelegate); 98 if (command_line.HasSwitch(switches::kDumpRenderTree)) 99 ShellNetworkDelegate::SetAcceptAllCookies(false); 100 url_request_context_->set_network_delegate(network_delegate_.get()); 101 storage_.reset( 102 new net::URLRequestContextStorage(url_request_context_.get())); 103 storage_->set_cookie_store(new net::CookieMonster(NULL, NULL)); 104 storage_->set_server_bound_cert_service(new net::ServerBoundCertService( 105 new net::DefaultServerBoundCertStore(NULL), 106 base::WorkerPool::GetTaskRunner(true))); 107 storage_->set_http_user_agent_settings( 108 new net::StaticHttpUserAgentSettings("en-us,en", EmptyString())); 109 110 scoped_ptr<net::HostResolver> host_resolver( 111 net::HostResolver::CreateDefaultResolver( 112 url_request_context_->net_log())); 113 114 storage_->set_cert_verifier(net::CertVerifier::CreateDefault()); 115 storage_->set_transport_security_state(new net::TransportSecurityState); 116 if (command_line.HasSwitch(switches::kDumpRenderTree)) { 117 storage_->set_proxy_service(net::ProxyService::CreateDirect()); 118 } else { 119 // TODO(jam): use v8 if possible, look at chrome code. 120 storage_->set_proxy_service( 121 net::ProxyService::CreateUsingSystemProxyResolver( 122 proxy_config_service_.release(), 123 0, 124 url_request_context_->net_log())); 125 } 126 storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults); 127 storage_->set_http_auth_handler_factory( 128 net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); 129 storage_->set_http_server_properties( 130 scoped_ptr<net::HttpServerProperties>( 131 new net::HttpServerPropertiesImpl())); 132 133 base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache")); 134 net::HttpCache::DefaultBackend* main_backend = 135 new net::HttpCache::DefaultBackend( 136 net::DISK_CACHE, 137 #if defined(OS_ANDROID) 138 // TODO(rdsmith): Remove when default backend for Android is 139 // changed to simple cache. 140 net::CACHE_BACKEND_SIMPLE, 141 #else 142 net::CACHE_BACKEND_DEFAULT, 143 #endif 144 cache_path, 145 0, 146 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE) 147 .get()); 148 149 net::HttpNetworkSession::Params network_session_params; 150 network_session_params.cert_verifier = 151 url_request_context_->cert_verifier(); 152 network_session_params.transport_security_state = 153 url_request_context_->transport_security_state(); 154 network_session_params.server_bound_cert_service = 155 url_request_context_->server_bound_cert_service(); 156 network_session_params.proxy_service = 157 url_request_context_->proxy_service(); 158 network_session_params.ssl_config_service = 159 url_request_context_->ssl_config_service(); 160 network_session_params.http_auth_handler_factory = 161 url_request_context_->http_auth_handler_factory(); 162 network_session_params.network_delegate = 163 network_delegate_.get(); 164 network_session_params.http_server_properties = 165 url_request_context_->http_server_properties(); 166 network_session_params.net_log = 167 url_request_context_->net_log(); 168 network_session_params.ignore_certificate_errors = 169 ignore_certificate_errors_; 170 if (command_line.HasSwitch(switches::kTestingFixedHttpPort)) { 171 int value; 172 base::StringToInt(command_line.GetSwitchValueASCII( 173 switches::kTestingFixedHttpPort), &value); 174 network_session_params.testing_fixed_http_port = value; 175 } 176 if (command_line.HasSwitch(switches::kTestingFixedHttpsPort)) { 177 int value; 178 base::StringToInt(command_line.GetSwitchValueASCII( 179 switches::kTestingFixedHttpsPort), &value); 180 network_session_params.testing_fixed_https_port = value; 181 } 182 if (command_line.HasSwitch(switches::kHostResolverRules)) { 183 scoped_ptr<net::MappedHostResolver> mapped_host_resolver( 184 new net::MappedHostResolver(host_resolver.Pass())); 185 mapped_host_resolver->SetRulesFromString( 186 command_line.GetSwitchValueASCII(switches::kHostResolverRules)); 187 host_resolver = mapped_host_resolver.Pass(); 188 } 189 190 // Give |storage_| ownership at the end in case it's |mapped_host_resolver|. 191 storage_->set_host_resolver(host_resolver.Pass()); 192 network_session_params.host_resolver = 193 url_request_context_->host_resolver(); 194 195 net::HttpCache* main_cache = new net::HttpCache( 196 network_session_params, main_backend); 197 storage_->set_http_transaction_factory(main_cache); 198 199 scoped_ptr<net::URLRequestJobFactoryImpl> job_factory( 200 new net::URLRequestJobFactoryImpl()); 201 // Keep ProtocolHandlers added in sync with 202 // ShellContentBrowserClient::IsHandledURL(). 203 InstallProtocolHandlers(job_factory.get(), &protocol_handlers_); 204 bool set_protocol = job_factory->SetProtocolHandler( 205 chrome::kDataScheme, 206 new net::DataProtocolHandler); 207 DCHECK(set_protocol); 208 set_protocol = job_factory->SetProtocolHandler( 209 chrome::kFileScheme, 210 new net::FileProtocolHandler); 211 DCHECK(set_protocol); 212 storage_->set_job_factory(job_factory.release()); 213 } 214 215 return url_request_context_.get(); 216 } 217 218 scoped_refptr<base::SingleThreadTaskRunner> 219 ShellURLRequestContextGetter::GetNetworkTaskRunner() const { 220 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 221 } 222 223 net::HostResolver* ShellURLRequestContextGetter::host_resolver() { 224 return url_request_context_->host_resolver(); 225 } 226 227 } // namespace content 228