From 47696f6d0b107cdb363ef541931927828daca998 Mon Sep 17 00:00:00 2001 From: Robert O'Callahan Date: Wed, 30 Sep 2009 07:32:30 +1000 Subject: [PATCH] Bug 517818. Treat HTTP errors (other than 416 'Requested Range Not Available') as network errors. And do not allow an error page to be treated as media data. r=kinetik --HG-- extra : rebase_source : 47f44d18ff0d2c33f2642ae5bedb132cc43eb3cb --- content/media/nsMediaStream.cpp | 40 +++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/content/media/nsMediaStream.cpp b/content/media/nsMediaStream.cpp index 4689f02bba95..ebe19d728f38 100644 --- a/content/media/nsMediaStream.cpp +++ b/content/media/nsMediaStream.cpp @@ -59,6 +59,7 @@ #define HTTP_OK_CODE 200 #define HTTP_PARTIAL_RESPONSE_CODE 206 +#define HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE 416 using mozilla::TimeStamp; @@ -148,12 +149,14 @@ nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest) nsHTMLMediaElement* element = mDecoder->GetMediaElement(); NS_ENSURE_TRUE(element, NS_ERROR_FAILURE); + nsresult status; + nsresult rv = aRequest->GetStatus(&status); + NS_ENSURE_SUCCESS(rv, rv); + if (element->ShouldCheckAllowOrigin()) { // If the request was cancelled by nsCrossSiteListenerProxy due to failing // the Access Control check, send an error through to the media element. - nsresult status; - nsresult rv = aRequest->GetStatus(&status); - if (NS_FAILED(rv) || status == NS_ERROR_DOM_BAD_URI) { + if (status == NS_ERROR_DOM_BAD_URI) { mDecoder->NetworkError(); return NS_ERROR_DOM_BAD_URI; } @@ -162,6 +165,31 @@ nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest) nsCOMPtr hc = do_QueryInterface(aRequest); PRBool seekable = PR_FALSE; if (hc) { + PRUint32 responseStatus = 0; + hc->GetResponseStatus(&responseStatus); + PRBool succeeded = PR_FALSE; + hc->GetRequestSucceeded(&succeeded); + + if (!succeeded && NS_SUCCEEDED(status)) { + // HTTP-level error (e.g. 4xx); treat this as a fatal network-level error. + // We might get this on a seek. + // (Note that lower-level errors indicated by NS_FAILED(status) are + // handled in OnStopRequest.) + // A 416 error should treated as EOF here... it's possible + // that we don't get Content-Length, we read N bytes, then we + // suspend and resume, the resume reopens the channel and we seek to + // offset N, but there are no more bytes, so we get a 416 + // "Requested Range Not Satisfiable". + if (responseStatus != HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE) { + mDecoder->NetworkError(); + } + + // This disconnects our listener so we don't get any more data. We + // certainly don't want an error page to end up in our cache! + CloseChannel(); + return NS_OK; + } + nsCAutoString ranges; hc->GetResponseHeader(NS_LITERAL_CSTRING("Accept-Ranges"), ranges); @@ -176,7 +204,7 @@ nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest) // 4) Perform a seek in the decoder to find the value. nsCAutoString durationText; PRInt32 ec = 0; - nsresult rv = hc->GetResponseHeader(NS_LITERAL_CSTRING("X-Content-Duration"), durationText); + rv = hc->GetResponseHeader(NS_LITERAL_CSTRING("X-Content-Duration"), durationText); if (NS_FAILED(rv)) { rv = hc->GetResponseHeader(NS_LITERAL_CSTRING("X-AMZ-Meta-Content-Duration"), durationText); } @@ -189,8 +217,6 @@ nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest) } } - PRUint32 responseStatus = 0; - hc->GetResponseStatus(&responseStatus); if (mOffset > 0 && responseStatus == HTTP_OK_CODE) { // If we get an OK response but we were seeking, we have to assume // that seeking doesn't work. We also need to tell the cache that @@ -223,7 +249,7 @@ nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest) nsCOMPtr cc = do_QueryInterface(aRequest); if (cc) { PRBool fromCache = PR_FALSE; - nsresult rv = cc->IsFromCache(&fromCache); + rv = cc->IsFromCache(&fromCache); if (NS_SUCCEEDED(rv) && !fromCache) { cc->SetCacheAsFile(PR_TRUE); }