From dc0151099c787b81a4e99ff04c40fa347e2464e6 Mon Sep 17 00:00:00 2001 From: Robo Date: Tue, 26 Jan 2016 13:58:21 +0530 Subject: [PATCH] session: provide uploadData with webrequest api when available --- atom/browser/net/atom_network_delegate.cc | 4 ++ .../native_mate_converters/net_converter.cc | 70 +++++++++++-------- .../native_mate_converters/net_converter.h | 11 +++ docs/api/session.md | 3 + spec/api-web-request-spec.js | 29 ++++++++ 5 files changed, 88 insertions(+), 29 deletions(-) diff --git a/atom/browser/net/atom_network_delegate.cc b/atom/browser/net/atom_network_delegate.cc index 4f9bc835ed21..f993138ccc58 100644 --- a/atom/browser/net/atom_network_delegate.cc +++ b/atom/browser/net/atom_network_delegate.cc @@ -75,6 +75,10 @@ void ToDictionary(base::DictionaryValue* details, net::URLRequest* request) { details->SetString("resourceType", info ? ResourceTypeToString(info->GetResourceType()) : "other"); + scoped_ptr list(new base::ListValue); + GetUploadData(list.get(), request); + if (!list->empty()) + details->Set("uploadData", list.Pass()); } void ToDictionary(base::DictionaryValue* details, diff --git a/atom/common/native_mate_converters/net_converter.cc b/atom/common/native_mate_converters/net_converter.cc index 7a1b48d9311a..94081b88a3d9 100644 --- a/atom/common/native_mate_converters/net_converter.cc +++ b/atom/common/native_mate_converters/net_converter.cc @@ -10,6 +10,7 @@ #include "atom/common/node_includes.h" #include "atom/common/native_mate_converters/gurl_converter.h" #include "atom/common/native_mate_converters/value_converter.h" +#include "base/values.h" #include "native_mate/dictionary.h" #include "net/base/upload_bytes_element_reader.h" #include "net/base/upload_data_stream.h" @@ -24,35 +25,15 @@ namespace mate { // static v8::Local Converter::ToV8( v8::Isolate* isolate, const net::URLRequest* val) { - mate::Dictionary dict = mate::Dictionary::CreateEmpty(isolate); - dict.Set("method", val->method()); - dict.Set("url", val->url().spec()); - dict.Set("referrer", val->referrer()); - const net::UploadDataStream* upload_data = val->get_upload(); - if (upload_data) { - const ScopedVector* readers = - upload_data->GetElementReaders(); - std::vector upload_data_list; - upload_data_list.reserve(readers->size()); - for (const auto& reader : *readers) { - auto upload_data_dict = mate::Dictionary::CreateEmpty(isolate); - if (reader->AsBytesReader()) { - const net::UploadBytesElementReader* bytes_reader = - reader->AsBytesReader(); - auto bytes = - node::Buffer::Copy(isolate, bytes_reader->bytes(), - bytes_reader->length()).ToLocalChecked(); - upload_data_dict.Set("bytes", bytes); - } else if (reader->AsFileReader()) { - const net::UploadFileElementReader* file_reader = - reader->AsFileReader(); - upload_data_dict.Set("file", file_reader->path().AsUTF8Unsafe()); - } - upload_data_list.push_back(upload_data_dict); - } - dict.Set("uploadData", upload_data_list); - } - return mate::ConvertToV8(isolate, dict); + scoped_ptr dict(new base::DictionaryValue); + dict->SetString("method", val->method()); + dict->SetStringWithoutPathExpansion("url", val->url().spec()); + dict->SetString("referrer", val->referrer()); + scoped_ptr list(new base::ListValue); + atom::GetUploadData(list.get(), val); + if (!list->empty()) + dict->Set("uploadData", list.Pass()); + return mate::ConvertToV8(isolate, *(dict.get())); } // static @@ -83,3 +64,34 @@ v8::Local Converter>::ToV8( } } // namespace mate + +namespace atom { + +void GetUploadData(base::ListValue* upload_data_list, + const net::URLRequest* request) { + const net::UploadDataStream* upload_data = request->get_upload(); + if (!upload_data) + return; + const ScopedVector* readers = + upload_data->GetElementReaders(); + for (const auto& reader : *readers) { + scoped_ptr upload_data_dict( + new base::DictionaryValue); + if (reader->AsBytesReader()) { + const net::UploadBytesElementReader* bytes_reader = + reader->AsBytesReader(); + scoped_ptr bytes( + base::BinaryValue::CreateWithCopiedBuffer(bytes_reader->bytes(), + bytes_reader->length())); + upload_data_dict->Set("bytes", bytes.Pass()); + } else if (reader->AsFileReader()) { + const net::UploadFileElementReader* file_reader = + reader->AsFileReader(); + auto file_path = file_reader->path().AsUTF8Unsafe(); + upload_data_dict->SetStringWithoutPathExpansion("file", file_path); + } + upload_data_list->Append(upload_data_dict.Pass()); + } +} + +} // namespace atom diff --git a/atom/common/native_mate_converters/net_converter.h b/atom/common/native_mate_converters/net_converter.h index b11c55929b98..b7fd9481a207 100644 --- a/atom/common/native_mate_converters/net_converter.h +++ b/atom/common/native_mate_converters/net_converter.h @@ -8,6 +8,10 @@ #include "base/memory/ref_counted.h" #include "native_mate/converter.h" +namespace base { +class ListValue; +} + namespace net { class AuthChallengeInfo; class URLRequest; @@ -36,4 +40,11 @@ struct Converter> { } // namespace mate +namespace atom { + +void GetUploadData(base::ListValue* upload_data_list, + const net::URLRequest* request); + +} // namespace atom + #endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_NET_CONVERTER_H_ diff --git a/docs/api/session.md b/docs/api/session.md index ffed58797c43..1bef70e5105f 100644 --- a/docs/api/session.md +++ b/docs/api/session.md @@ -332,6 +332,9 @@ is about to occur. * `method` String * `resourceType` String * `timestamp` Double + * `uploadData` Array (optional) + * `bytes` Buffer - Content being sent. + * `file` String - Path of file being uploaded. The `callback` has to be called with an `response` object: diff --git a/spec/api-web-request-spec.js b/spec/api-web-request-spec.js index 6731d995a610..91b84c77e1b3 100644 --- a/spec/api-web-request-spec.js +++ b/spec/api-web-request-spec.js @@ -1,5 +1,6 @@ const assert = require('assert'); const http = require('http'); +const qs = require('querystring'); const remote = require('electron').remote; const session = remote.session; @@ -83,6 +84,7 @@ describe('webRequest module', function() { assert.equal(details.url, defaultURL); assert.equal(details.method, 'GET'); assert.equal(details.resourceType, 'xhr'); + assert(!details.uploadData); return callback({}); }); return $.ajax({ @@ -96,6 +98,33 @@ describe('webRequest module', function() { } }); }); + it('receives post data in details object', function(done) { + var postData = { + name: 'post test', + type: 'string' + }; + ses.webRequest.onBeforeRequest(function(details, callback) { + var data; + assert.equal(details.url, defaultURL); + assert.equal(details.method, 'POST'); + assert.equal(details.uploadData.length, 1); + data = qs.parse(details.uploadData[0].bytes.toString()); + assert.deepEqual(data, postData); + return callback({ + cancel: true + }); + }); + return $.ajax({ + url: defaultURL, + type: 'POST', + data: postData, + success: function() { + }, + error: function() { + done(); + } + }); + }); return it('can redirect the request', function(done) { ses.webRequest.onBeforeRequest(function(details, callback) { if (details.url === defaultURL) {