Bug 862401: make sure nsDefaultURIFixup::KeywordToURI propagates POST data. sr=bz, r=gavin
authorMike de Boer <mdeboer@mozilla.com>
Wed, 01 May 2013 13:04:21 +0200
changeset 132050 8b36d359f8896b7d5fbbaafcc189e52eb808dfec
parent 132049 338af3238e84c7ca3fbbdbe1c1322a9d6b9fc886
child 132051 6358dfe4de6981021acff29abe653317523d1bbb
push id28097
push usergsharp@mozilla.com
push dateThu, 16 May 2013 04:35:23 +0000
treeherdermozilla-inbound@8b36d359f889 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, gavin
bugs862401
milestone24.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 862401: make sure nsDefaultURIFixup::KeywordToURI propagates POST data. sr=bz, r=gavin
browser/base/content/test/Makefile.in
browser/base/content/test/POSTSearchEngine.xml
browser/base/content/test/browser_keywordSearch_postData.js
browser/base/content/test/print_postdata.sjs
caps/src/nsScriptSecurityManager.cpp
docshell/base/nsDefaultURIFixup.cpp
docshell/base/nsDefaultURIFixup.h
docshell/base/nsDocShell.cpp
docshell/base/nsIURIFixup.idl
--- a/browser/base/content/test/Makefile.in
+++ b/browser/base/content/test/Makefile.in
@@ -59,16 +59,19 @@ endif
 # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638.
 
 # browser_bug321000.js is disabled because newline handling is shaky (bug 592528)
 
 _BROWSER_FILES = \
                  head.js \
                  browser_typeAheadFind.js \
                  browser_keywordSearch.js \
+                 browser_keywordSearch_postData.js \
+                 POSTSearchEngine.xml \
+                 print_postdata.sjs \
                  browser_alltabslistener.js \
                  browser_bug304198.js \
                  title_test.svg \
                  browser_bug329212.js \
                  browser_bug356571.js \
                  browser_bug380960.js \
                  browser_bug386835.js \
                  browser_bug405137.js \
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/POSTSearchEngine.xml
@@ -0,0 +1,6 @@
+<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
+  <ShortName>POST Search</ShortName>
+  <Url type="text/html" method="POST" template="http://mochi.test:8888/browser/browser/base/content/test/print_postdata.sjs">
+    <Param name="searchterms" value="{searchTerms}"/>
+  </Url>
+</OpenSearchDescription>
copy from browser/base/content/test/browser_keywordSearch.js
copy to browser/base/content/test/browser_keywordSearch_postData.js
--- a/browser/base/content/test/browser_keywordSearch.js
+++ b/browser/base/content/test/browser_keywordSearch_postData.js
@@ -2,85 +2,93 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  **/
 
 var gTests = [
   {
     name: "normal search (search service)",
     testText: "test search",
-    searchURL: Services.search.defaultEngine.getSubmission("test search", null, "keyword").uri.spec
+    expectText: "test+search"
   },
   {
     name: "?-prefixed search (search service)",
     testText: "?   foo  ",
-    searchURL: Services.search.defaultEngine.getSubmission("foo", null, "keyword").uri.spec
+    expectText: "foo"
   }
 ];
 
 function test() {
   waitForExplicitFinish();
 
-  let windowObserver = {
-    observe: function(aSubject, aTopic, aData) {
-      if (aTopic == "domwindowopened") {
-        ok(false, "Alert window opened");
-        let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget);
-        win.addEventListener("load", function() {
-          win.removeEventListener("load", arguments.callee, false);
-          win.close();
-        }, false);
-        executeSoon(finish);
-      }
-    }
-  };
-
-  Services.ww.registerNotification(windowObserver);
-
   let tab = gBrowser.selectedTab = gBrowser.addTab();
 
