author | Yury Delendik <ydelendik@mozilla.com> |
Mon, 30 Nov 2015 08:54:11 -0600 | |
changeset 275114 | 73cfba395b86e5c2520a0828a5ce4413dffb1c5c |
parent 275113 | 9e68f234636f55415f9803a06e83096e24d7884d |
child 275115 | 6fb6aac48d4d90fbb38e752e9e38bb86a4653f59 |
push id | 29747 |
push user | cbook@mozilla.com |
push date | Wed, 02 Dec 2015 14:21:19 +0000 |
treeherder | mozilla-central@f6ac392322b3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | djvj |
bugs | 1218029 |
milestone | 45.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/nsScriptLoader.cpp +++ b/dom/base/nsScriptLoader.cpp @@ -152,20 +152,20 @@ nsScriptLoader::~nsScriptLoader() req = req->getNext()) { req->FireScriptAvailable(NS_ERROR_ABORT); } // Unblock the kids, in case any of them moved to a different document // subtree in the meantime and therefore aren't actually going away. for (uint32_t j = 0; j < mPendingChildLoaders.Length(); ++j) { mPendingChildLoaders[j]->RemoveExecuteBlocker(); - } + } } -NS_IMPL_ISUPPORTS(nsScriptLoader, nsIStreamLoaderObserver) +NS_IMPL_ISUPPORTS(nsScriptLoader, nsIIncrementalStreamLoaderObserver) // Helper method for checking if the script element is an event-handler // This means that it has both a for-attribute and a event-attribute. // Also, if the for-attribute has a value that matches "\s*window\s*", // and the event-attribute matches "\s*onload([ \(].*)?" then it isn't an // eventhandler. (both matches are case insensitive). // This is how IE seems to filter out a window's onload handler from a // <script for=... event=...> element. @@ -264,36 +264,36 @@ nsScriptLoader::ShouldLoadScript(nsIDocu rv = CheckContentPolicy(aDocument, aContext, aURI, aType, aIsPreLoad); if (NS_FAILED(rv)) { return rv; } return NS_OK; } -class ContextMediator : public nsIStreamLoaderObserver +class ContextMediator : public nsIIncrementalStreamLoaderObserver { public: explicit ContextMediator(nsScriptLoader *aScriptLoader, nsISupports *aContext) : mScriptLoader(aScriptLoader) , mContext(aContext) {} NS_DECL_ISUPPORTS - NS_DECL_NSISTREAMLOADEROBSERVER + NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER private: virtual ~ContextMediator() {} RefPtr<nsScriptLoader> mScriptLoader; nsCOMPtr<nsISupports> mContext; }; -NS_IMPL_ISUPPORTS(ContextMediator, nsIStreamLoaderObserver) +NS_IMPL_ISUPPORTS(ContextMediator, nsIIncrementalStreamLoaderObserver) NS_IMETHODIMP -ContextMediator::OnStreamComplete(nsIStreamLoader* aLoader, +ContextMediator::OnStreamComplete(nsIIncrementalStreamLoader* aLoader, nsISupports* aContext, nsresult aStatus, uint32_t aStringLen, const uint8_t* aString) { // pass arguments through except for the aContext, // we have to mediate and use mContext instead. return mScriptLoader->OnStreamComplete(aLoader, mContext, aStatus, @@ -380,18 +380,18 @@ nsScriptLoader::StartLoad(nsScriptLoadRe // Set the initiator type nsCOMPtr<nsITimedChannel> timedChannel(do_QueryInterface(httpChannel)); if (timedChannel) { timedChannel->SetInitiatorType(NS_LITERAL_STRING("script")); } RefPtr<ContextMediator> mediator = new ContextMediator(this, aRequest); - nsCOMPtr<nsIStreamLoader> loader; - rv = NS_NewStreamLoader(getter_AddRefs(loader), mediator); + nsCOMPtr<nsIIncrementalStreamLoader> loader; + rv = NS_NewIncrementalStreamLoader(getter_AddRefs(loader), mediator); NS_ENSURE_SUCCESS(rv, rv); return channel->AsyncOpen2(loader); } bool nsScriptLoader::PreloadURIComparator::Equals(const PreloadInfo &aPi, nsIURI * const &aURI) const @@ -1434,17 +1434,17 @@ nsScriptLoader::ConvertToUTF16(nsIChanne js_free(aBufOut); aBufOut = nullptr; aLengthOut = 0; } return rv; } NS_IMETHODIMP -nsScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, +nsScriptLoader::OnStreamComplete(nsIIncrementalStreamLoader* aLoader, nsISupports* aContext, nsresult aStatus, uint32_t aStringLen, const uint8_t* aString) { nsScriptLoadRequest* request = static_cast<nsScriptLoadRequest*>(aContext); NS_ASSERTION(request, "null request in stream complete handler"); NS_ENSURE_TRUE(request, NS_ERROR_FAILURE); @@ -1530,17 +1530,17 @@ nsScriptLoader::NumberOfProcessors() int32_t numProcs = PR_GetNumberOfProcessors(); if (numProcs > 0) mNumberOfProcessors = numProcs; return mNumberOfProcessors; } nsresult nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest, - nsIStreamLoader* aLoader, + nsIIncrementalStreamLoader* aLoader, nsresult aStatus, uint32_t aStringLen, const uint8_t* aString) { if (NS_FAILED(aStatus)) { return aStatus; }
--- a/dom/base/nsScriptLoader.h +++ b/dom/base/nsScriptLoader.h @@ -12,17 +12,17 @@ #define __nsScriptLoader_h__ #include "nsCOMPtr.h" #include "nsIScriptElement.h" #include "nsCOMArray.h" #include "nsTArray.h" #include "nsAutoPtr.h" #include "nsIDocument.h" -#include "nsIStreamLoader.h" +#include "nsIIncrementalStreamLoader.h" #include "mozilla/CORSMode.h" #include "mozilla/dom/SRIMetadata.h" #include "mozilla/LinkedList.h" #include "mozilla/net/ReferrerPolicy.h" class nsScriptLoadRequestList; class nsIURI; @@ -190,17 +190,17 @@ public: return Steal(getFirst()); } }; ////////////////////////////////////////////////////////////// // Script loader implementation ////////////////////////////////////////////////////////////// -class nsScriptLoader final : public nsIStreamLoaderObserver +class nsScriptLoader final : public nsIIncrementalStreamLoaderObserver { class MOZ_STACK_CLASS AutoCurrentScriptUpdater { public: AutoCurrentScriptUpdater(nsScriptLoader* aScriptLoader, nsIScriptElement* aCurrentScript) : mOldScript(aScriptLoader->mCurrentScript) , mScriptLoader(aScriptLoader) @@ -218,17 +218,17 @@ class nsScriptLoader final : public nsIS friend class nsScriptRequestProcessor; friend class AutoCurrentScriptUpdater; public: explicit nsScriptLoader(nsIDocument* aDocument); NS_DECL_ISUPPORTS - NS_DECL_NSISTREAMLOADEROBSERVER + NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER /** * The loader maintains a weak reference to the document with * which it is initialized. This call forces the reference to * be dropped. */ void DropDocumentReference() { @@ -484,17 +484,17 @@ private: already_AddRefed<nsIScriptGlobalObject> GetScriptGlobalObject(); void FillCompileOptionsForRequest(const mozilla::dom::AutoJSAPI &jsapi, nsScriptLoadRequest *aRequest, JS::Handle<JSObject *> aScopeChain, JS::CompileOptions *aOptions); uint32_t NumberOfProcessors(); nsresult PrepareLoadedRequest(nsScriptLoadRequest* aRequest, - nsIStreamLoader* aLoader, + nsIIncrementalStreamLoader* aLoader, nsresult aStatus, uint32_t aStringLen, const uint8_t* aString); void AddDeferRequest(nsScriptLoadRequest* aRequest); bool MaybeRemovedDeferRequests(); nsIDocument* mDocument; // [WEAK]
--- a/dom/security/SRICheck.cpp +++ b/dom/security/SRICheck.cpp @@ -11,17 +11,17 @@ #include "mozilla/Preferences.h" #include "nsContentUtils.h" #include "nsIChannel.h" #include "nsICryptoHash.h" #include "nsIDocument.h" #include "nsIProtocolHandler.h" #include "nsIScriptError.h" #include "nsIScriptSecurityManager.h" -#include "nsIStreamLoader.h" +#include "nsIIncrementalStreamLoader.h" #include "nsIUnicharStreamLoader.h" #include "nsIURI.h" #include "nsNetUtil.h" #include "nsWhitespaceTokenizer.h" static mozilla::LogModule* GetSriLog() { @@ -312,17 +312,17 @@ SRICheck::VerifyIntegrity(const SRIMetad return VerifyIntegrityInternal(aMetadata, channel, aCORSMode, utf8Hash.Length(), (uint8_t*)utf8Hash.get(), aDocument); } /* static */ nsresult SRICheck::VerifyIntegrity(const SRIMetadata& aMetadata, - nsIStreamLoader* aLoader, + nsIIncrementalStreamLoader* aLoader, const CORSMode aCORSMode, uint32_t aStringLen, const uint8_t* aString, const nsIDocument* aDocument) { NS_ENSURE_ARG_POINTER(aLoader); nsCOMPtr<nsIRequest> request;
--- a/dom/security/SRICheck.h +++ b/dom/security/SRICheck.h @@ -7,17 +7,17 @@ #ifndef mozilla_dom_SRICheck_h #define mozilla_dom_SRICheck_h #include "mozilla/CORSMode.h" #include "nsCOMPtr.h" #include "SRIMetadata.h" class nsIDocument; -class nsIStreamLoader; +class nsIIncrementalStreamLoader; class nsIUnicharStreamLoader; namespace mozilla { namespace dom { class SRICheck final { public: @@ -42,17 +42,17 @@ public: const nsAString& aString, const nsIDocument* aDocument); /** * Process the integrity attribute of the element. A result of false * must prevent the resource from loading. */ static nsresult VerifyIntegrity(const SRIMetadata& aMetadata, - nsIStreamLoader* aLoader, + nsIIncrementalStreamLoader* aLoader, const CORSMode aCORSMode, uint32_t aStringLen, const uint8_t* aString, const nsIDocument* aDocument); }; } // namespace dom } // namespace mozilla
--- a/dom/xul/XULDocument.h +++ b/dom/xul/XULDocument.h @@ -16,16 +16,17 @@ #include "nsIContent.h" #include "nsIDOMXULCommandDispatcher.h" #include "nsIDOMXULDocument.h" #include "nsCOMArray.h" #include "nsIURI.h" #include "nsIXULDocument.h" #include "nsScriptLoader.h" #include "nsIStreamListener.h" +#include "nsIStreamLoader.h" #include "nsICSSLoaderObserver.h" #include "nsIXULStore.h" #include "mozilla/Attributes.h" #include "js/TracingAPI.h" #include "js/TypeDecls.h"
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp +++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp @@ -234,21 +234,21 @@ EvalScript(JSContext* cx, if (cache && ok && !!script) { WriteCachedScript(StartupCache::GetSingleton(), cachePath, cx, principal, script); } return NS_OK; } -class AsyncScriptLoader : public nsIStreamLoaderObserver +class AsyncScriptLoader : public nsIIncrementalStreamLoaderObserver { public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_NSISTREAMLOADEROBSERVER + NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AsyncScriptLoader) AsyncScriptLoader(nsIChannel* aChannel, bool aReuseGlobal, JSObject* aTargetObj, const nsAString& aCharset, bool aCache, Promise* aPromise) : mChannel(aChannel) , mTargetObj(aTargetObj) @@ -272,17 +272,17 @@ private: nsString mCharset; bool mReuseGlobal; bool mCache; }; NS_IMPL_CYCLE_COLLECTION_CLASS(AsyncScriptLoader) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AsyncScriptLoader) - NS_INTERFACE_MAP_ENTRY(nsIStreamLoaderObserver) + NS_INTERFACE_MAP_ENTRY(nsIIncrementalStreamLoaderObserver) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AsyncScriptLoader) NS_IMPL_CYCLE_COLLECTION_UNLINK(mPromise) tmp->mTargetObj = nullptr; NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AsyncScriptLoader) @@ -321,17 +321,17 @@ class MOZ_STACK_CLASS AutoRejectPromise private: JSContext* mCx; RefPtr<Promise> mPromise; nsCOMPtr<nsIGlobalObject> mGlobalObject; }; NS_IMETHODIMP -AsyncScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, +AsyncScriptLoader::OnStreamComplete(nsIIncrementalStreamLoader* aLoader, nsISupports* aContext, nsresult aStatus, uint32_t aLength, const uint8_t* aBuf) { nsCOMPtr<nsIURI> uri; mChannel->GetURI(getter_AddRefs(uri)); @@ -426,18 +426,18 @@ mozJSSubScriptLoader::ReadScriptAsync(ns RefPtr<AsyncScriptLoader> loadObserver = new AsyncScriptLoader(channel, reuseGlobal, target_obj, charset, cache, promise); - nsCOMPtr<nsIStreamLoader> loader; - rv = NS_NewStreamLoader(getter_AddRefs(loader), loadObserver); + nsCOMPtr<nsIIncrementalStreamLoader> loader; + rv = NS_NewIncrementalStreamLoader(getter_AddRefs(loader), loadObserver); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIStreamListener> listener = loader.get(); return channel->AsyncOpen2(listener); } nsresult mozJSSubScriptLoader::ReadScript(nsIURI* uri, JSContext* cx, JSObject* targetObjArg, @@ -668,21 +668,21 @@ mozJSSubScriptLoader::DoLoadSubScriptWit return EvalScript(cx, targetObj, retval, uri, !!cache, script, function); } /** * Let us compile scripts from a URI off the main thread. */ -class ScriptPrecompiler : public nsIStreamLoaderObserver +class ScriptPrecompiler : public nsIIncrementalStreamLoaderObserver { public: NS_DECL_ISUPPORTS - NS_DECL_NSISTREAMLOADEROBSERVER + NS_DECL_NSIINCREMENTALSTREAMLOADEROBSERVER ScriptPrecompiler(nsIObserver* aObserver, nsIPrincipal* aPrincipal, nsIChannel* aChannel) : mObserver(aObserver) , mPrincipal(aPrincipal) , mChannel(aChannel) , mScriptBuf(nullptr) @@ -704,17 +704,17 @@ private: RefPtr<nsIObserver> mObserver; RefPtr<nsIPrincipal> mPrincipal; RefPtr<nsIChannel> mChannel; char16_t* mScriptBuf; size_t mScriptLength; }; -NS_IMPL_ISUPPORTS(ScriptPrecompiler, nsIStreamLoaderObserver); +NS_IMPL_ISUPPORTS(ScriptPrecompiler, nsIIncrementalStreamLoaderObserver); class NotifyPrecompilationCompleteRunnable : public nsRunnable { public: NS_DECL_NSIRUNNABLE explicit NotifyPrecompilationCompleteRunnable(ScriptPrecompiler* aPrecompiler) : mPrecompiler(aPrecompiler) @@ -765,17 +765,17 @@ NotifyPrecompilationCompleteRunnable::Ru NS_ENSURE_TRUE(rt, NS_ERROR_FAILURE); JS::FinishOffThreadScript(nullptr, rt, mToken); } return NS_OK; } NS_IMETHODIMP -ScriptPrecompiler::OnStreamComplete(nsIStreamLoader* aLoader, +ScriptPrecompiler::OnStreamComplete(nsIIncrementalStreamLoader* aLoader, nsISupports* aContext, nsresult aStatus, uint32_t aLength, const uint8_t* aString) { AutoSendObserverNotification notifier(this); // Just notify that we are done with this load. @@ -871,18 +871,18 @@ mozJSSubScriptLoader::PrecompileScript(n nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, nsIContentPolicy::TYPE_OTHER); NS_ENSURE_SUCCESS(rv, rv); RefPtr<ScriptPrecompiler> loadObserver = new ScriptPrecompiler(aObserver, aPrincipal, channel); - nsCOMPtr<nsIStreamLoader> loader; - rv = NS_NewStreamLoader(getter_AddRefs(loader), loadObserver); + nsCOMPtr<nsIIncrementalStreamLoader> loader; + rv = NS_NewIncrementalStreamLoader(getter_AddRefs(loader), loadObserver); NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr<nsIStreamListener> listener = loader.get(); rv = channel->AsyncOpen2(listener); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; }
--- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -43,16 +43,17 @@ XPIDL_SOURCES += [ 'nsIDownloader.idl', 'nsIEncodedChannel.idl', 'nsIExternalProtocolHandler.idl', 'nsIFileStreams.idl', 'nsIFileURL.idl', 'nsIForcePendingChannel.idl', 'nsIHttpPushListener.idl', 'nsIIncrementalDownload.idl', + 'nsIIncrementalStreamLoader.idl', 'nsIInputStreamChannel.idl', 'nsIInputStreamPump.idl', 'nsIIOService.idl', 'nsIIOService2.idl', 'nsILoadContextInfo.idl', 'nsILoadGroup.idl', 'nsILoadGroupChild.idl', 'nsILoadInfo.idl', @@ -207,16 +208,17 @@ UNIFIED_SOURCES += [ 'nsBaseContentStream.cpp', 'nsBufferedStreams.cpp', 'nsChannelClassifier.cpp', 'nsDirectoryIndexStream.cpp', 'nsDNSPrefetch.cpp', 'nsDownloader.cpp', 'nsFileStreams.cpp', 'nsIncrementalDownload.cpp', + 'nsIncrementalStreamLoader.cpp', 'nsInputStreamChannel.cpp', 'nsInputStreamPump.cpp', 'nsIOService.cpp', 'nsLoadGroup.cpp', 'nsMediaFragmentURIParser.cpp', 'nsMIMEInputStream.cpp', 'nsNetAddr.cpp', 'nsNetUtil.cpp',
new file mode 100644 --- /dev/null +++ b/netwerk/base/nsIIncrementalStreamLoader.idl @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsIStreamListener.idl" + +interface nsIRequest; +interface nsIIncrementalStreamLoader; + +[scriptable, uuid(2143eaad-674e-4613-87f8-359d4c40f590)] +interface nsIIncrementalStreamLoaderObserver : nsISupports +{ + /** + * Called when the entire stream has been loaded. + * + * @param loader the stream loader that loaded the stream. + * @param ctxt the context parameter of the underlying channel + * @param status the status of the underlying channel + * @param resultLength the length of the data loaded + * @param result the data + * + * This method will always be called asynchronously by the + * nsIIncrementalStreamLoader involved, on the thread that called the + * loader's init() method. + * + * If the observer wants to take over responsibility for the + * data buffer (result), it returns NS_SUCCESS_ADOPTED_DATA + * in place of NS_OK as its success code. The loader will then + * "forget" about the data and not free() it after + * onStreamComplete() returns; observer must call free() + * when the data is no longer required. + */ + void onStreamComplete(in nsIIncrementalStreamLoader loader, + in nsISupports ctxt, + in nsresult status, + in unsigned long resultLength, + [const,array,size_is(resultLength)] in octet result); +}; + +/** + * Asynchronously loads a channel into a memory buffer. + * + * To use this interface, first call init() with a nsIIncrementalStreamLoaderObserver + * that will be notified when the data has been loaded. Then call asyncOpen() + * on the channel with the nsIIncrementalStreamLoader as the listener. The context + * argument in the asyncOpen() call will be passed to the onStreamComplete() + * callback. + * + * XXX define behaviour for sizes >4 GB + */ +[scriptable, uuid(a023b060-ba23-431a-b449-2dd63e220554)] +interface nsIIncrementalStreamLoader : nsIStreamListener +{ + /** + * Initialize this stream loader, and start loading the data. + * + * @param aObserver + * An observer that will be notified when the data is complete. + */ + void init(in nsIIncrementalStreamLoaderObserver aObserver); + + /** + * Gets the number of bytes read so far. + */ + readonly attribute unsigned long numBytesRead; + + /** + * Gets the request that loaded this file. + * null after the request has finished loading. + */ + readonly attribute nsIRequest request; +};
new file mode 100644 --- /dev/null +++ b/netwerk/base/nsIncrementalStreamLoader.cpp @@ -0,0 +1,153 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsIncrementalStreamLoader.h" +#include "nsIInputStream.h" +#include "nsIChannel.h" +#include "nsError.h" +#include "GeckoProfiler.h" + +#include <limits> + +nsIncrementalStreamLoader::nsIncrementalStreamLoader() + : mData() +{ +} + +nsIncrementalStreamLoader::~nsIncrementalStreamLoader() +{ +} + +NS_IMETHODIMP +nsIncrementalStreamLoader::Init(nsIIncrementalStreamLoaderObserver* observer) +{ + NS_ENSURE_ARG_POINTER(observer); + mObserver = observer; + return NS_OK; +} + +nsresult +nsIncrementalStreamLoader::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) +{ + if (aOuter) return NS_ERROR_NO_AGGREGATION; + + nsIncrementalStreamLoader* it = new nsIncrementalStreamLoader(); + if (it == nullptr) + return NS_ERROR_OUT_OF_MEMORY; + NS_ADDREF(it); + nsresult rv = it->QueryInterface(aIID, aResult); + NS_RELEASE(it); + return rv; +} + +NS_IMPL_ISUPPORTS(nsIncrementalStreamLoader, nsIIncrementalStreamLoader, + nsIRequestObserver, nsIStreamListener, + nsIThreadRetargetableStreamListener) + +NS_IMETHODIMP +nsIncrementalStreamLoader::GetNumBytesRead(uint32_t* aNumBytes) +{ + *aNumBytes = mData.length(); + return NS_OK; +} + +/* readonly attribute nsIRequest request; */ +NS_IMETHODIMP +nsIncrementalStreamLoader::GetRequest(nsIRequest **aRequest) +{ + NS_IF_ADDREF(*aRequest = mRequest); + return NS_OK; +} + +NS_IMETHODIMP +nsIncrementalStreamLoader::OnStartRequest(nsIRequest* request, nsISupports *ctxt) +{ + nsCOMPtr<nsIChannel> chan( do_QueryInterface(request) ); + if (chan) { + int64_t contentLength = -1; + chan->GetContentLength(&contentLength); + if (contentLength >= 0) { + if (uint64_t(contentLength) > std::numeric_limits<size_t>::max()) { + // Too big to fit into size_t, so let's bail. + return NS_ERROR_OUT_OF_MEMORY; + } + // preallocate buffer + if (!mData.initCapacity(contentLength)) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + } + mContext = ctxt; + return NS_OK; +} + +NS_IMETHODIMP +nsIncrementalStreamLoader::OnStopRequest(nsIRequest* request, nsISupports *ctxt, + nsresult aStatus) +{ + PROFILER_LABEL("nsIncrementalStreamLoader", "OnStopRequest", + js::ProfileEntry::Category::NETWORK); + + if (mObserver) { + // provide nsIIncrementalStreamLoader::request during call to OnStreamComplete + mRequest = request; + size_t length = mData.length(); + uint8_t* elems = mData.extractRawBuffer(); + nsresult rv = mObserver->OnStreamComplete(this, mContext, aStatus, + length, elems); + if (rv != NS_SUCCESS_ADOPTED_DATA) { + // The observer didn't take ownership of the extracted data buffer, so + // put it back into mData. + mData.replaceRawBuffer(elems, length); + } + // done.. cleanup + ReleaseData(); + mRequest = 0; + mObserver = 0; + mContext = 0; + } + return NS_OK; +} + +NS_METHOD +nsIncrementalStreamLoader::WriteSegmentFun(nsIInputStream *inStr, + void *closure, + const char *fromSegment, + uint32_t toOffset, + uint32_t count, + uint32_t *writeCount) +{ + nsIncrementalStreamLoader *self = (nsIncrementalStreamLoader *) closure; + + if (!self->mData.append(fromSegment, count)) { + self->mData.clearAndFree(); + return NS_ERROR_OUT_OF_MEMORY; + } + + *writeCount = count; + + return NS_OK; +} + +NS_IMETHODIMP +nsIncrementalStreamLoader::OnDataAvailable(nsIRequest* request, nsISupports *ctxt, + nsIInputStream *inStr, + uint64_t sourceOffset, uint32_t count) +{ + uint32_t countRead; + return inStr->ReadSegments(WriteSegmentFun, this, count, &countRead); +} + +void +nsIncrementalStreamLoader::ReleaseData() +{ + mData.clearAndFree(); +} + +NS_IMETHODIMP +nsIncrementalStreamLoader::CheckListenerChain() +{ + return NS_OK; +}
new file mode 100644 --- /dev/null +++ b/netwerk/base/nsIncrementalStreamLoader.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef nsIncrementalStreamLoader_h__ +#define nsIncrementalStreamLoader_h__ + +#include "nsIThreadRetargetableStreamListener.h" +#include "nsIIncrementalStreamLoader.h" +#include "nsCOMPtr.h" +#include "mozilla/Attributes.h" +#include "mozilla/Vector.h" + +class nsIRequest; + +class nsIncrementalStreamLoader final : public nsIIncrementalStreamLoader + , public nsIThreadRetargetableStreamListener +{ +public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIINCREMENTALSTREAMLOADER + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER + + nsIncrementalStreamLoader(); + + static nsresult + Create(nsISupports *aOuter, REFNSIID aIID, void **aResult); + +protected: + ~nsIncrementalStreamLoader(); + + static NS_METHOD WriteSegmentFun(nsIInputStream *, void *, const char *, + uint32_t, uint32_t, uint32_t *); + + // Utility method to free mData, if present, and update other state to + // reflect that no data has been allocated. + void ReleaseData(); + + nsCOMPtr<nsIIncrementalStreamLoaderObserver> mObserver; + nsCOMPtr<nsISupports> mContext; // the observer's context + nsCOMPtr<nsIRequest> mRequest; + + // Buffer to accumulate incoming data. We preallocate if contentSize is + // available. + mozilla::Vector<uint8_t, 0> mData; +}; + +#endif // nsIncrementalStreamLoader_h__
--- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -40,16 +40,17 @@ #include "nsIRedirectChannelRegistrar.h" #include "nsIRequestObserverProxy.h" #include "nsIScriptSecurityManager.h" #include "nsISimpleStreamListener.h" #include "nsISocketProvider.h" #include "nsISocketProviderService.h" #include "nsIStandardURL.h" #include "nsIStreamLoader.h" +#include "nsIIncrementalStreamLoader.h" #include "nsIStreamTransportService.h" #include "nsStringStream.h" #include "nsISyncStreamListener.h" #include "nsITransport.h" #include "nsIUnicharStreamLoader.h" #include "nsIURIWithPrincipal.h" #include "nsIURLParser.h" #include "nsIUUIDGenerator.h" @@ -576,16 +577,33 @@ NS_NewDownloader(nsIStreamListener **r if (NS_SUCCEEDED(rv)) { downloader.forget(result); } } return rv; } nsresult +NS_NewIncrementalStreamLoader(nsIIncrementalStreamLoader **result, + nsIIncrementalStreamLoaderObserver *observer) +{ + nsresult rv; + nsCOMPtr<nsIIncrementalStreamLoader> loader = + do_CreateInstance(NS_INCREMENTALSTREAMLOADER_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) { + rv = loader->Init(observer); + if (NS_SUCCEEDED(rv)) { + *result = nullptr; + loader.swap(*result); + } + } + return rv; +} + +nsresult NS_NewStreamLoaderInternal(nsIStreamLoader **outStream, nsIURI *aUri, nsIStreamLoaderObserver *aObserver, nsINode *aLoadingNode, nsIPrincipal *aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup *aLoadGroup /* = nullptr */,
--- a/netwerk/base/nsNetUtil.h +++ b/netwerk/base/nsNetUtil.h @@ -37,16 +37,18 @@ class nsINetworkInterface; class nsIOutputStream; class nsIParentChannel; class nsIPersistentProperties; class nsIProxyInfo; class nsIRequestObserver; class nsIStreamListener; class nsIStreamLoader; class nsIStreamLoaderObserver; +class nsIIncrementalStreamLoader; +class nsIIncrementalStreamLoaderObserver; class nsIUnicharStreamLoader; class nsIUnicharStreamLoaderObserver; namespace mozilla { class NeckoOriginAttributes; } template <class> class nsCOMPtr; template <typename> struct already_AddRefed; @@ -364,16 +366,19 @@ NS_LoadGroupMatchesPrincipal(nsILoadGrou nsresult NS_NewDownloader(nsIStreamListener **result, nsIDownloadObserver *observer, nsIFile *downloadLocation = nullptr); nsresult NS_NewStreamLoader(nsIStreamLoader **result, nsIStreamLoaderObserver *observer, nsIRequestObserver *requestObserver = nullptr); +nsresult NS_NewIncrementalStreamLoader(nsIIncrementalStreamLoader **result, + nsIIncrementalStreamLoaderObserver *observer); + nsresult NS_NewStreamLoaderInternal(nsIStreamLoader **outStream, nsIURI *aUri, nsIStreamLoaderObserver *aObserver, nsINode *aLoadingNode, nsIPrincipal *aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup *aLoadGroup = nullptr,
--- a/netwerk/base/nsNetUtil.inl +++ b/netwerk/base/nsNetUtil.inl @@ -18,16 +18,17 @@ #include "nsIHttpChannel.h" #include "nsIInputStreamChannel.h" #include "nsIIOService.h" #include "nsINestedURI.h" #include "nsINode.h" #include "nsIProtocolHandler.h" #include "nsIStandardURL.h" #include "nsIStreamLoader.h" +#include "nsIIncrementalStreamLoader.h" #include "nsIURI.h" #include "nsIURIWithPrincipal.h" #include "nsIWritablePropertyBag2.h" #include "nsNetCID.h" #include "nsStringStream.h" #ifdef MOZILLA_INTERNAL_API // Don't allow functions that end up in nsNetUtil.cpp to be inlined out.
--- a/netwerk/build/nsNetCID.h +++ b/netwerk/build/nsNetCID.h @@ -221,16 +221,28 @@ #define NS_STREAMLOADER_CID \ { /* 5BA6D920-D4E9-11d3-A1A5-0050041CAF44 */ \ 0x5ba6d920, \ 0xd4e9, \ 0x11d3, \ { 0xa1, 0xa5, 0x0, 0x50, 0x4, 0x1c, 0xaf, 0x44 } \ } +// component implementing nsIStreamLoader. +#define NS_INCREMENTALSTREAMLOADER_CONTRACTID \ + "@mozilla.org/network/incremental-stream-loader;1" +#define NS_INCREMENTALSTREAMLOADER_CID \ +{ /* 5d6352a3-b9c3-4fa3-87aa-b2a3c6e5a501 */ \ + 0x5d6352a3, \ + 0xb9c3, \ + 0x4fa3, \ + {0x87, 0xaa, 0xb2, 0xa3, 0xc6, 0xe5, 0xa5, 0x01} \ +} + + // component implementing nsIUnicharStreamLoader. #define NS_UNICHARSTREAMLOADER_CONTRACTID \ "@mozilla.org/network/unichar-stream-loader;1" #define NS_UNICHARSTREAMLOADER_CID \ { /* 9445791f-fa4c-4669-b174-df5032bb67b3 */ \ 0x9445791f, \ 0xfa4c, \ 0x4669, \
--- a/netwerk/build/nsNetModule.cpp +++ b/netwerk/build/nsNetModule.cpp @@ -16,16 +16,17 @@ #include "nsIServiceManager.h" #include "nsICategoryManager.h" #include "nsSocketProviderService.h" #include "nscore.h" #include "nsSimpleURI.h" #include "nsSimpleNestedURI.h" #include "nsLoadGroup.h" #include "nsStreamLoader.h" +#include "nsIncrementalStreamLoader.h" #include "nsUnicharStreamLoader.h" #include "nsFileStreams.h" #include "nsBufferedStreams.h" #include "nsMIMEInputStream.h" #include "nsSOCKSSocketProvider.h" #include "nsCacheService.h" #include "nsDiskCacheDeviceSQL.h" #include "nsApplicationCache.h" @@ -702,16 +703,17 @@ NS_DEFINE_NAMED_CID(NS_DNSSERVICE_CID); NS_DEFINE_NAMED_CID(NS_IDNSERVICE_CID); NS_DEFINE_NAMED_CID(NS_EFFECTIVETLDSERVICE_CID); NS_DEFINE_NAMED_CID(NS_SIMPLEURI_CID); NS_DEFINE_NAMED_CID(NS_SIMPLENESTEDURI_CID); NS_DEFINE_NAMED_CID(NS_ASYNCSTREAMCOPIER_CID); NS_DEFINE_NAMED_CID(NS_INPUTSTREAMPUMP_CID); NS_DEFINE_NAMED_CID(NS_INPUTSTREAMCHANNEL_CID); NS_DEFINE_NAMED_CID(NS_STREAMLOADER_CID); +NS_DEFINE_NAMED_CID(NS_INCREMENTALSTREAMLOADER_CID); NS_DEFINE_NAMED_CID(NS_UNICHARSTREAMLOADER_CID); NS_DEFINE_NAMED_CID(NS_DOWNLOADER_CID); NS_DEFINE_NAMED_CID(NS_BACKGROUNDFILESAVEROUTPUTSTREAM_CID); NS_DEFINE_NAMED_CID(NS_BACKGROUNDFILESAVERSTREAMLISTENER_CID); NS_DEFINE_NAMED_CID(NS_SYNCSTREAMLISTENER_CID); NS_DEFINE_NAMED_CID(NS_REQUESTOBSERVERPROXY_CID); NS_DEFINE_NAMED_CID(NS_SIMPLESTREAMLISTENER_CID); NS_DEFINE_NAMED_CID(NS_STREAMLISTENERTEE_CID); @@ -849,16 +851,17 @@ static const mozilla::Module::CIDEntry k { &kNS_IDNSERVICE_CID, false, nullptr, nsIDNServiceConstructor }, { &kNS_EFFECTIVETLDSERVICE_CID, false, nullptr, nsEffectiveTLDServiceConstructor }, { &kNS_SIMPLEURI_CID, false, nullptr, nsSimpleURIConstructor }, { &kNS_SIMPLENESTEDURI_CID, false, nullptr, nsSimpleNestedURIConstructor }, { &kNS_ASYNCSTREAMCOPIER_CID, false, nullptr, nsAsyncStreamCopierConstructor }, { &kNS_INPUTSTREAMPUMP_CID, false, nullptr, nsInputStreamPumpConstructor }, { &kNS_INPUTSTREAMCHANNEL_CID, false, nullptr, nsInputStreamChannelConstructor }, { &kNS_STREAMLOADER_CID, false, nullptr, nsStreamLoader::Create }, + { &kNS_INCREMENTALSTREAMLOADER_CID, false, nullptr, nsIncrementalStreamLoader::Create }, { &kNS_UNICHARSTREAMLOADER_CID, false, nullptr, nsUnicharStreamLoader::Create }, { &kNS_DOWNLOADER_CID, false, nullptr, nsDownloaderConstructor }, { &kNS_BACKGROUNDFILESAVEROUTPUTSTREAM_CID, false, nullptr, mozilla::net::BackgroundFileSaverOutputStreamConstructor }, { &kNS_BACKGROUNDFILESAVERSTREAMLISTENER_CID, false, nullptr, mozilla::net::BackgroundFileSaverStreamListenerConstructor }, { &kNS_SYNCSTREAMLISTENER_CID, false, nullptr, nsSyncStreamListenerConstructor }, { &kNS_REQUESTOBSERVERPROXY_CID, false, nullptr, nsRequestObserverProxyConstructor }, @@ -1002,16 +1005,17 @@ static const mozilla::Module::ContractID { NS_DNSSERVICE_CONTRACTID, &kNS_DNSSERVICE_CID }, { NS_IDNSERVICE_CONTRACTID, &kNS_IDNSERVICE_CID }, { NS_EFFECTIVETLDSERVICE_CONTRACTID, &kNS_EFFECTIVETLDSERVICE_CID }, { NS_SIMPLEURI_CONTRACTID, &kNS_SIMPLEURI_CID }, { NS_ASYNCSTREAMCOPIER_CONTRACTID, &kNS_ASYNCSTREAMCOPIER_CID }, { NS_INPUTSTREAMPUMP_CONTRACTID, &kNS_INPUTSTREAMPUMP_CID }, { NS_INPUTSTREAMCHANNEL_CONTRACTID, &kNS_INPUTSTREAMCHANNEL_CID }, { NS_STREAMLOADER_CONTRACTID, &kNS_STREAMLOADER_CID }, + { NS_INCREMENTALSTREAMLOADER_CONTRACTID, &kNS_INCREMENTALSTREAMLOADER_CID }, { NS_UNICHARSTREAMLOADER_CONTRACTID, &kNS_UNICHARSTREAMLOADER_CID }, { NS_DOWNLOADER_CONTRACTID, &kNS_DOWNLOADER_CID }, { NS_BACKGROUNDFILESAVEROUTPUTSTREAM_CONTRACTID, &kNS_BACKGROUNDFILESAVEROUTPUTSTREAM_CID }, { NS_BACKGROUNDFILESAVERSTREAMLISTENER_CONTRACTID, &kNS_BACKGROUNDFILESAVERSTREAMLISTENER_CID }, { NS_SYNCSTREAMLISTENER_CONTRACTID, &kNS_SYNCSTREAMLISTENER_CID }, { NS_REQUESTOBSERVERPROXY_CONTRACTID, &kNS_REQUESTOBSERVERPROXY_CID }, { NS_SIMPLESTREAMLISTENER_CONTRACTID, &kNS_SIMPLESTREAMLISTENER_CID }, { NS_STREAMLISTENERTEE_CONTRACTID, &kNS_STREAMLISTENERTEE_CID },