/*---------------------------------------------------------------------- | AP4_CtrStreamCipher::SetIV +---------------------------------------------------------------------*/ AP4_Result AP4_CtrStreamCipher::SetIV(const AP4_UI08* iv) { if (iv) { AP4_CopyMemory(m_IV, iv, AP4_CIPHER_BLOCK_SIZE); } else { AP4_SetMemory(m_IV, 0, AP4_CIPHER_BLOCK_SIZE); } // for the stream offset back to 0 m_CacheValid = false; return SetStreamOffset(0); }
/*---------------------------------------------------------------------- | AP4_CtrStreamCipher::AP4_CtrStreamCipher +---------------------------------------------------------------------*/ AP4_CtrStreamCipher::AP4_CtrStreamCipher(AP4_BlockCipher* block_cipher, AP4_Size counter_size) : m_StreamOffset(0), m_CounterSize(counter_size), m_CacheValid(false), m_BlockCipher(block_cipher) { if (m_CounterSize > 16) m_CounterSize = 16; // reset the stream offset AP4_SetMemory(m_IV, 0, AP4_CIPHER_BLOCK_SIZE); SetStreamOffset(0); SetIV(NULL); }
NS_IMETHODIMP nsPluginStreamListenerPeer::OnDataAvailable(nsIRequest *request, nsISupports* aContext, nsIInputStream *aIStream, uint64_t sourceOffset, uint32_t aLength) { if (mRequests.IndexOfObject(GetBaseRequest(request)) == -1) { MOZ_ASSERT(false, "Received OnDataAvailable for untracked request."); return NS_ERROR_UNEXPECTED; } if (mRequestFailed) return NS_ERROR_FAILURE; if (mAbort) { uint32_t magicNumber = 0; // set it to something that is not the magic number. nsCOMPtr<nsISupportsPRUint32> container = do_QueryInterface(aContext); if (container) container->GetData(&magicNumber); if (magicNumber != MAGIC_REQUEST_CONTEXT) { // this is not one of our range requests mAbort = false; return NS_BINDING_ABORTED; } } nsresult rv = NS_OK; if (!mPStreamListener) return NS_ERROR_FAILURE; const char * url = nullptr; GetURL(&url); PLUGIN_LOG(PLUGIN_LOG_NOISY, ("nsPluginStreamListenerPeer::OnDataAvailable this=%p request=%p, offset=%llu, length=%u, url=%s\n", this, request, sourceOffset, aLength, url ? url : "no url set")); // if the plugin has requested an AsFileOnly stream, then don't // call OnDataAvailable if (mStreamType != NP_ASFILEONLY) { // get the absolute offset of the request, if one exists. nsCOMPtr<nsIByteRangeRequest> brr = do_QueryInterface(request); if (brr) { if (!mDataForwardToRequest) return NS_ERROR_FAILURE; int64_t absoluteOffset64 = 0; brr->GetStartRange(&absoluteOffset64); // XXX handle 64-bit for real int32_t absoluteOffset = (int32_t)int64_t(absoluteOffset64); // we need to track how much data we have forwarded to the // plugin. // FIXME: http://bugzilla.mozilla.org/show_bug.cgi?id=240130 // // Why couldn't this be tracked on the plugin info, and not in a // *hash table*? int32_t amtForwardToPlugin = mDataForwardToRequest->Get(absoluteOffset); mDataForwardToRequest->Put(absoluteOffset, (amtForwardToPlugin + aLength)); SetStreamOffset(absoluteOffset + amtForwardToPlugin); } nsCOMPtr<nsIInputStream> stream = aIStream; // if we are caching the file ourselves to disk, we want to 'tee' off // the data as the plugin read from the stream. We do this by the magic // of an input stream tee. if (mFileCacheOutputStream) { rv = NS_NewInputStreamTee(getter_AddRefs(stream), aIStream, mFileCacheOutputStream); if (NS_FAILED(rv)) return rv; } rv = mPStreamListener->OnDataAvailable(this, stream, aLength); // if a plugin returns an error, the peer must kill the stream // else the stream and PluginStreamListener leak if (NS_FAILED(rv)) request->Cancel(rv); } else { // if we don't read from the stream, OnStopRequest will never be called char* buffer = new char[aLength]; uint32_t amountRead, amountWrote = 0; rv = aIStream->Read(buffer, aLength, &amountRead); // if we are caching this to disk ourselves, lets write the bytes out. if (mFileCacheOutputStream) { while (amountWrote < amountRead && NS_SUCCEEDED(rv)) { rv = mFileCacheOutputStream->Write(buffer, amountRead, &amountWrote); } } delete [] buffer; } return rv; }
nsresult nsPluginStreamListenerPeer::RequestRead(NPByteRange* rangeList) { nsAutoCString rangeString; int32_t numRequests; MakeByteRangeString(rangeList, rangeString, &numRequests); if (numRequests == 0) return NS_ERROR_FAILURE; nsresult rv = NS_OK; nsRefPtr<nsPluginInstanceOwner> owner = mPluginInstance->GetOwner(); nsCOMPtr<nsIDOMElement> element; nsCOMPtr<nsIDocument> doc; if (owner) { rv = owner->GetDOMElement(getter_AddRefs(element)); NS_ENSURE_SUCCESS(rv, rv); rv = owner->GetDocument(getter_AddRefs(doc)); NS_ENSURE_SUCCESS(rv, rv); } nsCOMPtr<nsIInterfaceRequestor> callbacks = do_QueryReferent(mWeakPtrChannelCallbacks); nsCOMPtr<nsILoadGroup> loadGroup = do_QueryReferent(mWeakPtrChannelLoadGroup); nsCOMPtr<nsIChannel> channel; nsCOMPtr<nsINode> requestingNode(do_QueryInterface(element)); if (requestingNode) { rv = NS_NewChannel(getter_AddRefs(channel), mURL, requestingNode, nsILoadInfo::SEC_NORMAL, nsIContentPolicy::TYPE_OTHER, loadGroup, callbacks); } else { // in this else branch we really don't know where the load is coming // from and in fact should use something better than just using // a nullPrincipal as the loadingPrincipal. nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create(); NS_ENSURE_TRUE(principal, NS_ERROR_FAILURE); rv = NS_NewChannel(getter_AddRefs(channel), mURL, principal, nsILoadInfo::SEC_NORMAL, nsIContentPolicy::TYPE_OTHER, loadGroup, callbacks); } if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel)); if (!httpChannel) return NS_ERROR_FAILURE; httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, false); mAbort = true; // instruct old stream listener to cancel // the request on the next ODA. nsCOMPtr<nsIStreamListener> converter; if (numRequests == 1) { converter = this; // set current stream offset equal to the first offset in the range list // it will work for single byte range request // for multy range we'll reset it in ODA SetStreamOffset(rangeList->offset); } else { nsWeakPtr weakpeer = do_GetWeakReference(static_cast<nsISupportsWeakReference*>(this)); nsPluginByteRangeStreamListener *brrListener = new nsPluginByteRangeStreamListener(weakpeer); if (brrListener) converter = brrListener; else return NS_ERROR_OUT_OF_MEMORY; } mPendingRequests += numRequests; nsCOMPtr<nsISupportsPRUint32> container = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; rv = container->SetData(MAGIC_REQUEST_CONTEXT); if (NS_FAILED(rv)) return rv; rv = channel->AsyncOpen(converter, container); if (NS_SUCCEEDED(rv)) TrackRequest(channel); return rv; }
nsresult nsPluginStreamListenerPeer::RequestRead(NPByteRange* rangeList) { nsAutoCString rangeString; int32_t numRequests; MakeByteRangeString(rangeList, rangeString, &numRequests); if (numRequests == 0) return NS_ERROR_FAILURE; nsresult rv = NS_OK; nsCOMPtr<nsIInterfaceRequestor> callbacks = do_QueryReferent(mWeakPtrChannelCallbacks); nsCOMPtr<nsILoadGroup> loadGroup = do_QueryReferent(mWeakPtrChannelLoadGroup); nsCOMPtr<nsIChannel> channel; rv = NS_NewChannel(getter_AddRefs(channel), mURL, nullptr, loadGroup, callbacks); if (NS_FAILED(rv)) return rv; nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel)); if (!httpChannel) return NS_ERROR_FAILURE; httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("Range"), rangeString, false); mAbort = true; // instruct old stream listener to cancel // the request on the next ODA. nsCOMPtr<nsIStreamListener> converter; if (numRequests == 1) { converter = this; // set current stream offset equal to the first offset in the range list // it will work for single byte range request // for multy range we'll reset it in ODA SetStreamOffset(rangeList->offset); } else { nsWeakPtr weakpeer = do_GetWeakReference(static_cast<nsISupportsWeakReference*>(this)); nsPluginByteRangeStreamListener *brrListener = new nsPluginByteRangeStreamListener(weakpeer); if (brrListener) converter = brrListener; else return NS_ERROR_OUT_OF_MEMORY; } mPendingRequests += numRequests; nsCOMPtr<nsISupportsPRUint32> container = do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; rv = container->SetData(MAGIC_REQUEST_CONTEXT); if (NS_FAILED(rv)) return rv; rv = channel->AsyncOpen(converter, container); if (NS_SUCCEEDED(rv)) TrackRequest(channel); return rv; }