Bug 1398733 - HTMLFormSubmission should pass the size of the post data inputStream if known, r=smaug
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 22 Sep 2017 08:12:03 +0200
changeset 382480 90af1cb3c4e3dc475ba446524c94cc45de452a0f
parent 382479 e77471a16ff7406ee33fb964d40f0ee0343ed8a4
child 382481 726caa0c36bac0763e33ffd6b65b306ebb3a676b
push id32559
push userkwierso@gmail.com
push dateFri, 22 Sep 2017 21:56:17 +0000
treeherdermozilla-central@3d72fdb0e561 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1398733
milestone58.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 1398733 - HTMLFormSubmission should pass the size of the post data inputStream if known, r=smaug
dom/base/FormData.cpp
dom/base/FormData.h
dom/html/HTMLFormElement.cpp
dom/html/HTMLFormSubmission.cpp
dom/html/HTMLFormSubmission.h
--- a/dom/base/FormData.cpp
+++ b/dom/base/FormData.cpp
@@ -98,17 +98,18 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFormData)
 NS_INTERFACE_MAP_END
 
 // -------------------------------------------------------------------------
 // HTMLFormSubmission
 nsresult
 FormData::GetEncodedSubmission(nsIURI* aURI,
-                               nsIInputStream** aPostDataStream)
+                               nsIInputStream** aPostDataStream,
+                               int64_t* aPostDataStreamLength)
 {
   NS_NOTREACHED("Shouldn't call FormData::GetEncodedSubmission");
   return NS_OK;
 }
 
 void
 FormData::Append(const nsAString& aName, const nsAString& aValue,
                  ErrorResult& aRv)
--- a/dom/base/FormData.h
+++ b/dom/base/FormData.h
@@ -108,17 +108,18 @@ public:
   uint32_t GetIterableLength() const;
 
   const nsAString& GetKeyAtIndex(uint32_t aIndex) const;
 
   const OwningBlobOrDirectoryOrUSVString& GetValueAtIndex(uint32_t aIndex) const;
 
   // HTMLFormSubmission
   virtual nsresult
-  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream) override;
+  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream,
+                       int64_t* aPostDataStreamLength) override;
 
   virtual nsresult AddNameValuePair(const nsAString& aName,
                                     const nsAString& aValue) override
   {
     FormDataTuple* data = mFormData.AppendElement();
     SetNameValuePair(data, aName, aValue);
     return NS_OK;
   }
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -791,24 +791,26 @@ HTMLFormElement::SubmitSubmission(HTMLFo
   {
     nsAutoPopupStatePusher popupStatePusher(mSubmitPopupState);
 
     AutoHandlingUserInputStatePusher userInpStatePusher(
                                        mSubmitInitiatedFromUserInput,
                                        nullptr, doc);
 
     nsCOMPtr<nsIInputStream> postDataStream;
+    int64_t postDataStreamLength = -1;
     rv = aFormSubmission->GetEncodedSubmission(actionURI,
-                                               getter_AddRefs(postDataStream));
+                                               getter_AddRefs(postDataStream),
+                                               &postDataStreamLength);
     NS_ENSURE_SUBMIT_SUCCESS(rv);
 
     rv = linkHandler->OnLinkClickSync(this, actionURI,
                                       target.get(),
                                       VoidString(),
-                                      postDataStream, -1 /* XXXbaku */,
+                                      postDataStream, postDataStreamLength,
                                       nullptr, false,
                                       getter_AddRefs(docShell),
                                       getter_AddRefs(mSubmittingRequest));
     NS_ENSURE_SUBMIT_SUCCESS(rv);
   }
 
   // Even if the submit succeeds, it's possible for there to be no docshell
   // or request; for example, if it's to a named anchor within the same page
--- a/dom/html/HTMLFormSubmission.cpp
+++ b/dom/html/HTMLFormSubmission.cpp
@@ -107,17 +107,18 @@ public:
 
   virtual nsresult
   AddNameBlobOrNullPair(const nsAString& aName, Blob* aBlob) override;
 
   virtual nsresult
   AddNameDirectoryPair(const nsAString& aName, Directory* aDirectory) override;
 
   virtual nsresult
