Bug 1249904: Use content-range values to determine length if content-length is unknown. r?roc draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 24 Feb 2016 21:16:20 +1100
changeset 334243 ee5ca015aea607ef73c7d7740990905aa0fbf674
parent 334242 af1a61d6afdec0fb55ee38128bd9651e185e00ea
child 514866 c4b2f4ac9bf8cf42c16a3d8673de729979904eca
push id11496
push userbmo:jyavenard@mozilla.com
push dateWed, 24 Feb 2016 21:28:58 +0000
reviewersroc
bugs1249904
milestone47.0a1
Bug 1249904: Use content-range values to determine length if content-length is unknown. r?roc While currently unused, the functionality of mByteRange was preserved. To avoid unforeseen regressions, we only error on an invalid Content-Range response if mByteRange was set, otherwise the error is ignored and code proceed as before. MozReview-Commit-ID: BRiO633uTh7
dom/media/MediaResource.cpp
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -231,69 +231,74 @@ ChannelMediaResource::OnStartRequest(nsI
       // Since that's bounded, we know we have a finite-length resource.
       dataIsBounded = true;
     }
 
     // Assume Range requests have a bounded upper limit unless the
     // Content-Range header tells us otherwise.
     bool boundedSeekLimit = true;
     // Check response code for byte-range requests (seeking, chunk requests).
-    if (!mByteRange.IsEmpty() && (responseStatus == HTTP_PARTIAL_RESPONSE_CODE)) {
+    if (responseStatus == HTTP_PARTIAL_RESPONSE_CODE) {
       // Parse Content-Range header.
       int64_t rangeStart = 0;
       int64_t rangeEnd = 0;
       int64_t rangeTotal = 0;
       rv = ParseContentRangeHeader(hc, rangeStart, rangeEnd, rangeTotal);
-      if (NS_FAILED(rv)) {
-        // Content-Range header text should be parse-able.
-        CMLOG("Error processing \'Content-Range' for "
-              "HTTP_PARTIAL_RESPONSE_CODE: rv[%x] channel[%p] decoder[%p]",
-              rv, hc.get(), mCallback.get());
-        mCallback->NotifyNetworkError();
-        CloseChannel();
-        return NS_OK;
-      }
+
+      // We received 'Content-Range', so the server accepts range requests.
+      acceptsRanges = NS_SUCCEEDED(rv);
 
-      // Give some warnings if the ranges are unexpected.
-      // XXX These could be error conditions.
-      NS_WARN_IF_FALSE(mByteRange.mStart == rangeStart,
-                       "response range start does not match request");
-      NS_WARN_IF_FALSE(mOffset == rangeStart,
-                       "response range start does not match current offset");
-      NS_WARN_IF_FALSE(mByteRange.mEnd == rangeEnd,
-                       "response range end does not match request");
-      // Notify media cache about the length and start offset of data received.
-      // Note: If aRangeTotal == -1, then the total bytes is unknown at this stage.
-      //       For now, tell the decoder that the stream is infinite.
-      if (rangeTotal == -1) {
-        boundedSeekLimit = false;
-      } else {
-        mCacheStream.NotifyDataLength(rangeTotal);
+      if (!mByteRange.IsEmpty()) {
+        if (!acceptsRanges) {
+          // Content-Range header text should be parse-able when processing a
+          // range requests.
+          CMLOG("Error processing \'Content-Range' for "
+                "HTTP_PARTIAL_RESPONSE_CODE: rv[%x] channel[%p] decoder[%p]",
+                rv, hc.get(), mCallback.get());
+          mCallback->NotifyNetworkError();
+          CloseChannel();
+          return NS_OK;
+        }
+        // Give some warnings if the ranges are unexpected.
+        // XXX These could be error conditions.
+        NS_WARN_IF_FALSE(mByteRange.mStart == rangeStart,
+                         "response range start does not match request");
+        NS_WARN_IF_FALSE(mOffset == rangeStart,
+                         "response range start does not match current offset");
+        NS_WARN_IF_FALSE(mByteRange.mEnd == rangeEnd,
+                         "response range end does not match request");
+        // Notify media cache about the length and start offset of data received.
+        // Note: If aRangeTotal == -1, then the total bytes is unknown at this stage.
+        //       For now, tell the decoder that the stream is infinite.
+        if (rangeTotal == -1) {
+          boundedSeekLimit = false;
+        } else {
+          mCacheStream.NotifyDataLength(rangeTotal);
+        }
+        mCacheStream.NotifyDataStarted(rangeStart);
+        mOffset = rangeStart;
+      } else if (contentLength < 0 && acceptsRanges && rangeTotal > 0) {
+        // Content-Length was unknown, use content-range instead.
+        contentLength = rangeTotal;
       }
-      mCacheStream.NotifyDataStarted(rangeStart);
-
-      mOffset = rangeStart;
-      // We received 'Content-Range', so the server accepts range requests.
-      acceptsRanges = true;
     } else if (((mOffset > 0) || !mByteRange.IsEmpty())
                && (responseStatus == HTTP_OK_CODE)) {
       // If we get an OK response but we were seeking, or requesting a byte
       // range, then we have to assume that seeking doesn't work. We also need
       // to tell the cache that it's getting data for the start of the stream.
       mCacheStream.NotifyDataStarted(0);
       mOffset = 0;
 
       // The server claimed it supported range requests.  It lied.
       acceptsRanges = false;
-    } else if (mOffset == 0 &&
-               (responseStatus == HTTP_OK_CODE ||
-                responseStatus == HTTP_PARTIAL_RESPONSE_CODE)) {
-      if (contentLength >= 0) {
-        mCacheStream.NotifyDataLength(contentLength);
-      }
+    }
+    if (mOffset == 0 && contentLength >= 0 &&
+        (responseStatus == HTTP_OK_CODE ||
+         responseStatus == HTTP_PARTIAL_RESPONSE_CODE)) {
+      mCacheStream.NotifyDataLength(contentLength);
     }
     // XXX we probably should examine the Content-Range header in case
     // the server gave us a range which is not quite what we asked for
 
     // If we get an HTTP_OK_CODE response to our byte range request,
     // and the server isn't sending Accept-Ranges:bytes then we don't
     // support seeking.
     seekable =