Backed out changeset fbb7cc8d04b9 (bug 1333899)
authorSebastian Hengst <archaeopteryx@coole-files.de>
Wed, 22 Feb 2017 09:59:53 +0100
changeset 373250 d931cdfe0da3e6134e3398246c9b95a46eda61ae
parent 373249 8a1a04cf1bc7c25a72694640fa772913e10459a4
child 373251 65061c29c70cfacf1abd77d2429688941881b07d
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1333899
milestone54.0a1
backs outfbb7cc8d04b9b4baff398ef14836414862a0ed5c
Backed out changeset fbb7cc8d04b9 (bug 1333899)
netwerk/protocol/data/nsDataChannel.cpp
--- a/netwerk/protocol/data/nsDataChannel.cpp
+++ b/netwerk/protocol/data/nsDataChannel.cpp
@@ -3,106 +3,86 @@
  * 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/. */
 
 // data implementation
 
 #include "nsDataChannel.h"
 
 #include "mozilla/Base64.h"
+#include "nsIOService.h"
 #include "nsDataHandler.h"
+#include "nsIPipe.h"
 #include "nsIInputStream.h"
+#include "nsIOutputStream.h"
 #include "nsEscape.h"
-#include "nsStringStream.h"
 
 using namespace mozilla;
 
-/**
- * Helper for performing a fallible unescape.
- *
- * @param aStr The string to unescape.
- * @param aBuffer Buffer to unescape into if necessary.
- * @param rv Out: nsresult indicating success or failure of unescaping.
- * @return Reference to the string containing the unescaped data.
- */
-const nsACString& Unescape(const nsACString& aStr, nsACString& aBuffer,
-                           nsresult* rv)
-{
-    MOZ_ASSERT(rv);
-
-    bool appended = false;
-    *rv = NS_UnescapeURL(aStr.Data(), aStr.Length(), /* flags = */ 0,
-                         aBuffer, appended, mozilla::fallible);
-    if (NS_FAILED(*rv) || !appended) {
-        return aStr;
-    }
-
-    return aBuffer;
-}
-
 nsresult
 nsDataChannel::OpenContentStream(bool async, nsIInputStream **result,
                                  nsIChannel** channel)
 {
     NS_ENSURE_TRUE(URI(), NS_ERROR_NOT_INITIALIZED);
 
     nsresult rv;
 
-    // In order to avoid potentially building up a new path including the
-    // ref portion of the URI, which we don't care about, we clone a version
-    // of the URI that does not have a ref and in most cases should share
-    // string buffers with the original URI.
-    nsCOMPtr<nsIURI> uri;
-    rv = URI()->CloneIgnoringRef(getter_AddRefs(uri));
-    if (NS_FAILED(rv))
-        return rv;
+    nsAutoCString spec;
+    rv = URI()->GetAsciiSpec(spec);
+    if (NS_FAILED(rv)) return rv;
 
-    nsAutoCString path;
-    rv = uri->GetPath(path);
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsCString contentType, contentCharset;
-    nsDependentCSubstring dataRange;
+    nsCString contentType, contentCharset, dataBuffer;
     bool lBase64;
-    rv = nsDataHandler::ParsePathWithoutRef(path, contentType, &contentCharset,
-                                            lBase64, &dataRange);
+    rv = nsDataHandler::ParseURI(spec, contentType, &contentCharset,
+                                 lBase64, &dataBuffer);
     if (NS_FAILED(rv))
         return rv;
 
-    // This will avoid a copy if nothing needs to be unescaped.
-    nsAutoCString unescapedBuffer;
-    const nsACString& data = Unescape(dataRange, unescapedBuffer, &rv);
-    if (NS_FAILED(rv)) {
-        return rv;
-    }
+    NS_UnescapeURL(dataBuffer);
 
-    if (lBase64 && &data == &unescapedBuffer) {
+    if (lBase64) {
         // Don't allow spaces in base64-encoded content. This is only
         // relevant for escaped spaces; other spaces are stripped in
-        // NewURI. We know there were no escaped spaces if the data buffer
-        // wasn't used in |Unescape|.
-        unescapedBuffer.StripWhitespace();
+        // NewURI.
+        dataBuffer.StripWhitespace();
     }
-
+    
     nsCOMPtr<nsIInputStream> bufInStream;
+    nsCOMPtr<nsIOutputStream> bufOutStream;
+    
+    // create an unbounded pipe.
+    rv = NS_NewPipe(getter_AddRefs(bufInStream),
+                    getter_AddRefs(bufOutStream),
+                    nsIOService::gDefaultSegmentSize,
+                    UINT32_MAX,
+                    async, true);
+    if (NS_FAILED(rv))
+        return rv;
 
     uint32_t contentLen;
     if (lBase64) {
-        nsAutoCString decodedData;
-        rv = Base64Decode(data, decodedData);
-        NS_ENSURE_SUCCESS(rv, rv);
+        const uint32_t dataLen = dataBuffer.Length();
+        int32_t resultLen = 0;
+        if (dataLen >= 1 && dataBuffer[dataLen-1] == '=') {
+            if (dataLen >= 2 && dataBuffer[dataLen-2] == '=')
+                resultLen = dataLen-2;
+            else
+                resultLen = dataLen-1;
+        } else {
+            resultLen = dataLen;
+        }
+        resultLen = ((resultLen * 3) / 4);
 
-        contentLen = decodedData.Length();
-        rv = NS_NewCStringInputStream(getter_AddRefs(bufInStream), decodedData);
+        nsAutoCString decodedData;
+        rv = Base64Decode(dataBuffer, decodedData);
+        NS_ENSURE_SUCCESS(rv, rv);
+        rv = bufOutStream->Write(decodedData.get(), resultLen, &contentLen);
     } else {
-        contentLen = data.Length();
-        rv = NS_NewCStringInputStream(getter_AddRefs(bufInStream), data);
+        rv = bufOutStream->Write(dataBuffer.get(), dataBuffer.Length(), &contentLen);
     }
-
     if (NS_FAILED(rv))
         return rv;
 
     SetContentType(contentType);
     SetContentCharset(contentCharset);
     mContentLength = contentLen;
 
     bufInStream.forget(result);