mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Backing out bug 489415 due to Linux test failures
This commit is contained in:
commit
b1b462d25c
@ -172,15 +172,11 @@ void nsHTMLMediaElement::QueueLoadFromSourceTask()
|
|||||||
NS_DispatchToMainThread(event);
|
NS_DispatchToMainThread(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
class nsHTMLMediaElement::MediaLoadListener : public nsIStreamListener,
|
class nsHTMLMediaElement::MediaLoadListener : public nsIStreamListener
|
||||||
public nsIChannelEventSink,
|
|
||||||
public nsIInterfaceRequestor
|
|
||||||
{
|
{
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIREQUESTOBSERVER
|
NS_DECL_NSIREQUESTOBSERVER
|
||||||
NS_DECL_NSISTREAMLISTENER
|
NS_DECL_NSISTREAMLISTENER
|
||||||
NS_DECL_NSICHANNELEVENTSINK
|
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MediaLoadListener(nsHTMLMediaElement* aElement)
|
MediaLoadListener(nsHTMLMediaElement* aElement)
|
||||||
@ -194,9 +190,7 @@ private:
|
|||||||
nsCOMPtr<nsIStreamListener> mNextListener;
|
nsCOMPtr<nsIStreamListener> mNextListener;
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS4(nsHTMLMediaElement::MediaLoadListener, nsIRequestObserver,
|
NS_IMPL_ISUPPORTS2(nsHTMLMediaElement::MediaLoadListener, nsIRequestObserver, nsIStreamListener)
|
||||||
nsIStreamListener, nsIChannelEventSink,
|
|
||||||
nsIInterfaceRequestor)
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
||||||
{
|
{
|
||||||
@ -258,21 +252,6 @@ NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnDataAvailable(nsIRequest*
|
|||||||
return mNextListener->OnDataAvailable(aRequest, aContext, aStream, aOffset, aCount);
|
return mNextListener->OnDataAvailable(aRequest, aContext, aStream, aOffset, aCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnChannelRedirect(nsIChannel* aOldChannel,
|
|
||||||
nsIChannel* aNewChannel,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIChannelEventSink> sink = do_QueryInterface(mNextListener);
|
|
||||||
if (sink)
|
|
||||||
return sink->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::GetInterface(const nsIID & aIID, void **aResult)
|
|
||||||
{
|
|
||||||
return QueryInterface(aIID, aResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ADDREF_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
|
NS_IMPL_ADDREF_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
|
||||||
NS_IMPL_RELEASE_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
|
NS_IMPL_RELEASE_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement)
|
||||||
|
|
||||||
@ -534,10 +513,8 @@ nsresult nsHTMLMediaElement::LoadResource(nsIURI* aURI)
|
|||||||
// The listener holds a strong reference to us. This creates a reference
|
// The listener holds a strong reference to us. This creates a reference
|
||||||
// cycle which is manually broken in the listener's OnStartRequest method
|
// cycle which is manually broken in the listener's OnStartRequest method
|
||||||
// after it is finished with the element.
|
// after it is finished with the element.
|
||||||
nsRefPtr<MediaLoadListener> loadListener = new MediaLoadListener(this);
|
nsCOMPtr<nsIStreamListener> loadListener = new MediaLoadListener(this);
|
||||||
if (!loadListener) return NS_ERROR_OUT_OF_MEMORY;
|
if (!loadListener) return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
mChannel->SetNotificationCallbacks(loadListener);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIStreamListener> listener;
|
nsCOMPtr<nsIStreamListener> listener;
|
||||||
if (ShouldCheckAllowOrigin()) {
|
if (ShouldCheckAllowOrigin()) {
|
||||||
|
@ -41,8 +41,6 @@
|
|||||||
|
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsAutoLock.h"
|
#include "nsAutoLock.h"
|
||||||
#include "nsIPrincipal.h"
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Media applications want fast, "on demand" random access to media data,
|
* Media applications want fast, "on demand" random access to media data,
|
||||||
@ -188,13 +186,6 @@
|
|||||||
* we must not acquire any nsMediaDecoder locks or nsMediaStream locks
|
* we must not acquire any nsMediaDecoder locks or nsMediaStream locks
|
||||||
* while holding the nsMediaCache lock. But it's OK to hold those locks
|
* while holding the nsMediaCache lock. But it's OK to hold those locks
|
||||||
* and then get the nsMediaCache lock.
|
* and then get the nsMediaCache lock.
|
||||||
*
|
|
||||||
* nsMediaCache associates a principal with each stream. CacheClientSeek
|
|
||||||
* can trigger new HTTP requests; due to redirects to other domains,
|
|
||||||
* each HTTP load can return data with a different principal. This
|
|
||||||
* principal must be passed to NotifyDataReceived, and nsMediaCache
|
|
||||||
* will detect when different principals are associated with data in the
|
|
||||||
* same stream, and replace them with a null principal.
|
|
||||||
*/
|
*/
|
||||||
class nsMediaCache;
|
class nsMediaCache;
|
||||||
// defined in nsMediaStream.h
|
// defined in nsMediaStream.h
|
||||||
@ -224,8 +215,7 @@ public:
|
|||||||
mStreamOffset(0), mStreamLength(-1), mPlaybackBytesPerSecond(10000),
|
mStreamOffset(0), mStreamLength(-1), mPlaybackBytesPerSecond(10000),
|
||||||
mPinCount(0), mCurrentMode(MODE_PLAYBACK), mClosed(PR_FALSE),
|
mPinCount(0), mCurrentMode(MODE_PLAYBACK), mClosed(PR_FALSE),
|
||||||
mIsSeekable(PR_FALSE), mCacheSuspended(PR_FALSE),
|
mIsSeekable(PR_FALSE), mCacheSuspended(PR_FALSE),
|
||||||
mMetadataInPartialBlockBuffer(PR_FALSE),
|
mMetadataInPartialBlockBuffer(PR_FALSE) {}
|
||||||
mUsingNullPrincipal(PR_FALSE) {}
|
|
||||||
~nsMediaCacheStream();
|
~nsMediaCacheStream();
|
||||||
|
|
||||||
// Set up this stream with the cache. Can fail on OOM. Must be called
|
// Set up this stream with the cache. Can fail on OOM. Must be called
|
||||||
@ -246,8 +236,6 @@ public:
|
|||||||
void Close();
|
void Close();
|
||||||
// This returns true when the stream has been closed
|
// This returns true when the stream has been closed
|
||||||
PRBool IsClosed() const { return mClosed; }
|
PRBool IsClosed() const { return mClosed; }
|
||||||
// Get the principal for this stream.
|
|
||||||
nsIPrincipal* GetCurrentPrincipal() { return mPrincipal; }
|
|
||||||
|
|
||||||
// These callbacks are called on the main thread by the client
|
// These callbacks are called on the main thread by the client
|
||||||
// when data has been received via the channel.
|
// when data has been received via the channel.
|
||||||
@ -275,9 +263,7 @@ public:
|
|||||||
// the starting offset is known via NotifyDataStarted or because
|
// the starting offset is known via NotifyDataStarted or because
|
||||||
// the cache requested the offset in
|
// the cache requested the offset in
|
||||||
// nsMediaChannelStream::CacheClientSeek, or because it defaulted to 0.
|
// nsMediaChannelStream::CacheClientSeek, or because it defaulted to 0.
|
||||||
// We pass in the principal that was used to load this data.
|
void NotifyDataReceived(PRInt64 aSize, const char* aData);
|
||||||
void NotifyDataReceived(PRInt64 aSize, const char* aData,
|
|
||||||
nsIPrincipal* aPrincipal);
|
|
||||||
// Notifies the cache that the channel has closed with the given status.
|
// Notifies the cache that the channel has closed with the given status.
|
||||||
void NotifyDataEnded(nsresult aStatus);
|
void NotifyDataEnded(nsresult aStatus);
|
||||||
|
|
||||||
@ -377,12 +363,9 @@ private:
|
|||||||
// This is used to NotifyAll to wake up threads that might be
|
// This is used to NotifyAll to wake up threads that might be
|
||||||
// blocked on reading from this stream.
|
// blocked on reading from this stream.
|
||||||
void CloseInternal(nsAutoMonitor* aMonitor);
|
void CloseInternal(nsAutoMonitor* aMonitor);
|
||||||
// Update mPrincipal given that data has been received from aPrincipal
|
|
||||||
void UpdatePrincipal(nsIPrincipal* aPrincipal);
|
|
||||||
|
|
||||||
// These fields are main-thread-only.
|
// This field is main-thread-only.
|
||||||
nsMediaChannelStream* mClient;
|
nsMediaChannelStream* mClient;
|
||||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
|
||||||
|
|
||||||
// All other fields are all protected by the cache's monitor and
|
// All other fields are all protected by the cache's monitor and
|
||||||
// can be accessed by by any thread.
|
// can be accessed by by any thread.
|
||||||
@ -418,9 +401,6 @@ private:
|
|||||||
PRPackedBool mCacheSuspended;
|
PRPackedBool mCacheSuspended;
|
||||||
// true if some data in mPartialBlockBuffer has been read as metadata
|
// true if some data in mPartialBlockBuffer has been read as metadata
|
||||||
PRPackedBool mMetadataInPartialBlockBuffer;
|
PRPackedBool mMetadataInPartialBlockBuffer;
|
||||||
// true if mPrincipal is a null principal because we saw data from
|
|
||||||
// multiple origins
|
|
||||||
PRPackedBool mUsingNullPrincipal;
|
|
||||||
|
|
||||||
// Data received for the block containing mChannelOffset. Data needs
|
// Data received for the block containing mChannelOffset. Data needs
|
||||||
// to wait here so we can write back a complete block. The first
|
// to wait here so we can write back a complete block. The first
|
||||||
|
@ -44,8 +44,6 @@
|
|||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsIStreamListener.h"
|
#include "nsIStreamListener.h"
|
||||||
#include "nsIChannelEventSink.h"
|
|
||||||
#include "nsIInterfaceRequestor.h"
|
|
||||||
#include "prlock.h"
|
#include "prlock.h"
|
||||||
#include "nsMediaCache.h"
|
#include "nsMediaCache.h"
|
||||||
#include "nsTimeStamp.h"
|
#include "nsTimeStamp.h"
|
||||||
@ -151,6 +149,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The following can be called on the main thread only:
|
// The following can be called on the main thread only:
|
||||||
|
// Get the current principal for the channel
|
||||||
|
already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
|
||||||
// Get the decoder
|
// Get the decoder
|
||||||
nsMediaDecoder* Decoder() { return mDecoder; }
|
nsMediaDecoder* Decoder() { return mDecoder; }
|
||||||
// Close the stream, stop any listeners, channels, etc.
|
// Close the stream, stop any listeners, channels, etc.
|
||||||
@ -161,8 +161,6 @@ public:
|
|||||||
virtual void Suspend() = 0;
|
virtual void Suspend() = 0;
|
||||||
// Resume any downloads that have been suspended.
|
// Resume any downloads that have been suspended.
|
||||||
virtual void Resume() = 0;
|
virtual void Resume() = 0;
|
||||||
// Get the current principal for the channel
|
|
||||||
virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal() = 0;
|
|
||||||
|
|
||||||
// These methods are called off the main thread.
|
// These methods are called off the main thread.
|
||||||
// The mode is initially MODE_PLAYBACK.
|
// The mode is initially MODE_PLAYBACK.
|
||||||
@ -319,7 +317,6 @@ public:
|
|||||||
virtual nsresult Close();
|
virtual nsresult Close();
|
||||||
virtual void Suspend();
|
virtual void Suspend();
|
||||||
virtual void Resume();
|
virtual void Resume();
|
||||||
virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
|
|
||||||
// Return PR_TRUE if the stream has been closed.
|
// Return PR_TRUE if the stream has been closed.
|
||||||
PRBool IsClosed() const { return mCacheStream.IsClosed(); }
|
PRBool IsClosed() const { return mCacheStream.IsClosed(); }
|
||||||
|
|
||||||
@ -340,18 +337,13 @@ public:
|
|||||||
virtual PRBool IsSuspendedByCache();
|
virtual PRBool IsSuspendedByCache();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class Listener : public nsIStreamListener,
|
class Listener : public nsIStreamListener {
|
||||||
public nsIInterfaceRequestor,
|
|
||||||
public nsIChannelEventSink
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Listener(nsMediaChannelStream* aStream) : mStream(aStream) {}
|
Listener(nsMediaChannelStream* aStream) : mStream(aStream) {}
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIREQUESTOBSERVER
|
NS_DECL_NSIREQUESTOBSERVER
|
||||||
NS_DECL_NSISTREAMLISTENER
|
NS_DECL_NSISTREAMLISTENER
|
||||||
NS_DECL_NSICHANNELEVENTSINK
|
|
||||||
NS_DECL_NSIINTERFACEREQUESTOR
|
|
||||||
|
|
||||||
void Revoke() { mStream = nsnull; }
|
void Revoke() { mStream = nsnull; }
|
||||||
|
|
||||||
@ -366,12 +358,10 @@ protected:
|
|||||||
nsresult OnDataAvailable(nsIRequest* aRequest,
|
nsresult OnDataAvailable(nsIRequest* aRequest,
|
||||||
nsIInputStream* aStream,
|
nsIInputStream* aStream,
|
||||||
PRUint32 aCount);
|
PRUint32 aCount);
|
||||||
nsresult OnChannelRedirect(nsIChannel* aOld, nsIChannel* aNew, PRUint32 aFlags);
|
|
||||||
|
|
||||||
// Opens the channel, using an HTTP byte range request to start at aOffset
|
// Opens the channel, using an HTTP byte range request to start at aOffset
|
||||||
// if possible. Main thread only.
|
// if possible. Main thread only.
|
||||||
nsresult OpenChannel(nsIStreamListener** aStreamListener, PRInt64 aOffset);
|
nsresult OpenChannel(nsIStreamListener** aStreamListener, PRInt64 aOffset);
|
||||||
void SetupChannelHeaders();
|
|
||||||
// Closes the channel. Main thread only.
|
// Closes the channel. Main thread only.
|
||||||
void CloseChannel();
|
void CloseChannel();
|
||||||
|
|
||||||
@ -383,9 +373,9 @@ protected:
|
|||||||
PRUint32 *aWriteCount);
|
PRUint32 *aWriteCount);
|
||||||
|
|
||||||
// Main thread access only
|
// Main thread access only
|
||||||
PRInt64 mLastSeekOffset;
|
|
||||||
nsRefPtr<Listener> mListener;
|
nsRefPtr<Listener> mListener;
|
||||||
PRUint32 mSuspendCount;
|
PRUint32 mSuspendCount;
|
||||||
|
PRPackedBool mSeeking;
|
||||||
|
|
||||||
// Any thread access
|
// Any thread access
|
||||||
nsMediaCacheStream mCacheStream;
|
nsMediaCacheStream mCacheStream;
|
||||||
|
@ -1390,47 +1390,10 @@ nsMediaCacheStream::NotifyDataStarted(PRInt64 aOffset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsMediaCacheStream::UpdatePrincipal(nsIPrincipal* aPrincipal)
|
nsMediaCacheStream::NotifyDataReceived(PRInt64 aSize, const char* aData)
|
||||||
{
|
|
||||||
if (!mPrincipal) {
|
|
||||||
NS_ASSERTION(!mUsingNullPrincipal, "Are we using a null principal or not?");
|
|
||||||
if (mUsingNullPrincipal) {
|
|
||||||
// Don't let mPrincipal be set to anything
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mPrincipal = aPrincipal;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mPrincipal == aPrincipal) {
|
|
||||||
// Common case
|
|
||||||
NS_ASSERTION(!mUsingNullPrincipal, "We can't receive data from a null principal");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mUsingNullPrincipal) {
|
|
||||||
// We've already fallen back to a null principal, so nothing more
|
|
||||||
// to do.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool equal;
|
|
||||||
nsresult rv = mPrincipal->Equals(aPrincipal, &equal);
|
|
||||||
if (NS_SUCCEEDED(rv) && equal)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Principals are not equal, so set mPrincipal to a null principal.
|
|
||||||
mPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1");
|
|
||||||
mUsingNullPrincipal = PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsMediaCacheStream::NotifyDataReceived(PRInt64 aSize, const char* aData,
|
|
||||||
nsIPrincipal* aPrincipal)
|
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||||
|
|
||||||
UpdatePrincipal(aPrincipal);
|
|
||||||
|
|
||||||
nsAutoMonitor mon(gMediaCache->Monitor());
|
nsAutoMonitor mon(gMediaCache->Monitor());
|
||||||
PRInt64 size = aSize;
|
PRInt64 size = aSize;
|
||||||
const char* data = aData;
|
const char* data = aData;
|
||||||
|
@ -65,7 +65,7 @@ using mozilla::TimeStamp;
|
|||||||
nsMediaChannelStream::nsMediaChannelStream(nsMediaDecoder* aDecoder,
|
nsMediaChannelStream::nsMediaChannelStream(nsMediaDecoder* aDecoder,
|
||||||
nsIChannel* aChannel, nsIURI* aURI)
|
nsIChannel* aChannel, nsIURI* aURI)
|
||||||
: nsMediaStream(aDecoder, aChannel, aURI),
|
: nsMediaStream(aDecoder, aChannel, aURI),
|
||||||
mLastSeekOffset(0), mSuspendCount(0),
|
mSuspendCount(0), mSeeking(PR_FALSE),
|
||||||
mCacheStream(this),
|
mCacheStream(this),
|
||||||
mLock(nsAutoLock::NewLock("media.channel.stream")),
|
mLock(nsAutoLock::NewLock("media.channel.stream")),
|
||||||
mCacheSuspendCount(0)
|
mCacheSuspendCount(0)
|
||||||
@ -89,9 +89,7 @@ nsMediaChannelStream::~nsMediaChannelStream()
|
|||||||
// disconnect the old listener from the nsMediaChannelStream and hook up
|
// disconnect the old listener from the nsMediaChannelStream and hook up
|
||||||
// a new listener, so notifications from the old channel are discarded
|
// a new listener, so notifications from the old channel are discarded
|
||||||
// and don't confuse us.
|
// and don't confuse us.
|
||||||
NS_IMPL_ISUPPORTS4(nsMediaChannelStream::Listener,
|
NS_IMPL_ISUPPORTS2(nsMediaChannelStream::Listener, nsIRequestObserver, nsIStreamListener)
|
||||||
nsIRequestObserver, nsIStreamListener, nsIChannelEventSink,
|
|
||||||
nsIInterfaceRequestor)
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsMediaChannelStream::Listener::OnStartRequest(nsIRequest* aRequest,
|
nsMediaChannelStream::Listener::OnStartRequest(nsIRequest* aRequest,
|
||||||
@ -124,22 +122,6 @@ nsMediaChannelStream::Listener::OnDataAvailable(nsIRequest* aRequest,
|
|||||||
return mStream->OnDataAvailable(aRequest, aStream, aCount);
|
return mStream->OnDataAvailable(aRequest, aStream, aCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsMediaChannelStream::Listener::OnChannelRedirect(nsIChannel* aOldChannel,
|
|
||||||
nsIChannel* aNewChannel,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
if (!mStream)
|
|
||||||
return NS_OK;
|
|
||||||
return mStream->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsMediaChannelStream::Listener::GetInterface(const nsIID & aIID, void **aResult)
|
|
||||||
{
|
|
||||||
return QueryInterface(aIID, aResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest)
|
nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest)
|
||||||
{
|
{
|
||||||
@ -166,7 +148,7 @@ nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest)
|
|||||||
ranges);
|
ranges);
|
||||||
PRBool acceptsRanges = ranges.EqualsLiteral("bytes");
|
PRBool acceptsRanges = ranges.EqualsLiteral("bytes");
|
||||||
|
|
||||||
if (mLastSeekOffset == 0) {
|
if (!mSeeking) {
|
||||||
// Look for duration headers from known Ogg content systems. In the case
|
// Look for duration headers from known Ogg content systems. In the case
|
||||||
// of multiple options for obtaining the duration the order of precedence is;
|
// of multiple options for obtaining the duration the order of precedence is;
|
||||||
// 1) The Media resource metadata if possible (done by the decoder itself).
|
// 1) The Media resource metadata if possible (done by the decoder itself).
|
||||||
@ -190,12 +172,12 @@ nsMediaChannelStream::OnStartRequest(nsIRequest* aRequest)
|
|||||||
|
|
||||||
PRUint32 responseStatus = 0;
|
PRUint32 responseStatus = 0;
|
||||||
hc->GetResponseStatus(&responseStatus);
|
hc->GetResponseStatus(&responseStatus);
|
||||||
if (mLastSeekOffset > 0 && responseStatus == HTTP_OK_CODE) {
|
if (mSeeking && responseStatus == HTTP_OK_CODE) {
|
||||||
// If we get an OK response but we were seeking, we have to assume
|
// 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
|
// that seeking doesn't work. We also need to tell the cache that
|
||||||
// it's getting data for the start of the stream.
|
// it's getting data for the start of the stream.
|
||||||
mCacheStream.NotifyDataStarted(0);
|
mCacheStream.NotifyDataStarted(0);
|
||||||
} else if (mLastSeekOffset == 0 &&
|
} else if (!mSeeking &&
|
||||||
(responseStatus == HTTP_OK_CODE ||
|
(responseStatus == HTTP_OK_CODE ||
|
||||||
responseStatus == HTTP_PARTIAL_RESPONSE_CODE)) {
|
responseStatus == HTTP_PARTIAL_RESPONSE_CODE)) {
|
||||||
// We weren't seeking and got a valid response status,
|
// We weren't seeking and got a valid response status,
|
||||||
@ -261,20 +243,6 @@ nsMediaChannelStream::OnStopRequest(nsIRequest* aRequest, nsresult aStatus)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsMediaChannelStream::OnChannelRedirect(nsIChannel* aOld, nsIChannel* aNew,
|
|
||||||
PRUint32 aFlags)
|
|
||||||
{
|
|
||||||
mChannel = aNew;
|
|
||||||
SetupChannelHeaders();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CopySegmentClosure {
|
|
||||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
|
||||||
nsMediaChannelStream* mStream;
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_METHOD
|
NS_METHOD
|
||||||
nsMediaChannelStream::CopySegmentToCache(nsIInputStream *aInStream,
|
nsMediaChannelStream::CopySegmentToCache(nsIInputStream *aInStream,
|
||||||
void *aClosure,
|
void *aClosure,
|
||||||
@ -283,9 +251,8 @@ nsMediaChannelStream::CopySegmentToCache(nsIInputStream *aInStream,
|
|||||||
PRUint32 aCount,
|
PRUint32 aCount,
|
||||||
PRUint32 *aWriteCount)
|
PRUint32 *aWriteCount)
|
||||||
{
|
{
|
||||||
CopySegmentClosure* closure = static_cast<CopySegmentClosure*>(aClosure);
|
nsMediaChannelStream* stream = static_cast<nsMediaChannelStream*>(aClosure);
|
||||||
closure->mStream->mCacheStream.NotifyDataReceived(aCount, aFromSegment,
|
stream->mCacheStream.NotifyDataReceived(aCount, aFromSegment);
|
||||||
closure->mPrincipal);
|
|
||||||
*aWriteCount = aCount;
|
*aWriteCount = aCount;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -302,17 +269,10 @@ nsMediaChannelStream::OnDataAvailable(nsIRequest* aRequest,
|
|||||||
mChannelStatistics.AddBytes(aCount);
|
mChannelStatistics.AddBytes(aCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
CopySegmentClosure closure;
|
|
||||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
|
||||||
if (secMan && mChannel) {
|
|
||||||
secMan->GetChannelPrincipal(mChannel, getter_AddRefs(closure.mPrincipal));
|
|
||||||
}
|
|
||||||
closure.mStream = this;
|
|
||||||
|
|
||||||
PRUint32 count = aCount;
|
PRUint32 count = aCount;
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
PRUint32 read;
|
PRUint32 read;
|
||||||
nsresult rv = aStream->ReadSegments(CopySegmentToCache, &closure, count,
|
nsresult rv = aStream->ReadSegments(CopySegmentToCache, this, count,
|
||||||
&read);
|
&read);
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
@ -350,7 +310,7 @@ nsresult nsMediaChannelStream::OpenChannel(nsIStreamListener** aStreamListener,
|
|||||||
*aStreamListener = nsnull;
|
*aStreamListener = nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLastSeekOffset = aOffset;
|
mSeeking = aOffset != 0;
|
||||||
|
|
||||||
mListener = new Listener(this);
|
mListener = new Listener(this);
|
||||||
NS_ENSURE_TRUE(mListener, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(mListener, NS_ERROR_OUT_OF_MEMORY);
|
||||||
@ -359,8 +319,6 @@ nsresult nsMediaChannelStream::OpenChannel(nsIStreamListener** aStreamListener,
|
|||||||
*aStreamListener = mListener;
|
*aStreamListener = mListener;
|
||||||
NS_ADDREF(*aStreamListener);
|
NS_ADDREF(*aStreamListener);
|
||||||
} else {
|
} else {
|
||||||
mChannel->SetNotificationCallbacks(mListener.get());
|
|
||||||
|
|
||||||
nsCOMPtr<nsIStreamListener> listener = mListener.get();
|
nsCOMPtr<nsIStreamListener> listener = mListener.get();
|
||||||
|
|
||||||
// Ensure that if we're loading cross domain, that the server is sending
|
// Ensure that if we're loading cross domain, that the server is sending
|
||||||
@ -384,7 +342,18 @@ nsresult nsMediaChannelStream::OpenChannel(nsIStreamListener** aStreamListener,
|
|||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupChannelHeaders();
|
// Use a byte range request from the start of the resource.
|
||||||
|
// This enables us to detect if the stream supports byte range
|
||||||
|
// requests, and therefore seeking, early.
|
||||||
|
nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(mChannel);
|
||||||
|
if (hc) {
|
||||||
|
nsCAutoString rangeString("bytes=");
|
||||||
|
rangeString.AppendInt(aOffset);
|
||||||
|
rangeString.Append("-");
|
||||||
|
hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, PR_FALSE);
|
||||||
|
} else {
|
||||||
|
NS_ASSERTION(aOffset == 0, "Don't know how to seek on this channel type");
|
||||||
|
}
|
||||||
|
|
||||||
nsresult rv = mChannel->AsyncOpen(listener, nsnull);
|
nsresult rv = mChannel->AsyncOpen(listener, nsnull);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
@ -393,23 +362,6 @@ nsresult nsMediaChannelStream::OpenChannel(nsIStreamListener** aStreamListener,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsMediaChannelStream::SetupChannelHeaders()
|
|
||||||
{
|
|
||||||
// Always use a byte range request even if we're reading from the start
|
|
||||||
// of the resource.
|
|
||||||
// This enables us to detect if the stream supports byte range
|
|
||||||
// requests, and therefore seeking, early.
|
|
||||||
nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(mChannel);
|
|
||||||
if (hc) {
|
|
||||||
nsCAutoString rangeString("bytes=");
|
|
||||||
rangeString.AppendInt(mLastSeekOffset);
|
|
||||||
rangeString.Append("-");
|
|
||||||
hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, PR_FALSE);
|
|
||||||
} else {
|
|
||||||
NS_ASSERTION(mLastSeekOffset == 0, "Don't know how to seek on this channel type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult nsMediaChannelStream::Close()
|
nsresult nsMediaChannelStream::Close()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||||
@ -419,14 +371,6 @@ nsresult nsMediaChannelStream::Close()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIPrincipal> nsMediaChannelStream::GetCurrentPrincipal()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> principal = mCacheStream.GetCurrentPrincipal();
|
|
||||||
return principal.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsMediaChannelStream::CloseChannel()
|
void nsMediaChannelStream::CloseChannel()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||||
@ -672,7 +616,6 @@ public:
|
|||||||
virtual nsresult Close();
|
virtual nsresult Close();
|
||||||
virtual void Suspend() {}
|
virtual void Suspend() {}
|
||||||
virtual void Resume() {}
|
virtual void Resume() {}
|
||||||
virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
|
|
||||||
|
|
||||||
// These methods are called off the main thread.
|
// These methods are called off the main thread.
|
||||||
|
|
||||||
@ -814,18 +757,6 @@ nsresult nsMediaFileStream::Close()
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIPrincipal> nsMediaFileStream::GetCurrentPrincipal()
|
|
||||||
{
|
|
||||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> principal;
|
|
||||||
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
|
||||||
if (!secMan || !mChannel)
|
|
||||||
return nsnull;
|
|
||||||
secMan->GetChannelPrincipal(mChannel, getter_AddRefs(principal));
|
|
||||||
return principal.forget();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult nsMediaFileStream::Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes)
|
nsresult nsMediaFileStream::Read(char* aBuffer, PRUint32 aCount, PRUint32* aBytes)
|
||||||
{
|
{
|
||||||
nsAutoLock lock(mLock);
|
nsAutoLock lock(mLock);
|
||||||
@ -900,6 +831,18 @@ nsMediaStream::Open(nsMediaDecoder* aDecoder, nsIURI* aURI,
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
already_AddRefed<nsIPrincipal> nsMediaStream::GetCurrentPrincipal()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPrincipal> principal;
|
||||||
|
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
|
||||||
|
if (!secMan || !mChannel)
|
||||||
|
return nsnull;
|
||||||
|
secMan->GetChannelPrincipal(mChannel, getter_AddRefs(principal));
|
||||||
|
return principal.forget();
|
||||||
|
}
|
||||||
|
|
||||||
void nsMediaStream::MoveLoadsToBackground() {
|
void nsMediaStream::MoveLoadsToBackground() {
|
||||||
NS_ASSERTION(!mLoadInBackground, "Why are you calling this more than once?");
|
NS_ASSERTION(!mLoadInBackground, "Why are you calling this more than once?");
|
||||||
mLoadInBackground = PR_TRUE;
|
mLoadInBackground = PR_TRUE;
|
||||||
|
@ -61,7 +61,6 @@ _TEST_FILES = \
|
|||||||
|
|
||||||
ifdef MOZ_OGG
|
ifdef MOZ_OGG
|
||||||
_TEST_FILES += \
|
_TEST_FILES += \
|
||||||
dynamic_redirect.sjs \
|
|
||||||
test_access_control.html \
|
test_access_control.html \
|
||||||
file_access_controls.html \
|
file_access_controls.html \
|
||||||
test_bug448534.html \
|
test_bug448534.html \
|
||||||
@ -83,7 +82,6 @@ _TEST_FILES += \
|
|||||||
test_info_leak.html \
|
test_info_leak.html \
|
||||||
test_onloadedmetadata.html \
|
test_onloadedmetadata.html \
|
||||||
test_load_candidates.html \
|
test_load_candidates.html \
|
||||||
test_mixed_principals.html \
|
|
||||||
test_play.html \
|
test_play.html \
|
||||||
test_progress1.html \
|
test_progress1.html \
|
||||||
test_progress3.html \
|
test_progress3.html \
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
// Return seek.ogv file content for the first request with a given key.
|
|
||||||
// All subsequent requests return a redirect to a different-origin resource.
|
|
||||||
function handleRequest(request, response)
|
|
||||||
{
|
|
||||||
var key = request.queryString.match(/^key=(.*)$/);
|
|
||||||
|
|
||||||
if (getState(key[1]) == "redirect") {
|
|
||||||
var origin = request.host == "localhost" ? "example.org" : "localhost:8888";
|
|
||||||
response.setStatusLine(request.httpVersion, 303, "See Other");
|
|
||||||
response.setHeader("Location", "http://" + origin + "/tests/content/media/video/test/seek.ogv");
|
|
||||||
response.setHeader("Content-Type", "text/html");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setState(key[1], "redirect");
|
|
||||||
|
|
||||||
var file = Components.classes["@mozilla.org/file/directory_service;1"].
|
|
||||||
getService(Components.interfaces.nsIProperties).
|
|
||||||
get("CurWorkD", Components.interfaces.nsILocalFile);
|
|
||||||
var fis = Components.classes['@mozilla.org/network/file-input-stream;1'].
|
|
||||||
createInstance(Components.interfaces.nsIFileInputStream);
|
|
||||||
var bis = Components.classes["@mozilla.org/binaryinputstream;1"].
|
|
||||||
createInstance(Components.interfaces.nsIBinaryInputStream);
|
|
||||||
var paths = "tests/content/media/video/test/seek.ogv";
|
|
||||||
var split = paths.split("/");
|
|
||||||
for(var i = 0; i < split.length; ++i) {
|
|
||||||
file.append(split[i]);
|
|
||||||
}
|
|
||||||
fis.init(file, -1, -1, false);
|
|
||||||
dump("file=" + file + "\n");
|
|
||||||
bis.setInputStream(fis);
|
|
||||||
var bytes = bis.readBytes(bis.available());
|
|
||||||
response.setStatusLine(request.httpVersion, 206, "Partial Content");
|
|
||||||
response.setHeader("Content-Range", "bytes 0-" + (bytes.length - 1) + "/" + bytes.length);
|
|
||||||
response.setHeader("Content-Length", ""+bytes.length, false);
|
|
||||||
response.setHeader("Content-Type", "video/ogg", false);
|
|
||||||
response.write(bytes, bytes.length);
|
|
||||||
bis.close();
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<!--
|
|
||||||
https://bugzilla.mozilla.org/show_bug.cgi?id=489415
|
|
||||||
-->
|
|
||||||
<head>
|
|
||||||
<title>Test for Bug 489415</title>
|
|
||||||
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=489415">Mozilla Bug 489415</a>
|
|
||||||
<p id="display"></p>
|
|
||||||
|
|
||||||
<video id="v1" autoplay onended="loaded('v1')"></video>
|
|
||||||
<video id="v2" autoplay onended="loaded('v2')"></video>
|
|
||||||
|
|
||||||
<pre id="test">
|
|
||||||
<script type="text/javascript">
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
var v1 = document.getElementById("v1");
|
|
||||||
var v2 = document.getElementById("v2");
|
|
||||||
|
|
||||||
var count = 0;
|
|
||||||
|
|
||||||
function loaded(id) {
|
|
||||||
var c = document.createElement("canvas");
|
|
||||||
var ctx = c.getContext("2d");
|
|
||||||
var v = document.getElementById(id);
|
|
||||||
ctx.drawImage(v, 0, 0);
|
|
||||||
try {
|
|
||||||
c.toDataURL();
|
|
||||||
ok(false, "Failed to throw exception in toDataURL for " + id);
|
|
||||||
} catch (ex) {
|
|
||||||
ok(true, "Threw exception in toDataURL for " + id);
|
|
||||||
}
|
|
||||||
if (++count == 2) {
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a random key. The first load with that key will return
|
|
||||||
// data, the second and subsequent loads with that key will return a redirect
|
|
||||||
// to a different origin ('localhost:8888' will be redirected to 'example.org',
|
|
||||||
// and 'example.org' will be redirected to 'localhost:8888'). We rely on the
|
|
||||||
// fact that Ogg will do a seek to the end of the resource, triggering a new
|
|
||||||
// load with the same key which will return a same-origin resource.
|
|
||||||
// Loading data from two different origins should be detected by the media
|
|
||||||
// cache and result in a null principal so that the canvas usage above fails.
|
|
||||||
var key = Math.floor(Math.random()*100000000);
|
|
||||||
|
|
||||||
// In v1, try loading from same-origin first and then getting redirected to
|
|
||||||
// another origin.
|
|
||||||
v1.src = "http://localhost:8888/tests/content/media/video/test/dynamic_redirect.sjs?key=v1_" + key;
|
|
||||||
v1.load();
|
|
||||||
|
|
||||||
// In v2, try loading cross-origin first and then getting redirected to
|
|
||||||
// our origin.
|
|
||||||
v2.src = "http://example.org/tests/content/media/video/test/dynamic_redirect.sjs?key=v2_" + key;
|
|
||||||
v2.load();
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</pre>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
Reference in New Issue
Block a user