Use custom url request getter to setup request job factory.
authorCheng Zhao <zcbenz@gmail.com>
Fri, 20 Sep 2013 08:47:47 +0000 (16:47 +0800)
committerCheng Zhao <zcbenz@gmail.com>
Fri, 20 Sep 2013 08:47:47 +0000 (16:47 +0800)
atom.gyp
browser/api/atom_api_protocol.cc
browser/atom_browser_client.cc
browser/atom_browser_client.h
browser/atom_browser_context.cc
browser/atom_browser_context.h
browser/net/atom_url_request_context_getter.cc [new file with mode: 0644]
browser/net/atom_url_request_context_getter.h [new file with mode: 0644]

index 4d0bab4..c9aff86 100644 (file)
--- a/atom.gyp
+++ b/atom.gyp
       'browser/native_window_observer.h',
       'browser/net/adapter_request_job.cc',
       'browser/net/adapter_request_job.h',
+      'browser/net/atom_url_request_context_getter.cc',
+      'browser/net/atom_url_request_context_getter.h',
       'browser/net/atom_url_request_job_factory.cc',
       'browser/net/atom_url_request_job_factory.h',
       'browser/net/url_request_string_job.cc',
index 498dae4..5b1919f 100644 (file)
@@ -7,10 +7,10 @@
 #include "base/stl_util.h"
 #include "browser/atom_browser_context.h"
 #include "browser/net/adapter_request_job.h"
+#include "browser/net/atom_url_request_context_getter.h"
 #include "browser/net/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 "vendor/node/src/node.h"
 #include "vendor/node/src/node_internals.h"
 
