Bug 1477076 - Add POST support to addEngineWithDetails. r=florian
authorMichael Kaply <mozilla@kaply.com>
Fri, 20 Jul 2018 18:40:00 +0000
changeset 821157 ac4f07373dad1a680294238cb0fd6bb22ca46a7e
parent 821156 2727ea579453784ab7933bf2ca4390d180211651
child 821158 7635ef4a997ddfac1a33604bb799af8d71057847
push id117021
push usercholler@mozilla.com
push dateSat, 21 Jul 2018 09:50:19 +0000
reviewersflorian
bugs1477076
milestone63.0a1
Bug 1477076 - Add POST support to addEngineWithDetails. r=florian Differential Revision: https://phabricator.services.mozilla.com/D2254
netwerk/base/nsIBrowserSearchService.idl
toolkit/components/search/nsSearchService.js
toolkit/components/search/tests/xpcshell/test_addEngineWithDetailsObject.js
--- a/netwerk/base/nsIBrowserSearchService.idl
+++ b/netwerk/base/nsIBrowserSearchService.idl
@@ -362,22 +362,27 @@ interface nsIBrowserSearchService : nsIS
    * passed as an object in place of parameter two.
    *
    *   Services.search.addEngineWithDetails("Example engine", {
    *     template: "http://example.com/?search={searchTerms}",
    *     description: "Example search engine description",
    *     suggestURL: http://example.com/?suggest={searchTerms},
    * });
    *
-   * Using this method, you can use a new parameter, suggestURL:
+   * Using this method, you can use new parameters:
    *
    * @param suggestURL [optional]
    *        Optional: The URL to which search suggestion requests
    *        should be sent.
    *
+   * @param postData [optional]
+   *        Optional: For POST requests, a string of URL parameters
+   *        to send, separated by '&'.  The string will be subjected
+   *        to OpenSearch parameter substitution.
+   *
    */
   void addEngineWithDetails(in AString name,
                             in jsval iconURL,
                             [optional] in AString alias,
                             [optional] in AString description,
                             [optional] in AString method,
                             [optional] in AString url,
                             [optional] in AString extensionID);
--- a/toolkit/components/search/nsSearchService.js
+++ b/toolkit/components/search/nsSearchService.js
@@ -36,17 +36,17 @@ XPCOMUtils.defineLazyGetter(this, "reset
 XPCOMUtils.defineLazyGetter(this, "distroID", () => {
   return Services.prefs.getDefaultBranch("distribution.").getCharPref("id", "");
 });
 
 const BinaryInputStream = Components.Constructor(
   "@mozilla.org/binaryinputstream;1",
   "nsIBinaryInputStream", "setInputStream");
 
-XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser", "XMLHttpRequest"]);
+XPCOMUtils.defineLazyGlobalGetters(this, ["DOMParser", "XMLHttpRequest", "URLSearchParams"]);
 
 // A text encoder to UTF8, used whenever we commit the cache to disk.
 XPCOMUtils.defineLazyGetter(this, "gEncoder",
                             function() {
                               return new TextEncoder();
                             });
 
 
@@ -1737,16 +1737,22 @@ Engine.prototype = {
     let method = aParams.method || "GET";
     this._urls.push(new EngineURL(URLTYPE_SEARCH_HTML, method, aParams.template));
     if (aParams.suggestURL) {
       this._urls.push(new EngineURL(URLTYPE_SUGGEST_JSON, "GET", aParams.suggestURL));
     }
     if (aParams.queryCharset) {
       this._queryCharset = aParams.queryCharset;
     }
+    if (aParams.postData) {
+      let queries = new URLSearchParams(aParams.postData);
+      for (let [name, value] of queries) {
+        this.addParam(name, value);
+      }
+    }
 
     this._name = aName;
     this.alias = aParams.alias;
     this._description = aParams.description;
     this._setIcon(aParams.iconURL, true);
     this._extensionID = aParams.extensionID;
   },
 
--- a/toolkit/components/search/tests/xpcshell/test_addEngineWithDetailsObject.js
+++ b/toolkit/components/search/tests/xpcshell/test_addEngineWithDetailsObject.js
@@ -7,16 +7,19 @@ const kSearchEngineID = "addEngineWithDe
 const kSearchEngineURL = "http://example.com/?search={searchTerms}";
 const kSearchSuggestURL = "http://example.com/?suggest={searchTerms}";
 const kIconURL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==";
 const kDescription = "Test Description";
 const kAlias = "alias_foo";
 const kSearchTerm = "foo";
 const kExtensionID = "test@example.com";
 const URLTYPE_SUGGEST_JSON = "application/x-suggestions+json";
+const kSearchEnginePOSTID = "addEngineWithDetails_post_test_engine";
+const kSearchEnginePOSTURL = "http://example.com/";
+const kSearchEnginePOSTData = "search={searchTerms}&extra=more";
 
 add_task(async function test_addEngineWithDetails() {
   Assert.ok(!Services.search.isInitialized);
 
   Services.prefs.getDefaultBranch(BROWSER_SEARCH_PREF)
           .setBoolPref("reset.enabled", true);
 
   await asyncInit();
@@ -46,8 +49,28 @@ add_task(async function test_addEngineWi
   let submission =
     Services.search.currentEngine.getSubmission(kSearchTerm, null, "searchbar");
   Assert.equal(submission.uri.spec, expectedURL);
   let expectedSuggestURL = kSearchSuggestURL.replace("{searchTerms}", kSearchTerm);
   let submissionSuggest =
     Services.search.currentEngine.getSubmission(kSearchTerm, URLTYPE_SUGGEST_JSON);
   Assert.equal(submissionSuggest.uri.spec, expectedSuggestURL);
 });
+
+add_task(async function test_addEngineWithDetailsPOST() {
+  Assert.ok(Services.search.isInitialized);
+
+  Services.search.addEngineWithDetails(kSearchEnginePOSTID, {
+    template: kSearchEnginePOSTURL,
+    method: "POST",
+    postData: kSearchEnginePOSTData,
+  });
+
+  let engine = Services.search.getEngineByName(kSearchEnginePOSTID);
+
+  let expectedPOSTData = kSearchEnginePOSTData.replace("{searchTerms}", kSearchTerm);
+  let submission = engine.getSubmission(kSearchTerm, null, "searchbar");
+  Assert.equal(submission.uri.spec, kSearchEnginePOSTURL);
+  let sis = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
+  sis.init(submission.postData);
+  let data = sis.read(submission.postData.available());
+  Assert.equal(data, expectedPOSTData);
+});