Bug 1129957 - RemoteWebNavigation doesn't accept postdata or headers. r=Mossop
☠☠ backed out by 1fd19d8fc936 ☠ ☠
authorNeil Rashbrook <neil@parkwaycc.co.uk>
Wed, 10 Jun 2015 11:17:35 -0300
changeset 248007 109474240d8cd0fb38839d92b2d2722ef16f0911
parent 248006 cbc9af5b38ee8aaa9230f1812e4ab687f027b85f
child 248008 9ac1d4aadc38dbec98cd0cd4bae6a9ff474dd8e8
push id28887
push userkwierso@gmail.com
push dateThu, 11 Jun 2015 01:10:53 +0000
treeherdermozilla-central@1fd19d8fc936 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMossop
bugs1129957
milestone41.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1129957 - RemoteWebNavigation doesn't accept postdata or headers. r=Mossop
browser/base/content/browser.js
browser/components/sessionstore/ContentRestore.jsm
browser/components/sessionstore/Utils.jsm
toolkit/content/browser-child.js
toolkit/modules/RemoteWebNavigation.jsm
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -871,37 +871,42 @@ function _loadURIWithFlags(browser, uri,
   if (!uri) {
     uri = "about:blank";
   }
   let flags = params.flags || 0;
   let referrer = params.referrerURI;
   let referrerPolicy = ('referrerPolicy' in params ? params.referrerPolicy :
                         Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
   let charset = params.charset;
-  let postdata = params.postData;
+  let postData = params.postData;
 
   if (!(flags & browser.webNavigation.LOAD_FLAGS_FROM_EXTERNAL)) {
     browser.userTypedClear++;
   }
 
   let process = browser.isRemoteBrowser ? Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
                                         : Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
   let mustChangeProcess = gMultiProcessBrowser &&
                           !E10SUtils.canLoadURIInProcess(uri, process);
   try {
     if (!mustChangeProcess) {
       browser.webNavigation.loadURIWithOptions(uri, flags,
                                                referrer, referrerPolicy,
-                                               postdata, null, null);
+                                               postData, null, null);
     } else {
+      if (postData) {
+        postData = NetUtil.readInputStreamToString(postData, postData.available());
+      }
+
       LoadInOtherProcess(browser, {
         uri: uri,
         flags: flags,
         referrer: referrer ? referrer.spec : null,
         referrerPolicy: referrerPolicy,
+        postData: postData,
       });
     }
   } catch (e) {
     // If anything goes wrong just switch remoteness manually and load the URI.
     // We might lose history that way but at least the browser loaded a page.
     // This might be necessary if SessionStore wasn't initialized yet i.e.
     // when the homepage is a non-remote page.
     gBrowser.updateBrowserRemotenessByURL(browser, uri);
--- a/browser/components/sessionstore/ContentRestore.jsm
+++ b/browser/components/sessionstore/ContentRestore.jsm
@@ -197,19 +197,21 @@ ContentRestoreInternal.prototype = {
       if (loadArguments) {
         // A load has been redirected to a new process so get history into the
         // same state it was before the load started then trigger the load.
         let referrer = loadArguments.referrer ?
                        Utils.makeURI(loadArguments.referrer) : null;
         let referrerPolicy = ('referrerPolicy' in loadArguments
             ? loadArguments.referrerPolicy
             : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
+        let postData = loadArguments.postData ?
+                       Utils.makeInputStream(loadArguments.postData) : null;
         webNavigation.loadURIWithOptions(loadArguments.uri, loadArguments.flags,
-                                         referrer, referrerPolicy, null, null,
-                                         null);
+                                         referrer, referrerPolicy, postData,
+                                         null, null);
       } else if (tabData.userTypedValue && tabData.userTypedClear) {
         // If the user typed a URL into the URL bar and hit enter right before
         // we crashed, we want to start loading that page again. A non-zero
         // userTypedClear value means that the load had started.
         // Load userTypedValue and fix up the URL if it's partial/broken.
         webNavigation.loadURI(tabData.userTypedValue,
                               Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP,
                               null, null, null);
--- a/browser/components/sessionstore/Utils.jsm
+++ b/browser/components/sessionstore/Utils.jsm
@@ -2,24 +2,33 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 this.EXPORTED_SYMBOLS = ["Utils"];
 
 const Cu = Components.utils;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
 
 Cu.import("resource://gre/modules/Services.jsm", this);
 
 this.Utils = Object.freeze({
   makeURI: function (url) {
     return Services.io.newURI(url, null, null);
   },
 
+  makeInputStream: function (aString) {
+    let stream = Cc["@mozilla.org/io/string-input-stream;1"].
+                 createInstance(Ci.nsISupportsCString);
+    stream.data = aString;
+    return stream; // XPConnect will QI this to nsIInputStream for us.
+  },
+
   /**
    * Returns true if the |url| passed in is part of the given root |domain|.
    * For example, if |url| is "www.mozilla.org", and we pass in |domain| as
    * "mozilla.org", this will return true. It would return false the other way
    * around.
    */
   hasRootDomain: function (url, domain) {
     let host;
--- a/toolkit/content/browser-child.js
+++ b/toolkit/content/browser-child.js
@@ -16,16 +16,23 @@ XPCOMUtils.defineLazyModuleGetter(this, 
   "resource://gre/modules/PageThumbUtils.jsm");
 
 if (AppConstants.MOZ_CRASHREPORTER) {
   XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
                                      "@mozilla.org/xre/app-info;1",
                                      "nsICrashReporter");
 }
 
+function makeInputStream(aString) {
+  let stream = Cc["@mozilla.org/io/string-input-stream;1"].
+               createInstance(Ci.nsISupportsCString);
+  stream.data = aString;
+  return stream; // XPConnect will QI this to nsIInputStream for us.
+}
+
 let WebProgressListener = {
   init: function() {
     this._filter = Cc["@mozilla.org/appshell/component/browser-status-filter;1"]
                      .createInstance(Ci.nsIWebProgress);
     this._filter.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_ALL);
 
     let webProgress = docShell.QueryInterface(Ci.nsIInterfaceRequestor)
                               .getInterface(Ci.nsIWebProgress);
@@ -238,16 +245,17 @@ let WebNavigation =  {
         this.goForward();
         break;
       case "WebNavigation:GotoIndex":
         this.gotoIndex(message.data.index);
         break;
       case "WebNavigation:LoadURI":
         this.loadURI(message.data.uri, message.data.flags,
                      message.data.referrer, message.data.referrerPolicy,
+                     message.data.postData, message.data.headers,
                      message.data.baseURI);
         break;
       case "WebNavigation:Reload":
         this.reload(message.data.flags);
         break;
       case "WebNavigation:Stop":
         this.stop(message.data.flags);
         break;
@@ -264,34 +272,38 @@ let WebNavigation =  {
     if (this.webNavigation.canGoForward)
       this.webNavigation.goForward();
   },
 
   gotoIndex: function(index) {
     this.webNavigation.gotoIndex(index);
   },
 
-  loadURI: function(uri, flags, referrer, referrerPolicy, baseURI) {
+  loadURI: function(uri, flags, referrer, referrerPolicy, postData, headers, baseURI) {
     if (AppConstants.MOZ_CRASHREPORTER && CrashReporter.enabled) {
       let annotation = uri;
       try {
         let url = Services.io.newURI(uri, null, null);
         // If the current URI contains a username/password, remove it.
         url.userPass = "";
         annotation = url.spec;
       } catch (ex) { /* Ignore failures to parse and failures
                       on about: URIs. */ }
       CrashReporter.annotateCrashReport("URL", annotation);
     }
     if (referrer)
       referrer = Services.io.newURI(referrer, null, null);
+    if (postData)
+      postData = makeInputStream(postData);
+    if (headers)
+      headers = makeInputStream(headers);
     if (baseURI)
       baseURI = Services.io.newURI(baseURI, null, null);
     this.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
-                                          null, null, baseURI);
+                                          postData, headers, baseURI);
   },
 
   reload: function(flags) {
     this.webNavigation.reload(flags);
   },
 
   stop: function(flags) {
     this.webNavigation.stop(flags);
--- a/toolkit/modules/RemoteWebNavigation.jsm
+++ b/toolkit/modules/RemoteWebNavigation.jsm
@@ -11,16 +11,22 @@ Cu.import("resource://gre/modules/XPCOMU
 
 function makeURI(url)
 {
   return Cc["@mozilla.org/network/io-service;1"].
          getService(Ci.nsIIOService).
          newURI(url, null, null);
 }
 
+function readInputStreamToString(aStream)
+{
+  Cu.import("resource://gre/modules/NetUtil.jsm");
+  return NetUtil.readInputStreamToString(aStream, aStream.available());
+}
+
 function RemoteWebNavigation(browser)
 {
   this.swapBrowser(browser);
 }
 
 RemoteWebNavigation.prototype = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebNavigation, Ci.nsISupports]),
 
@@ -68,24 +74,23 @@ RemoteWebNavigation.prototype = {
   },
   loadURI: function(aURI, aLoadFlags, aReferrer, aPostData, aHeaders) {
     this.loadURIWithOptions(aURI, aLoadFlags, aReferrer,
                             Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT,
                             aPostData, aHeaders, null);
   },
   loadURIWithOptions: function(aURI, aLoadFlags, aReferrer, aReferrerPolicy,
                                aPostData, aHeaders, aBaseURI) {
-    if (aPostData || aHeaders)
-      throw Components.Exception("RemoteWebNavigation doesn't accept postdata or headers.", Cr.NS_ERROR_INVALID_ARGS);
-
     this._sendMessage("WebNavigation:LoadURI", {
       uri: aURI,
       flags: aLoadFlags,
       referrer: aReferrer ? aReferrer.spec : null,
       referrerPolicy: aReferrerPolicy,
+      postData: aPostData ? readInputStreamToString(aPostData) : null,
+      headers: aHeaders ? readInputStreamToString(aHeaders) : null,
       baseURI: aBaseURI ? aBaseURI.spec : null,
     });
   },
   reload: function(aReloadFlags) {
     this._sendMessage("WebNavigation:Reload", {flags: aReloadFlags});
   },
   stop: function(aStopFlags) {
     this._sendMessage("WebNavigation:Stop", {flags: aStopFlags});