Bug 1399760. P2 - ensure mCacheStream.NotifyDataStarted() is always called in OnStartRequest(). draft
authorJW Wang <jwwang@mozilla.com>
Thu, 14 Sep 2017 14:56:01 +0800
changeset 666824 ee1b60d2f0f859fd4de578b2aa699cb016a8322e
parent 666823 6e81842faab0def555dfbc130aa92bfdedef9d1a
child 666825 a93bebe4c84d646e19eeca05200db1dffab62018
child 667437 229c489ad8324a63731f43aac4ae75ae8011531f
push id80502
push userjwwang@mozilla.com
push dateTue, 19 Sep 2017 07:13:04 +0000
bugs1399760
milestone57.0a1
Bug 1399760. P2 - ensure mCacheStream.NotifyDataStarted() is always called in OnStartRequest(). This keeps us in a good shape that NotifyDataStarted() is always called before subsequent NotifyDataReceived() calls. This is also required by P3 where we need to set the loadID before NotifyDataReceived(). MozReview-Commit-ID: 9TPodkMM4EH
dom/media/MediaResource.cpp
--- a/dom/media/MediaResource.cpp
+++ b/dom/media/MediaResource.cpp
@@ -219,16 +219,18 @@ ChannelMediaResource::OnStartRequest(nsI
     if (status == NS_ERROR_DOM_BAD_URI) {
       mCallback->NotifyNetworkError();
       return NS_ERROR_DOM_BAD_URI;
     }
   }
 
   nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(aRequest);
   bool seekable = false;
+  int64_t startOffset = aRequestOffset;
+
   if (hc) {
     uint32_t responseStatus = 0;
     Unused << hc->GetResponseStatus(&responseStatus);
     bool succeeded = false;
     Unused << hc->GetRequestSucceeded(&succeeded);
 
     if (!succeeded && NS_SUCCEEDED(status)) {
       // HTTP-level error (e.g. 4xx); treat this as a fatal network-level error.
@@ -274,48 +276,54 @@ ChannelMediaResource::OnStartRequest(nsI
       int64_t rangeEnd = 0;
       int64_t rangeTotal = 0;
       rv = ParseContentRangeHeader(hc, rangeStart, rangeEnd, rangeTotal);
 
       // We received 'Content-Range', so the server accepts range requests.
       bool gotRangeHeader = NS_SUCCEEDED(rv);
 
       if (gotRangeHeader) {
+        startOffset = rangeStart;
         // We received 'Content-Range', so the server accepts range requests.
         // 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) {
           contentLength = std::max(contentLength, rangeTotal);
         }
-        mCacheStream.NotifyDataStarted(rangeStart);
       }
       acceptsRanges = gotRangeHeader;
-    } else if (aRequestOffset > 0 && 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);
+    } else if (responseStatus == HTTP_OK_CODE) {
+      // HTTP_OK_CODE means data will be sent from the start of the stream.
+      startOffset = 0;
 
-      // The server claimed it supported range requests.  It lied.
-      acceptsRanges = false;
+      if (aRequestOffset > 0) {
+        // If HTTP_OK_CODE is responded for a non-zero range request, we have
+        // to assume seeking doesn't work.
+        acceptsRanges = false;
+      }
     }
     if (aRequestOffset == 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. We also can't seek in compressed streams.
     seekable = !isCompressed && acceptsRanges;
+  } else {
+    // Not an HTTP channel. Assume data will be sent from position zero.
+    startOffset = 0;
   }
+
+  mCacheStream.NotifyDataStarted(startOffset);
   mCacheStream.SetTransportSeekable(seekable);
   mChannelStatistics.Start();
   mReopenOnError = false;
 
   mSuspendAgent.UpdateSuspendedStatusIfNeeded();
 
   // Fires an initial progress event.
   owner->DownloadProgressed();