diff options
58 files changed, 299 insertions, 238 deletions
diff --git a/android_webview/browser/net/aw_url_request_context_getter.cc b/android_webview/browser/net/aw_url_request_context_getter.cc index 882a967..83774a0 100644 --- a/android_webview/browser/net/aw_url_request_context_getter.cc +++ b/android_webview/browser/net/aw_url_request_context_getter.cc @@ -52,7 +52,9 @@ void AwURLRequestContextGetter::Init() { net::URLRequestContextBuilder builder; builder.set_user_agent(content::GetUserAgent(GURL())); builder.set_network_delegate(new AwNetworkDelegate()); +#if !defined(DISABLE_FTP_SUPPORT) builder.set_ftp_enabled(false); // Android WebView does not support ftp yet. +#endif builder.set_proxy_config_service(proxy_config_service_.release()); builder.set_accept_language(net::HttpUtil::GenerateAcceptLanguageHeader( content::GetContentClient()->browser()->GetAcceptLangs( diff --git a/android_webview/browser/net/aw_url_request_job_factory.cc b/android_webview/browser/net/aw_url_request_job_factory.cc index c14cd17..5014336 100644 --- a/android_webview/browser/net/aw_url_request_job_factory.cc +++ b/android_webview/browser/net/aw_url_request_job_factory.cc @@ -63,4 +63,8 @@ bool AwURLRequestJobFactory::SetProtocolHandler( return next_factory_->SetProtocolHandler(scheme, protocol_handler); } +bool AwURLRequestJobFactory::IsSafeRedirectTarget(const GURL& location) const { + return next_factory_->IsSafeRedirectTarget(location); +} + } // namespace android_webview diff --git a/android_webview/browser/net/aw_url_request_job_factory.h b/android_webview/browser/net/aw_url_request_job_factory.h index 8978df5..b4745bd 100644 --- a/android_webview/browser/net/aw_url_request_job_factory.h +++ b/android_webview/browser/net/aw_url_request_job_factory.h @@ -35,6 +35,7 @@ class AwURLRequestJobFactory : public net::URLRequestJobFactory { net::NetworkDelegate* network_delegate) const OVERRIDE; virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE; virtual bool IsHandledURL(const GURL& url) const OVERRIDE; + virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE; private: // By default calls are forwarded to this factory, to avoid having to diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc index 0a1913d..675dd6e 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry.cc +++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc @@ -205,6 +205,12 @@ bool ProtocolHandlerRegistry::JobInterceptorFactory::IsHandledURL( job_factory_->IsHandledURL(url); } +bool ProtocolHandlerRegistry::JobInterceptorFactory::IsSafeRedirectTarget( + const GURL& location) const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + return job_factory_->IsSafeRedirectTarget(location); +} + // DefaultClientObserver ------------------------------------------------------ ProtocolHandlerRegistry::DefaultClientObserver::DefaultClientObserver( diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.h b/chrome/browser/custom_handlers/protocol_handler_registry.h index ead2149..4d4270b 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry.h +++ b/chrome/browser/custom_handlers/protocol_handler_registry.h @@ -112,6 +112,7 @@ class ProtocolHandlerRegistry : public ProfileKeyedService { net::NetworkDelegate* network_delegate) const OVERRIDE; virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE; virtual bool IsHandledURL(const GURL& url) const OVERRIDE; + virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE; private: // When JobInterceptorFactory decides to pass on particular requests, diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc index d2869ef..db486c2 100644 --- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc +++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc @@ -73,6 +73,9 @@ class FakeURLRequestJobFactory : public net::URLRequestJobFactory { virtual bool IsHandledURL(const GURL& url) const OVERRIDE { return false; } + virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE { + return true; + } }; void AssertWillHandleIO( diff --git a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc index 12ff0e2..c962a545 100644 --- a/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_api_unittest.cc @@ -28,6 +28,7 @@ #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" #include "chrome/browser/extensions/event_router_forwarder.h" #include "chrome/browser/extensions/extension_warning_set.h" +#include "chrome/browser/net/about_protocol_handler.h" #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/common/extensions/extension_messages.h" #include "chrome/common/extensions/features/feature.h" @@ -36,6 +37,7 @@ #include "chrome/test/base/testing_pref_service_syncable.h" #include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile_manager.h" +#include "content/public/common/url_constants.h" #include "content/public/test/test_browser_thread.h" #include "net/base/auth.h" #include "net/base/capturing_net_log.h" @@ -44,6 +46,7 @@ #include "net/base/upload_bytes_element_reader.h" #include "net/base/upload_data_stream.h" #include "net/base/upload_file_element_reader.h" +#include "net/url_request/url_request_job_factory_impl.h" #include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest-message.h" #include "testing/gtest/include/gtest/gtest.h" @@ -230,6 +233,12 @@ TEST_F(ExtensionWebRequestTest, BlockingEventPrecedenceRedirect) { filter, ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING, -1, -1, ipc_sender_factory.GetWeakPtr()); + net::URLRequestJobFactoryImpl job_factory; + job_factory.SetProtocolHandler( + chrome::kAboutScheme, + new chrome_browser_net::AboutProtocolHandler()); + context_->set_job_factory(&job_factory); + GURL redirect_url("about:redirected"); GURL not_chosen_redirect_url("about:not_chosen"); diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 625ff0b..96811be2 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -48,7 +48,6 @@ #include "net/base/net_util.h" #include "net/base/sdch_manager.h" #include "net/cookies/cookie_monster.h" -#include "net/ftp/ftp_network_layer.h" #include "net/http/http_auth_filter.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_network_layer.h" @@ -186,8 +185,6 @@ ConstructProxyScriptFetcherContext(IOThread::Globals* globals, context->set_proxy_service(globals->proxy_script_fetcher_proxy_service.get()); context->set_http_transaction_factory( globals->proxy_script_fetcher_http_transaction_factory.get()); - context->set_ftp_transaction_factory( - globals->proxy_script_fetcher_ftp_transaction_factory.get()); context->set_cookie_store(globals->system_cookie_store.get()); context->set_server_bound_cert_service( globals->system_server_bound_cert_service.get()); @@ -214,8 +211,6 @@ ConstructSystemRequestContext(IOThread::Globals* globals, context->set_proxy_service(globals->system_proxy_service.get()); context->set_http_transaction_factory( globals->system_http_transaction_factory.get()); - context->set_ftp_transaction_factory( - globals->system_ftp_transaction_factory.get()); context->set_cookie_store(globals->system_cookie_store.get()); context->set_server_bound_cert_service( globals->system_server_bound_cert_service.get()); @@ -550,8 +545,6 @@ void IOThread::Init() { new net::HttpNetworkSession(session_params)); globals_->proxy_script_fetcher_http_transaction_factory.reset( new net::HttpNetworkLayer(network_session)); - globals_->proxy_script_fetcher_ftp_transaction_factory.reset( - new net::FtpNetworkLayer(globals_->host_resolver.get())); globals_->throttler_manager.reset(new net::URLRequestThrottlerManager()); globals_->throttler_manager->set_net_log(net_log_); @@ -896,8 +889,6 @@ void IOThread::InitSystemRequestContextOnIOThread() { globals_->system_http_transaction_factory.reset( new net::HttpNetworkLayer( new net::HttpNetworkSession(system_params))); - globals_->system_ftp_transaction_factory.reset( - new net::FtpNetworkLayer(globals_->host_resolver.get())); globals_->system_request_context.reset( ConstructSystemRequestContext(globals_, net_log_)); diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h index 627dcfb..4319135 100644 --- a/chrome/browser/io_thread.h +++ b/chrome/browser/io_thread.h @@ -121,8 +121,6 @@ class IOThread : public content::BrowserThreadDelegate { scoped_ptr<net::ProxyService> proxy_script_fetcher_proxy_service; scoped_ptr<net::HttpTransactionFactory> proxy_script_fetcher_http_transaction_factory; - scoped_ptr<net::FtpTransactionFactory> - proxy_script_fetcher_ftp_transaction_factory; scoped_ptr<net::URLRequestThrottlerManager> throttler_manager; scoped_ptr<net::URLSecurityManager> url_security_manager; // TODO(willchan): Remove proxy script fetcher context since it's not @@ -134,7 +132,6 @@ class IOThread : public content::BrowserThreadDelegate { scoped_ptr<net::URLRequestContext> proxy_script_fetcher_context; scoped_ptr<net::ProxyService> system_proxy_service; scoped_ptr<net::HttpTransactionFactory> system_http_transaction_factory; - scoped_ptr<net::FtpTransactionFactory> system_ftp_transaction_factory; scoped_ptr<net::URLRequestContext> system_request_context; SystemRequestContextLeakChecker system_request_context_leak_checker; // |system_cookie_store| and |system_server_bound_cert_service| are shared diff --git a/chrome/browser/net/about_protocol_handler.cc b/chrome/browser/net/about_protocol_handler.cc index 3c6afe1..13f0c3b 100644 --- a/chrome/browser/net/about_protocol_handler.cc +++ b/chrome/browser/net/about_protocol_handler.cc @@ -16,4 +16,8 @@ net::URLRequestJob* AboutProtocolHandler::MaybeCreateJob( return new net::URLRequestAboutJob(request, network_delegate); } +bool AboutProtocolHandler::IsSafeRedirectTarget(const GURL& location) const { + return false; +} + } // namespace chrome_browser_net diff --git a/chrome/browser/net/about_protocol_handler.h b/chrome/browser/net/about_protocol_handler.h index b156b82..623b1b0 100644 --- a/chrome/browser/net/about_protocol_handler.h +++ b/chrome/browser/net/about_protocol_handler.h @@ -18,6 +18,7 @@ class AboutProtocolHandler : public net::URLRequestJobFactory::ProtocolHandler { virtual net::URLRequestJob* MaybeCreateJob( net::URLRequest* request, net::NetworkDelegate* network_delegate) const OVERRIDE; + virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(AboutProtocolHandler); diff --git a/chrome/browser/net/connection_tester.cc b/chrome/browser/net/connection_tester.cc index 34906a6..a52b212 100644 --- a/chrome/browser/net/connection_tester.cc +++ b/chrome/browser/net/connection_tester.cc @@ -21,7 +21,6 @@ #include "net/base/net_errors.h" #include "net/base/net_util.h" #include "net/cookies/cookie_monster.h" -#include "net/ftp/ftp_network_layer.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_cache.h" #include "net/http/http_network_session.h" @@ -109,10 +108,6 @@ class ExperimentURLRequestContext : public net::URLRequestContext { // The rest of the dependencies are standard, and don't depend on the // experiment being run. storage_.set_cert_verifier(net::CertVerifier::CreateDefault()); -#if !defined(DISABLE_FTP_SUPPORT) - storage_.set_ftp_transaction_factory( - new net::FtpNetworkLayer(host_resolver())); -#endif storage_.set_ssl_config_service(new net::SSLConfigServiceDefaults); storage_.set_http_auth_handler_factory( net::HttpAuthHandlerFactory::CreateDefault(host_resolver())); diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc index 4029bc3..034f7bb 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.cc +++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc @@ -216,7 +216,6 @@ void OffTheRecordProfileIOData::InitializeInternal( #if !defined(DISABLE_FTP_SUPPORT) ftp_factory_.reset( new net::FtpNetworkLayer(main_context->host_resolver())); - main_context->set_ftp_transaction_factory(ftp_factory_.get()); #endif // !defined(DISABLE_FTP_SUPPORT) scoped_ptr<net::URLRequestJobFactoryImpl> main_job_factory( @@ -227,8 +226,7 @@ void OffTheRecordProfileIOData::InitializeInternal( main_job_factory.Pass(), profile_params->protocol_handler_interceptor.Pass(), network_delegate(), - main_context->ftp_transaction_factory(), - main_context->ftp_auth_cache()); + ftp_factory_.get()); main_context->set_job_factory(main_job_factory_.get()); #if defined(ENABLE_EXTENSIONS) @@ -262,11 +260,6 @@ void OffTheRecordProfileIOData:: extensions_cookie_store->SetCookieableSchemes(schemes, 2); extensions_context->set_cookie_store(extensions_cookie_store); -#if !defined(DISABLE_FTP_SUPPORT) - DCHECK(ftp_factory_.get()); - extensions_context->set_ftp_transaction_factory(ftp_factory_.get()); -#endif // !defined(DISABLE_FTP_SUPPORT) - scoped_ptr<net::URLRequestJobFactoryImpl> extensions_job_factory( new net::URLRequestJobFactoryImpl()); // TODO(shalev): The extensions_job_factory has a NULL NetworkDelegate. @@ -279,8 +272,7 @@ void OffTheRecordProfileIOData:: extensions_job_factory.Pass(), scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>(NULL), NULL, - extensions_context->ftp_transaction_factory(), - extensions_context->ftp_auth_cache()); + ftp_factory_.get()); extensions_context->set_job_factory(extensions_job_factory_.get()); } @@ -318,8 +310,7 @@ OffTheRecordProfileIOData::InitializeAppRequestContext( top_job_factory = SetUpJobFactoryDefaults(job_factory.Pass(), protocol_handler_interceptor.Pass(), network_delegate(), - context->ftp_transaction_factory(), - context->ftp_auth_cache()); + ftp_factory_.get()); context->SetJobFactory(top_job_factory.Pass()); return context; } diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.h b/chrome/browser/profiles/off_the_record_profile_io_data.h index cfa6cb6..72db359 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.h +++ b/chrome/browser/profiles/off_the_record_profile_io_data.h @@ -19,6 +19,11 @@ class ChromeURLRequestContext; class ChromeURLRequestContextGetter; class Profile; +namespace net { +class FtpTransactionFactory; +class HttpTransactionFactory; +} // namespace net + // OffTheRecordProfile owns a OffTheRecordProfileIOData::Handle, which holds a // reference to the OffTheRecordProfileIOData. OffTheRecordProfileIOData is // intended to own all the objects owned by OffTheRecordProfile which live on diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index 38e5d87..8eb533f 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc @@ -411,7 +411,6 @@ void ProfileImplIOData::InitializeInternal( #if !defined(DISABLE_FTP_SUPPORT) ftp_factory_.reset( new net::FtpNetworkLayer(io_thread_globals->host_resolver.get())); - main_context->set_ftp_transaction_factory(ftp_factory_.get()); #endif // !defined(DISABLE_FTP_SUPPORT) scoped_ptr<net::URLRequestJobFactoryImpl> main_job_factory( @@ -421,8 +420,7 @@ void ProfileImplIOData::InitializeInternal( main_job_factory.Pass(), profile_params->protocol_handler_interceptor.Pass(), network_delegate(), - main_context->ftp_transaction_factory(), - main_context->ftp_auth_cache()); + ftp_factory_.get()); main_context->set_job_factory(main_job_factory_.get()); #if defined(ENABLE_EXTENSIONS) @@ -466,11 +464,6 @@ void ProfileImplIOData:: extensions_cookie_store->SetCookieableSchemes(schemes, 2); extensions_context->set_cookie_store(extensions_cookie_store); -#if !defined(DISABLE_FTP_SUPPORT) - DCHECK(ftp_factory_.get()); - extensions_context->set_ftp_transaction_factory(ftp_factory_.get()); -#endif // !defined(DISABLE_FTP_SUPPORT) - scoped_ptr<net::URLRequestJobFactoryImpl> extensions_job_factory( new net::URLRequestJobFactoryImpl()); // TODO(shalev): The extensions_job_factory has a NULL NetworkDelegate. @@ -483,8 +476,7 @@ void ProfileImplIOData:: extensions_job_factory.Pass(), scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>(NULL), NULL, - extensions_context->ftp_transaction_factory(), - extensions_context->ftp_auth_cache()); + ftp_factory_.get()); extensions_context->set_job_factory(extensions_job_factory_.get()); } @@ -576,8 +568,7 @@ ProfileImplIOData::InitializeAppRequestContext( top_job_factory = SetUpJobFactoryDefaults( job_factory.Pass(), protocol_handler_interceptor.Pass(), network_delegate(), - context->ftp_transaction_factory(), - context->ftp_auth_cache()); + ftp_factory_.get()); } else { top_job_factory = job_factory.PassAs<net::URLRequestJobFactory>(); } diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h index 8fa27a7..b2eb4d0d 100644 --- a/chrome/browser/profiles/profile_impl_io_data.h +++ b/chrome/browser/profiles/profile_impl_io_data.h @@ -18,6 +18,7 @@ class Predictor; } // namespace chrome_browser_net namespace net { +class FtpTransactionFactory; class HttpServerProperties; class HttpTransactionFactory; } // namespace net diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 35f0a2f..be40516 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc @@ -421,16 +421,21 @@ ProfileIOData* ProfileIOData::FromResourceContext( bool ProfileIOData::IsHandledProtocol(const std::string& scheme) { DCHECK_EQ(scheme, StringToLowerASCII(scheme)); static const char* const kProtocolList[] = { + chrome::kFileScheme, + chrome::kChromeDevToolsScheme, extensions::kExtensionScheme, + chrome::kExtensionResourceScheme, chrome::kChromeUIScheme, - chrome::kChromeDevToolsScheme, + chrome::kDataScheme, #if defined(OS_CHROMEOS) - chrome::kMetadataScheme, chrome::kDriveScheme, #endif // defined(OS_CHROMEOS) + chrome::kAboutScheme, +#if !defined(DISABLE_FTP_SUPPORT) + chrome::kFtpScheme, +#endif // !defined(DISABLE_FTP_SUPPORT) chrome::kBlobScheme, chrome::kFileSystemScheme, - chrome::kExtensionResourceScheme, chrome::kChromeSearchScheme, }; for (size_t i = 0; i < arraysize(kProtocolList); ++i) { @@ -712,8 +717,7 @@ scoped_ptr<net::URLRequestJobFactory> ProfileIOData::SetUpJobFactoryDefaults( scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> protocol_handler_interceptor, net::NetworkDelegate* network_delegate, - net::FtpTransactionFactory* ftp_transaction_factory, - net::FtpAuthCache* ftp_auth_cache) const { + net::FtpTransactionFactory* ftp_transaction_factory) const { // NOTE(willchan): Keep these protocol handlers in sync with // ProfileIOData::IsHandledProtocol(). bool set_protocol = job_factory->SetProtocolHandler( @@ -748,8 +752,7 @@ scoped_ptr<net::URLRequestJobFactory> ProfileIOData::SetUpJobFactoryDefaults( DCHECK(ftp_transaction_factory); job_factory->SetProtocolHandler( chrome::kFtpScheme, - new net::FtpProtocolHandler(ftp_transaction_factory, - ftp_auth_cache)); + new net::FtpProtocolHandler(ftp_transaction_factory)); #endif // !defined(DISABLE_FTP_SUPPORT) scoped_ptr<net::URLRequestJobFactory> top_job_factory = diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index 406fa98..074b803 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h @@ -45,6 +45,7 @@ class ResourcePrefetchPredictorObserver; namespace net { class CookieStore; class FraudulentCertificateReporter; +class FtpTransactionFactory; class HttpServerProperties; class HttpTransactionFactory; class ServerBoundCertService; @@ -286,8 +287,7 @@ class ProfileIOData { scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory> protocol_handler_interceptor, net::NetworkDelegate* network_delegate, - net::FtpTransactionFactory* ftp_transaction_factory, - net::FtpAuthCache* ftp_auth_cache) const; + net::FtpTransactionFactory* ftp_transaction_factory) const; // Called when the profile is destroyed. void ShutdownOnUIThread(); diff --git a/chrome/service/net/service_url_request_context.cc b/chrome/service/net/service_url_request_context.cc index cc8bacb..379a22f 100644 --- a/chrome/service/net/service_url_request_context.cc +++ b/chrome/service/net/service_url_request_context.cc @@ -17,7 +17,6 @@ #include "net/base/cert_verifier.h" #include "net/base/host_resolver.h" #include "net/cookies/cookie_monster.h" -#include "net/ftp/ftp_network_layer.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_cache.h" #include "net/http/http_network_session.h" @@ -114,8 +113,6 @@ ServiceURLRequestContext::ServiceURLRequestContext( storage_.set_proxy_service(net::ProxyService::CreateUsingSystemProxyResolver( net_proxy_config_service, 0u, NULL)); storage_.set_cert_verifier(net::CertVerifier::CreateDefault()); - storage_.set_ftp_transaction_factory( - new net::FtpNetworkLayer(host_resolver())); storage_.set_ssl_config_service(new net::SSLConfigServiceDefaults); storage_.set_http_auth_handler_factory( net::HttpAuthHandlerFactory::CreateDefault(host_resolver())); diff --git a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc index 66dd8aa..91a9d3e1 100644 --- a/content/browser/browser_plugin/browser_plugin_host_browsertest.cc +++ b/content/browser/browser_plugin/browser_plugin_host_browsertest.cc @@ -14,6 +14,7 @@ #include "content/browser/browser_plugin/test_browser_plugin_embedder.h" #include "content/browser/browser_plugin/test_browser_plugin_guest.h" #include "content/browser/browser_plugin/test_browser_plugin_guest_manager.h" +#include "content/browser/child_process_security_policy_impl.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/common/view_messages.h" @@ -852,12 +853,18 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, LoadAbort) { { // Navigate the guest to an illegal chrome:// URL. + GURL test_url("chrome://newtab"); + ChildProcessSecurityPolicyImpl* policy = + ChildProcessSecurityPolicyImpl::GetInstance(); + // Register chrome:// as a safe scheme so as to bypass + // ChildProcessSecurityPolicyImpl::CanRequestURL(). + if (!policy->IsWebSafeScheme(test_url.scheme())) + policy->RegisterWebSafeScheme(test_url.scheme()); const string16 expected_title = ASCIIToUTF16("ERR_INVALID_URL"); content::TitleWatcher title_watcher(test_embedder()->web_contents(), expected_title); RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( test_embedder()->web_contents()->GetRenderViewHost()); - GURL test_url("chrome://newtab"); ExecuteSyncJSFunction( rvh, base::StringPrintf("SetSrc('%s');", test_url.spec().c_str())); string16 actual_title = title_watcher.WaitAndGetTitle(); diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc index a2eed34..462d9b3 100644 --- a/content/browser/child_process_security_policy_unittest.cc +++ b/content/browser/child_process_security_policy_unittest.cc @@ -60,7 +60,13 @@ class ChildProcessSecurityPolicyTest : public testing::Test { // Claim to always handle chrome:// URLs because the CPSP's notion of // allowing WebUI bindings is hard-wired to this particular scheme. - test_browser_client_.AddScheme("chrome"); + test_browser_client_.AddScheme(chrome::kChromeUIScheme); + + // Claim to always handle file:// URLs like the browser would. + // net::URLRequest::IsHandledURL() no longer claims support for default + // protocols as this is the responsibility of the browser (which is + // responsible for adding the appropriate ProtocolHandler). + test_browser_client_.AddScheme(chrome::kFileScheme); } virtual void TearDown() { diff --git a/content/browser/renderer_host/render_view_host_unittest.cc b/content/browser/renderer_host/render_view_host_unittest.cc index 2645f62..f085525 100644 --- a/content/browser/renderer_host/render_view_host_unittest.cc +++ b/content/browser/renderer_host/render_view_host_unittest.cc @@ -11,7 +11,9 @@ #include "content/public/browser/navigation_entry.h" #include "content/public/common/bindings_policy.h" #include "content/public/common/page_transition_types.h" +#include "content/public/common/url_constants.h" #include "content/public/test/mock_render_process_host.h" +#include "content/test/test_content_browser_client.h" #include "content/test/test_web_contents.h" #include "net/base/net_util.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDragOperation.h" @@ -19,7 +21,40 @@ namespace content { +class RenderViewHostTestBrowserClient : public TestContentBrowserClient { + public: + RenderViewHostTestBrowserClient() {} + virtual ~RenderViewHostTestBrowserClient() {} + + virtual bool IsHandledURL(const GURL& url) OVERRIDE { + return url.scheme() == chrome::kFileScheme; + } + + private: + DISALLOW_COPY_AND_ASSIGN(RenderViewHostTestBrowserClient); +}; + class RenderViewHostTest : public RenderViewHostImplTestHarness { + public: + RenderViewHostTest() : old_browser_client_(NULL) {} + virtual ~RenderViewHostTest() {} + + virtual void SetUp() OVERRIDE { + RenderViewHostImplTestHarness::SetUp(); + old_browser_client_ = GetContentClient()->browser(); + GetContentClient()->set_browser_for_testing(&test_browser_client_); + } + + virtual void TearDown() OVERRIDE { + GetContentClient()->set_browser_for_testing(old_browser_client_); + RenderViewHostImplTestHarness::TearDown(); + } + + private: + RenderViewHostTestBrowserClient test_browser_client_; + ContentBrowserClient* old_browser_client_; + + DISALLOW_COPY_AND_ASSIGN(RenderViewHostTest); }; // All about URLs reported by the renderer should get rewritten to about:blank. diff --git a/content/browser/webui/url_data_manager_backend.cc b/content/browser/webui/url_data_manager_backend.cc index 2f28b2a..0bed5e1 100644 --- a/content/browser/webui/url_data_manager_backend.cc +++ b/content/browser/webui/url_data_manager_backend.cc @@ -404,6 +404,10 @@ class ChromeProtocolHandler GetURLDataManagerForResourceContext(resource_context_), is_incognito_); } + virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE { + return false; + } + private: // These members are owned by ProfileIOData, which owns this ProtocolHandler. content::ResourceContext* const resource_context_; diff --git a/content/shell/shell_content_browser_client.cc b/content/shell/shell_content_browser_client.cc index bd44716e..6bbe337 100644 --- a/content/shell/shell_content_browser_client.cc +++ b/content/shell/shell_content_browser_client.cc @@ -10,6 +10,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/resource_dispatcher_host.h" #include "content/public/browser/storage_partition.h" +#include "content/public/common/url_constants.h" #include "content/shell/geolocation/shell_access_token_store.h" #include "content/shell/shell.h" #include "content/shell/shell_browser_context.h" @@ -134,6 +135,27 @@ ShellContentBrowserClient::CreateRequestContextForStoragePartition( partition_path, in_memory, protocol_handlers); } +bool ShellContentBrowserClient::IsHandledURL(const GURL& url) { + if (!url.is_valid()) + return false; + DCHECK_EQ(url.scheme(), StringToLowerASCII(url.scheme())); + // Keep in sync with ProtocolHandlers added by + // ShellURLRequestContextGetter::GetURLRequestContext(). + static const char* const kProtocolList[] = { + chrome::kBlobScheme, + chrome::kFileSystemScheme, + chrome::kChromeUIScheme, + chrome::kChromeDevToolsScheme, + chrome::kDataScheme, + chrome::kFileScheme, + }; + for (size_t i = 0; i < arraysize(kProtocolList); ++i) { + if (url.scheme() == kProtocolList[i]) + return true; + } + return false; +} + void ShellContentBrowserClient::AppendExtraCommandLineSwitches( CommandLine* command_line, int child_process_id) { if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) diff --git a/content/shell/shell_content_browser_client.h b/content/shell/shell_content_browser_client.h index 015b82d..b8b4524 100644 --- a/content/shell/shell_content_browser_client.h +++ b/content/shell/shell_content_browser_client.h @@ -36,6 +36,7 @@ class ShellContentBrowserClient : public ContentBrowserClient { const base::FilePath& partition_path, bool in_memory, ProtocolHandlerMap* protocol_handlers) OVERRIDE; + virtual bool IsHandledURL(const GURL& url) OVERRIDE; virtual void AppendExtraCommandLineSwitches(CommandLine* command_line, int child_process_id) OVERRIDE; virtual void OverrideWebkitPrefs(RenderViewHost* render_view_host, diff --git a/content/shell/shell_url_request_context_getter.cc b/content/shell/shell_url_request_context_getter.cc index 70a3dae..c3a847f 100644 --- a/content/shell/shell_url_request_context_getter.cc +++ b/content/shell/shell_url_request_context_getter.cc @@ -27,6 +27,8 @@ #include "net/ssl/default_server_bound_cert_store.h" #include "net/ssl/server_bound_cert_service.h" #include "net/ssl/ssl_config_service_defaults.h" +#include "net/url_request/data_protocol_handler.h" +#include "net/url_request/file_protocol_handler.h" #include "net/url_request/protocol_intercept_job_factory.h" #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_context.h" @@ -176,7 +178,17 @@ net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() { scoped_ptr<net::URLRequestJobFactoryImpl> job_factory( new net::URLRequestJobFactoryImpl()); + // Keep ProtocolHandlers added in sync with + // ShellContentBrowserClient::IsHandledURL(). InstallProtocolHandlers(job_factory.get(), &protocol_handlers_); + bool set_protocol = job_factory->SetProtocolHandler( + chrome::kDataScheme, + new net::DataProtocolHandler); + DCHECK(set_protocol); + set_protocol = job_factory->SetProtocolHandler( + chrome::kFileScheme, + new net::FileProtocolHandler); + DCHECK(set_protocol); storage_->set_job_factory(job_factory.release()); } diff --git a/net/ftp/ftp_network_session.h b/net/ftp/ftp_network_session.h index c9b3388..e92bb06 100644 --- a/net/ftp/ftp_network_session.h +++ b/net/ftp/ftp_network_session.h @@ -7,7 +7,6 @@ #include "base/memory/ref_counted.h" #include "net/base/net_export.h" -#include "net/ftp/ftp_auth_cache.h" namespace net { @@ -20,7 +19,6 @@ class NET_EXPORT_PRIVATE FtpNetworkSession explicit FtpNetworkSession(HostResolver* host_resolver); HostResolver* host_resolver() { return host_resolver_; } - FtpAuthCache* auth_cache() { return &auth_cache_; } private: friend class base::RefCounted<FtpNetworkSession>; @@ -28,7 +26,6 @@ class NET_EXPORT_PRIVATE FtpNetworkSession virtual ~FtpNetworkSession(); HostResolver* const host_resolver_; - FtpAuthCache auth_cache_; }; } // namespace net diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc index e4ea2b9..42117e3 100644 --- a/net/proxy/proxy_script_fetcher_impl_unittest.cc +++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc @@ -21,6 +21,7 @@ #include "net/http/http_server_properties_impl.h" #include "net/ssl/ssl_config_service_defaults.h" #include "net/test/test_server.h" +#include "net/url_request/file_protocol_handler.h" #include "net/url_request/url_request_context_storage.h" #include "net/url_request/url_request_file_job.h" #include "net/url_request/url_request_job_factory_impl.h" @@ -66,7 +67,9 @@ class RequestContext : public URLRequestContext { storage_.set_http_transaction_factory(new HttpCache( network_session, HttpCache::DefaultBackend::InMemory(0))); - storage_.set_job_factory(new URLRequestJobFactoryImpl()); + URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl(); + job_factory->SetProtocolHandler("file", new FileProtocolHandler()); + storage_.set_job_factory(job_factory); } virtual ~RequestContext() { diff --git a/net/url_request/file_protocol_handler.cc b/net/url_request/file_protocol_handler.cc index 13a772e..c58c56b 100644 --- a/net/url_request/file_protocol_handler.cc +++ b/net/url_request/file_protocol_handler.cc @@ -44,4 +44,8 @@ URLRequestJob* FileProtocolHandler::MaybeCreateJob( return new URLRequestFileJob(request, network_delegate, file_path); } +bool FileProtocolHandler::IsSafeRedirectTarget(const GURL& location) const { + return false; +} + } // namespace net diff --git a/net/url_request/file_protocol_handler.h b/net/url_request/file_protocol_handler.h index 619227b..8087a6e 100644 --- a/net/url_request/file_protocol_handler.h +++ b/net/url_request/file_protocol_handler.h @@ -9,6 +9,8 @@ #include "base/compiler_specific.h" #include "net/url_request/url_request_job_factory.h" +class GURL; + namespace net { class NetworkDelegate; @@ -22,6 +24,7 @@ class NET_EXPORT FileProtocolHandler : FileProtocolHandler(); virtual URLRequestJob* MaybeCreateJob( URLRequest* request, NetworkDelegate* network_delegate) const OVERRIDE; + virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE; private: DISALLOW_COPY_AND_ASSIGN(FileProtocolHandler); diff --git a/net/url_request/ftp_protocol_handler.cc b/net/url_request/ftp_protocol_handler.cc index 7d9ba88..08071f3 100644 --- a/net/url_request/ftp_protocol_handler.cc +++ b/net/url_request/ftp_protocol_handler.cc @@ -15,12 +15,9 @@ namespace net { FtpProtocolHandler::FtpProtocolHandler( - FtpTransactionFactory* ftp_transaction_factory, - FtpAuthCache* ftp_auth_cache) - : ftp_transaction_factory_(ftp_transaction_factory), - ftp_auth_cache_(ftp_auth_cache) { + FtpTransactionFactory* ftp_transaction_factory) + : ftp_transaction_factory_(ftp_transaction_factory) { DCHECK(ftp_transaction_factory_); - DCHECK(ftp_auth_cache_); } URLRequestJob* FtpProtocolHandler::MaybeCreateJob( @@ -34,7 +31,7 @@ URLRequestJob* FtpProtocolHandler::MaybeCreateJob( return new URLRequestFtpJob(request, network_delegate, ftp_transaction_factory_, - ftp_auth_cache_); + &ftp_auth_cache_); } } // namespace net diff --git a/net/url_request/ftp_protocol_handler.h b/net/url_request/ftp_protocol_handler.h index 871f422..52aea7c 100644 --- a/net/url_request/ftp_protocol_handler.h +++ b/net/url_request/ftp_protocol_handler.h @@ -7,11 +7,11 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "net/ftp/ftp_auth_cache.h" #include "net/url_request/url_request_job_factory.h" namespace net { -class FtpAuthCache; class FtpTransactionFactory; class NetworkDelegate; class URLRequestJob; @@ -20,14 +20,13 @@ class URLRequestJob; class NET_EXPORT FtpProtocolHandler : public URLRequestJobFactory::ProtocolHandler { public: - FtpProtocolHandler(FtpTransactionFactory* ftp_transaction_factory, - FtpAuthCache* ftp_auth_cache); + explicit FtpProtocolHandler(FtpTransactionFactory* ftp_transaction_factory); virtual URLRequestJob* MaybeCreateJob( URLRequest* request, NetworkDelegate* network_delegate) const OVERRIDE; private: FtpTransactionFactory* ftp_transaction_factory_; - FtpAuthCache* ftp_auth_cache_; + mutable FtpAuthCache ftp_auth_cache_; DISALLOW_COPY_AND_ASSIGN(FtpProtocolHandler); }; diff --git a/net/url_request/protocol_intercept_job_factory.cc b/net/url_request/protocol_intercept_job_factory.cc index f72fbf9..d0f92f4 100644 --- a/net/url_request/protocol_intercept_job_factory.cc +++ b/net/url_request/protocol_intercept_job_factory.cc @@ -39,4 +39,9 @@ bool ProtocolInterceptJobFactory::IsHandledURL(const GURL& url) const { return job_factory_->IsHandledURL(url); } +bool ProtocolInterceptJobFactory::IsSafeRedirectTarget( + const GURL& location) const { + return job_factory_->IsSafeRedirectTarget(location); +} + } // namespace net diff --git a/net/url_request/protocol_intercept_job_factory.h b/net/url_request/protocol_intercept_job_factory.h index 7deeb30..abc2fb8 100644 --- a/net/url_request/protocol_intercept_job_factory.h +++ b/net/url_request/protocol_intercept_job_factory.h @@ -22,6 +22,8 @@ class URLRequestJob; // given the option of creating a URLRequestJob for each potential URLRequest. // If |protocol_handler_| does not create a job (i.e. MaybeCreateJob() returns // NULL) the URLRequest is forwarded to the |job_factory_| to be handled there. +// Only the MaybeCreateJob() member of |protocol_handler_| is called; the +// IsSafeRedirectTarget() member is not used. class NET_EXPORT ProtocolInterceptJobFactory : public URLRequestJobFactory { public: ProtocolInterceptJobFactory(scoped_ptr<URLRequestJobFactory> job_factory, @@ -35,6 +37,7 @@ class NET_EXPORT ProtocolInterceptJobFactory : public URLRequestJobFactory { NetworkDelegate* network_delegate) const OVERRIDE; virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE; virtual bool IsHandledURL(const GURL& url) const OVERRIDE; + virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE; private: scoped_ptr<URLRequestJobFactory> job_factory_; diff --git a/net/url_request/url_request_about_job.cc b/net/url_request/url_request_about_job.cc index 242a735..04ad6d8 100644 --- a/net/url_request/url_request_about_job.cc +++ b/net/url_request/url_request_about_job.cc @@ -20,13 +20,6 @@ URLRequestAboutJob::URLRequestAboutJob(URLRequest* request, ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { } -// static -URLRequestJob* URLRequestAboutJob::Factory(URLRequest* request, - NetworkDelegate* network_delegate, - const std::string& scheme) { - return new URLRequestAboutJob(request, network_delegate); -} - void URLRequestAboutJob::Start() { // Start reading asynchronously so that all error reporting and data // callbacks happen as they would for network requests. diff --git a/net/url_request/url_request_about_job.h b/net/url_request/url_request_about_job.h index ea2b83f..66a888a 100644 --- a/net/url_request/url_request_about_job.h +++ b/net/url_request/url_request_about_job.h @@ -17,8 +17,6 @@ class NET_EXPORT URLRequestAboutJob : public URLRequestJob { public: URLRequestAboutJob(URLRequest* request, NetworkDelegate* network_delegate); - static URLRequest::ProtocolFactory Factory; - // URLRequestJob: virtual void Start() OVERRIDE; virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc index e88750b..ae3a938 100644 --- a/net/url_request/url_request_context.cc +++ b/net/url_request/url_request_context.cc @@ -10,7 +10,6 @@ #include "base/string_util.h" #include "net/base/host_resolver.h" #include "net/cookies/cookie_store.h" -#include "net/ftp/ftp_transaction_factory.h" #include "net/http/http_transaction_factory.h" #include "net/url_request/http_user_agent_settings.h" #include "net/url_request/url_request.h" @@ -29,11 +28,7 @@ URLRequestContext::URLRequestContext() http_server_properties_(NULL), http_user_agent_settings_(NULL), transport_security_state_(NULL), -#if !defined(DISABLE_FTP_SUPPORT) - ftp_auth_cache_(new FtpAuthCache), -#endif http_transaction_factory_(NULL), - ftp_transaction_factory_(NULL), job_factory_(NULL), throttler_manager_(NULL), url_requests_(new std::set<const URLRequest*>) { @@ -57,9 +52,7 @@ void URLRequestContext::CopyFrom(const URLRequestContext* other) { set_http_server_properties(other->http_server_properties_); set_cookie_store(other->cookie_store_); set_transport_security_state(other->transport_security_state_); - // FTPAuthCache is unique per context. set_http_transaction_factory(other->http_transaction_factory_); - set_ftp_transaction_factory(other->ftp_transaction_factory_); set_job_factory(other->job_factory_); set_throttler_manager(other->throttler_manager_); set_http_user_agent_settings(other->http_user_agent_settings_); diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h index f5dc635..bb26897 100644 --- a/net/url_request/url_request_context.h +++ b/net/url_request/url_request_context.h @@ -19,7 +19,6 @@ #include "base/threading/non_thread_safe.h" #include "net/base/net_export.h" #include "net/base/net_log.h" -#include "net/ftp/ftp_auth_cache.h" #include "net/http/http_network_session.h" #include "net/http/http_server_properties.h" #include "net/http/transport_security_state.h" @@ -30,7 +29,6 @@ namespace net { class CertVerifier; class CookieStore; class FraudulentCertificateReporter; -class FtpTransactionFactory; class HostResolver; class HttpAuthHandlerFactory; class HttpTransactionFactory; @@ -131,14 +129,6 @@ class NET_EXPORT URLRequestContext http_transaction_factory_ = factory; } - // Gets the ftp transaction factory for this context. - FtpTransactionFactory* ftp_transaction_factory() const { - return ftp_transaction_factory_; - } - void set_ftp_transaction_factory(FtpTransactionFactory* factory) { - ftp_transaction_factory_ = factory; - } - void set_network_delegate(NetworkDelegate* network_delegate) { network_delegate_ = network_delegate; } @@ -165,15 +155,6 @@ class NET_EXPORT URLRequestContext transport_security_state_ = state; } - // Gets the FTP authentication cache for this context. - FtpAuthCache* ftp_auth_cache() const { -#if !defined(DISABLE_FTP_SUPPORT) - return ftp_auth_cache_.get(); -#else - return NULL; -#endif - } - // --------------------------------------------------------------------------- // Legacy accessors that delegate to http_user_agent_settings_. // TODO(pauljensen): Remove after all clients are updated to directly access @@ -237,11 +218,7 @@ class NET_EXPORT URLRequestContext HttpUserAgentSettings* http_user_agent_settings_; scoped_refptr<CookieStore> cookie_store_; TransportSecurityState* transport_security_state_; -#if !defined(DISABLE_FTP_SUPPORT) - scoped_ptr<FtpAuthCache> ftp_auth_cache_; -#endif HttpTransactionFactory* http_transaction_factory_; - FtpTransactionFactory* ftp_transaction_factory_; const URLRequestJobFactory* job_factory_; URLRequestThrottlerManager* throttler_manager_; diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc index 498e0ca..4fd9bd9 100644 --- a/net/url_request/url_request_context_builder.cc +++ b/net/url_request/url_request_context_builder.cc @@ -26,9 +26,13 @@ #include "net/http/transport_security_state.h" #include "net/proxy/proxy_service.h" #include "net/ssl/ssl_config_service_defaults.h" +#include "net/url_request/data_protocol_handler.h" +#include "net/url_request/file_protocol_handler.h" +#include "net/url_request/ftp_protocol_handler.h" #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_storage.h" +#include "net/url_request/url_request_job_factory_impl.h" namespace net { @@ -180,7 +184,11 @@ URLRequestContextBuilder::HttpNetworkSessionParams::~HttpNetworkSessionParams() {} URLRequestContextBuilder::URLRequestContextBuilder() - : ftp_enabled_(false), + : data_enabled_(false), + file_enabled_(false), +#if !defined(DISABLE_FTP_SUPPORT) + ftp_enabled_(false), +#endif http_cache_enabled_(true) {} URLRequestContextBuilder::~URLRequestContextBuilder() {} @@ -205,11 +213,6 @@ URLRequestContext* URLRequestContextBuilder::Build() { storage->set_host_resolver(net::HostResolver::CreateDefaultResolver(NULL)); - if (ftp_enabled_) { - storage->set_ftp_transaction_factory( - new FtpNetworkLayer(context->host_resolver())); - } - context->StartFileThread(); // TODO(willchan): Switch to using this code when @@ -290,6 +293,21 @@ URLRequestContext* URLRequestContextBuilder::Build() { } storage->set_http_transaction_factory(http_transaction_factory); + URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl; + if (data_enabled_) + job_factory->SetProtocolHandler("data", new DataProtocolHandler); + if (file_enabled_) + job_factory->SetProtocolHandler("file", new FileProtocolHandler); +#if !defined(DISABLE_FTP_SUPPORT) + if (ftp_enabled_) { + ftp_transaction_factory_.reset( + new FtpNetworkLayer(context->host_resolver())); + job_factory->SetProtocolHandler("ftp", + new FtpProtocolHandler(ftp_transaction_factory_.get())); + } +#endif + storage->set_job_factory(job_factory); + // TODO(willchan): Support sdch. return context; diff --git a/net/url_request/url_request_context_builder.h b/net/url_request/url_request_context_builder.h index 2163ed5..20fc30e 100644 --- a/net/url_request/url_request_context_builder.h +++ b/net/url_request/url_request_context_builder.h @@ -25,6 +25,7 @@ namespace net { +class FtpTransactionFactory; class HostMappingRules; class ProxyConfigService; class URLRequestContext; @@ -82,10 +83,22 @@ class NET_EXPORT URLRequestContextBuilder { user_agent_ = user_agent; } - // By default it's disabled. + // Control support for data:// requests. By default it's disabled. + void set_data_enabled(bool enable) { + data_enabled_ = enable; + } + + // Control support for file:// requests. By default it's disabled. + void set_file_enabled(bool enable) { + file_enabled_ = enable; + } + +#if !defined(DISABLE_FTP_SUPPORT) + // Control support for ftp:// requests. By default it's disabled. void set_ftp_enabled(bool enable) { ftp_enabled_ = enable; } +#endif // Uses BasicNetworkDelegate by default. Note that calling Build will unset // any custom delegate in builder, so this must be called each time before @@ -114,7 +127,14 @@ class NET_EXPORT URLRequestContextBuilder { private: std::string accept_language_; std::string user_agent_; + // Include support for data:// requests. + bool data_enabled_; + // Include support for file:// requests. + bool file_enabled_; +#if !defined(DISABLE_FTP_SUPPORT) + // Include support for ftp:// requests. bool ftp_enabled_; +#endif bool http_cache_enabled_; HttpCacheParams http_cache_params_; HttpNetworkSessionParams http_network_session_params_; @@ -122,6 +142,7 @@ class NET_EXPORT URLRequestContextBuilder { scoped_ptr<ProxyConfigService> proxy_config_service_; #endif // defined(OS_LINUX) || defined(OS_ANDROID) scoped_ptr<NetworkDelegate> network_delegate_; + scoped_ptr<FtpTransactionFactory> ftp_transaction_factory_; DISALLOW_COPY_AND_ASSIGN(URLRequestContextBuilder); }; diff --git a/net/url_request/url_request_context_storage.cc b/net/url_request/url_request_context_storage.cc index e201b8e..7104ab8 100644 --- a/net/url_request/url_request_context_storage.cc +++ b/net/url_request/url_request_context_storage.cc @@ -106,12 +106,6 @@ void URLRequestContextStorage::set_http_transaction_factory( http_transaction_factory_.reset(http_transaction_factory); } -void URLRequestContextStorage::set_ftp_transaction_factory( - FtpTransactionFactory* ftp_transaction_factory) { - context_->set_ftp_transaction_factory(ftp_transaction_factory); - ftp_transaction_factory_.reset(ftp_transaction_factory); -} - void URLRequestContextStorage::set_job_factory( URLRequestJobFactory* job_factory) { context_->set_job_factory(job_factory); diff --git a/net/url_request/url_request_context_storage.h b/net/url_request/url_request_context_storage.h index e08b3c8..0a9d066 100644 --- a/net/url_request/url_request_context_storage.h +++ b/net/url_request/url_request_context_storage.h @@ -62,8 +62,6 @@ class NET_EXPORT URLRequestContextStorage { TransportSecurityState* transport_security_state); void set_http_transaction_factory( HttpTransactionFactory* http_transaction_factory); - void set_ftp_transaction_factory( - FtpTransactionFactory* ftp_transaction_factory); void set_job_factory(URLRequestJobFactory* job_factory); void set_throttler_manager(URLRequestThrottlerManager* throttler_manager); void set_http_user_agent_settings( @@ -93,7 +91,6 @@ class NET_EXPORT URLRequestContextStorage { scoped_ptr<TransportSecurityState> transport_security_state_; scoped_ptr<HttpTransactionFactory> http_transaction_factory_; - scoped_ptr<FtpTransactionFactory> ftp_transaction_factory_; scoped_ptr<URLRequestJobFactory> job_factory_; scoped_ptr<URLRequestThrottlerManager> throttler_manager_; diff --git a/net/url_request/url_request_data_job.cc b/net/url_request/url_request_data_job.cc index 5dffe32..fd248c7 100644 --- a/net/url_request/url_request_data_job.cc +++ b/net/url_request/url_request_data_job.cc @@ -16,13 +16,6 @@ URLRequestDataJob::URLRequestDataJob( : URLRequestSimpleJob(request, network_delegate) { } -// static -URLRequestJob* URLRequestDataJob::Factory(URLRequest* request, - NetworkDelegate* network_delegate, - const std::string& scheme) { - return new URLRequestDataJob(request, network_delegate); -} - int URLRequestDataJob::GetData(std::string* mime_type, std::string* charset, std::string* data, diff --git a/net/url_request/url_request_data_job.h b/net/url_request/url_request_data_job.h index 7ab6561..d9b2621 100644 --- a/net/url_request/url_request_data_job.h +++ b/net/url_request/url_request_data_job.h @@ -18,8 +18,6 @@ class URLRequestDataJob : public URLRequestSimpleJob { public: URLRequestDataJob(URLRequest* request, NetworkDelegate* network_delegate); - static URLRequest::ProtocolFactory Factory; - // URLRequestSimpleJob virtual int GetData(std::string* mime_type, std::string* charset, diff --git a/net/url_request/url_request_file_job.cc b/net/url_request/url_request_file_job.cc index 6b2798b..28dbcd5 100644 --- a/net/url_request/url_request_file_job.cc +++ b/net/url_request/url_request_file_job.cc @@ -62,34 +62,6 @@ URLRequestFileJob::URLRequestFileJob(URLRequest* request, weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { } -// static -URLRequestJob* URLRequestFileJob::Factory(URLRequest* request, - NetworkDelegate* network_delegate, - const std::string& scheme) { - base::FilePath file_path; - const bool is_file = FileURLToFilePath(request->url(), &file_path); - - // Check file access permissions. - if (!network_delegate || - !network_delegate->CanAccessFile(*request, file_path)) { - return new URLRequestErrorJob(request, network_delegate, ERR_ACCESS_DENIED); - } - // We need to decide whether to create URLRequestFileJob for file access or - // URLRequestFileDirJob for directory access. To avoid accessing the - // filesystem, we only look at the path string here. - // The code in the URLRequestFileJob::Start() method discovers that a path, - // which doesn't end with a slash, should really be treated as a directory, - // and it then redirects to the URLRequestFileDirJob. - if (is_file && - file_util::EndsWithSeparator(file_path) && - file_path.IsAbsolute()) - return new URLRequestFileDirJob(request, network_delegate, file_path); - - // Use a regular file request job for all non-directories (including invalid - // file names). - return new URLRequestFileJob(request, network_delegate, file_path); -} - void URLRequestFileJob::Start() { FileMetaInfo* meta_info = new FileMetaInfo(); base::WorkerPool::PostTaskAndReply( diff --git a/net/url_request/url_request_file_job.h b/net/url_request/url_request_file_job.h index 0d9e192..6fc7fb9 100644 --- a/net/url_request/url_request_file_job.h +++ b/net/url_request/url_request_file_job.h @@ -33,8 +33,6 @@ class NET_EXPORT URLRequestFileJob : public URLRequestJob { NetworkDelegate* network_delegate, const base::FilePath& file_path); - static URLRequest::ProtocolFactory Factory; - // URLRequestJob: virtual void Start() OVERRIDE; virtual void Kill() OVERRIDE; diff --git a/net/url_request/url_request_ftp_job.cc b/net/url_request/url_request_ftp_job.cc index 343c4d7..62124e1 100644 --- a/net/url_request/url_request_ftp_job.cc +++ b/net/url_request/url_request_ftp_job.cc @@ -12,6 +12,7 @@ #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/base/net_util.h" +#include "net/ftp/ftp_auth_cache.h" #include "net/ftp/ftp_response_info.h" #include "net/ftp/ftp_transaction_factory.h" #include "net/http/http_response_headers.h" @@ -38,26 +39,6 @@ URLRequestFtpJob::URLRequestFtpJob( DCHECK(ftp_auth_cache); } -// static -URLRequestJob* URLRequestFtpJob::Factory(URLRequest* request, - NetworkDelegate* network_delegate, - const std::string& scheme) { - DCHECK_EQ(scheme, "ftp"); - - int port = request->url().IntPort(); - if (request->url().has_port() && - !IsPortAllowedByFtp(port) && !IsPortAllowedByOverride(port)) { - return new URLRequestErrorJob(request, - network_delegate, - ERR_UNSAFE_PORT); - } - - return new URLRequestFtpJob(request, - network_delegate, - request->context()->ftp_transaction_factory(), - request->context()->ftp_auth_cache()); -} - bool URLRequestFtpJob::IsSafeRedirect(const GURL& location) { // Disallow all redirects. return false; diff --git a/net/url_request/url_request_ftp_job.h b/net/url_request/url_request_ftp_job.h index 3b053c1..dd16b9a 100644 --- a/net/url_request/url_request_ftp_job.h +++ b/net/url_request/url_request_ftp_job.h @@ -32,11 +32,6 @@ class URLRequestFtpJob : public URLRequestJob { FtpTransactionFactory* ftp_transaction_factory, FtpAuthCache* ftp_auth_cache); - // TODO(shalev): get rid of this function in favor of FtpProtocolHandler. - static URLRequestJob* Factory(URLRequest* request, - NetworkDelegate* network_delegate, - const std::string& scheme); - // Overridden from URLRequestJob: virtual bool IsSafeRedirect(const GURL& location) OVERRIDE; virtual bool GetMimeType(std::string* mime_type) const OVERRIDE; diff --git a/net/url_request/url_request_ftp_job_unittest.cc b/net/url_request/url_request_ftp_job_unittest.cc index 61dde753..50f5d05 100644 --- a/net/url_request/url_request_ftp_job_unittest.cc +++ b/net/url_request/url_request_ftp_job_unittest.cc @@ -6,10 +6,13 @@ #include "base/run_loop.h" #include "net/proxy/proxy_config_service.h" #include "net/socket/socket_test_util.h" +#include "net/url_request/ftp_protocol_handler.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_job_factory_impl.h" #include "net/url_request/url_request_status.h" #include "net/url_request/url_request_test_util.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { @@ -49,15 +52,26 @@ class SimpleProxyConfigService : public ProxyConfigService { Observer* observer_; }; +class MockFtpTransactionFactory : public FtpTransactionFactory { + public: + MOCK_METHOD0(CreateTransaction, FtpTransaction*()); + MOCK_METHOD1(Suspend, void(bool suspend)); +}; + class FtpTestURLRequestContext : public TestURLRequestContext { public: FtpTestURLRequestContext(ClientSocketFactory* socket_factory, ProxyService* proxy_service, - NetworkDelegate* network_delegate) + NetworkDelegate* network_delegate, + FtpTransactionFactory* ftp_transaction_factory) : TestURLRequestContext(true) { set_client_socket_factory(socket_factory); context_storage_.set_proxy_service(proxy_service); set_network_delegate(network_delegate); + URLRequestJobFactoryImpl* job_factory = new URLRequestJobFactoryImpl; + job_factory->SetProtocolHandler( + "ftp", new FtpProtocolHandler(ftp_transaction_factory)); + context_storage_.set_job_factory(job_factory); Init(); } }; @@ -69,7 +83,8 @@ class URLRequestFtpJobTest : public testing::Test { new SimpleProxyConfigService, NULL, NULL)), request_context_(&socket_factory_, proxy_service_, - &network_delegate_) { + &network_delegate_, + &ftp_transaction_factory_) { } virtual ~URLRequestFtpJobTest() { @@ -99,6 +114,7 @@ class URLRequestFtpJobTest : public testing::Test { ScopedVector<DeterministicSocketData> socket_data_; DeterministicMockClientSocketFactory socket_factory_; TestNetworkDelegate network_delegate_; + ::testing::StrictMock<MockFtpTransactionFactory> ftp_transaction_factory_; // Owned by |request_context_|: ProxyService* proxy_service_; diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index 716fe4c..5b116b9 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -43,6 +43,7 @@ #include "net/url_request/url_request.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_error_job.h" +#include "net/url_request/url_request_job_factory.h" #include "net/url_request/url_request_redirect_job.h" #include "net/url_request/url_request_throttler_header_adapter.h" #include "net/url_request/url_request_throttler_manager.h" @@ -1013,25 +1014,16 @@ Filter* URLRequestHttpJob::SetupFilter() const { } bool URLRequestHttpJob::IsSafeRedirect(const GURL& location) { - // We only allow redirects to certain "safe" protocols. This does not - // restrict redirects to externally handled protocols. Our consumer would - // need to take care of those. - - if (!URLRequest::IsHandledURL(location)) + // HTTP is always safe. + // TODO(pauljensen): Remove once crbug.com/146591 is fixed. + if (location.is_valid() && + (location.scheme() == "http" || location.scheme() == "https")) { return true; - - static const char* kSafeSchemes[] = { - "http", - "https", - "ftp" - }; - - for (size_t i = 0; i < arraysize(kSafeSchemes); ++i) { - if (location.SchemeIs(kSafeSchemes[i])) - return true; } - - return false; + // Query URLRequestJobFactory as to whether |location| would be safe to + // redirect to. + return request_->context()->job_factory() && + request_->context()->job_factory()->IsSafeRedirectTarget(location); } bool URLRequestHttpJob::NeedsAuth() { diff --git a/net/url_request/url_request_job_factory.cc b/net/url_request/url_request_job_factory.cc index c1f070b..e203cb1 100644 --- a/net/url_request/url_request_job_factory.cc +++ b/net/url_request/url_request_job_factory.cc @@ -8,6 +8,11 @@ namespace net { URLRequestJobFactory::ProtocolHandler::~ProtocolHandler() {} +bool URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget( + const GURL& location) const { + return true; +} + URLRequestJobFactory::URLRequestJobFactory() {} URLRequestJobFactory::~URLRequestJobFactory() {} diff --git a/net/url_request/url_request_job_factory.h b/net/url_request/url_request_job_factory.h index bbd1d09..d4cc49e 100644 --- a/net/url_request/url_request_job_factory.h +++ b/net/url_request/url_request_job_factory.h @@ -30,6 +30,13 @@ class NET_EXPORT URLRequestJobFactory virtual URLRequestJob* MaybeCreateJob( URLRequest* request, NetworkDelegate* network_delegate) const = 0; + + // Indicates if it should be safe to redirect to |location|. Should handle + // protocols handled by MaybeCreateJob(). Only called when registered with + // URLRequestJobFactoryImpl::SetProtocolHandler() not called when used with + // ProtocolInterceptJobFactory. + // NOTE(pauljensen): Default implementation returns true. + virtual bool IsSafeRedirectTarget(const GURL& location) const; }; URLRequestJobFactory(); @@ -44,6 +51,8 @@ class NET_EXPORT URLRequestJobFactory virtual bool IsHandledURL(const GURL& url) const = 0; + virtual bool IsSafeRedirectTarget(const GURL& location) const = 0; + private: DISALLOW_COPY_AND_ASSIGN(URLRequestJobFactory); }; diff --git a/net/url_request/url_request_job_factory_impl.cc b/net/url_request/url_request_job_factory_impl.cc index f4c1d01..84fb951 100644 --- a/net/url_request/url_request_job_factory_impl.cc +++ b/net/url_request/url_request_job_factory_impl.cc @@ -64,4 +64,20 @@ bool URLRequestJobFactoryImpl::IsHandledURL(const GURL& url) const { return IsHandledProtocol(url.scheme()); } +bool URLRequestJobFactoryImpl::IsSafeRedirectTarget( + const GURL& location) const { + DCHECK(CalledOnValidThread()); + if (!location.is_valid()) { + // Error cases are safely handled. + return true; + } + ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find( + location.scheme()); + if (it == protocol_handler_map_.end()) { + // Unhandled cases are safely handled. + return true; + } + return it->second->IsSafeRedirectTarget(location); +} + } // namespace net diff --git a/net/url_request/url_request_job_factory_impl.h b/net/url_request/url_request_job_factory_impl.h index 8f394e2..4f03fb0 100644 --- a/net/url_request/url_request_job_factory_impl.h +++ b/net/url_request/url_request_job_factory_impl.h @@ -33,6 +33,7 @@ class NET_EXPORT URLRequestJobFactoryImpl : public URLRequestJobFactory { NetworkDelegate* network_delegate) const OVERRIDE; virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE; virtual bool IsHandledURL(const GURL& url) const OVERRIDE; + virtual bool IsSafeRedirectTarget(const GURL& location) const OVERRIDE; private: typedef std::map<std::string, ProtocolHandler*> ProtocolHandlerMap; diff --git a/net/url_request/url_request_job_manager.cc b/net/url_request/url_request_job_manager.cc index 283ee0d..5a64b41 100644 --- a/net/url_request/url_request_job_manager.cc +++ b/net/url_request/url_request_job_manager.cc @@ -12,12 +12,8 @@ #include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/base/network_delegate.h" -#include "net/url_request/url_request_about_job.h" #include "net/url_request/url_request_context.h" -#include "net/url_request/url_request_data_job.h" #include "net/url_request/url_request_error_job.h" -#include "net/url_request/url_request_file_job.h" -#include "net/url_request/url_request_ftp_job.h" #include "net/url_request/url_request_http_job.h" #include "net/url_request/url_request_job_factory.h" @@ -36,12 +32,6 @@ struct SchemeToFactory { static const SchemeToFactory kBuiltinFactories[] = { { "http", URLRequestHttpJob::Factory }, { "https", URLRequestHttpJob::Factory }, - { "file", URLRequestFileJob::Factory }, -#if !defined(DISABLE_FTP_SUPPORT) - { "ftp", URLRequestFtpJob::Factory }, -#endif - { "about", URLRequestAboutJob::Factory }, - { "data", URLRequestDataJob::Factory }, }; // static diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index e5c0051..5f00999 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc @@ -72,14 +72,6 @@ void TestURLRequestContext::Init() { context_storage_.set_proxy_service(ProxyService::CreateDirect()); if (!cert_verifier()) context_storage_.set_cert_verifier(CertVerifier::CreateDefault()); - if (!ftp_transaction_factory()) { -#if !defined(DISABLE_FTP_SUPPORT) - context_storage_.set_ftp_transaction_factory( - new FtpNetworkLayer(host_resolver())); -#else - context_storage_.set_ftp_transaction_factory(NULL); -#endif // !defined(DISABLE_FTP_SUPPORT) - } if (!ssl_config_service()) context_storage_.set_ssl_config_service(new SSLConfigServiceDefaults); if (!http_auth_handler_factory()) { diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 32b99ac..c7e535a 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -58,6 +58,8 @@ #include "net/socket/ssl_client_socket.h" #include "net/ssl/ssl_connection_status_flags.h" #include "net/test/test_server.h" +#include "net/url_request/data_protocol_handler.h" +#include "net/url_request/file_protocol_handler.h" #include "net/url_request/ftp_protocol_handler.h" #include "net/url_request/static_http_user_agent_settings.h" #include "net/url_request/url_request.h" @@ -514,6 +516,9 @@ class URLRequestTest : public PlatformTest { URLRequestTest() : default_context_(true) { default_context_.set_network_delegate(&default_network_delegate_); default_context_.set_net_log(&net_log_); + job_factory_.SetProtocolHandler("data", new DataProtocolHandler); + job_factory_.SetProtocolHandler("file", new FileProtocolHandler); + default_context_.set_job_factory(&job_factory_); default_context_.Init(); } virtual ~URLRequestTest() {} @@ -521,16 +526,14 @@ class URLRequestTest : public PlatformTest { // Adds the TestJobInterceptor to the default context. TestJobInterceptor* AddTestInterceptor() { TestJobInterceptor* protocol_handler_ = new TestJobInterceptor(); - job_factory_.reset(new URLRequestJobFactoryImpl); - job_factory_->SetProtocolHandler("http", protocol_handler_); - default_context_.set_job_factory(job_factory_.get()); + job_factory_.SetProtocolHandler("http", protocol_handler_); return protocol_handler_; } protected: CapturingNetLog net_log_; TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest. - scoped_ptr<URLRequestJobFactoryImpl> job_factory_; + URLRequestJobFactoryImpl job_factory_; TestURLRequestContext default_context_; }; @@ -3464,6 +3467,20 @@ TEST_F(URLRequestTestHTTP, ContentTypeNormalizationTest) { req.Cancel(); } +TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictRedirects) { + // Test URLRequestJobFactory::ProtocolHandler::IsSafeRedirectTarget(). + GURL file_url("file:///foo.txt"); + GURL data_url("data:,foo"); + FileProtocolHandler file_protocol_handler; + EXPECT_FALSE(file_protocol_handler.IsSafeRedirectTarget(file_url)); + DataProtocolHandler data_protocol_handler; + EXPECT_TRUE(data_protocol_handler.IsSafeRedirectTarget(data_url)); + + // Test URLRequestJobFactoryImpl::IsSafeRedirectTarget(). + EXPECT_FALSE(job_factory_.IsSafeRedirectTarget(file_url)); + EXPECT_TRUE(job_factory_.IsSafeRedirectTarget(data_url)); +} + TEST_F(URLRequestTestHTTP, RestrictRedirects) { ASSERT_TRUE(test_server_.Start()); @@ -4983,15 +5000,12 @@ TEST_F(URLRequestTestFTP, UnsafePort) { ASSERT_TRUE(test_server_.Start()); URLRequestJobFactoryImpl job_factory; + FtpNetworkLayer ftp_transaction_factory(default_context_.host_resolver()); GURL url("ftp://127.0.0.1:7"); - FtpProtocolHandler ftp_protocol_handler( - default_context_.ftp_transaction_factory(), - default_context_.ftp_auth_cache()); job_factory.SetProtocolHandler( "ftp", - new FtpProtocolHandler(default_context_.ftp_transaction_factory(), - default_context_.ftp_auth_cache())); + new FtpProtocolHandler(&ftp_transaction_factory)); default_context_.set_job_factory(&job_factory); TestDelegate d; diff --git a/webkit/tools/test_shell/test_shell_request_context.cc b/webkit/tools/test_shell/test_shell_request_context.cc index bfd2eb4d..1e71999 100644 --- a/webkit/tools/test_shell/test_shell_request_context.cc +++ b/webkit/tools/test_shell/test_shell_request_context.cc @@ -13,7 +13,6 @@ #include "net/base/cert_verifier.h" #include "net/base/host_resolver.h" #include "net/cookies/cookie_monster.h" -#include "net/ftp/ftp_network_layer.h" #include "net/http/http_auth_handler_factory.h" #include "net/http/http_network_session.h" #include "net/http/http_server_properties_impl.h" @@ -23,6 +22,7 @@ #include "net/ssl/default_server_bound_cert_store.h" #include "net/ssl/server_bound_cert_service.h" #include "net/ssl/ssl_config_service_defaults.h" +#include "net/url_request/file_protocol_handler.h" #include "net/url_request/http_user_agent_settings.h" #include "net/url_request/url_request_job_factory_impl.h" #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h" @@ -114,9 +114,6 @@ void TestShellRequestContext::Init( cache->set_mode(cache_mode); storage_.set_http_transaction_factory(cache); - storage_.set_ftp_transaction_factory( - new net::FtpNetworkLayer(host_resolver())); - blob_storage_controller_.reset(new webkit_blob::BlobStorageController()); file_system_context_ = static_cast<SimpleFileSystem*>( WebKit::Platform::current()->fileSystem())->file_system_context(); @@ -132,6 +129,7 @@ void TestShellRequestContext::Init( job_factory->SetProtocolHandler( "filesystem", fileapi::CreateFileSystemProtocolHandler(file_system_context_.get())); + job_factory->SetProtocolHandler("file", new net::FileProtocolHandler); storage_.set_job_factory(job_factory); } |