-  let listener = {
-    onStateChange: function onLocationChange(webProgress, req, flags, status) {
-      // Only care about document starts
-      let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
-                     Ci.nsIWebProgressListener.STATE_START;
-      if (!(flags & docStart))
-        return;
+  let searchObserver = function search_observer(aSubject, aTopic, aData) {
+    let engine = aSubject.QueryInterface(Ci.nsISearchEngine);
+    info("Observer: " + aData + " for " + engine.name);
+
+    if (aData != "engine-added")
+      return;
+
+    if (engine.name != "POST Search")
+      return;
 
-      info("received document start");
+    Services.search.defaultEngine = engine;
+
+    registerCleanupFunction(function () {
+      Services.search.removeEngine(engine);
+    });
 
-      ok(req instanceof Ci.nsIChannel, "req is a channel");
-      is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
-      info("Actual URI: " + req.URI.spec);
+    // ready to execute the tests!
+    executeSoon(nextTest);
+  };
 
-      executeSoon(nextTest);
-    }
-  }
-  gBrowser.addProgressListener(listener);
+  Services.obs.addObserver(searchObserver, "browser-search-engine-modified", false);
 
   registerCleanupFunction(function () {
-    Services.ww.unregisterNotification(windowObserver);
+    gBrowser.removeTab(tab);
 
-    gBrowser.removeProgressListener(listener);
-    gBrowser.removeTab(tab);
+    Services.obs.removeObserver(searchObserver, "browser-search-engine-modified");
   });
 
-  nextTest();
+  Services.search.addEngine("http://test:80/browser/browser/base/content/test/POSTSearchEngine.xml",
+                            Ci.nsISearchEngine.DATA_XML, null, false);
 }
 
 var gCurrTest;
 function nextTest() {
   if (gTests.length) {
     gCurrTest = gTests.shift();
     doTest();
   } else {
     finish();
   }
 }
 
 function doTest() {
   info("Running test: " + gCurrTest.name);
 
+  waitForLoad(function () {
+    let loadedText = gBrowser.contentDocument.body.textContent;
+    ok(loadedText, "search page loaded");
+    let needle = "searchterms=" + gCurrTest.expectText;
+    is(loadedText, needle, "The query POST data should be returned in the response");
+    nextTest();
+  });
+
   // Simulate a user entering search terms
   gURLBar.value = gCurrTest.testText;
   gURLBar.focus();
   EventUtils.synthesizeKey("VK_RETURN", {});
 }
+
+
+function waitForLoad(cb) {
+  let browser = gBrowser.selectedBrowser;
+  browser.addEventListener("load", function listener() {
+    if (browser.currentURI.spec == "about:blank")
+      return;
+    info("Page loaded: " + browser.currentURI.spec);
+    browser.removeEventListener("load", listener, true);
+
+    cb();
+  }, true);
+}
copy from content/base/test/bug435425.sjs
copy to browser/base/content/test/print_postdata.sjs
--- a/content/base/test/bug435425.sjs
+++ b/browser/base/content/test/print_postdata.sjs
@@ -1,24 +1,22 @@
 const CC = Components.Constructor;
 const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
                              "nsIBinaryInputStream",
                              "setInputStream");
 