-  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream) override;
+  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream,
+                       int64_t* aPostDataStreamLength) override;
 
 protected:
 
   /**
    * URL encode a Unicode string by encoding it to bytes, converting linebreaks
    * properly, and then escaping many bytes as %xx.
    *
    * @param aStr the string to encode
@@ -261,21 +262,23 @@ HandleMailtoSubject(nsCString& aPath)
       return;
 
     aPath.Append(subjectStrEscaped);
   }
 }
 
 nsresult
 FSURLEncoded::GetEncodedSubmission(nsIURI* aURI,
-                                   nsIInputStream** aPostDataStream)
+                                   nsIInputStream** aPostDataStream,
+                                   int64_t* aPostDataStreamLength)
 {
   nsresult rv = NS_OK;
 
   *aPostDataStream = nullptr;
+  *aPostDataStreamLength = -1;
 
   if (mMethod == NS_FORM_METHOD_POST) {
 
     bool isMailto = false;
     aURI->SchemeIs("mailto", &isMailto);
     if (isMailto) {
 
       nsAutoCString path;
@@ -308,16 +311,18 @@ FSURLEncoded::GetEncodedSubmission(nsIUR
       NS_ENSURE_SUCCESS(rv, rv);
 
       mimeStream->AddHeader("Content-Type",
                             "application/x-www-form-urlencoded");
       mimeStream->SetData(dataStream);
 
       *aPostDataStream = mimeStream;
       NS_ADDREF(*aPostDataStream);
+
+      *aPostDataStreamLength = mQueryString.Length();
     }
 
   } else {
     // Get the full query string
     bool schemeIsJavaScript;
     rv = aURI->SchemeIs("javascript", &schemeIsJavaScript);
     NS_ENSURE_SUCCESS(rv, rv);
     if (schemeIsJavaScript) {
@@ -610,30 +615,33 @@ FSMultipartFormData::AddDataChunk(const 
   }
 
   // CRLF after file
   mPostDataChunk.AppendLiteral(CRLF);
 }
 
 nsresult
 FSMultipartFormData::GetEncodedSubmission(nsIURI* aURI,
-                                          nsIInputStream** aPostDataStream)
+                                          nsIInputStream** aPostDataStream,
+                                          int64_t* aPostDataStreamLength)
 {
   nsresult rv;
 
   // Make header
   nsCOMPtr<nsIMIMEInputStream> mimeStream
     = do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString contentType;
   GetContentType(contentType);
   mimeStream->AddHeader("Content-Type", contentType.get());
-  uint64_t unused;
-  mimeStream->SetData(GetSubmissionBody(&unused));
+
+  uint64_t bodySize;
+  mimeStream->SetData(GetSubmissionBody(&bodySize));
+  *aPostDataStreamLength = bodySize;
 
   mimeStream.forget(aPostDataStream);
 
   return NS_OK;
 }
 
 nsresult
 FSMultipartFormData::AddPostDataStream()
@@ -672,17 +680,18 @@ public:
 
   virtual nsresult
   AddNameBlobOrNullPair(const nsAString& aName, Blob* aBlob) override;
 
   virtual nsresult
   AddNameDirectoryPair(const nsAString& aName, Directory* aDirectory) override;
 
   virtual nsresult
-  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream) override;
+  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream,
+                       int64_t* aPostDataStreaLength) override;
 
 private:
   nsString mBody;
 };
 
 nsresult
 FSTextPlain::AddNameValuePair(const nsAString& aName, const nsAString& aValue)
 {
@@ -711,20 +720,24 @@ FSTextPlain::AddNameDirectoryPair(const 
   nsAutoString dirname;
   RetrieveDirectoryName(aDirectory, dirname);
   AddNameValuePair(aName, dirname);
   return NS_OK;
 }
 
 nsresult
 FSTextPlain::GetEncodedSubmission(nsIURI* aURI,
-                                  nsIInputStream** aPostDataStream)
+                                  nsIInputStream** aPostDataStream,
+                                  int64_t* aPostDataStreamLength)
 {
   nsresult rv = NS_OK;
 
+  *aPostDataStream = nullptr;
+  *aPostDataStreamLength = -1;
+
   // XXX HACK We are using the standard URL mechanism to give the body to the
   // mailer instead of passing the post data stream to it, since that sounds
   // hard.
   bool isMailto = false;
   aURI->SchemeIs("mailto", &isMailto);
   if (isMailto) {
     nsAutoCString path;
     rv = aURI->GetPathQueryRef(path);
@@ -765,16 +778,18 @@ FSTextPlain::GetEncodedSubmission(nsIURI
     // Create mime stream with headers and such
     nsCOMPtr<nsIMIMEInputStream> mimeStream
         = do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     mimeStream->AddHeader("Content-Type", "text/plain");
     mimeStream->SetData(bodyStream);
     CallQueryInterface(mimeStream, aPostDataStream);
+
+    *aPostDataStreamLength = cbody.Length();
   }
 
   return rv;
 }
 
 } // anonymous namespace
 
 // --------------------------------------------------------------------------
--- a/dom/html/HTMLFormSubmission.h
+++ b/dom/html/HTMLFormSubmission.h
@@ -79,19 +79,21 @@ public:
                                         Directory* aDirectory) = 0;
 
   /**
    * Given a URI and the current submission, create the final URI and data
    * stream that will be submitted.  Subclasses *must* implement this.
    *
    * @param aURI the URI being submitted to [INOUT]
    * @param aPostDataStream a data stream for POST data [OUT]
+   * @param aPostDataStreamLength a data stream for POST data length [OUT]
    */
   virtual nsresult
-  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream) = 0;
+  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream,
+                       int64_t* aPostDataStreamLength) = 0;
 
   /**
    * Get the charset that will be used for submission.
    */
   void GetCharset(nsACString& aCharset) { mEncoding->Name(aCharset); }
 
   nsIContent* GetOriginatingElement() const
   {
@@ -160,17 +162,18 @@ public:
 
   virtual nsresult
   AddNameBlobOrNullPair(const nsAString& aName, Blob* aBlob) override;
 
   virtual nsresult
   AddNameDirectoryPair(const nsAString& aName, Directory* aDirectory) override;
 
   virtual nsresult
-  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream) override;
+  GetEncodedSubmission(nsIURI* aURI, nsIInputStream** aPostDataStream,
+                       int64_t* aPostDataStreamLength) override;
 
   void GetContentType(nsACString& aContentType)
   {
     aContentType =
       NS_LITERAL_CSTRING("multipart/form-data; boundary=") + mBoundary;
   }
 
   nsIInputStream* GetSubmissionBody(uint64_t* aContentLength);