Bug 1399760. P2 - ensure mCacheStream.NotifyDataStarted() is always called in OnStartRequest(). draft
authorJW Wang <jwwang@mozilla.com>
Wed, 20 Sep 2017 11:30:03 +0800
changeset 667463 d58361930c66a573c8cb75cd284f4d180cce9d2e
parent 667462 71c9a373a316ceba0093935437919b0898634cb2
child 667464 9c4e9145e3a8424ec624177cf6a66c00bf06357c
push id80715
push userjwwang@mozilla.com
push dateWed, 20 Sep 2017 04:01:13 +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/ChannelMediaResource.cpp
--- a/dom/media/ChannelMediaResource.cpp
+++ b/dom/media/ChannelMediaResource.cpp
@@ -165,16 +165,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.
@@ -220,48 +222,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();