diff --git a/atom.gyp b/atom.gyp index 3d1a6ffe3a0..91375d53949 100644 --- a/atom.gyp +++ b/atom.gyp @@ -61,6 +61,8 @@ 'browser/api/atom_api_window.h', 'browser/api/atom_browser_bindings.cc', 'browser/api/atom_browser_bindings.h', + 'browser/atom_url_request_job_factory.cc', + 'browser/atom_url_request_job_factory.h', 'browser/auto_updater.cc', 'browser/auto_updater.h', 'browser/auto_updater_delegate.cc', diff --git a/browser/api/atom_api_protocol.cc b/browser/api/atom_api_protocol.cc index 170ef1e55e5..5094c98e7bd 100644 --- a/browser/api/atom_api_protocol.cc +++ b/browser/api/atom_api_protocol.cc @@ -6,12 +6,12 @@ #include "base/memory/weak_ptr.h" #include "browser/atom_browser_context.h" +#include "browser/atom_url_request_job_factory.h" #include "content/public/browser/browser_thread.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.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_job_factory_impl.h" #include "net/url_request/url_request_simple_job.h" #include "vendor/node/src/node.h" #include "vendor/node/src/node_internals.h" @@ -22,7 +22,7 @@ namespace api { namespace { -// Remember the protocol module object. +// The protocol module object. v8::Persistent g_protocol_object; // Registered protocol handlers. @@ -53,15 +53,13 @@ v8::Handle ConvertURLRequestToV8Object( return obj; } -net::URLRequestJobFactoryImpl* GetRequestJobFactory() { +// Get the job factory. +AtomURLRequestJobFactory* GetRequestJobFactory() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - // Get the job factory. - net::URLRequestJobFactoryImpl* job_factory = - static_cast( - const_cast( - static_cast(AtomBrowserContext::Get())-> - GetRequestContext()->GetURLRequestContext()->job_factory())); - return job_factory; + return static_cast( + const_cast( + static_cast(AtomBrowserContext::Get())-> + GetRequestContext()->GetURLRequestContext()->job_factory())); } class URLRequestStringJob : public net::URLRequestSimpleJob { @@ -345,7 +343,7 @@ v8::Handle Protocol::UninterceptProtocol(const v8::Arguments& args) { // static void Protocol::RegisterProtocolInIO(const std::string& scheme) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - net::URLRequestJobFactoryImpl* job_factory(GetRequestJobFactory()); + AtomURLRequestJobFactory* job_factory(GetRequestJobFactory()); job_factory->SetProtocolHandler(scheme, new AdapterProtocolHandler); content::BrowserThread::PostTask(content::BrowserThread::UI, @@ -358,7 +356,7 @@ void Protocol::RegisterProtocolInIO(const std::string& scheme) { // static void Protocol::UnregisterProtocolInIO(const std::string& scheme) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - net::URLRequestJobFactoryImpl* job_factory(GetRequestJobFactory()); + AtomURLRequestJobFactory* job_factory(GetRequestJobFactory()); job_factory->SetProtocolHandler(scheme, NULL); content::BrowserThread::PostTask(content::BrowserThread::UI, @@ -371,7 +369,7 @@ void Protocol::UnregisterProtocolInIO(const std::string& scheme) { // static void Protocol::InterceptProtocolInIO(const std::string& scheme) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); - net::URLRequestJobFactoryImpl* job_factory(GetRequestJobFactory()); + AtomURLRequestJobFactory* job_factory(GetRequestJobFactory()); job_factory->SetProtocolHandler(scheme, new AdapterProtocolHandler); } @@ -381,6 +379,7 @@ void Protocol::UninterceptProtocolInIO(const std::string& scheme) { // static void Protocol::Initialize(v8::Handle target) { + // Remember the protocol object, used for emitting event later. g_protocol_object = v8::Persistent::New( node::node_isolate, target); diff --git a/browser/atom_browser_client.cc b/browser/atom_browser_client.cc index b3a04a1553c..d3f9964fba5 100644 --- a/browser/atom_browser_client.cc +++ b/browser/atom_browser_client.cc @@ -5,6 +5,13 @@ #include "browser/atom_browser_client.h" #include "browser/atom_browser_main_parts.h" +#include "browser/atom_url_request_job_factory.h" +#include "content/public/common/url_constants.h" +#include "net/url_request/data_protocol_handler.h" +#include "net/url_request/file_protocol_handler.h" +#include "net/url_request/url_request_context.h" +#include "net/url_request/url_request_context_storage.h" +#include "vendor/brightray/browser/url_request_context_getter.h" #include "webkit/glue/webpreferences.h" namespace atom { @@ -15,6 +22,36 @@ AtomBrowserClient::AtomBrowserClient() { AtomBrowserClient::~AtomBrowserClient() { } +net::URLRequestContextGetter* AtomBrowserClient::CreateRequestContext( + content::BrowserContext* browser_context, + content::ProtocolHandlerMap* protocol_handlers) { + content::ProtocolHandlerMap preset_handlers; + std::swap(preset_handlers, *protocol_handlers); + + // Create our implementaton of job factory. + AtomURLRequestJobFactory* job_factory = new AtomURLRequestJobFactory; + content::ProtocolHandlerMap::iterator it; + for (it = preset_handlers.begin(); it != preset_handlers.end(); ++it) + job_factory->SetProtocolHandler(it->first, it->second.release()); + job_factory->SetProtocolHandler(chrome::kDataScheme, + new net::DataProtocolHandler); + job_factory->SetProtocolHandler(chrome::kFileScheme, + new net::FileProtocolHandler); + + // Go through default procedure. + net::URLRequestContextGetter* request_context_getter = + brightray::BrowserClient::CreateRequestContext(browser_context, + protocol_handlers); + net::URLRequestContext* request_context = + request_context_getter->GetURLRequestContext(); + + // Replace default job factory. + storage_.reset(new net::URLRequestContextStorage(request_context)); + storage_->set_job_factory(job_factory); + + return request_context_getter; +} + void AtomBrowserClient::OverrideWebkitPrefs( content::RenderViewHost* render_view_host, const GURL& url, diff --git a/browser/atom_browser_client.h b/browser/atom_browser_client.h index 16fcbe3b9dd..456ea1a2913 100644 --- a/browser/atom_browser_client.h +++ b/browser/atom_browser_client.h @@ -7,6 +7,10 @@ #include "brightray/browser/browser_client.h" +namespace net { +class URLRequestContextStorage; +} + namespace atom { class AtomBrowserClient : public brightray::BrowserClient { @@ -15,6 +19,9 @@ class AtomBrowserClient : public brightray::BrowserClient { virtual ~AtomBrowserClient(); protected: + net::URLRequestContextGetter* CreateRequestContext( + content::BrowserContext* browser_context, + content::ProtocolHandlerMap* protocol_handlers) OVERRIDE; virtual void OverrideWebkitPrefs(content::RenderViewHost* render_view_host, const GURL& url, WebPreferences* prefs) OVERRIDE; @@ -27,6 +34,8 @@ class AtomBrowserClient : public brightray::BrowserClient { virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts( const content::MainFunctionParams&) OVERRIDE; + scoped_ptr storage_; + DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient); }; diff --git a/browser/atom_url_request_job_factory.cc b/browser/atom_url_request_job_factory.cc new file mode 100644 index 00000000000..b01d0886a0f --- /dev/null +++ b/browser/atom_url_request_job_factory.cc @@ -0,0 +1,68 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "browser/atom_url_request_job_factory.h" + +#include "base/stl_util.h" +#include "googleurl/src/gurl.h" +#include "net/base/load_flags.h" +#include "net/url_request/url_request.h" + +namespace atom { + +AtomURLRequestJobFactory::AtomURLRequestJobFactory() {} + +AtomURLRequestJobFactory::~AtomURLRequestJobFactory() { + STLDeleteValues(&protocol_handler_map_); +} + +bool AtomURLRequestJobFactory::SetProtocolHandler( + const std::string& scheme, + ProtocolHandler* protocol_handler) { + DCHECK(CalledOnValidThread()); + + if (!protocol_handler) { + ProtocolHandlerMap::iterator it = protocol_handler_map_.find(scheme); + if (it == protocol_handler_map_.end()) + return false; + + delete it->second; + protocol_handler_map_.erase(it); + return true; + } + + if (ContainsKey(protocol_handler_map_, scheme)) + return false; + protocol_handler_map_[scheme] = protocol_handler; + return true; +} + +net::URLRequestJob* AtomURLRequestJobFactory::MaybeCreateJobWithProtocolHandler( + const std::string& scheme, + net::URLRequest* request, + net::NetworkDelegate* network_delegate) const { + DCHECK(CalledOnValidThread()); + ProtocolHandlerMap::const_iterator it = protocol_handler_map_.find(scheme); + if (it == protocol_handler_map_.end()) + return NULL; + return it->second->MaybeCreateJob(request, network_delegate); +} + +bool AtomURLRequestJobFactory::IsHandledProtocol( + const std::string& scheme) const { + DCHECK(CalledOnValidThread()); + return ContainsKey(protocol_handler_map_, scheme) || + net::URLRequest::IsHandledProtocol(scheme); +} + +bool AtomURLRequestJobFactory::IsHandledURL(const GURL& url) const { + if (!url.is_valid()) { + // We handle error cases. + return true; + } + return IsHandledProtocol(url.scheme()); +} + +} // namespace atom diff --git a/browser/atom_url_request_job_factory.h b/browser/atom_url_request_job_factory.h new file mode 100644 index 00000000000..036020e24de --- /dev/null +++ b/browser/atom_url_request_job_factory.h @@ -0,0 +1,47 @@ +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_ATOM_URL_REQUEST_URL_REQUEST_JOB_FACTORY_H_ +#define ATOM_BROWSER_ATOM_URL_REQUEST_URL_REQUEST_JOB_FACTORY_H_ + +#include +#include + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "net/url_request/url_request_job_factory.h" + +namespace atom { + +class AtomURLRequestJobFactory : public net::URLRequestJobFactory { + public: + AtomURLRequestJobFactory(); + virtual ~AtomURLRequestJobFactory(); + + // Sets the ProtocolHandler for a scheme. Returns true on success, false on + // failure (a ProtocolHandler already exists for |scheme|). On success, + // URLRequestJobFactory takes ownership of |protocol_handler|. + bool SetProtocolHandler(const std::string& scheme, + ProtocolHandler* protocol_handler); + + // URLRequestJobFactory implementation + virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler( + const std::string& scheme, + net::URLRequest* request, + net::NetworkDelegate* network_delegate) const OVERRIDE; + virtual bool IsHandledProtocol(const std::string& scheme) const OVERRIDE; + virtual bool IsHandledURL(const GURL& url) const OVERRIDE; + + private: + typedef std::map ProtocolHandlerMap; + + ProtocolHandlerMap protocol_handler_map_; + + DISALLOW_COPY_AND_ASSIGN(AtomURLRequestJobFactory); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_ATOM_URL_REQUEST_URL_REQUEST_JOB_FACTORY_H_