Bug 1305162: Part 2 - Remove support for upload streams with embedded headers. r=mixedpuppy,dragana draft
authorKris Maglione <maglione.k@gmail.com>
Fri, 09 Dec 2016 14:02:05 -1000
changeset 458716 e3115f38e1079569055b3b056d25de22759cad39
parent 458715 c639b044f833122f70a6492dba95a2e95652a231
child 458717 a3ea454571c3d6185a32760006fe786233e05dd4
push id41026
push usermaglione.k@gmail.com
push dateTue, 10 Jan 2017 22:29:18 +0000
reviewersmixedpuppy, dragana
bugs1305162
milestone53.0a1
Bug 1305162: Part 2 - Remove support for upload streams with embedded headers. r=mixedpuppy,dragana MozReview-Commit-ID: CuqOmas4WDM
toolkit/modules/addons/WebRequestUpload.jsm
--- a/toolkit/modules/addons/WebRequestUpload.jsm
+++ b/toolkit/modules/addons/WebRequestUpload.jsm
@@ -363,43 +363,21 @@ function parseFormData(stream, channel, 
       let [name, value] = part.replace(/\+/g, " ").split("=").map(decodeURIComponent);
       formData.get(name).push(value);
     }
 
     return formData;
   }
 
   try {
-    let headers;
     if (stream instanceof Ci.nsIMIMEInputStream && stream.data) {
-      if (channel instanceof Ci.nsIUploadChannel2 && channel.uploadStreamHasHeaders) {
-        // MIME input streams encode additional headers as a block at the
-        // beginning of their stream. The actual request data comes from a
-        // sub-stream, which is accessible via their `data` member. The
-        // difference in available bytes between the outer stream and the
-        // inner data stream tells us the size of that header block.
-        //
-        // Since we need to know at least the value of the Content-Type
-        // header to properly parse the request body, we need to read and
-        // parse the header block in order to extract it.
-
-        headers = readString(createTextStream(stream),
-                             stream.available() - stream.data.available());
-      }
-
-      rewind(stream);
       stream = stream.data;
     }
 
-    let contentType;
-    try {
-      contentType = channel.getRequestHeader("Content-Type");
-    } catch (e) {
-      contentType = new Headers(headers).get("content-type");
-    }
+    let contentType = channel.getRequestHeader("Content-Type");
 
     switch (Headers.getParam(contentType, "")) {
       case "multipart/form-data":
         let boundary = Headers.getParam(contentType, "boundary");
         return parseMultiPart(stream, `\r\n--${boundary}`);
 
       case "application/x-www-form-urlencoded":
         return parseUrlEncoded(stream);
@@ -499,36 +477,40 @@ function* getRawDataChunked(outerStream,
     } finally {
       rewind(stream);
     }
   }
 }
 
 WebRequestUpload = {
   createRequestBody(channel) {
-    if (channel instanceof Ci.nsIUploadChannel && channel.uploadStream) {
-      try {
-        let stream = channel.uploadStream;
-
-        let formData = createFormData(stream, channel);
-        if (formData) {
-          return {formData};
-        }
+    if (!(channel instanceof Ci.nsIUploadChannel) || !channel.uploadStream) {
+      return null;
+    }
 
-        // If we failed to parse the stream as form data, return it as a
-        // sequence of raw data chunks, along with a leniently-parsed form
-        // data object, which ignores encoding errors.
-        return {
-          raw: Array.from(getRawDataChunked(stream)),
-          lenientFormData: createFormData(stream, channel, true),
-        };
-      } catch (e) {
-        Cu.reportError(e);
-        return {error: e.message || String(e)};
-      }
+    if (channel instanceof Ci.nsIUploadChannel2 && channel.uploadStreamHasHeaders) {
+      return {error: "Upload streams with headers are unsupported"};
     }
 
-    return null;
+    try {
+      let stream = channel.uploadStream;
+
+      let formData = createFormData(stream, channel);
+      if (formData) {
+        return {formData};
+      }
+
+      // If we failed to parse the stream as form data, return it as a
+      // sequence of raw data chunks, along with a leniently-parsed form
+      // data object, which ignores encoding errors.
+      return {
+        raw: Array.from(getRawDataChunked(stream)),
+        lenientFormData: createFormData(stream, channel, true),
+      };
+    } catch (e) {
+      Cu.reportError(e);
+      return {error: e.message || String(e)};
+    }
   },
 };
 
 XPCOMUtils.defineLazyPreferenceGetter(WebRequestUpload, "MAX_RAW_BYTES",
                                       "webextensions.webRequest.requestBodyMaxRawBytes");