session: provide uploadData with webrequest api when available
authorRobo <hop2deep@gmail.com>
Tue, 26 Jan 2016 08:28:21 +0000 (13:58 +0530)
committerRobo <hop2deep@gmail.com>
Wed, 27 Jan 2016 13:09:40 +0000 (18:39 +0530)
atom/browser/net/atom_network_delegate.cc
atom/common/native_mate_converters/net_converter.cc
atom/common/native_mate_converters/net_converter.h
docs/api/session.md
spec/api-web-request-spec.js

index 4f9bc83..f993138 100644 (file)
@@ -75,6 +75,10 @@ void ToDictionary(base::DictionaryValue* details, net::URLRequest* request) {
   details->SetString("resourceType",
                      info ? ResourceTypeToString(info->GetResourceType())
                           : "other");
+  scoped_ptr<base::ListValue> list(new base::ListValue);
+  GetUploadData(list.get(), request);
+  if (!list->empty())
+    details->Set("uploadData", list.Pass());
 }
 
 void ToDictionary(base::DictionaryValue* details,
index 7a1b48d..94081b8 100644 (file)
@@ -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<v8::Value> Converter<const net::URLRequest*>::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<net::UploadElementReader>* readers =
-        upload_data->GetElementReaders();
-    std::vector<mate::Dictionary> 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<base::DictionaryValue> dict(new base::DictionaryValue);
+  dict->SetString("method", val->method());
+  dict->SetStringWithoutPathExpansion("url", val->url().spec());
+  dict->SetString("referrer", val->referrer());
+  scoped_ptr<base::ListValue> 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<v8::Value> Converter<scoped_refptr<net::X509Certificate>>::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<net::UploadElementReader>* readers =
+      upload_data->GetElementReaders();
+  for (const auto& reader : *readers) {
+    scoped_ptr<base::DictionaryValue> upload_data_dict(
+        new base::DictionaryValue);
+    if (reader->AsBytesReader()) {
+      const net::UploadBytesElementReader* bytes_reader =
+          reader->AsBytesReader();
+      scoped_ptr<base::Value> 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
index b11c559..b7fd948 100644 (file)
@@ -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<scoped_refptr<net::X509Certificate>> {
 
 }  // 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_
index ffed587..1bef70e 100644 (file)
@@ -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:
 
index 6731d99..91b84c7 100644 (file)
@@ -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) {