-function handleRequest(request, response)
-{
+function handleRequest(request, response) {
   response.setHeader("Content-Type", "text/plain", false);
   if (request.method == "GET") {
     response.write(request.queryString);
   } else {
     var body = new BinaryInputStream(request.bodyInputStream);
 
     var avail;
     var bytes = [];
 
     while ((avail = body.available()) > 0)
       Array.prototype.push.apply(bytes, body.readByteArray(avail));
 
     var data = String.fromCharCode.apply(null, bytes);
     response.bodyOutputStream.write(data, data.length);
   }
 }
-
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1565,17 +1565,17 @@ nsScriptSecurityManager::CheckLoadURIStr
         nsIURIFixup::FIXUP_FLAG_NONE,
         nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP,
         nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI,
         nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP |
         nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI
     };
 
     for (uint32_t i = 0; i < ArrayLength(flags); ++i) {
-        rv = fixup->CreateFixupURI(aTargetURIStr, flags[i],
+        rv = fixup->CreateFixupURI(aTargetURIStr, flags[i], nullptr,
                                    getter_AddRefs(target));
         NS_ENSURE_SUCCESS(rv, rv);
 
         rv = CheckLoadURIWithPrincipal(aPrincipal, target, aFlags);
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     return rv;
--- a/docshell/base/nsDefaultURIFixup.cpp
+++ b/docshell/base/nsDefaultURIFixup.cpp
@@ -108,17 +108,18 @@ nsDefaultURIFixup::CreateExposableURI(ns
     // return the fixed-up URI
     *aReturn = uri;
     NS_ADDREF(*aReturn);
     return NS_OK;
 }
 
 /* nsIURI createFixupURI (in nsAUTF8String aURIText, in unsigned long aFixupFlags); */
 NS_IMETHODIMP
-nsDefaultURIFixup::CreateFixupURI(const nsACString& aStringURI, uint32_t aFixupFlags, nsIURI **aURI)
+nsDefaultURIFixup::CreateFixupURI(const nsACString& aStringURI, uint32_t aFixupFlags,
+                                  nsIInputStream **aPostData, nsIURI **aURI)
 {
     NS_ENSURE_ARG(!aStringURI.IsEmpty());
     NS_ENSURE_ARG_POINTER(aURI);
 
     nsresult rv;
     *aURI = nullptr;
 
     nsAutoCString uriString(aStringURI);
@@ -142,17 +143,17 @@ nsDefaultURIFixup::CreateFixupURI(const 
     {
         nsCOMPtr<nsIURI> uri;
         uint32_t newFixupFlags = aFixupFlags & ~FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
 
         rv =  CreateFixupURI(Substring(uriString,
                                        sizeof("view-source:") - 1,
                                        uriString.Length() -
                                          (sizeof("view-source:") - 1)),
-                             newFixupFlags, getter_AddRefs(uri));
+                             newFixupFlags, aPostData, getter_AddRefs(uri));
         if (NS_FAILED(rv))
             return NS_ERROR_FAILURE;
         nsAutoCString spec;
         uri->GetSpec(spec);
         uriString.Assign(NS_LITERAL_CSTRING("view-source:") + spec);
     }
     else {
         // Check for if it is a file URL
@@ -238,17 +239,17 @@ nsDefaultURIFixup::CreateFixupURI(const 
     // See if it is a keyword
     // Test whether keywords need to be fixed up
     bool fixupKeywords = false;
     if (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP) {
         nsresult rv = Preferences::GetBool("keyword.enabled", &fixupKeywords);
         NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
         if (fixupKeywords)
         {
-            KeywordURIFixup(uriString, aURI);
+            KeywordURIFixup(uriString, aPostData, aURI);
             if(*aURI)
                 return NS_OK;
         }
     }
 
     // Prune duff protocol schemes
     //
     //   ://totallybroken.url.com
@@ -304,28 +305,32 @@ nsDefaultURIFixup::CreateFixupURI(const 
     if (*aURI && aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) {
         MakeAlternateURI(*aURI);
     }
 
     // If we still haven't been able to construct a valid URI, try to force a
     // keyword match.  This catches search strings with '.' or ':' in them.
     if (!*aURI && fixupKeywords)
     {
-        KeywordToURI(aStringURI, aURI);
+        KeywordToURI(aStringURI, aPostData, aURI);
         if(*aURI)
             return NS_OK;
     }
 
     return rv;
 }
 
 NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
+                                              nsIInputStream **aPostData,
                                               nsIURI **aURI)
 {
     *aURI = nullptr;
+    if (aPostData) {
+        *aPostData = nullptr;
+    }
     NS_ENSURE_STATE(Preferences::GetRootBranch());
 
     // Strip leading "?" and leading/trailing spaces from aKeyword
     nsAutoCString keyword(aKeyword);
     if (StringBeginsWith(keyword, NS_LITERAL_CSTRING("?"))) {
         keyword.Cut(0, 1);
     }
     keyword.Trim(" ");
@@ -349,23 +354,26 @@ NS_IMETHODIMP nsDefaultURIFixup::Keyword
                                            NS_LITERAL_STRING("keyword"),
                                            getter_AddRefs(submission));
             else
               defaultEngine->GetSubmission(NS_ConvertUTF8toUTF16(keyword),
                                            EmptyString(),
                                            NS_LITERAL_STRING("keyword"),
                                            getter_AddRefs(submission));
             if (submission) {
-                // The submission depends on POST data (i.e. the search engine's
-                // "method" is POST), we can't use this engine for keyword
-                // searches
                 nsCOMPtr<nsIInputStream> postData;
                 submission->GetPostData(getter_AddRefs(postData));
-                if (postData) {
-                    return NS_ERROR_NOT_AVAILABLE;
+                if (aPostData) {
+                  postData.forget(aPostData);
+                } else if (postData) {
+                  // The submission specifies POST data (i.e. the search
+                  // engine's "method" is POST), but our caller didn't allow
+                  // passing post data back. No point passing back a URL that
+                  // won't load properly.
+                  return NS_ERROR_FAILURE;
                 }
 
                 // This notification is meant for Firefox Health Report so it
                 // can increment counts from the search engine. The assumption
                 // here is that this keyword/submission will eventually result
                 // in a search. Since we only generate a URI here, there is the
                 // possibility we'll increment the counter without actually
                 // incurring a search. A robust solution would involve currying
@@ -757,18 +765,19 @@ const char * nsDefaultURIFixup::GetFileS
 }
 
 const char * nsDefaultURIFixup::GetCharsetForUrlBar()
 {
   const char *charset = GetFileSystemCharset();
   return charset;
 }
 
-nsresult nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString, 
-                                            nsIURI** aURI)
+void nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString,
+                                        nsIInputStream **aPostData,
+                                        nsIURI** aURI)
 {
     // These are keyword formatted strings
     // "what is mozilla"
     // "what is mozilla?"
     // "docshell site:mozilla.org" - has no dot/colon in the first space-separated substring
     // "?mozilla" - anything that begins with a question mark
     // "?site:mozilla.org docshell"
     // Things that have a quote before the first dot/colon
@@ -797,23 +806,18 @@ nsresult nsDefaultURIFixup::KeywordURIFi
     uint32_t quoteLoc = std::min(uint32_t(aURIString.FindChar('"')),
                                uint32_t(aURIString.FindChar('\'')));
 
     if (((spaceLoc < dotLoc || quoteLoc < dotLoc) &&
          (spaceLoc < colonLoc || quoteLoc < colonLoc) &&
          (spaceLoc < qMarkLoc || quoteLoc < qMarkLoc)) ||
         qMarkLoc == 0)
     {
-        KeywordToURI(aURIString, aURI);
+        KeywordToURI(aURIString, aPostData, aURI);
     }
-
-    if(*aURI)
-        return NS_OK;
-
-    return NS_ERROR_FAILURE;
 }
 
 
 nsresult NS_NewURIFixup(nsIURIFixup **aURIFixup)
 {
     nsDefaultURIFixup *fixup = new nsDefaultURIFixup;
     if (fixup == nullptr)
     {
--- a/docshell/base/nsDefaultURIFixup.h
+++ b/docshell/base/nsDefaultURIFixup.h
@@ -24,17 +24,17 @@ public:
 
 protected:
     virtual ~nsDefaultURIFixup();
 
 private:
     /* additional members */
     nsresult FileURIFixup(const nsACString &aStringURI, nsIURI** aURI);
     nsresult ConvertFileToStringURI(const nsACString& aIn, nsCString& aOut);
-    nsresult KeywordURIFixup(const nsACString &aStringURI, nsIURI** aURI);
+    void KeywordURIFixup(const nsACString &aStringURI, nsIInputStream** aPostData, nsIURI** aURI);
     bool PossiblyByteExpandedFileName(const nsAString& aIn);
     bool PossiblyHostPortUrl(const nsACString& aUrl);
     bool MakeAlternateURI(nsIURI *aURI);
     bool IsLikelyFTP(const nsCString& aHostSpec);
     const char * GetFileSystemCharset();
     const char * GetCharsetForUrlBar();
 
     nsCString mFsCharset;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -4000,16 +4000,17 @@ nsDocShell::LoadURI(const PRUnichar * aU
                     nsIInputStream * aHeaderStream)
 {
     NS_ASSERTION((aLoadFlags & 0xf) == 0, "Unexpected flags");
     
     if (!IsNavigationAllowed()) {
       return NS_OK; // JS may not handle returning of an error code
     }
     nsCOMPtr<nsIURI> uri;
+    nsCOMPtr<nsIInputStream> postStream(aPostStream);
     nsresult rv = NS_OK;
 
     // Create a URI from our string; if that succeeds, we want to
     // change aLoadFlags to not include the ALLOW_THIRD_PARTY_FIXUP
     // flag.
 
     NS_ConvertUTF16toUTF8 uriString(aURI);
     // Cleanup the empty spaces that might be on each end.
@@ -4031,16 +4032,17 @@ nsDocShell::LoadURI(const PRUnichar * aU
         uint32_t fixupFlags = 0;
         if (aLoadFlags & LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP) {
           fixupFlags |= nsIURIFixup::FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
         }
         if (aLoadFlags & LOAD_FLAGS_URI_IS_UTF8) {
           fixupFlags |= nsIURIFixup::FIXUP_FLAG_USE_UTF8;
         }
         rv = sURIFixup->CreateFixupURI(uriString, fixupFlags,
+                                       getter_AddRefs(postStream),
                                        getter_AddRefs(uri));
     }
     // else no fixup service so just use the URI we created and see
     // what happens
 
     if (NS_ERROR_MALFORMED_URI == rv) {
         DisplayLoadError(rv, uri, aURI);
     }
@@ -4064,17 +4066,17 @@ nsDocShell::LoadURI(const PRUnichar * aU
     aLoadFlags &= ~EXTRA_LOAD_FLAGS;
 
     nsCOMPtr<nsIDocShellLoadInfo> loadInfo;
     rv = CreateLoadInfo(getter_AddRefs(loadInfo));
     if (NS_FAILED(rv)) return rv;
     
     uint32_t loadType = MAKE_LOAD_TYPE(LOAD_NORMAL, aLoadFlags);
     loadInfo->SetLoadType(ConvertLoadTypeToDocShellLoadInfo(loadType));
-    loadInfo->SetPostDataStream(aPostStream);
+    loadInfo->SetPostDataStream(postStream);
     loadInfo->SetReferrer(aReferringURI);
     loadInfo->SetHeadersStream(aHeaderStream);
 
     rv = LoadURI(uri, loadInfo, extraFlags, true);
 
     // Save URI string in case it's needed later when
     // sending to search engine service in EndPageLoad()
     mOriginalUriString = uriString; 
@@ -6679,16 +6681,17 @@ nsDocShell::EndPageLoad(nsIWebProgress *
             return NS_OK;
         }
 
         if (sURIFixup) {
             //
             // Try and make an alternative URI from the old one
             //
             nsCOMPtr<nsIURI> newURI;
+            nsCOMPtr<nsIInputStream> newPostData;
 
             nsAutoCString oldSpec;
             url->GetSpec(oldSpec);
       
             //
             // First try keyword fixup
             //
             if (aStatus == NS_ERROR_UNKNOWN_HOST && mAllowKeywordFixup) {
@@ -6719,16 +6722,17 @@ nsDocShell::EndPageLoad(nsIWebProgress *
                     (scheme.Find("http") != 0)) {
                     keywordsEnabled = false;
                 }
 
                 if (keywordsEnabled && (kNotFound == dotLoc)) {
                     // only send non-qualified hosts to the keyword server
                     if (!mOriginalUriString.IsEmpty()) {
                         sURIFixup->KeywordToURI(mOriginalUriString,
+                                                getter_AddRefs(newPostData),
                                                 getter_AddRefs(newURI));
                     }
                     else {
                         //
                         // If this string was passed through nsStandardURL by
                         // chance, then it may have been converted from UTF-8 to
                         // ACE, which would result in a completely bogus keyword
                         // query.  Here we try to recover the original Unicode
@@ -6738,21 +6742,25 @@ nsDocShell::EndPageLoad(nsIWebProgress *
                         // Since we don't have access to the exact original string
                         // that was entered by the user, this will just have to do.
                         bool isACE;
                         nsAutoCString utf8Host;
                         nsCOMPtr<nsIIDNService> idnSrv =
                             do_GetService(NS_IDNSERVICE_CONTRACTID);
                         if (idnSrv &&
                             NS_SUCCEEDED(idnSrv->IsACE(host, &isACE)) && isACE &&
-                            NS_SUCCEEDED(idnSrv->ConvertACEtoUTF8(host, utf8Host)))
+                            NS_SUCCEEDED(idnSrv->ConvertACEtoUTF8(host, utf8Host))) {
                             sURIFixup->KeywordToURI(utf8Host,
+                                                    getter_AddRefs(newPostData),
                                                     getter_AddRefs(newURI));
-                        else
-                            sURIFixup->KeywordToURI(host, getter_AddRefs(newURI));
+                        } else {
+                            sURIFixup->KeywordToURI(host,
+                                                    getter_AddRefs(newPostData),
+                                                    getter_AddRefs(newURI));
+                        }
                     }
                 } // end keywordsEnabled
             }
 
             //
             // Now try change the address, e.g. turn http://foo into
             // http://www.foo.com
             //
@@ -6775,18 +6783,20 @@ nsDocShell::EndPageLoad(nsIWebProgress *
                             // Keyword lookup made a new URI so no need to try
                             // an alternate one.
                             doCreateAlternate = false;
                         }
                     }
                 }
                 if (doCreateAlternate) {
                     newURI = nullptr;
+                    newPostData = nullptr;
                     sURIFixup->CreateFixupURI(oldSpec,
                       nsIURIFixup::FIXUP_FLAGS_MAKE_ALTERNATE_URI,
+                                              getter_AddRefs(newPostData),
                                               getter_AddRefs(newURI));
                 }
             }
 
             // Did we make a new URI that is different to the old one? If so
             // load it.
             //
             if (newURI) {
@@ -6797,17 +6807,17 @@ nsDocShell::EndPageLoad(nsIWebProgress *
                 if (!sameURI) {
                     nsAutoCString newSpec;
                     newURI->GetSpec(newSpec);
                     NS_ConvertUTF8toUTF16 newSpecW(newSpec);
 
                     return LoadURI(newSpecW.get(),  // URI string
                                    LOAD_FLAGS_NONE, // Load flags
                                    nullptr,          // Referring URI
-                                   nullptr,          // Post data stream
+                                   newPostData,      // Post data stream
                                    nullptr);         // Headers stream
                 }
             }
         }
 
         // Well, fixup didn't work :-(
         // It is time to throw an error dialog box, and be done with it...
 
--- a/docshell/base/nsIURIFixup.idl
+++ b/docshell/base/nsIURIFixup.idl
@@ -2,21 +2,22 @@
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #include "nsISupports.idl"
 
 interface nsIURI;
+interface nsIInputStream;
 
 /**
  * Interface implemented by objects capable of fixing up strings into URIs
  */
-[scriptable, uuid(773081ac-9f81-4bdb-9e7a-5e87b4361f09)]
+[scriptable, uuid(552a23bb-c1b2-426e-a801-d346c6a98f1d)]
 interface nsIURIFixup : nsISupports
 {
     /** No fixup flags. */
     const unsigned long FIXUP_FLAG_NONE = 0;
 
     /**
      * Allow the fixup to use a keyword lookup service to complete the URI.
      * The fixup object implementer should honour this flag and only perform
@@ -49,19 +50,30 @@ interface nsIURIFixup : nsISupports
 
     /**
      * Converts the specified string into a URI, first attempting
      * to correct any errors in the syntax or other vagaries. Returns
      * a wellformed URI or nullptr if it can't.
      *
      * @param aURIText    Candidate URI.
      * @param aFixupFlags Flags that govern ways the URI may be fixed up.
+     * @param aPostData   The POST data to submit with the returned
+     *                    URI (see nsISearchSubmission).
      */
-    nsIURI createFixupURI(in AUTF8String aURIText, in unsigned long aFixupFlags);
+    nsIURI createFixupURI(in AUTF8String aURIText, in unsigned long aFixupFlags,
+                          [optional] out nsIInputStream aPostData);
 
     /**
      * Converts the specified keyword string into a URI.  Note that it's the
      * caller's responsibility to check whether keywords are enabled and
      * whether aKeyword is a sensible keyword.
+     *
+     * @param aKeyword  The keyword string to convert into a URI
+     * @param aPostData The POST data to submit to the returned URI
+     *                  (see nsISearchSubmission).
+     *
+     * @throws NS_ERROR_FAILURE if the resulting URI requires submission of POST
+     *         data and aPostData is null.
      */
-    nsIURI keywordToURI(in AUTF8String aKeyword);
+    nsIURI keywordToURI(in AUTF8String aKeyword,
+                        [optional] out nsIInputStream aPostData);
 };