Bug 1454325 - update XHR upload content-type handling to match the spec. r=baku
authorThomas Wisniewski <twisniewski@mozilla.com>
Tue, 19 Mar 2019 19:34:39 +0000
changeset 465090 d12bb5576d0f1ce9e24ff42dd567c337431504a3
parent 465089 195cd323a4830c9a17e35821d9e3c86ce62e07c9
child 465091 cd0c67b9aeddba87b444752885396697da387620
push id35732
push useropoprus@mozilla.com
push dateWed, 20 Mar 2019 10:52:37 +0000
treeherdermozilla-central@708979f9c3f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1454325
milestone68.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 1454325 - update XHR upload content-type handling to match the spec. r=baku update XHR upload content-type handling to match the spec Differential Revision: https://phabricator.services.mozilla.com/D23251
dom/xhr/XMLHttpRequestMainThread.cpp
dom/xhr/tests/test_XHRSendData.html
modules/libpref/init/StaticPrefList.h
testing/web-platform/meta/xhr/send-content-type-charset.htm.ini
toolkit/modules/tests/xpcshell/test_Http.js
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -2771,26 +2771,29 @@ nsresult XMLHttpRequestMainThread::SendI
 
     if (uploadStream) {
       // If author set no Content-Type, use the default from GetAsStream().
       mAuthorRequestHeaders.Get("content-type", uploadContentType);
       if (uploadContentType.IsVoid()) {
         uploadContentType = defaultContentType;
       } else if (aBodyIsDocumentOrString &&
                  StaticPrefs::dom_xhr_standard_content_type_normalization()) {
-        UniquePtr<CMimeType> parsed = CMimeType::Parse(uploadContentType);
-        if (parsed && parsed->HasParameter(kLiteralString_charset)) {
-          parsed->SetParameterValue(kLiteralString_charset,
-                                    kLiteralString_UTF_8);
-          parsed->Serialize(uploadContentType);
+        UniquePtr<CMimeType> contentTypeRecord =
+            CMimeType::Parse(uploadContentType);
+        nsAutoCString charset;
+        if (contentTypeRecord &&
+            contentTypeRecord->GetParameterValue(kLiteralString_charset,
+                                                 charset) &&
+            !charset.EqualsIgnoreCase("utf-8")) {
+          contentTypeRecord->SetParameterValue(kLiteralString_charset,
+                                               kLiteralString_UTF_8);
+          contentTypeRecord->Serialize(uploadContentType);
         }
-      }
-
-      // We don't want to set a charset for streams.
-      if (!charset.IsEmpty()) {
+      } else if (!charset.IsEmpty()) {
+        // We don't want to set a charset for streams.
         // Replace all case-insensitive matches of the charset in the
         // content-type with the correct case.
         RequestHeaders::CharsetIterator iter(uploadContentType);
         const nsCaseInsensitiveCStringComparator cmp;
         while (iter.Next()) {
           if (!iter.Equals(charset, cmp)) {
             iter.Replace(charset);
           }
--- a/dom/xhr/tests/test_XHRSendData.html
+++ b/dom/xhr/tests/test_XHRSendData.html
@@ -119,17 +119,17 @@ tests = [{ body: null,
          { body: "hi",
            contentType: "foo/bar; charset=ascii; baz=bin",
            resBody: "hi",
            resContentType: "foo/bar;charset=UTF-8;baz=bin",
          },
          { body: "hi",
            contentType: "foo/bar; charset=uTf-8",
            resBody: "hi",
-           resContentType: "foo/bar;charset=UTF-8",
+           resContentType: "foo/bar; charset=uTf-8",
          },
          { body: testDoc1,
            resBody: "<!-- comment -->\n<out>hi</out>",
            resContentType: "application/xml;charset=UTF-8",
          },
          { body: testDoc1,
            contentType: "foo/bar",
            resBody: "<!-- comment -->\n<out>hi</out>",
@@ -157,17 +157,17 @@ tests = [{ body: null,
          { body: testDoc2,
            contentType: "foo/bar; charset=ascii; baz=bin",
            resBody: "<!-- doc 2 -->\n<res>text</res>",
            resContentType: "foo/bar;charset=UTF-8;baz=bin",
          },
          { body: testDoc2,
            contentType: "foo/bar; charset=uTf-8",
            resBody: "<!-- doc 2 -->\n<res>text</res>",
-           resContentType: "foo/bar;charset=UTF-8",
+           resContentType: "foo/bar; charset=uTf-8",
          },
          { //will trigger a redirect test server-side
            body: ("TEST_REDIRECT_STR&url=" + window.location.host + window.location.pathname),
            redirect: true,
          },
          { body: shortArray,
            resBody: shortArray,
            resType: "arraybuffer"
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -478,21 +478,20 @@ VARCACHE_PREF(
 
 VARCACHE_PREF(
   "dom.worker.use_medium_high_event_queue",
    dom_worker_use_medium_high_event_queue,
   RelaxedAtomicBool, true
 )
 
 // Enable content type normalization of XHR uploads via MIME Sniffing standard
-// Disabled for now in bz1499136
 VARCACHE_PREF(
   "dom.xhr.standard_content_type_normalization",
    dom_xhr_standard_content_type_normalization,
-  RelaxedAtomicBool, false
+  RelaxedAtomicBool, true
 )
 
 // Block multiple external protocol URLs in iframes per single event.
 VARCACHE_PREF(
   "dom.block_external_protocol_in_iframes",
    dom_block_external_protocol_in_iframes,
   bool, true
 )
deleted file mode 100644
--- a/testing/web-platform/meta/xhr/send-content-type-charset.htm.ini
+++ /dev/null
@@ -1,19 +0,0 @@
-[send-content-type-charset.htm]
-  [charset with space that is UTF-8 does not change]
-    expected: FAIL
-
-  [charset in double quotes with backslashes that is UTF-8 does not change]
-    expected: FAIL
-
-  [If charset= param is UTF-8 (case-insensitive), it should not be changed (bogus charset)]
-    expected: FAIL
-
-  [If charset= param is UTF-8 (case-insensitive), it should not be changed]
-    expected: FAIL
-
-  [charset in double quotes that is UTF-8 does not change]
-    expected: FAIL
-
-  [charset with trailing space that is UTF-8 does not change]
-    expected: FAIL
-
--- a/toolkit/modules/tests/xpcshell/test_Http.js
+++ b/toolkit/modules/tests/xpcshell/test_Http.js
@@ -13,17 +13,17 @@ const kDefaultServerPort = 9000;
 const kSuccessPath = "/success";
 const kBaseUrl = "http://localhost:" + kDefaultServerPort;
 const kSuccessUrl = kBaseUrl + kSuccessPath;
 
 const kPostPath = "/post";
 const kPostUrl = kBaseUrl + kPostPath;
 const kPostDataSent = [["foo", "bar"], ["complex", "!*()@"]];
 const kPostDataReceived = "foo=bar&complex=%21%2A%28%29%40";
-const kPostMimeTypeReceived = "application/x-www-form-urlencoded;charset=UTF-8";
+const kPostMimeTypeReceived = "application/x-www-form-urlencoded; charset=utf-8";
 
 const kJsonPostPath = "/json_post";
 const kJsonPostUrl = kBaseUrl + kJsonPostPath;
 const kJsonPostData = JSON.stringify(kPostDataSent);
 const kJsonPostMimeType = "application/json";
 
 const kPutPath = "/put";
 const kPutUrl = kBaseUrl + kPutPath;