@@ -55,10 +55,7 @@ v8::Handle<v8::Object> ConvertURLRequestToV8Object(
 
 // Get the job factory.
 AtomURLRequestJobFactory* GetRequestJobFactory() {
-  return static_cast<AtomURLRequestJobFactory*>(
-      const_cast<net::URLRequestJobFactory*>(
-          static_cast<content::BrowserContext*>(AtomBrowserContext::Get())->
-              GetRequestContext()->GetURLRequestContext()->job_factory()));
+  return AtomBrowserContext::Get()->url_request_context_getter()->job_factory();
 }
 
 class CustomProtocolRequestJob : public AdapterRequestJob {
index 2476dd7..bdff197 100644 (file)
@@ -4,14 +4,9 @@
 
 #include "browser/atom_browser_client.h"
 
+#include "browser/atom_browser_context.h"
 #include "browser/atom_browser_main_parts.h"
-#include "browser/net/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 "browser/net/atom_url_request_context_getter.h"
 #include "webkit/glue/webpreferences.h"
 
 namespace atom {
@@ -25,31 +20,8 @@ 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;
+  return static_cast<AtomBrowserContext*>(browser_context)->
+      CreateRequestContext(protocol_handlers);
 }
 
 void AtomBrowserClient::OverrideWebkitPrefs(
index 456ea1a..3443f0a 100644 (file)
@@ -7,10 +7,6 @@
 
 #include "brightray/browser/browser_client.h"
 
-namespace net {
-class URLRequestContextStorage;
-}
-
 namespace atom {
 
 class AtomBrowserClient : public brightray::BrowserClient {
@@ -34,8 +30,6 @@ class AtomBrowserClient : public brightray::BrowserClient {
   virtual brightray::BrowserMainParts* OverrideCreateBrowserMainParts(
       const content::MainFunctionParams&) OVERRIDE;
 
-  scoped_ptr<net::URLRequestContextStorage> storage_;
-
   DISALLOW_COPY_AND_ASSIGN(AtomBrowserClient);
 };
 
index 59649b2..e2a80b8 100644 (file)
@@ -5,15 +5,65 @@
 #include "browser/atom_browser_context.h"
 
 #include "browser/atom_browser_main_parts.h"
+#include "browser/net/atom_url_request_context_getter.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/resource_context.h"
+#include "vendor/brightray/browser/network_delegate.h"
 
 namespace atom {
 
-AtomBrowserContext::AtomBrowserContext() {
+using content::BrowserThread;
+
+class AtomResourceContext : public content::ResourceContext {
+ public:
+  AtomResourceContext() : getter_(NULL) {}
+
+  void set_url_request_context_getter(AtomURLRequestContextGetter* getter) {
+    getter_ = getter;
+  }
+
+ protected:
+  virtual net::HostResolver* GetHostResolver() OVERRIDE {
+    DCHECK(getter_);
+    return getter_->host_resolver();
+  }
+
+  virtual net::URLRequestContext* GetRequestContext() OVERRIDE {
+    DCHECK(getter_);
+    return getter_->GetURLRequestContext();
+  }
+
+ private:
+  AtomURLRequestContextGetter* getter_;
+
+  DISALLOW_COPY_AND_ASSIGN(AtomResourceContext);
+};
+
+AtomBrowserContext::AtomBrowserContext()
+    : resource_context_(new AtomResourceContext) {
 }
 
 AtomBrowserContext::~AtomBrowserContext() {
 }
 
+AtomURLRequestContextGetter* AtomBrowserContext::CreateRequestContext(
+    content::ProtocolHandlerMap* protocol_handlers) {
+  DCHECK(!url_request_getter_);
+  url_request_getter_ = new AtomURLRequestContextGetter(
+      GetPath(),
+      BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::IO),
+      BrowserThread::UnsafeGetMessageLoopForThread(BrowserThread::FILE),
+      CreateNetworkDelegate().Pass(),
+      protocol_handlers);
+
+  resource_context_->set_url_request_context_getter(url_request_getter_.get());
+  return url_request_getter_.get();
+}
+
+content::ResourceContext* AtomBrowserContext::GetResourceContext() {
+  return resource_context_.get();
+}
+
 // static
 AtomBrowserContext* AtomBrowserContext::Get() {
   return static_cast<AtomBrowserContext*>(
index 1a97bc3..45c0322 100644 (file)
 
 namespace atom {
 
+class AtomResourceContext;
+class AtomURLRequestContextGetter;
+
 class AtomBrowserContext : public brightray::BrowserContext {
  public:
   AtomBrowserContext();
   virtual ~AtomBrowserContext();
 
+  // Returns the browser context singleton.
   static AtomBrowserContext* Get();
 
+  // Creates or returns the request context.
+  AtomURLRequestContextGetter* CreateRequestContext(
+      content::ProtocolHandlerMap*);
+
+  AtomURLRequestContextGetter* url_request_context_getter() const {
+    DCHECK(url_request_getter_);
+    return url_request_getter_.get();
+  }
+
+ protected:
+  // content::BrowserContext implementations:
+  virtual content::ResourceContext* GetResourceContext() OVERRIDE;
+
  private:
+  scoped_ptr<AtomResourceContext> resource_context_;
+  scoped_refptr<AtomURLRequestContextGetter> url_request_getter_;
+
   DISALLOW_COPY_AND_ASSIGN(AtomBrowserContext);
 };
 
diff --git a/browser/net/atom_url_request_context_getter.cc b/browser/net/atom_url_request_context_getter.cc
new file mode 100644 (file)
index 0000000..0472905
--- /dev/null
@@ -0,0 +1,157 @@
+// Copyright (c) 2013 GitHub, Inc. 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/net/atom_url_request_context_getter.h"
+
+#include "base/string_util.h"
+#include "base/threading/worker_pool.h"
+#include "browser/net/atom_url_request_job_factory.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/cookie_store_factory.h"
+#include "content/public/common/url_constants.h"
+#include "net/cert/cert_verifier.h"
+#include "net/cookies/cookie_monster.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_cache.h"
+#include "net/http/http_server_properties_impl.h"
+#include "net/proxy/proxy_service.h"
+#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/static_http_user_agent_settings.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_storage.h"
+#include "vendor/brightray/browser/network_delegate.h"
+
+namespace atom {
+
+using content::BrowserThread;
+
+AtomURLRequestContextGetter::AtomURLRequestContextGetter(
+    const base::FilePath& base_path,
+    MessageLoop* io_loop,
+    MessageLoop* file_loop,
+    scoped_ptr<brightray::NetworkDelegate> network_delegate,
+    content::ProtocolHandlerMap* protocol_handlers)
+    : base_path_(base_path),
+      io_loop_(io_loop),
+      file_loop_(file_loop),
+      job_factory_(NULL),
+      network_delegate_(network_delegate.Pass()) {
+  // Must first be created on the UI thread.
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  std::swap(protocol_handlers_, *protocol_handlers);
+  proxy_config_service_.reset(
+      net::ProxyService::CreateSystemProxyConfigService(
+          io_loop_->message_loop_proxy(),
+          file_loop_));
+}
+
+AtomURLRequestContextGetter::~AtomURLRequestContextGetter() {
+}
+
+net::URLRequestContext* AtomURLRequestContextGetter::GetURLRequestContext() {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+  if (!url_request_context_.get()) {
+    url_request_context_.reset(new net::URLRequestContext());
+    url_request_context_->set_network_delegate(network_delegate_.get());
+    storage_.reset(
+        new net::URLRequestContextStorage(url_request_context_.get()));
+    storage_->set_cookie_store(content::CreatePersistentCookieStore(
+        base_path_.Append(FILE_PATH_LITERAL("Cookies")),
+        false,
+        nullptr,
+        nullptr));
+    storage_->set_server_bound_cert_service(new net::ServerBoundCertService(
+        new net::DefaultServerBoundCertStore(NULL),
+        base::WorkerPool::GetTaskRunner(true)));
+    storage_->set_http_user_agent_settings(
+        new net::StaticHttpUserAgentSettings(
+            "en-us,en", EmptyString()));
+
+    scoped_ptr<net::HostResolver> host_resolver(
+        net::HostResolver::CreateDefaultResolver(NULL));
+
+    storage_->set_cert_verifier(net::CertVerifier::CreateDefault());
+    // TODO(jam): use v8 if possible, look at chrome code.
+    storage_->set_proxy_service(
+        net::ProxyService::CreateUsingSystemProxyResolver(
+        proxy_config_service_.release(),
+        0,
+        NULL));
+    storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
+    storage_->set_http_auth_handler_factory(
+        net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get()));
+    storage_->set_http_server_properties(new net::HttpServerPropertiesImpl);
+
+    base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache"));
+    net::HttpCache::DefaultBackend* main_backend =
+        new net::HttpCache::DefaultBackend(
+            net::DISK_CACHE,
+            net::CACHE_BACKEND_DEFAULT,
+            cache_path,
+            0,
+            BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE));
+
+    net::HttpNetworkSession::Params network_session_params;
+    network_session_params.cert_verifier =
+        url_request_context_->cert_verifier();
+    network_session_params.server_bound_cert_service =
+        url_request_context_->server_bound_cert_service();
+    network_session_params.proxy_service =
+        url_request_context_->proxy_service();
+    network_session_params.ssl_config_service =
+        url_request_context_->ssl_config_service();
+    network_session_params.http_auth_handler_factory =
+        url_request_context_->http_auth_handler_factory();
+    network_session_params.network_delegate =
+        url_request_context_->network_delegate();
+    network_session_params.http_server_properties =
+        url_request_context_->http_server_properties();
+    network_session_params.ignore_certificate_errors = false;
+
+    // Give |storage_| ownership at the end in case it's |mapped_host_resolver|.
+    storage_->set_host_resolver(host_resolver.Pass());
+    network_session_params.host_resolver =
+        url_request_context_->host_resolver();
+
+    net::HttpCache* main_cache = new net::HttpCache(
+        network_session_params, main_backend);
+    storage_->set_http_transaction_factory(main_cache);
+
+    DCHECK(!job_factory_);
+    job_factory_ = new AtomURLRequestJobFactory;
+    for (content::ProtocolHandlerMap::iterator it = protocol_handlers_.begin();
+         it != protocol_handlers_.end();
+         ++it) {
+      bool set_protocol = job_factory_->SetProtocolHandler(
+          it->first,
+          it->second.release());
+      DCHECK(set_protocol);
+    }
+    protocol_handlers_.clear();
+
+    job_factory_->SetProtocolHandler(chrome::kDataScheme,
+                                     new net::DataProtocolHandler);
+    job_factory_->SetProtocolHandler(chrome::kFileScheme,
+                                     new net::FileProtocolHandler);
+    storage_->set_job_factory(job_factory_);
+  }
+
+  return url_request_context_.get();
+}
+
+scoped_refptr<base::SingleThreadTaskRunner>
+    AtomURLRequestContextGetter::GetNetworkTaskRunner() const {
+  return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
+}
+
+net::HostResolver* AtomURLRequestContextGetter::host_resolver() {
+  return url_request_context_->host_resolver();
+}
+
+}  // namespace atom
diff --git a/browser/net/atom_url_request_context_getter.h b/browser/net/atom_url_request_context_getter.h
new file mode 100644 (file)
index 0000000..51a64d8
--- /dev/null
@@ -0,0 +1,69 @@
+// Copyright (c) 2013 GitHub, Inc. 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_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_
+#define ATOM_BROWSER_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_
+
+#include "base/files/file_path.h"
+#include "base/memory/scoped_ptr.h"
+#include "content/public/browser/content_browser_client.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace base {
+class MessageLoop;
+}
+
+namespace brightray {
+class NetworkDelegate;
+}
+
+namespace net {
+class HostResolver;
+class ProxyConfigService;
+class URLRequestContextStorage;
+}
+
+namespace atom {
+
+class AtomURLRequestJobFactory;
+
+class AtomURLRequestContextGetter : public net::URLRequestContextGetter {
+ public:
+  AtomURLRequestContextGetter(
+      const base::FilePath& base_path,
+      base::MessageLoop* io_loop,
+      base::MessageLoop* file_loop,
+      scoped_ptr<brightray::NetworkDelegate> network_delegate,
+      content::ProtocolHandlerMap* protocol_handlers);
+
+  // net::URLRequestContextGetter implementations:
+  virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE;
+  virtual scoped_refptr<base::SingleThreadTaskRunner>
+      GetNetworkTaskRunner() const OVERRIDE;
+
+  net::HostResolver* host_resolver();
+  net::URLRequestContextStorage* storage() const { return storage_.get(); }
+  AtomURLRequestJobFactory* job_factory() const { return job_factory_; }
+
+ protected:
+  virtual ~AtomURLRequestContextGetter();
+
+ private:
+  base::FilePath base_path_;
+  base::MessageLoop* io_loop_;
+  base::MessageLoop* file_loop_;
+  AtomURLRequestJobFactory* job_factory_;
+
+  scoped_ptr<net::ProxyConfigService> proxy_config_service_;
+  scoped_ptr<brightray::NetworkDelegate> network_delegate_;
+  scoped_ptr<net::URLRequestContextStorage> storage_;
+  scoped_ptr<net::URLRequestContext> url_request_context_;
+  content::ProtocolHandlerMap protocol_handlers_;
+
+  DISALLOW_COPY_AND_ASSIGN(AtomURLRequestContextGetter);
+};
+
+}  // namespace atom
+
+#endif  // ATOM_BROWSER_NET_ATOM_URL_REQUEST_CONTEXT_GETTER_H_