Bug 1437360 - do not attempt to parse XHRs as XML if content-length=0, to prevent logging "no root element found" errors; r=smaug
authorThomas Wisniewski <twisniewski@mozilla.com>
Wed, 20 Mar 2019 15:43:31 +0000
changeset 465230 6b9aee567032057ad7d598798362287297f85351
parent 465229 1ac6a585937779eb00a89289822286600c3e8d51
child 465231 c12cc38850b701b4fd37a111a8e053293aa21ceb
push id112496
push usershindli@mozilla.com
push dateThu, 21 Mar 2019 04:37:39 +0000
treeherdermozilla-inbound@29476d3ca61d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1437360
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 1437360 - do not attempt to parse XHRs as XML if content-length=0, to prevent logging "no root element found" errors; r=smaug do not attempt to parse XHRs as XML if content-length=0, to prevent logging "no root element found" errors Differential Revision: https://phabricator.services.mozilla.com/D23444
dom/base/test/chrome/bug884693.sjs
dom/base/test/chrome/test_bug884693.xul
dom/xhr/XMLHttpRequestMainThread.cpp
--- a/dom/base/test/chrome/bug884693.sjs
+++ b/dom/base/test/chrome/bug884693.sjs
@@ -1,8 +1,9 @@
 function handleRequest(request, response)
 {
-  let [status, statusText, body] = request.queryString.split("&");
+  let [status, statusText, encodedBody] = request.queryString.split("&");
+  let body = decodeURIComponent(encodedBody);
   response.setStatusLine(request.httpVersion, status, statusText);
   response.setHeader("Content-Type", "text/xml", false);
   response.setHeader("Content-Length", "" + body.length, false);
   response.write(body);
 }
--- a/dom/base/test/chrome/test_bug884693.xul
+++ b/dom/base/test/chrome/test_bug884693.xul
@@ -14,16 +14,17 @@ https://bugzilla.mozilla.org/show_bug.cg
      target="_blank">Mozilla Bug 884693</a>
   </body>
 
   <!-- test code goes here -->
   <script type="application/javascript"><![CDATA[
 
     const SERVER_URL = "http://mochi.test:8888/tests/dom/base/test/chrome/bug884693.sjs";
     const INVALID_XML = "InvalidXML";
+    const XML_WITHOUT_ROOT = "<?xml version='1.0'?>";
 
     let consoleService = Cc["@mozilla.org/consoleservice;1"].
                          getService(Ci.nsIConsoleService)
 
     function runTest(status, statusText, body, expectedResponse, expectedMessages)
     {
       return new Promise((resolve, reject) => {
         consoleService.reset();
@@ -58,14 +59,15 @@ https://bugzilla.mozilla.org/show_bug.cg
       then(() => { return runTest(202, "Accepted", "", "", []); }).
       then(() => { return runTest(202, "Accepted", INVALID_XML, INVALID_XML, []); }).
       then(() => { return runTest(204, "No Content", "", "", []); }).
       then(() => { return runTest(204, "No Content", INVALID_XML, "", []); }).
       then(() => { return runTest(205, "Reset Content", "", "", []); }).
       then(() => { return runTest(205, "Reset Content", INVALID_XML, "", []); }).
       then(() => { return runTest(304, "Not modified", "", "", []); }).
       then(() => { return runTest(304, "Not modified", INVALID_XML, "", []); }).
-      then(() => { return runTest(200, "OK", "", "", ["no root element found"]); }).
+      then(() => { return runTest(200, "OK", "", "", []); }).
+      then(() => { return runTest(200, "OK", XML_WITHOUT_ROOT, XML_WITHOUT_ROOT, ["no root element found"]); }).
       then(() => { return runTest(200, "OK", INVALID_XML, INVALID_XML, ["syntax error"]); }).
       then(SimpleTest.finish);
 
   ]]></script>
 </window>
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -1883,16 +1883,25 @@ XMLHttpRequestMainThread::OnStartRequest
 
   // Set up responseXML
   // Note: Main Fetch step 18 requires to ignore body for head/connect methods.
   bool parseBody = (mResponseType == XMLHttpRequestResponseType::_empty ||
                     mResponseType == XMLHttpRequestResponseType::Document) &&
                    !(mRequestMethod.EqualsLiteral("HEAD") ||
                      mRequestMethod.EqualsLiteral("CONNECT"));
 
+  if (parseBody) {
+    // Do not try to parse documents if content-length = 0
+    int64_t contentLength;
+    if (NS_SUCCEEDED(mChannel->GetContentLength(&contentLength)) &&
+        contentLength == 0) {
+      parseBody = false;
+    }
+  }
+
   mIsHtml = false;
   mWarnAboutSyncHtml = false;
   if (parseBody && NS_SUCCEEDED(status)) {
     // We can gain a huge performance win by not even trying to
     // parse non-XML data. This also protects us from the situation
     // where we have an XML document and sink, but HTML (or other)
     // parser, which can produce unreliable results.
     nsAutoCString type;