feat: promisify session.getBlobData() (#17303)

This commit is contained in:
Shelley Vohr 2019-03-14 08:11:01 -07:00 committed by GitHub
parent c082b3964c
commit aa8b66aae1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 45 additions and 38 deletions

View file

@ -209,7 +209,7 @@ const char kPersistPrefix[] = "persist:";
// Referenced session objects. // Referenced session objects.
std::map<uint32_t, v8::Global<v8::Object>> g_sessions; std::map<uint32_t, v8::Global<v8::Object>> g_sessions;
void ResolveOrRejectPromiseInUI(atom::util::Promise promise, int net_error) { void ResolveOrRejectPromiseInUI(util::Promise promise, int net_error) {
if (net_error != net::OK) { if (net_error != net::OK) {
std::string err_msg = net::ErrorToString(net_error); std::string err_msg = net::ErrorToString(net_error);
util::Promise::RejectPromise(std::move(promise), std::move(err_msg)); util::Promise::RejectPromise(std::move(promise), std::move(err_msg));
@ -221,7 +221,7 @@ void ResolveOrRejectPromiseInUI(atom::util::Promise promise, int net_error) {
// Callback of HttpCache::GetBackend. // Callback of HttpCache::GetBackend.
void OnGetBackend(disk_cache::Backend** backend_ptr, void OnGetBackend(disk_cache::Backend** backend_ptr,
Session::CacheAction action, Session::CacheAction action,
const atom::util::CopyablePromise& promise, const util::CopyablePromise& promise,
int result) { int result) {
if (result != net::OK) { if (result != net::OK) {
std::string err_msg = std::string err_msg =
@ -254,7 +254,7 @@ void OnGetBackend(disk_cache::Backend** backend_ptr,
void DoCacheActionInIO( void DoCacheActionInIO(
const scoped_refptr<net::URLRequestContextGetter>& context_getter, const scoped_refptr<net::URLRequestContextGetter>& context_getter,
Session::CacheAction action, Session::CacheAction action,
atom::util::Promise promise) { util::Promise promise) {
auto* request_context = context_getter->GetURLRequestContext(); auto* request_context = context_getter->GetURLRequestContext();
auto* http_cache = request_context->http_transaction_factory()->GetCache(); auto* http_cache = request_context->http_transaction_factory()->GetCache();
@ -270,7 +270,7 @@ void DoCacheActionInIO(
auto** backend_ptr = new BackendPtr(nullptr); auto** backend_ptr = new BackendPtr(nullptr);
net::CompletionCallback on_get_backend = net::CompletionCallback on_get_backend =
base::Bind(&OnGetBackend, base::Owned(backend_ptr), action, base::Bind(&OnGetBackend, base::Owned(backend_ptr), action,
atom::util::CopyablePromise(promise)); util::CopyablePromise(promise));
int rv = http_cache->GetBackend(backend_ptr, on_get_backend); int rv = http_cache->GetBackend(backend_ptr, on_get_backend);
if (rv != net::ERR_IO_PENDING) if (rv != net::ERR_IO_PENDING)
on_get_backend.Run(net::OK); on_get_backend.Run(net::OK);
@ -431,7 +431,7 @@ v8::Local<v8::Promise> Session::ResolveProxy(mate::Arguments* args) {
browser_context_->GetResolveProxyHelper()->ResolveProxy( browser_context_->GetResolveProxyHelper()->ResolveProxy(
url, url,
base::Bind(util::CopyablePromise::ResolveCopyablePromise<std::string>, base::Bind(util::CopyablePromise::ResolveCopyablePromise<std::string>,
atom::util::CopyablePromise(promise))); util::CopyablePromise(promise)));
return handle; return handle;
} }
@ -659,16 +659,17 @@ std::string Session::GetUserAgent() {
return browser_context_->GetUserAgent(); return browser_context_->GetUserAgent();
} }
void Session::GetBlobData(const std::string& uuid, v8::Local<v8::Promise> Session::GetBlobData(v8::Isolate* isolate,
const AtomBlobReader::CompletionCallback& callback) { const std::string& uuid) {
if (callback.is_null()) util::Promise promise(isolate);
return; v8::Local<v8::Promise> handle = promise.GetHandle();
AtomBlobReader* blob_reader = browser_context()->GetBlobReader(); AtomBlobReader* blob_reader = browser_context()->GetBlobReader();
base::PostTaskWithTraits( base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO}, FROM_HERE, {BrowserThread::IO},
base::BindOnce(&AtomBlobReader::StartReading, base::BindOnce(&AtomBlobReader::StartReading,
base::Unretained(blob_reader), uuid, callback)); base::Unretained(blob_reader), uuid, std::move(promise)));
return handle;
} }
void Session::CreateInterruptedDownload(const mate::Dictionary& options) { void Session::CreateInterruptedDownload(const mate::Dictionary& options) {

View file

@ -82,8 +82,8 @@ class Session : public mate::TrackableObject<Session>,
void AllowNTLMCredentialsForDomains(const std::string& domains); void AllowNTLMCredentialsForDomains(const std::string& domains);
void SetUserAgent(const std::string& user_agent, mate::Arguments* args); void SetUserAgent(const std::string& user_agent, mate::Arguments* args);
std::string GetUserAgent(); std::string GetUserAgent();
void GetBlobData(const std::string& uuid, v8::Local<v8::Promise> GetBlobData(v8::Isolate* isolate,
const AtomBlobReader::CompletionCallback& callback); const std::string& uuid);
void CreateInterruptedDownload(const mate::Dictionary& options); void CreateInterruptedDownload(const mate::Dictionary& options);
void SetPreloads(const std::vector<base::FilePath::StringType>& preloads); void SetPreloads(const std::vector<base::FilePath::StringType>& preloads);
std::vector<base::FilePath::StringType> GetPreloads() const; std::vector<base::FilePath::StringType> GetPreloads() const;

View file

@ -27,12 +27,10 @@ void FreeNodeBufferData(char* data, void* hint) {
delete[] data; delete[] data;
} }
void RunCallbackInUI(const AtomBlobReader::CompletionCallback& callback, void RunPromiseInUI(util::Promise promise, char* blob_data, int size) {
char* blob_data,
int size) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
v8::Isolate* isolate = promise.isolate();
v8::Isolate* isolate = v8::Isolate::GetCurrent();
v8::Locker locker(isolate); v8::Locker locker(isolate);
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);
if (blob_data) { if (blob_data) {
@ -40,9 +38,9 @@ void RunCallbackInUI(const AtomBlobReader::CompletionCallback& callback,
node::Buffer::New(isolate, blob_data, static_cast<size_t>(size), node::Buffer::New(isolate, blob_data, static_cast<size_t>(size),
&FreeNodeBufferData, nullptr) &FreeNodeBufferData, nullptr)
.ToLocalChecked(); .ToLocalChecked();
callback.Run(buffer); promise.Resolve(buffer);
} else { } else {
callback.Run(v8::Null(isolate)); promise.RejectWithErrorMessage("Could not get blob data");
} }
} }
@ -53,29 +51,29 @@ AtomBlobReader::AtomBlobReader(content::ChromeBlobStorageContext* blob_context)
AtomBlobReader::~AtomBlobReader() {} AtomBlobReader::~AtomBlobReader() {}
void AtomBlobReader::StartReading( void AtomBlobReader::StartReading(const std::string& uuid,
const std::string& uuid, util::Promise promise) {
const AtomBlobReader::CompletionCallback& completion_callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK_CURRENTLY_ON(BrowserThread::IO);
auto blob_data_handle = blob_context_->context()->GetBlobDataFromUUID(uuid); auto blob_data_handle = blob_context_->context()->GetBlobDataFromUUID(uuid);
auto callback = base::Bind(&RunCallbackInUI, completion_callback);
if (!blob_data_handle) { if (!blob_data_handle) {
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, util::Promise::RejectPromise(std::move(promise),
base::BindOnce(callback, nullptr, 0)); "Could not get blob data handle");
return; return;
} }
auto blob_reader = blob_data_handle->CreateReader(); auto blob_reader = blob_data_handle->CreateReader();
BlobReadHelper* blob_read_helper = BlobReadHelper* blob_read_helper =
new BlobReadHelper(std::move(blob_reader), callback); new BlobReadHelper(std::move(blob_reader),
base::BindOnce(&RunPromiseInUI, std::move(promise)));
blob_read_helper->Read(); blob_read_helper->Read();
} }
AtomBlobReader::BlobReadHelper::BlobReadHelper( AtomBlobReader::BlobReadHelper::BlobReadHelper(
std::unique_ptr<storage::BlobReader> blob_reader, std::unique_ptr<storage::BlobReader> blob_reader,
const BlobReadHelper::CompletionCallback& callback) BlobReadHelper::CompletionCallback callback)
: blob_reader_(std::move(blob_reader)), completion_callback_(callback) {} : blob_reader_(std::move(blob_reader)),
completion_callback_(std::move(callback)) {}
AtomBlobReader::BlobReadHelper::~BlobReadHelper() {} AtomBlobReader::BlobReadHelper::~BlobReadHelper() {}
@ -117,8 +115,9 @@ void AtomBlobReader::BlobReadHelper::DidReadBlobData(
char* data = new char[size]; char* data = new char[size];
memcpy(data, blob_data->data(), size); memcpy(data, blob_data->data(), size);
base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI}, base::PostTaskWithTraits(
base::BindOnce(completion_callback_, data, size)); FROM_HERE, {BrowserThread::UI},
base::BindOnce(std::move(completion_callback_), data, size));
delete this; delete this;
} }

View file

@ -8,6 +8,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "atom/common/promise_util.h"
#include "base/callback.h" #include "base/callback.h"
namespace content { namespace content {
@ -35,23 +36,20 @@ namespace atom {
// except Ctor are expected to be called on IO thread. // except Ctor are expected to be called on IO thread.
class AtomBlobReader { class AtomBlobReader {
public: public:
using CompletionCallback = base::Callback<void(v8::Local<v8::Value>)>;
explicit AtomBlobReader(content::ChromeBlobStorageContext* blob_context); explicit AtomBlobReader(content::ChromeBlobStorageContext* blob_context);
~AtomBlobReader(); ~AtomBlobReader();
void StartReading(const std::string& uuid, void StartReading(const std::string& uuid, atom::util::Promise promise);
const AtomBlobReader::CompletionCallback& callback);
private: private:
// A self-destroyed helper class to read the blob data. // A self-destroyed helper class to read the blob data.
// Must be accessed on IO thread. // Must be accessed on IO thread.
class BlobReadHelper { class BlobReadHelper {
public: public:
using CompletionCallback = base::Callback<void(char*, int)>; using CompletionCallback = base::OnceCallback<void(char*, int)>;
BlobReadHelper(std::unique_ptr<storage::BlobReader> blob_reader, BlobReadHelper(std::unique_ptr<storage::BlobReader> blob_reader,
const BlobReadHelper::CompletionCallback& callback); BlobReadHelper::CompletionCallback callback);
~BlobReadHelper(); ~BlobReadHelper();
void Read(); void Read();

View file

@ -11,7 +11,6 @@ When a majority of affected functions are migrated, this flag will be enabled by
- [app.importCertificate(options, callback)](https://github.com/electron/electron/blob/master/docs/api/app.md#importCertificate) - [app.importCertificate(options, callback)](https://github.com/electron/electron/blob/master/docs/api/app.md#importCertificate)
- [dialog.showMessageBox([browserWindow, ]options[, callback])](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showMessageBox) - [dialog.showMessageBox([browserWindow, ]options[, callback])](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showMessageBox)
- [dialog.showCertificateTrustDialog([browserWindow, ]options, callback)](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showCertificateTrustDialog) - [dialog.showCertificateTrustDialog([browserWindow, ]options, callback)](https://github.com/electron/electron/blob/master/docs/api/dialog.md#showCertificateTrustDialog)
- [ses.getBlobData(identifier, callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#getBlobData)
- [contents.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#executeJavaScript) - [contents.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#executeJavaScript)
- [contents.print([options], [callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#print) - [contents.print([options], [callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#print)
- [webFrame.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScript) - [webFrame.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScript)
@ -47,6 +46,7 @@ When a majority of affected functions are migrated, this flag will be enabled by
- [ses.getCacheSize(callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#getCacheSize) - [ses.getCacheSize(callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#getCacheSize)
- [ses.clearAuthCache(options[, callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearAuthCache) - [ses.clearAuthCache(options[, callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearAuthCache)
- [ses.clearCache(callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#clearCache) - [ses.clearCache(callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#clearCache)
- [ses.getBlobData(identifier, callback)](https://github.com/electron/electron/blob/master/docs/api/session.md#getBlobData)
- [shell.openExternal(url[, options, callback])](https://github.com/electron/electron/blob/master/docs/api/shell.md#openExternal) - [shell.openExternal(url[, options, callback])](https://github.com/electron/electron/blob/master/docs/api/shell.md#openExternal)
- [webviewTag.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#capturePage) - [webviewTag.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#capturePage)
- [webviewTag.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#printToPDF) - [webviewTag.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#printToPDF)

View file

@ -512,6 +512,14 @@ Returns `String` - The user agent for this session.
* `callback` Function * `callback` Function
* `result` Buffer - Blob data. * `result` Buffer - Blob data.
**[Deprecated Soon](promisification.md)**
#### `ses.getBlobData(identifier)`
* `identifier` String - Valid UUID.
Returns `Promise<Buffer>` - resolves with blob data.
#### `ses.createInterruptedDownload(options)` #### `ses.createInterruptedDownload(options)`
* `options` Object * `options` Object

View file

@ -30,6 +30,7 @@ Session.prototype.setProxy = deprecate.promisify(Session.prototype.setProxy)
Session.prototype.getCacheSize = deprecate.promisify(Session.prototype.getCacheSize) Session.prototype.getCacheSize = deprecate.promisify(Session.prototype.getCacheSize)
Session.prototype.clearCache = deprecate.promisify(Session.prototype.clearCache) Session.prototype.clearCache = deprecate.promisify(Session.prototype.clearCache)
Session.prototype.clearAuthCache = deprecate.promisify(Session.prototype.clearAuthCache) Session.prototype.clearAuthCache = deprecate.promisify(Session.prototype.clearAuthCache)
Session.prototype.getBlobData = deprecate.promisifyMultiArg(Session.prototype.getBlobData)
Cookies.prototype.flushStore = deprecate.promisify(Cookies.prototype.flushStore) Cookies.prototype.flushStore = deprecate.promisify(Cookies.prototype.flushStore)
Cookies.prototype.get = deprecate.promisify(Cookies.prototype.get) Cookies.prototype.get = deprecate.promisify(Cookies.prototype.get)

View file

@ -774,7 +774,7 @@ describe('session module', () => {
}) })
}) })
describe('ses.getBlobData(identifier, callback)', () => { describe('ses.getBlobData()', () => {
it('returns blob data for uuid', (done) => { it('returns blob data for uuid', (done) => {
const scheme = 'cors-blob' const scheme = 'cors-blob'
const protocol = session.defaultSession.protocol const protocol = session.defaultSession.protocol
@ -811,7 +811,7 @@ describe('session module', () => {
} else if (request.method === 'POST') { } else if (request.method === 'POST') {
const uuid = request.uploadData[1].blobUUID const uuid = request.uploadData[1].blobUUID
assert(uuid) assert(uuid)
session.defaultSession.getBlobData(uuid, (result) => { session.defaultSession.getBlobData(uuid).then(result => {
assert.strictEqual(result.toString(), postData) assert.strictEqual(result.toString(), postData)
done() done()
}) })