1 /* vim:set ts=2 sw=2 sts=2 et cindent: */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "CloneableWithRangeMediaResource.h"
8 #include "mozilla/AbstractThread.h"
9 #include "mozilla/Monitor.h"
10 #include "nsContentUtils.h"
11 #include "nsIAsyncInputStream.h"
12 #include "nsITimedChannel.h"
14 #include "nsServiceManagerUtils.h"
20 class InputStreamReader final
: public nsIInputStreamCallback
{
22 NS_DECL_THREADSAFE_ISUPPORTS
24 static already_AddRefed
<InputStreamReader
> Create(
25 nsICloneableInputStreamWithRange
* aStream
, int64_t aStart
,
29 nsCOMPtr
<nsIInputStream
> stream
;
31 aStream
->CloneWithRange(aStart
, aLength
, getter_AddRefs(stream
));
32 if (NS_WARN_IF(NS_FAILED(rv
))) {
36 RefPtr
<InputStreamReader
> reader
= new InputStreamReader(stream
);
37 return reader
.forget();
40 nsresult
Read(char* aBuffer
, uint32_t aSize
, uint32_t* aRead
) {
44 nsresult rv
= SyncRead(aBuffer
+ done
, aSize
- done
, &read
);
45 if (NS_SUCCEEDED(rv
) && read
== 0) {
48 if (NS_WARN_IF(NS_FAILED(rv
))) {
52 } while (done
!= aSize
);
59 OnInputStreamReady(nsIAsyncInputStream
* aStream
) override
{
60 // Let's continue with SyncRead().
61 MonitorAutoLock
lock(mMonitor
);
67 explicit InputStreamReader(nsIInputStream
* aStream
)
68 : mStream(aStream
), mMonitor("InputStreamReader::mMonitor") {
72 ~InputStreamReader() = default;
74 nsresult
SyncRead(char* aBuffer
, uint32_t aSize
, uint32_t* aRead
) {
76 nsresult rv
= mStream
->Read(aBuffer
, aSize
, aRead
);
78 if (rv
== NS_BASE_STREAM_CLOSED
|| NS_SUCCEEDED(rv
)) {
83 if (NS_FAILED(rv
) && rv
!= NS_BASE_STREAM_WOULD_BLOCK
) {
87 // We need to proceed async.
89 mAsyncStream
= do_QueryInterface(mStream
);
93 return NS_ERROR_FAILURE
;
96 nsCOMPtr
<nsIEventTarget
> target
=
97 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID
);
101 // We wait for ::OnInputStreamReady() to be called.
102 MonitorAutoLock
lock(mMonitor
);
104 rv
= mAsyncStream
->AsyncWait(this, 0, aSize
, target
);
105 if (NS_WARN_IF(NS_FAILED(rv
))) {
114 nsCOMPtr
<nsIInputStream
> mStream
;
115 nsCOMPtr
<nsIAsyncInputStream
> mAsyncStream
;
116 Monitor mMonitor MOZ_UNANNOTATED
;
119 NS_IMPL_ADDREF(InputStreamReader
);
120 NS_IMPL_RELEASE(InputStreamReader
);
122 NS_INTERFACE_MAP_BEGIN(InputStreamReader
)
123 NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback
)
124 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIInputStreamCallback
)
129 void CloneableWithRangeMediaResource::MaybeInitialize() {
132 mCallback
->AbstractMainThread()->Dispatch(NewRunnableMethod
<nsresult
>(
133 "MediaResourceCallback::NotifyDataEnded", mCallback
.get(),
134 &MediaResourceCallback::NotifyDataEnded
, NS_OK
));
138 nsresult
CloneableWithRangeMediaResource::GetCachedRanges(
139 MediaByteRangeSet
& aRanges
) {
141 aRanges
+= MediaByteRange(0, (int64_t)mSize
);
145 nsresult
CloneableWithRangeMediaResource::Open(
146 nsIStreamListener
** aStreamListener
) {
147 MOZ_ASSERT(NS_IsMainThread());
148 MOZ_ASSERT(aStreamListener
);
150 *aStreamListener
= nullptr;
154 RefPtr
<GenericPromise
> CloneableWithRangeMediaResource::Close() {
155 return GenericPromise::CreateAndResolve(true, __func__
);
158 already_AddRefed
<nsIPrincipal
>
159 CloneableWithRangeMediaResource::GetCurrentPrincipal() {
160 MOZ_ASSERT(NS_IsMainThread());
162 nsCOMPtr
<nsIPrincipal
> principal
;
163 nsIScriptSecurityManager
* secMan
= nsContentUtils::GetSecurityManager();
164 if (!secMan
|| !mChannel
) {
168 secMan
->GetChannelResultPrincipal(mChannel
, getter_AddRefs(principal
));
169 return principal
.forget();
172 bool CloneableWithRangeMediaResource::HadCrossOriginRedirects() {
173 MOZ_ASSERT(NS_IsMainThread());
175 nsCOMPtr
<nsITimedChannel
> timedChannel
= do_QueryInterface(mChannel
);
180 bool allRedirectsSameOrigin
= false;
181 return NS_SUCCEEDED(timedChannel
->GetAllRedirectsSameOrigin(
182 &allRedirectsSameOrigin
)) &&
183 !allRedirectsSameOrigin
;
186 nsresult
CloneableWithRangeMediaResource::ReadFromCache(char* aBuffer
,
194 RefPtr
<InputStreamReader
> reader
=
195 InputStreamReader::Create(mStream
, aOffset
, aCount
);
197 return NS_ERROR_FAILURE
;
201 nsresult rv
= reader
->Read(aBuffer
, aCount
, &bytes
);
202 if (NS_WARN_IF(NS_FAILED(rv
))) {
206 return bytes
== aCount
? NS_OK
: NS_ERROR_FAILURE
;
209 nsresult
CloneableWithRangeMediaResource::ReadAt(int64_t aOffset
, char* aBuffer
,
212 MOZ_ASSERT(!NS_IsMainThread());
214 RefPtr
<InputStreamReader
> reader
=
215 InputStreamReader::Create(mStream
, aOffset
, aCount
);
217 return NS_ERROR_FAILURE
;
220 nsresult rv
= reader
->Read(aBuffer
, aCount
, aBytes
);
221 if (NS_WARN_IF(NS_FAILED(rv
))) {
228 } // namespace mozilla