From 7521aeea09c994e4afef3c00d457246054798fee Mon Sep 17 00:00:00 2001 From: "ali.ibrahim" Date: Mon, 19 Sep 2016 11:21:09 +0200 Subject: [PATCH] Implement URLRequest::Delegate, handle thread sync. --- atom/browser/api/atom_api_net.cc | 1 + atom/browser/api/atom_api_url_request.cc | 67 ++++++++++++++++++-- atom/browser/api/atom_api_url_request.h | 21 ++++-- atom/browser/net/atom_url_request.cc | 81 ++++++++++++++++++++++++ atom/browser/net/atom_url_request.h | 52 +++++++++++++++ filenames.gypi | 2 + lib/browser/api/exports/electron.js | 12 ++-- lib/browser/api/net.js | 15 ++--- 8 files changed, 229 insertions(+), 22 deletions(-) create mode 100644 atom/browser/net/atom_url_request.cc create mode 100644 atom/browser/net/atom_url_request.h diff --git a/atom/browser/api/atom_api_net.cc b/atom/browser/api/atom_api_net.cc index ee1b4373925..1559cee4caf 100644 --- a/atom/browser/api/atom_api_net.cc +++ b/atom/browser/api/atom_api_net.cc @@ -57,6 +57,7 @@ void Initialize(v8::Local exports, v8::Local unused, mate::Dictionary dict(isolate, exports); dict.Set("net", Net::Create(isolate)); + dict.Set("Net", Net::GetConstructor(isolate)->GetFunction()); } diff --git a/atom/browser/api/atom_api_url_request.cc b/atom/browser/api/atom_api_url_request.cc index 8862fbaee2f..44b4581ef45 100644 --- a/atom/browser/api/atom_api_url_request.cc +++ b/atom/browser/api/atom_api_url_request.cc @@ -3,13 +3,20 @@ // found in the LICENSE file. #include "atom/browser/api/atom_api_url_request.h" +#include "atom/browser/api/atom_api_session.h" + +#include "native_mate/dictionary.h" +#include "atom/browser/net/atom_url_request.h" + namespace atom { namespace api { -URLRequest::URLRequest(v8::Isolate* isolate) { - Init(isolate); +URLRequest::URLRequest(v8::Isolate* isolate, + v8::Local wrapper) + : weak_ptr_factory_(this) { + InitWith(isolate, wrapper); } URLRequest::~URLRequest() { @@ -18,20 +25,72 @@ URLRequest::~URLRequest() { // static mate::WrappableBase* URLRequest::New(mate::Arguments* args) { - return new URLRequest(args->isolate()); + v8::Local options; + args->GetNext(&options); + mate::Dictionary dict(args->isolate(), options); + std::string url; + dict.Get("url", &url); + std::string method; + dict.Get("method", &method); + std::string session_name; + dict.Get("session", &session_name); + + auto session = Session::FromPartition(args->isolate(), session_name); + + auto browser_context = session->browser_context(); + + //auto url_request_context_getter = browser_context->url_request_context_getter(); + // auto url_request_context = url_request_context_getter->GetURLRequestContext(); + + //auto net_url_request = url_request_context->CreateRequest(GURL(url), + // net::RequestPriority::DEFAULT_PRIORITY, + // nullptr); + // net_url_request->set_method(method); + + // auto atom_url_request = new URLRequest(args->isolate(), args->GetThis(), net_url_request.release()); + + auto api_url_request = new URLRequest(args->isolate(), args->GetThis()); + auto weak_ptr = api_url_request->weak_ptr_factory_.GetWeakPtr(); + auto atom_url_request = AtomURLRequest::create(browser_context, url, weak_ptr); + + atom_url_request->set_method(method); + + api_url_request->atom_url_request_ = atom_url_request; + + + return api_url_request; } // static void URLRequest::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { - prototype->SetClassName(mate::StringToV8(isolate, "WebRequest")); + prototype->SetClassName(mate::StringToV8(isolate, "URLRequest")); mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate()) + .MakeDestroyable() .SetMethod("start", &URLRequest::start); } void URLRequest::start() { + pin(); + atom_url_request_->Start(); +} +void URLRequest::stop() { + +} +void URLRequest::OnResponseStarted() { + Emit("response-started"); +} + +void URLRequest::pin() { + if (wrapper_.IsEmpty()) { + wrapper_.Reset(isolate(), GetWrapper()); + } +} + +void URLRequest::unpin() { + wrapper_.Reset(); } } // namespace mate diff --git a/atom/browser/api/atom_api_url_request.h b/atom/browser/api/atom_api_url_request.h index 3d07b0712b4..474b13a7489 100644 --- a/atom/browser/api/atom_api_url_request.h +++ b/atom/browser/api/atom_api_url_request.h @@ -7,13 +7,15 @@ #include "atom/browser/api/trackable_object.h" #include "native_mate/handle.h" +#include "net/url_request/url_request_context.h" namespace atom { +class AtomURLRequest; + namespace api { - -class URLRequest : public mate::TrackableObject { +class URLRequest : public mate::EventEmitter { public: static mate::WrappableBase* New(mate::Arguments* args); @@ -21,12 +23,23 @@ class URLRequest : public mate::TrackableObject { v8::Local prototype); void start(); - + void stop(); + void OnResponseStarted(); protected: - URLRequest(v8::Isolate* isolate); + URLRequest(v8::Isolate* isolate, + v8::Local wrapper); ~URLRequest() override; + + private: + void pin(); + void unpin(); + + scoped_refptr atom_url_request_; + v8::Global wrapper_; + base::WeakPtrFactory weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(URLRequest); }; diff --git a/atom/browser/net/atom_url_request.cc b/atom/browser/net/atom_url_request.cc new file mode 100644 index 00000000000..50aee486534 --- /dev/null +++ b/atom/browser/net/atom_url_request.cc @@ -0,0 +1,81 @@ +// Copyright (c) 2013 GitHub, Inc. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/net/atom_url_request.h" +#include "atom/browser/api/atom_api_url_request.h" +#include "atom/browser/atom_browser_context.h" +#include "base/callback.h" +#include "content/public/browser/browser_thread.h" + +namespace atom { + +AtomURLRequest::AtomURLRequest(base::WeakPtr delegate) + : delegate_(delegate) { +} + +AtomURLRequest::~AtomURLRequest() { +} + +scoped_refptr AtomURLRequest::create( + AtomBrowserContext* browser_context, + const std::string& url, + base::WeakPtr delegate) { + + + auto url_request_context_getter = browser_context->url_request_context_getter(); + auto url_request_context = url_request_context_getter->GetURLRequestContext(); + + auto net_url_request = url_request_context->CreateRequest(GURL(url), + net::RequestPriority::DEFAULT_PRIORITY, + nullptr); + // net_url_request->set_method(method); + + scoped_refptr atom_url_request = new AtomURLRequest(delegate); + + net_url_request->set_delegate(atom_url_request.get()); + + atom_url_request->url_request_ = std::move(net_url_request); + + return atom_url_request; + +} + +void AtomURLRequest::Start() { + // post to io thread + content::BrowserThread::PostTask( + content::BrowserThread::IO, FROM_HERE, + base::Bind(&AtomURLRequest::StartOnIOThread, this)); +} + +void AtomURLRequest::StartOnIOThread() { + url_request_->Start(); +} + + +void AtomURLRequest::set_method(const std::string& method) { + url_request_->set_method(method); +} + +void AtomURLRequest::OnResponseStarted(net::URLRequest* request) +{ + // post to main thread + content::BrowserThread::PostTask( + content::BrowserThread::UI, FROM_HERE, + base::Bind(&AtomURLRequest::InformDelegeteResponseStarted, this)); +} + +void AtomURLRequest::OnReadCompleted(net::URLRequest* request, int bytes_read) +{ + // post to main thread +} + +void AtomURLRequest::InformDelegeteResponseStarted() { + if (delegate_) { + delegate_->OnResponseStarted(); + } +} + + +} // namespace atom \ No newline at end of file diff --git a/atom/browser/net/atom_url_request.h b/atom/browser/net/atom_url_request.h new file mode 100644 index 00000000000..e581008eb49 --- /dev/null +++ b/atom/browser/net/atom_url_request.h @@ -0,0 +1,52 @@ +// Copyright (c) 2013 GitHub, Inc. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_NET_ATOM_URL_REQUEST_H_ +#define ATOM_BROWSER_NET_ATOM_URL_REQUEST_H_ + +#include "base/memory/ref_counted.h" +#include "net/url_request/url_request.h" + +namespace atom { + +class AtomBrowserContext; + +namespace api { + class URLRequest; +} + +class AtomURLRequest : public base::RefCountedThreadSafe, + public net::URLRequest::Delegate { +public: + static scoped_refptr create( + AtomBrowserContext* browser_context, + const std::string& url, + base::WeakPtr delegate); + + void Start(); + void set_method(const std::string& method); + +protected: + // Overrides of net::URLRequest::Delegate + virtual void OnResponseStarted(net::URLRequest* request) override; + virtual void OnReadCompleted(net::URLRequest* request, int bytes_read) override; + +private: + friend class base::RefCountedThreadSafe; + void StartOnIOThread(); + void InformDelegeteResponseStarted(); + + AtomURLRequest(base::WeakPtr delegate); + virtual ~AtomURLRequest(); + + base::WeakPtr delegate_; + std::unique_ptr url_request_; + + DISALLOW_COPY_AND_ASSIGN(AtomURLRequest); + }; + +} // namespace atom + +#endif // ATOM_BROWSER_NET_ATOM_URL_REQUEST_H_ \ No newline at end of file diff --git a/filenames.gypi b/filenames.gypi index db6bd23d689..20375c6f4e5 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -238,6 +238,8 @@ 'atom/browser/net/atom_network_delegate.h', 'atom/browser/net/atom_ssl_config_service.cc', 'atom/browser/net/atom_ssl_config_service.h', + 'atom/browser/net/atom_url_request.cc', + 'atom/browser/net/atom_url_request.h', 'atom/browser/net/atom_url_request_job_factory.cc', 'atom/browser/net/atom_url_request_job_factory.h', 'atom/browser/net/http_protocol_handler.cc', diff --git a/lib/browser/api/exports/electron.js b/lib/browser/api/exports/electron.js index a96f5a711b7..09d5b0e47aa 100644 --- a/lib/browser/api/exports/electron.js +++ b/lib/browser/api/exports/electron.js @@ -107,12 +107,12 @@ Object.defineProperties(exports, { return require('../web-contents') } }, - //net: { - // enumerable: true, - // get: function () { - // return require('../net') - // } - //}, + net: { + enumerable: true, + get: function () { + return require('../net') + } + }, // The internal modules, invisible unless you know their names. NavigationController: { diff --git a/lib/browser/api/net.js b/lib/browser/api/net.js index 98e8104e92f..c443a8ee9ed 100644 --- a/lib/browser/api/net.js +++ b/lib/browser/api/net.js @@ -1,13 +1,12 @@ 'use strict' +const {EventEmitter} = require('events') const binding = process.atomBinding('net') -const {URLRequest} = binding +const {net, Net} = binding +const {URLRequest} = net -// Public API. -Object.defineProperties(exports, { - URLRequest: { - enumerable: true, - value: URLRequest - } -}) +Object.setPrototypeOf(Net.prototype, EventEmitter.prototype) +Object.setPrototypeOf(URLRequest.prototype, EventEmitter.prototype) + +module.exports = net \ No newline at end of file