summaryrefslogtreecommitdiff
path: root/uriloader/base
diff options
context:
space:
mode:
authorPale Moon <git-repo@palemoon.org>2016-09-01 13:39:08 +0200
committerPale Moon <git-repo@palemoon.org>2016-09-01 13:39:08 +0200
commit3d8ce1a11a7347cc94a937719c4bc8df46fb8d14 (patch)
tree8c26ca375a6312751c00a27e1653fb6f189f0463 /uriloader/base
parente449bdb1ec3a82f204bffdd9c3c54069d086eee3 (diff)
downloadpalemoon-gre-3d8ce1a11a7347cc94a937719c4bc8df46fb8d14.tar.gz
Base import of Tycho code (warning: huge commit)
Diffstat (limited to 'uriloader/base')
-rw-r--r--uriloader/base/Makefile.in21
-rw-r--r--uriloader/base/moz.build9
-rw-r--r--uriloader/base/nsDocLoader.cpp454
-rw-r--r--uriloader/base/nsDocLoader.h47
-rw-r--r--uriloader/base/nsITransfer.idl21
-rw-r--r--uriloader/base/nsIURIContentListener.idl6
-rw-r--r--uriloader/base/nsIURILoader.idl10
-rw-r--r--uriloader/base/nsIWebProgress.idl14
-rw-r--r--uriloader/base/nsIWebProgressListener.idl31
-rw-r--r--uriloader/base/nsURILoader.cpp91
-rw-r--r--uriloader/base/nsURILoader.h11
11 files changed, 317 insertions, 398 deletions
diff --git a/uriloader/base/Makefile.in b/uriloader/base/Makefile.in
deleted file mode 100644
index 20676731a..000000000
--- a/uriloader/base/Makefile.in
+++ /dev/null
@@ -1,21 +0,0 @@
-# vim:set noet:
-# 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/.
-
-DEPTH = @DEPTH@
-topsrcdir = @top_srcdir@
-srcdir = @srcdir@
-VPATH = @srcdir@
-
-include $(DEPTH)/config/autoconf.mk
-
-MSVC_ENABLE_PGO := 1
-LIBXUL_LIBRARY = 1
-FAIL_ON_WARNINGS = 1
-
-# we don't want the shared lib, but we want to force the creation of a static lib.
-FORCE_STATIC_LIB = 1
-
-include $(topsrcdir)/config/rules.mk
-
diff --git a/uriloader/base/moz.build b/uriloader/base/moz.build
index 3aad3281d..061389e83 100644
--- a/uriloader/base/moz.build
+++ b/uriloader/base/moz.build
@@ -16,17 +16,20 @@ XPIDL_SOURCES += [
'nsIWebProgressListener2.idl',
]
-MODULE = 'uriloader'
+XPIDL_MODULE = 'uriloader'
EXPORTS += [
'nsDocLoader.h',
'nsURILoader.h',
]
-CPP_SOURCES += [
+UNIFIED_SOURCES += [
'nsDocLoader.cpp',
'nsURILoader.cpp',
]
-LIBRARY_NAME = 'uriloaderbase_s'
+FAIL_ON_WARNINGS = True
+MSVC_ENABLE_PGO = True
+
+FINAL_LIBRARY = 'xul'
diff --git a/uriloader/base/nsDocLoader.cpp b/uriloader/base/nsDocLoader.cpp
index d08bc97e4..8a0e77735 100644
--- a/uriloader/base/nsDocLoader.cpp
+++ b/uriloader/base/nsDocLoader.cpp
@@ -64,14 +64,12 @@ void GetURIStringFromRequest(nsIRequest* request, nsACString &name)
-bool
-nsDocLoader::RequestInfoHashInitEntry(PLDHashTable* table,
- PLDHashEntryHdr* entry,
+void
+nsDocLoader::RequestInfoHashInitEntry(PLDHashEntryHdr* entry,
const void* key)
{
// Initialize the entry with placement new
new (entry) nsRequestInfo(key);
- return true;
}
void
@@ -82,24 +80,20 @@ nsDocLoader::RequestInfoHashClearEntry(PLDHashTable* table,
info->~nsRequestInfo();
}
-struct nsListenerInfo {
- nsListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask)
- : mWeakListener(aListener),
- mNotifyMask(aNotifyMask)
- {
- }
-
- // Weak pointer for the nsIWebProgressListener...
- nsWeakPtr mWeakListener;
-
- // Mask indicating which notifications the listener wants to receive.
- unsigned long mNotifyMask;
+// this is used for mListenerInfoList.Contains()
+template <>
+class nsDefaultComparator <nsDocLoader::nsListenerInfo, nsIWebProgressListener*> {
+ public:
+ bool Equals(const nsDocLoader::nsListenerInfo& aInfo,
+ nsIWebProgressListener* const& aListener) const {
+ nsCOMPtr<nsIWebProgressListener> listener =
+ do_QueryReferent(aInfo.mWeakListener);
+ return aListener == listener;
+ }
};
-
nsDocLoader::nsDocLoader()
: mParent(nullptr),
- mListenerInfoList(8),
mCurrentSelfProgress(0),
mMaxSelfProgress(0),
mCurrentTotalProgress(0),
@@ -116,26 +110,20 @@ nsDocLoader::nsDocLoader()
}
#endif /* PR_LOGGING */
- static PLDHashTableOps hash_table_ops =
+ static const PLDHashTableOps hash_table_ops =
{
- PL_DHashAllocTable,
- PL_DHashFreeTable,
PL_DHashVoidPtrKeyStub,
PL_DHashMatchEntryStub,
PL_DHashMoveEntryStub,
RequestInfoHashClearEntry,
- PL_DHashFinalizeStub,
RequestInfoHashInitEntry
};
- if (!PL_DHashTableInit(&mRequestInfoHash, &hash_table_ops, nullptr,
- sizeof(nsRequestInfo), 16)) {
- mRequestInfoHash.ops = nullptr;
- }
+ PL_DHashTableInit(&mRequestInfoHash, &hash_table_ops, sizeof(nsRequestInfo));
ClearInternalProgress();
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: created.\n", this));
}
@@ -143,20 +131,20 @@ nsresult
nsDocLoader::SetDocLoaderParent(nsDocLoader *aParent)
{
mParent = aParent;
- return NS_OK;
+ return NS_OK;
}
nsresult
nsDocLoader::Init()
{
- if (!mRequestInfoHash.ops) {
+ if (!mRequestInfoHash.IsInitialized()) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult rv = NS_NewLoadGroup(getter_AddRefs(mLoadGroup), this);
if (NS_FAILED(rv)) return rv;
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: load group %x.\n", this, mLoadGroup.get()));
return NS_OK;
@@ -182,7 +170,7 @@ nsDocLoader::~nsDocLoader()
PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: deleted.\n", this));
- if (mRequestInfoHash.ops) {
+ if (mRequestInfoHash.IsInitialized()) {
PL_DHashTableFinish(&mRequestInfoHash);
}
}
@@ -200,7 +188,7 @@ NS_INTERFACE_MAP_BEGIN(nsDocLoader)
NS_INTERFACE_MAP_ENTRY(nsIDocumentLoader)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY(nsIWebProgress)
- NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
+ NS_INTERFACE_MAP_ENTRY(nsIProgressEventSink)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
NS_INTERFACE_MAP_ENTRY(nsISecurityEventSink)
@@ -259,7 +247,7 @@ nsDocLoader::Stop(void)
{
nsresult rv = NS_OK;
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: Stop() called\n", this));
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mChildList, nsDocLoader, Stop, ());
@@ -289,9 +277,9 @@ nsDocLoader::Stop(void)
NS_ASSERTION(!IsBusy(), "Shouldn't be busy here");
DocLoaderIsEmpty(false);
-
+
return rv;
-}
+}
bool
@@ -317,7 +305,7 @@ nsDocLoader::IsBusy()
if (!mIsLoadingDocument) {
return false;
}
-
+
bool busy;
rv = mLoadGroup->IsPending(&busy);
if (NS_FAILED(rv)) {
@@ -369,7 +357,7 @@ nsDocLoader::Destroy()
Stop();
// Remove the document loader from the parent list of loaders...
- if (mParent)
+ if (mParent)
{
mParent->RemoveChildLoader(this);
}
@@ -377,15 +365,6 @@ nsDocLoader::Destroy()
// Release all the information about network requests...
ClearRequestInfoHash();
- // Release all the information about registered listeners...
- int32_t count = mListenerInfoList.Count();
- for(int32_t i = 0; i < count; i++) {
- nsListenerInfo *info =
- static_cast<nsListenerInfo*>(mListenerInfoList.ElementAt(i));
-
- delete info;
- }
-
mListenerInfoList.Clear();
mListenerInfoList.Compact();
@@ -472,7 +451,7 @@ nsDocLoader::OnStartRequest(nsIRequest *request, nsISupports *aCtxt)
// This request is associated with the entire document...
mDocumentRequest = request;
- mLoadGroup->SetDefaultLoadRequest(request);
+ mLoadGroup->SetDefaultLoadRequest(request);
// Only fire the start document load notification for the first
// document URI... Do not fire it again for redirections
@@ -485,7 +464,7 @@ nsDocLoader::OnStartRequest(nsIRequest *request, nsISupports *aCtxt)
doStartDocumentLoad();
return NS_OK;
}
- }
+ }
}
NS_ASSERTION(!mIsLoadingDocument || mDocumentRequest,
@@ -497,7 +476,7 @@ nsDocLoader::OnStartRequest(nsIRequest *request, nsISupports *aCtxt)
}
NS_IMETHODIMP
-nsDocLoader::OnStopRequest(nsIRequest *aRequest,
+nsDocLoader::OnStopRequest(nsIRequest *aRequest,
nsISupports *aCtxt,
nsresult aStatus)
{
@@ -538,7 +517,7 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest,
int64_t oldMax = info->mMaxProgress;
info->mMaxProgress = info->mCurrentProgress;
-
+
//
// If a request whose content-length was previously unknown has just
// finished loading, then use this new data to try to calculate a
@@ -552,7 +531,7 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest,
// of CalculateMaxProgress() result. We need to remove the info from the
// hash, see bug 480713.
mCompletedTotalProgress += info->mMaxProgress;
-
+
//
// Determine whether a STATE_TRANSFERRING notification should be
// 'synthesized'.
@@ -606,7 +585,7 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest,
if (bFireTransferring) {
// Send a STATE_TRANSFERRING notification for the request.
int32_t flags;
-
+
flags = nsIWebProgressListener::STATE_TRANSFERRING |
nsIWebProgressListener::STATE_IS_REQUEST;
//
@@ -626,11 +605,11 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest,
// Fire the OnStateChange(...) notification for stop request
//
doStopURLLoad(aRequest, aStatus);
-
+
// Clear this request out of the hash to avoid bypass of FireOnStateChange
// when address of the request is reused.
RemoveRequestInfo(aRequest);
-
+
//
// Only fire the DocLoaderIsEmpty(...) if the document loader has initiated a
// load. This will handle removing the request from our hashtable as needed.
@@ -638,7 +617,7 @@ nsDocLoader::OnStopRequest(nsIRequest *aRequest,
if (mIsLoadingDocument) {
DocLoaderIsEmpty(true);
}
-
+
return NS_OK;
}
@@ -667,7 +646,7 @@ NS_IMETHODIMP nsDocLoader::GetDocumentChannel(nsIChannel ** aChannel)
*aChannel = nullptr;
return NS_OK;
}
-
+
return CallQueryInterface(mDocumentRequest, aChannel);
}
@@ -718,7 +697,7 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout)
// we don't need it anymore to CalculateMaxProgress().
ClearInternalProgress();
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: Is now idle...\n", this));
nsCOMPtr<nsIRequest> docRequest = mDocumentRequest;
@@ -731,14 +710,14 @@ void nsDocLoader::DocLoaderIsEmpty(bool aFlushLayout)
mProgressStateFlags = nsIWebProgressListener::STATE_STOP;
- nsresult loadGroupStatus = NS_OK;
+ nsresult loadGroupStatus = NS_OK;
mLoadGroup->GetStatus(&loadGroupStatus);
- //
- // New code to break the circular reference between
- // the load group and the docloader...
- //
- mLoadGroup->SetDefaultLoadRequest(nullptr);
+ //
+ // New code to break the circular reference between
+ // the load group and the docloader...
+ //
+ mLoadGroup->SetDefaultLoadRequest(nullptr);
// Take a ref to our parent now so that we can call DocLoaderIsEmpty() on
// it even if our onload handler removes us from the docloader tree.
@@ -769,7 +748,7 @@ void nsDocLoader::doStartDocumentLoad(void)
nsAutoCString buffer;
GetURIStringFromRequest(mDocumentRequest, buffer);
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: ++ Firing OnStateChange for start document load (...)."
"\tURI: %s \n",
this, buffer.get()));
@@ -794,7 +773,7 @@ void nsDocLoader::doStartURLLoad(nsIRequest *request)
nsAutoCString buffer;
GetURIStringFromRequest(request, buffer);
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: ++ Firing OnStateChange start url load (...)."
"\tURI: %s\n",
this, buffer.get()));
@@ -813,7 +792,7 @@ void nsDocLoader::doStopURLLoad(nsIRequest *request, nsresult aStatus)
nsAutoCString buffer;
GetURIStringFromRequest(request, buffer);
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: ++ Firing OnStateChange for end url load (...)."
"\tURI: %s status=%x\n",
this, buffer.get(), aStatus));
@@ -842,7 +821,7 @@ void nsDocLoader::doStopDocumentLoad(nsIRequest *request,
nsAutoCString buffer;
GetURIStringFromRequest(request, buffer);
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: ++ Firing OnStateChange for end document load (...)."
"\tURI: %s Status=%x\n",
this, buffer.get(), aStatus));
@@ -854,7 +833,7 @@ void nsDocLoader::doStopDocumentLoad(nsIRequest *request,
// the onload handlers rearrange the docshell tree.
WebProgressList list;
GatherAncestorWebProgresses(list);
-
+
//
// Fire an OnStateChange(...) notification indicating the the
// current document has finished loading...
@@ -883,12 +862,9 @@ void nsDocLoader::doStopDocumentLoad(nsIRequest *request,
NS_IMETHODIMP
nsDocLoader::AddProgressListener(nsIWebProgressListener *aListener,
- uint32_t aNotifyMask)
+ uint32_t aNotifyMask)
{
- nsresult rv;
-
- nsListenerInfo* info = GetListenerInfo(aListener);
- if (info) {
+ if (mListenerInfoList.Contains(aListener)) {
// The listener is already registered!
return NS_ERROR_FAILURE;
}
@@ -898,29 +874,14 @@ nsDocLoader::AddProgressListener(nsIWebProgressListener *aListener,
return NS_ERROR_INVALID_ARG;
}
- info = new nsListenerInfo(listener, aNotifyMask);
- if (!info) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- rv = mListenerInfoList.AppendElement(info) ? NS_OK : NS_ERROR_FAILURE;
- return rv;
+ return mListenerInfoList.AppendElement(nsListenerInfo(listener, aNotifyMask)) ?
+ NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP
nsDocLoader::RemoveProgressListener(nsIWebProgressListener *aListener)
{
- nsresult rv;
-
- nsListenerInfo* info = GetListenerInfo(aListener);
- if (info) {
- rv = mListenerInfoList.RemoveElement(info) ? NS_OK : NS_ERROR_FAILURE;
- delete info;
- } else {
- // The listener is not registered!
- rv = NS_ERROR_FAILURE;
- }
- return rv;
+ return mListenerInfoList.RemoveElement(aListener) ? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
@@ -975,13 +936,21 @@ nsDocLoader::GetIsLoadingDocument(bool *aIsLoadingDocument)
return NS_OK;
}
+NS_IMETHODIMP
+nsDocLoader::GetLoadType(uint32_t *aLoadType)
+{
+ *aLoadType = 0;
+
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
int64_t nsDocLoader::GetMaxTotalProgress()
{
int64_t newMaxTotal = 0;
uint32_t count = mChildList.Length();
nsCOMPtr<nsIWebProgress> webProgress;
- for (uint32_t i=0; i < count; i++)
+ for (uint32_t i=0; i < count; i++)
{
int64_t individualProgress = 0;
nsIDocumentLoader* docloader = ChildAt(i);
@@ -1003,18 +972,18 @@ int64_t nsDocLoader::GetMaxTotalProgress()
int64_t progress = -1;
if (mMaxSelfProgress >= int64_t(0) && newMaxTotal >= int64_t(0))
progress = newMaxTotal + mMaxSelfProgress;
-
+
return progress;
}
////////////////////////////////////////////////////////////////////////////////////
-// The following section contains support for nsIProgressEventSink which is used to
+// The following section contains support for nsIProgressEventSink which is used to
// pass progress and status between the actual request and the doc loader. The doc loader
// then turns around and makes the right web progress calls based on this information.
////////////////////////////////////////////////////////////////////////////////////
-NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt,
- uint64_t aProgress, uint64_t aProgressMax)
+NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt,
+ int64_t aProgress, int64_t aProgressMax)
{
int64_t progressDelta = 0;
@@ -1025,8 +994,8 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt,
// Update info->mCurrentProgress before we call FireOnStateChange,
// since that can make the "info" pointer invalid.
int64_t oldCurrentProgress = info->mCurrentProgress;
- progressDelta = int64_t(aProgress) - oldCurrentProgress;
- info->mCurrentProgress = int64_t(aProgress);
+ progressDelta = aProgress - oldCurrentProgress;
+ info->mCurrentProgress = aProgress;
// suppress sending STATE_TRANSFERRING if this is upload progress (see bug 240053)
if (!info->mUploading && (int64_t(0) == oldCurrentProgress) && (int64_t(0) == info->mMaxProgress)) {
@@ -1039,20 +1008,20 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt,
nsLoadFlags lf = 0;
aRequest->GetLoadFlags(&lf);
if ((lf & nsIChannel::LOAD_DOCUMENT_URI) && !(lf & nsIChannel::LOAD_TARGETED)) {
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p Ignoring OnProgress while load is not targeted\n", this));
return NS_OK;
}
//
// This is the first progress notification for the entry. If
- // (aMaxProgress > 0) then the content-length of the data is known,
+ // (aMaxProgress != -1) then the content-length of the data is known,
// so update mMaxSelfProgress... Otherwise, set it to -1 to indicate
// that the content-length is no longer known.
//
- if (uint64_t(aProgressMax) != UINT64_MAX) {
- mMaxSelfProgress += int64_t(aProgressMax);
- info->mMaxProgress = int64_t(aProgressMax);
+ if (aProgressMax != -1) {
+ mMaxSelfProgress += aProgressMax;
+ info->mMaxProgress = aProgressMax;
} else {
mMaxSelfProgress = int64_t(-1);
info->mMaxProgress = int64_t(-1);
@@ -1060,8 +1029,8 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt,
// Send a STATE_TRANSFERRING notification for the request.
int32_t flags;
-
- flags = nsIWebProgressListener::STATE_TRANSFERRING |
+
+ flags = nsIWebProgressListener::STATE_TRANSFERRING |
nsIWebProgressListener::STATE_IS_REQUEST;
//
// Move the WebProgress into the STATE_TRANSFERRING state if necessary...
@@ -1088,7 +1057,7 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt,
nsAutoCString buffer;
GetURIStringFromRequest(aRequest, buffer);
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p OOPS - No Request Info for: %s\n",
this, buffer.get()));
#endif /* DEBUG */
@@ -1105,8 +1074,8 @@ NS_IMETHODIMP nsDocLoader::OnProgress(nsIRequest *aRequest, nsISupports* ctxt,
return NS_OK;
}
-NS_IMETHODIMP nsDocLoader::OnStatus(nsIRequest* aRequest, nsISupports* ctxt,
- nsresult aStatus, const PRUnichar* aStatusArg)
+NS_IMETHODIMP nsDocLoader::OnStatus(nsIRequest* aRequest, nsISupports* ctxt,
+ nsresult aStatus, const char16_t* aStatusArg)
{
//
// Fire progress notifications out to any registered nsIWebProgressListeners
@@ -1175,6 +1144,28 @@ void nsDocLoader::ClearInternalProgress()
mProgressStateFlags = nsIWebProgressListener::STATE_STOP;
}
+/**
+ * |_code| is executed for every listener matching |_flag|
+ * |listener| should be used inside |_code| as the nsIWebProgressListener var.
+ */
+#define NOTIFY_LISTENERS(_flag, _code) \
+PR_BEGIN_MACRO \
+ nsCOMPtr<nsIWebProgressListener> listener; \
+ ListenerArray::BackwardIterator iter(mListenerInfoList); \
+ while (iter.HasMore()) { \
+ nsListenerInfo &info = iter.GetNext(); \
+ if (!(info.mNotifyMask & (_flag))) { \
+ continue; \
+ } \
+ listener = do_QueryReferent(info.mWeakListener); \
+ if (!listener) { \
+ iter.Remove(); \
+ continue; \
+ } \
+ _code \
+ } \
+ mListenerInfoList.Compact(); \
+PR_END_MACRO
void nsDocLoader::FireOnProgressChange(nsDocLoader *aLoadInitiator,
nsIRequest *request,
@@ -1196,43 +1187,17 @@ void nsDocLoader::FireOnProgressChange(nsDocLoader *aLoadInitiator,
nsAutoCString buffer;
GetURIStringFromRequest(request, buffer);
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: Progress (%s): curSelf: %d maxSelf: %d curTotal: %d maxTotal %d\n",
this, buffer.get(), aProgress, aProgressMax, aTotalProgress, aMaxTotalProgress));
#endif /* DEBUG */
- /*
- * First notify any listeners of the new progress info...
- *
- * Operate the elements from back to front so that if items get
- * get removed from the list it won't affect our iteration
- */
- nsCOMPtr<nsIWebProgressListener> listener;
- int32_t count = mListenerInfoList.Count();
-
- while (--count >= 0) {
- nsListenerInfo *info;
-
- info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
- if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_PROGRESS)) {
- continue;
- }
-
- listener = do_QueryReferent(info->mWeakListener);
- if (!listener) {
- // the listener went away. gracefully pull it out of the list.
- mListenerInfoList.RemoveElementAt(count);
- delete info;
- continue;
- }
-
+ NOTIFY_LISTENERS(nsIWebProgress::NOTIFY_PROGRESS,
// XXX truncates 64-bit to 32-bit
listener->OnProgressChange(aLoadInitiator,request,
int32_t(aProgress), int32_t(aProgressMax),
int32_t(aTotalProgress), int32_t(aMaxTotalProgress));
- }
-
- mListenerInfoList.Compact();
+ );
// Pass the notification up to the parent...
if (mParent) {
@@ -1275,7 +1240,7 @@ void nsDocLoader::DoFireOnStateChange(nsIWebProgress * const aProgress,
// active...
//
if (mIsLoadingDocument &&
- (aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK) &&
+ (aStateFlags & nsIWebProgressListener::STATE_IS_NETWORK) &&
(this != aProgress)) {
aStateFlags &= ~nsIWebProgressListener::STATE_IS_NETWORK;
}
@@ -1288,43 +1253,16 @@ void nsDocLoader::DoFireOnStateChange(nsIWebProgress * const aProgress,
nsAutoCString buffer;
GetURIStringFromRequest(aRequest, buffer);
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: Status (%s): code: %x\n",
this, buffer.get(), aStateFlags));
#endif /* DEBUG */
NS_ASSERTION(aRequest, "Firing OnStateChange(...) notification with a NULL request!");
- /*
- * First notify any listeners of the new state info...
- *
- * Operate the elements from back to front so that if items get
- * get removed from the list it won't affect our iteration
- */
- nsCOMPtr<nsIWebProgressListener> listener;
- int32_t count = mListenerInfoList.Count();
- int32_t notifyMask = (aStateFlags >> 16) & nsIWebProgress::NOTIFY_STATE_ALL;
-
- while (--count >= 0) {
- nsListenerInfo *info;
-
- info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
- if (!info || !(info->mNotifyMask & notifyMask)) {
- continue;
- }
-
- listener = do_QueryReferent(info->mWeakListener);
- if (!listener) {
- // the listener went away. gracefully pull it out of the list.
- mListenerInfoList.RemoveElementAt(count);
- delete info;
- continue;
- }
-
+ NOTIFY_LISTENERS(((aStateFlags >> 16) & nsIWebProgress::NOTIFY_STATE_ALL),
listener->OnStateChange(aProgress, aRequest, aStateFlags, aStatus);
- }
-
- mListenerInfoList.Compact();
+ );
}
@@ -1335,36 +1273,10 @@ nsDocLoader::FireOnLocationChange(nsIWebProgress* aWebProgress,
nsIURI *aUri,
uint32_t aFlags)
{
- /*
- * First notify any listeners of the new state info...
- *
- * Operate the elements from back to front so that if items get
- * get removed from the list it won't affect our iteration
- */
- nsCOMPtr<nsIWebProgressListener> listener;
- int32_t count = mListenerInfoList.Count();
-
- while (--count >= 0) {
- nsListenerInfo *info;
-
- info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
- if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_LOCATION)) {
- continue;
- }
-
- listener = do_QueryReferent(info->mWeakListener);
- if (!listener) {
- // the listener went away. gracefully pull it out of the list.
- mListenerInfoList.RemoveElementAt(count);
- delete info;
- continue;
- }
-
+ NOTIFY_LISTENERS(nsIWebProgress::NOTIFY_LOCATION,
PR_LOG(gDocLoaderLog, PR_LOG_DEBUG, ("DocLoader [%p] calling %p->OnLocationChange", this, listener.get()));
listener->OnLocationChange(aWebProgress, aRequest, aUri, aFlags);
- }
-
- mListenerInfoList.Compact();
+ );
// Pass the notification up to the parent...
if (mParent) {
@@ -1376,37 +1288,12 @@ void
nsDocLoader::FireOnStatusChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
nsresult aStatus,
- const PRUnichar* aMessage)
+ const char16_t* aMessage)
{
- /*
- * First notify any listeners of the new state info...
- *
- * Operate the elements from back to front so that if items get
- * get removed from the list it won't affect our iteration
- */
- nsCOMPtr<nsIWebProgressListener> listener;
- int32_t count = mListenerInfoList.Count();
-
- while (--count >= 0) {
- nsListenerInfo *info;
-
- info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
- if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_STATUS)) {
- continue;
- }
-
- listener = do_QueryReferent(info->mWeakListener);
- if (!listener) {
- // the listener went away. gracefully pull it out of the list.
- mListenerInfoList.RemoveElementAt(count);
- delete info;
- continue;
- }
-
+ NOTIFY_LISTENERS(nsIWebProgress::NOTIFY_STATUS,
listener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
- }
- mListenerInfoList.Compact();
-
+ );
+
// Pass the notification up to the parent...
if (mParent) {
mParent->FireOnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
@@ -1422,34 +1309,12 @@ nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress,
/*
* Returns true if the refresh may proceed,
* false if the refresh should be blocked.
- *
- * First notify any listeners of the refresh attempt...
- *
- * Iterate the elements from back to front so that if items
- * get removed from the list it won't affect our iteration
*/
bool allowRefresh = true;
- int32_t count = mListenerInfoList.Count();
-
- while (--count >= 0) {
- nsListenerInfo *info;
-
- info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
- if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_REFRESH)) {
- continue;
- }
-
- nsCOMPtr<nsIWebProgressListener> listener =
- do_QueryReferent(info->mWeakListener);
- if (!listener) {
- // the listener went away. gracefully pull it out of the list.
- mListenerInfoList.RemoveElementAt(count);
- delete info;
- continue;
- }
+ NOTIFY_LISTENERS(nsIWebProgress::NOTIFY_REFRESH,
nsCOMPtr<nsIWebProgressListener2> listener2 =
- do_QueryReferent(info->mWeakListener);
+ do_QueryReferent(info.mWeakListener);
if (!listener2)
continue;
@@ -1460,9 +1325,7 @@ nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress,
continue;
allowRefresh = allowRefresh && listenerAllowedRefresh;
- }
-
- mListenerInfoList.Compact();
+ );
// Pass the notification up to the parent...
if (mParent) {
@@ -1473,30 +1336,9 @@ nsDocLoader::RefreshAttempted(nsIWebProgress* aWebProgress,
return allowRefresh;
}
-nsListenerInfo *
-nsDocLoader::GetListenerInfo(nsIWebProgressListener *aListener)
-{
- int32_t i, count;
- nsListenerInfo *info;
-
- nsCOMPtr<nsISupports> listener1 = do_QueryInterface(aListener);
- count = mListenerInfoList.Count();
- for (i=0; i<count; i++) {
- info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(i));
-
- NS_ASSERTION(info, "There should NEVER be a null listener in the list");
- if (info) {
- nsCOMPtr<nsISupports> listener2 = do_QueryReferent(info->mWeakListener);
- if (listener1 == listener2)
- return info;
- }
- }
- return nullptr;
-}
-
nsresult nsDocLoader::AddRequestInfo(nsIRequest *aRequest)
{
- if (!PL_DHashTableOperate(&mRequestInfoHash, aRequest, PL_DHASH_ADD)) {
+ if (!PL_DHashTableAdd(&mRequestInfoHash, aRequest, mozilla::fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
@@ -1505,25 +1347,13 @@ nsresult nsDocLoader::AddRequestInfo(nsIRequest *aRequest)
void nsDocLoader::RemoveRequestInfo(nsIRequest *aRequest)
{
- PL_DHashTableOperate(&mRequestInfoHash, aRequest, PL_DHASH_REMOVE);
+ PL_DHashTableRemove(&mRequestInfoHash, aRequest);
}
nsDocLoader::nsRequestInfo* nsDocLoader::GetRequestInfo(nsIRequest* aRequest)
{
- nsRequestInfo* info =
- static_cast<nsRequestInfo*>
- (PL_DHashTableOperate(&mRequestInfoHash, aRequest,
- PL_DHASH_LOOKUP));
-
- if (PL_DHASH_ENTRY_IS_FREE(info)) {
- // Nothing found in the hash, return null.
-
- return nullptr;
- }
-
- // Return what we found in the hash...
-
- return info;
+ return static_cast<nsRequestInfo*>
+ (PL_DHashTableSearch(&mRequestInfoHash, aRequest));
}
// PLDHashTable enumeration callback that just removes every entry
@@ -1537,7 +1367,7 @@ RemoveInfoCallback(PLDHashTable *table, PLDHashEntryHdr *hdr, uint32_t number,
void nsDocLoader::ClearRequestInfoHash(void)
{
- if (!mRequestInfoHash.ops || !mRequestInfoHash.entryCount) {
+ if (!mRequestInfoHash.IsInitialized() || !mRequestInfoHash.EntryCount()) {
// No hash, or the hash is empty, nothing to do here then...
return;
@@ -1612,41 +1442,15 @@ NS_IMETHODIMP nsDocLoader::OnSecurityChange(nsISupports * aContext,
uint32_t aState)
{
//
- // Fire progress notifications out to any registered nsIWebProgressListeners.
+ // Fire progress notifications out to any registered nsIWebProgressListeners.
//
-
+
nsCOMPtr<nsIRequest> request = do_QueryInterface(aContext);
nsIWebProgress* webProgress = static_cast<nsIWebProgress*>(this);
- /*
- * First notify any listeners of the new state info...
- *
- * Operate the elements from back to front so that if items get
- * get removed from the list it won't affect our iteration
- */
- nsCOMPtr<nsIWebProgressListener> listener;
- int32_t count = mListenerInfoList.Count();
-
- while (--count >= 0) {
- nsListenerInfo *info;
-
- info = static_cast<nsListenerInfo*>(mListenerInfoList.SafeElementAt(count));
- if (!info || !(info->mNotifyMask & nsIWebProgress::NOTIFY_SECURITY)) {
- continue;
- }
-
- listener = do_QueryReferent(info->mWeakListener);
- if (!listener) {
- // the listener went away. gracefully pull it out of the list.
- mListenerInfoList.RemoveElementAt(count);
- delete info;
- continue;
- }
-
+ NOTIFY_LISTENERS(nsIWebProgress::NOTIFY_SECURITY,
listener->OnSecurityChange(webProgress, request, aState);
- }
-
- mListenerInfoList.Compact();
+ );
// Pass the notification up to the parent...
if (mParent) {
@@ -1661,7 +1465,7 @@ NS_IMETHODIMP nsDocLoader::OnSecurityChange(nsISupports * aContext,
* The priority of the DocLoader _is_ the priority of its LoadGroup.
*
* XXX(darin): Once we start storing loadgroups in loadgroups, this code will
- * go away.
+ * go away.
*/
NS_IMETHODIMP nsDocLoader::GetPriority(int32_t *aPriority)
@@ -1676,7 +1480,7 @@ NS_IMETHODIMP nsDocLoader::GetPriority(int32_t *aPriority)
NS_IMETHODIMP nsDocLoader::SetPriority(int32_t aPriority)
{
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: SetPriority(%d) called\n", this, aPriority));
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mLoadGroup);
@@ -1691,7 +1495,7 @@ NS_IMETHODIMP nsDocLoader::SetPriority(int32_t aPriority)
NS_IMETHODIMP nsDocLoader::AdjustPriority(int32_t aDelta)
{
- PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
+ PR_LOG(gDocLoaderLog, PR_LOG_DEBUG,
("DocLoader:%p: AdjustPriority(%d) called\n", this, aDelta));
nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mLoadGroup);
@@ -1714,7 +1518,7 @@ void nsDocLoader::DumpChannelInfo()
int32_t i, count;
int32_t current=0, max=0;
-
+
printf("==== DocLoader=%x\n", this);
count = mChannelInfoList.Count();
@@ -1729,7 +1533,7 @@ void nsDocLoader::DumpChannelInfo()
}
printf(" [%d] current=%d max=%d [%s]\n", i,
- info->mCurrentProgress,
+ info->mCurrentProgress,
info->mMaxProgress, buffer.get());
#endif /* DEBUG */
diff --git a/uriloader/base/nsDocLoader.h b/uriloader/base/nsDocLoader.h
index 06ee1423b..011d2fdc6 100644
--- a/uriloader/base/nsDocLoader.h
+++ b/uriloader/base/nsDocLoader.h
@@ -3,7 +3,7 @@
* 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 nsDocLoader_h__
@@ -17,7 +17,6 @@
#include "nsILoadGroup.h"
#include "nsCOMArray.h"
#include "nsTObserverArray.h"
-#include "nsVoidArray.h"
#include "nsString.h"
#include "nsIChannel.h"
#include "nsIProgressEventSink.h"
@@ -32,8 +31,6 @@
#include "mozilla/LinkedList.h"
-struct nsListenerInfo;
-
/****************************************************************************
* nsDocLoader implementation...
****************************************************************************/
@@ -46,7 +43,7 @@ struct nsListenerInfo;
{0x93, 0xb6, 0x6d, 0x23, 0x06, 0x9c, 0x06, 0xf2} \
}
-class nsDocLoader : public nsIDocumentLoader,
+class nsDocLoader : public nsIDocumentLoader,
public nsIRequestObserver,
public nsSupportsWeakReference,
public nsIProgressEventSink,
@@ -74,7 +71,7 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOCUMENTLOADER
-
+
// nsIProgressEventSink
NS_DECL_NSIPROGRESSEVENTSINK
@@ -98,6 +95,20 @@ public:
nsresult AddChildLoader(nsDocLoader* aChild);
nsDocLoader* GetParent() const { return mParent; }
+ struct nsListenerInfo {
+ nsListenerInfo(nsIWeakReference *aListener, unsigned long aNotifyMask)
+ : mWeakListener(aListener),
+ mNotifyMask(aNotifyMask)
+ {
+ }
+
+ // Weak pointer for the nsIWebProgressListener...
+ nsWeakPtr mWeakListener;
+
+ // Mask indicating which notifications the listener wants to receive.
+ unsigned long mNotifyMask;
+ };
+
protected:
virtual ~nsDocLoader();
@@ -146,7 +157,7 @@ protected:
void FireOnStatusChange(nsIWebProgress *aWebProgress,
nsIRequest *aRequest,
nsresult aStatus,
- const PRUnichar* aMessage);
+ const char16_t* aMessage);
void FireOnLocationChange(nsIWebProgress* aWebProgress,
nsIRequest* aRequest,
@@ -188,7 +199,7 @@ protected:
void ChildDoneWithOnload(nsIDocumentLoader* aChild) {
mChildrenInOnload.RemoveObject(aChild);
DocLoaderIsEmpty(true);
- }
+ }
protected:
struct nsStatusInfo : public mozilla::LinkedListElement<nsStatusInfo>
@@ -198,7 +209,7 @@ protected:
// Weak mRequest is ok; we'll be told if it decides to go away.
nsIRequest * const mRequest;
- nsStatusInfo(nsIRequest* aRequest) :
+ explicit nsStatusInfo(nsIRequest* aRequest) :
mRequest(aRequest)
{
MOZ_COUNT_CTOR(nsStatusInfo);
@@ -211,7 +222,7 @@ protected:
struct nsRequestInfo : public PLDHashEntryHdr
{
- nsRequestInfo(const void* key)
+ explicit nsRequestInfo(const void* key)
: mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(false)
, mLastStatus(nullptr)
{
@@ -235,8 +246,7 @@ protected:
nsAutoPtr<nsStatusInfo> mLastStatus;
};
- static bool RequestInfoHashInitEntry(PLDHashTable* table, PLDHashEntryHdr* entry,
- const void* key);
+ static void RequestInfoHashInitEntry(PLDHashEntryHdr* entry, const void* key);
static void RequestInfoHashClearEntry(PLDHashTable* table, PLDHashEntryHdr* entry);
// IMPORTANT: The ownership implicit in the following member
@@ -244,18 +254,19 @@ protected:
// for owning pointers and raw COM interface pointers for weak
// (ie, non owning) references. If you add any members to this
// class, please make the ownership explicit (pinkerton, scc).
-
+
nsCOMPtr<nsIRequest> mDocumentRequest; // [OWNER] ???compare with document
nsDocLoader* mParent; // [WEAK]
- nsVoidArray mListenerInfoList;
+ typedef nsAutoTObserverArray<nsListenerInfo, 8> ListenerArray;
+ ListenerArray mListenerInfoList;
nsCOMPtr<nsILoadGroup> mLoadGroup;
// We hold weak refs to all our kids
nsTObserverArray<nsDocLoader*> mChildList;
- // The following member variables are related to the new nsIWebProgress
+ // The following member variables are related to the new nsIWebProgress
// feedback interfaces that travis cooked up.
int32_t mProgressStateFlags;
@@ -296,7 +307,7 @@ private:
// DocLoaderIsEmpty calls (those coming from requests finishing in our
// loadgroup) unless this is empty.
nsCOMArray<nsIDocumentLoader> mChildrenInOnload;
-
+
// DocLoaderIsEmpty should be called whenever the docloader may be empty.
// This method is idempotent and does nothing if the docloader is not in
// fact empty. This method _does_ make sure that layout is flushed if our
@@ -304,8 +315,6 @@ private:
// aFlushLayout is true.
void DocLoaderIsEmpty(bool aFlushLayout);
- nsListenerInfo *GetListenerInfo(nsIWebProgressListener* aListener);
-
int64_t GetMaxTotalProgress();
nsresult AddRequestInfo(nsIRequest* aRequest);
@@ -319,7 +328,7 @@ private:
/// void DumpChannelInfo(void);
// used to clear our internal progress state between loads...
- void ClearInternalProgress();
+ void ClearInternalProgress();
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsDocLoader, NS_THIS_DOCLOADER_IMPL_CID)
diff --git a/uriloader/base/nsITransfer.idl b/uriloader/base/nsITransfer.idl
index e1db1c0af..da34d4ac4 100644
--- a/uriloader/base/nsITransfer.idl
+++ b/uriloader/base/nsITransfer.idl
@@ -5,12 +5,13 @@
#include "nsIWebProgressListener2.idl"
+interface nsIArray;
interface nsIURI;
interface nsICancelable;
interface nsIMIMEInfo;
interface nsIFile;
-[scriptable, uuid(b1c81100-9d66-11e2-9e96-0800200c9a66)]
+[scriptable, uuid(37ec75d3-97ad-4da8-afaa-eabe5b4afd73)]
interface nsITransfer : nsIWebProgressListener2 {
/**
@@ -65,6 +66,24 @@ interface nsITransfer : nsIWebProgressListener2 {
* @param aHash The SHA-256 hash in raw bytes of the downloaded file.
*/
void setSha256Hash(in ACString aHash);
+
+ /*
+ * Used to notify the transfer object of the signature of the downloaded
+ * file. Must be called on the main thread, only after the download has
+ * finished successfully.
+ * @param aSignatureInfo The nsIArray of nsIX509CertList of nsIX509Cert
+ * certificates of the downloaded file.
+ */
+ void setSignatureInfo(in nsIArray aSignatureInfo);
+
+ /*
+ * Used to notify the transfer object of the redirects associated with the
+ * channel that terminated in the downloaded file. Must be called on the
+ * main thread, only after the download has finished successfully.
+ * @param aRedirects The nsIArray of nsIPrincipal of redirected URIs
+ * associated with the downloaded file.
+ */
+ void setRedirects(in nsIArray aRedirects);
};
%{C++
diff --git a/uriloader/base/nsIURIContentListener.idl b/uriloader/base/nsIURIContentListener.idl
index 6aa99e6c5..0f0b5335e 100644
--- a/uriloader/base/nsIURIContentListener.idl
+++ b/uriloader/base/nsIURIContentListener.idl
@@ -41,9 +41,11 @@ interface nsIURIContentListener : nsISupports
* @param aContentHandler nsIStreamListener that will consume the data.
* This should be set to <code>nullptr</code> if
* this content listener can't handle the content
- * type.
+ * type; in this case, doContent should also fail
+ * (i.e., return failure nsresult).
*
- * @return <code>true</code> if the consumer wants to
+ * @return <code>true</code> if the load should
+ * be aborted and consumer wants to
* handle the load completely by itself. This
* causes the URI Loader do nothing else...
* <code>false</code> if the URI Loader should
diff --git a/uriloader/base/nsIURILoader.idl b/uriloader/base/nsIURILoader.idl
index bfc607653..74f21e363 100644
--- a/uriloader/base/nsIURILoader.idl
+++ b/uriloader/base/nsIURILoader.idl
@@ -35,7 +35,7 @@ interface nsIInterfaceRequestor;
* or helper app. Or it may hand the url off to an OS registered
* application.
*/
-[scriptable, uuid(2f7e8051-f1c9-4bcc-8584-9cfd5849e343)]
+[scriptable, uuid(8762c4e7-be35-4958-9b81-a05685bb516d)]
interface nsIURILoader : nsISupports
{
/**
@@ -78,9 +78,9 @@ interface nsIURILoader : nsISupports
* The channel that should be opened. This must not be asyncOpen'd yet!
* If a loadgroup is set on the channel, it will get replaced with a
* different one.
- * @param aIsContentPreferred
- * Should the content be displayed in a container that prefers the
- * content-type, or will any container do.
+ * @param aFlags
+ * Combination (bitwise OR) of the flags specified above. 0 indicates
+ * default handling.
* @param aWindowContext
* If you are running the url from a doc shell or a web shell, this is
* your window context. If you have a content listener you want to
@@ -90,7 +90,7 @@ interface nsIURILoader : nsISupports
* <b>Must not be null!</b>
*/
void openURI(in nsIChannel aChannel,
- in boolean aIsContentPreferred,
+ in unsigned long aFlags,
in nsIInterfaceRequestor aWindowContext);
/**
diff --git a/uriloader/base/nsIWebProgress.idl b/uriloader/base/nsIWebProgress.idl
index 58db08b11..1d0958d72 100644
--- a/uriloader/base/nsIWebProgress.idl
+++ b/uriloader/base/nsIWebProgress.idl
@@ -26,14 +26,14 @@ interface nsIWebProgressListener;
* notifications from any nsIWebProgress instances that are children of that
* nsIWebProgress instance.
*/
-[scriptable, uuid(1c3437b0-9e2c-11e2-9e96-0800200c9a66)]
+[scriptable, uuid(bd0efb3b-1c81-4fb0-b16d-576a2be48a95)]
interface nsIWebProgress : nsISupports
{
/**
* The following flags may be combined to form the aNotifyMask parameter for
* the addProgressListener method. They limit the set of events that are
* delivered to an nsIWebProgressListener instance.
- */
+ */
/**
* These flags indicate the state transistions to observe, corresponding to
@@ -42,7 +42,7 @@ interface nsIWebProgress : nsISupports
* NOTIFY_STATE_REQUEST
* Only receive the onStateChange event if the aStateFlags parameter
* includes nsIWebProgressListener::STATE_IS_REQUEST.
- *
+ *
* NOTIFY_STATE_DOCUMENT
* Only receive the onStateChange event if the aStateFlags parameter
* includes nsIWebProgressListener::STATE_IS_DOCUMENT.
@@ -138,10 +138,16 @@ interface nsIWebProgress : nsISupports
* Indicates whether DOMWindow.top == DOMWindow.
*/
readonly attribute boolean isTopLevel;
-
+
/**
* Indicates whether or not a document is currently being loaded
* in the context of this nsIWebProgress instance.
*/
readonly attribute boolean isLoadingDocument;
+
+ /**
+ * Contains a load type as specified by the load* constants in
+ * nsIDocShellLoadInfo.idl.
+ */
+ readonly attribute unsigned long loadType;
};
diff --git a/uriloader/base/nsIWebProgressListener.idl b/uriloader/base/nsIWebProgressListener.idl
index 51a399896..c393529db 100644
--- a/uriloader/base/nsIWebProgressListener.idl
+++ b/uriloader/base/nsIWebProgressListener.idl
@@ -17,7 +17,7 @@ interface nsIURI;
* nsIWebProgress instances. nsIWebProgress.idl describes the parent-child
* relationship of nsIWebProgress instances.
*/
-[scriptable, uuid(a0cda7e4-c6ca-11e0-b6a5-001320257da5)]
+[scriptable, uuid(a9df523b-efe2-421e-9d8e-3d7f807dda4c)]
interface nsIWebProgressListener : nsISupports
{
/**
@@ -199,6 +199,21 @@ interface nsIWebProgressListener : nsISupports
const unsigned long STATE_BLOCKED_MIXED_DISPLAY_CONTENT = 0x00000100;
const unsigned long STATE_LOADED_MIXED_DISPLAY_CONTENT = 0x00000200;
+ /**
+ * Tracking content flags
+ *
+ * May be set in addition to the State security Flags, to indicate that
+ * tracking content has been encountered.
+ *
+ * STATE_BLOCKED_TRACKING_CONTENT
+ * Tracking content has been blocked from loading.
+ *
+ * STATE_LOADED_TRACKING_CONTENT
+ * Tracking content has been loaded.
+ */
+ const unsigned long STATE_BLOCKED_TRACKING_CONTENT = 0x00001000;
+ const unsigned long STATE_LOADED_TRACKING_CONTENT = 0x00002000;
+
/**
* Security Strength Flags
*
@@ -238,6 +253,20 @@ interface nsIWebProgressListener : nsISupports
const unsigned long STATE_IDENTITY_EV_TOPLEVEL = 0x00100000;
/**
+ * Broken state flags
+ *
+ * These flags describe the reason of the broken state.
+ *
+ * STATE_USES_SSL_3
+ * The topmost document uses SSL 3.0.
+ *
+ * STATE_USES_WEAK_CRYPTO
+ * The topmost document uses a weak cipher suite such as RC4.
+ */
+ const unsigned long STATE_USES_SSL_3 = 0x01000000;
+ const unsigned long STATE_USES_WEAK_CRYPTO = 0x02000000;
+
+ /**
* Notification indicating the state has changed for one of the requests
* associated with aWebProgress.
*
diff --git a/uriloader/base/nsURILoader.cpp b/uriloader/base/nsURILoader.cpp
index a03930dcb..8d604b8b9 100644
--- a/uriloader/base/nsURILoader.cpp
+++ b/uriloader/base/nsURILoader.cpp
@@ -30,10 +30,12 @@
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDocShellTreeOwner.h"
+#include "nsIThreadRetargetableStreamListener.h"
#include "nsXPIDLString.h"
#include "nsString.h"
#include "nsNetUtil.h"
+#include "nsThreadUtils.h"
#include "nsReadableUtils.h"
#include "nsError.h"
@@ -47,6 +49,7 @@
#include "nsDocLoader.h"
#include "mozilla/Attributes.h"
+#include "mozilla/Preferences.h"
#ifdef PR_LOGGING
PRLogModuleInfo* nsURILoader::mLog = nullptr;
@@ -56,13 +59,17 @@ PRLogModuleInfo* nsURILoader::mLog = nullptr;
#define LOG_ERROR(args) PR_LOG(nsURILoader::mLog, PR_LOG_ERROR, args)
#define LOG_ENABLED() PR_LOG_TEST(nsURILoader::mLog, PR_LOG_DEBUG)
+#define NS_PREF_DISABLE_BACKGROUND_HANDLING \
+ "security.exthelperapp.disable_background_handling"
+
/**
* The nsDocumentOpenInfo contains the state required when a single
* document is being opened in order to discover the content type...
* Each instance remains alive until its target URL has been loaded
* (or aborted).
*/
-class nsDocumentOpenInfo MOZ_FINAL : public nsIStreamListener
+class nsDocumentOpenInfo final : public nsIStreamListener
+ , public nsIThreadRetargetableStreamListener
{
public:
// Needed for nsCOMPtr to work right... Don't call this!
@@ -74,7 +81,7 @@ public:
uint32_t aFlags,
nsURILoader* aURILoader);
- NS_DECL_ISUPPORTS
+ NS_DECL_THREADSAFE_ISUPPORTS
/**
* Prepares this object for receiving data. The stream
@@ -110,6 +117,8 @@ public:
// nsIStreamListener methods:
NS_DECL_NSISTREAMLISTENER
+ // nsIThreadRetargetableStreamListener
+ NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
protected:
~nsDocumentOpenInfo();
@@ -152,13 +161,14 @@ protected:
nsRefPtr<nsURILoader> mURILoader;
};
-NS_IMPL_THREADSAFE_ADDREF(nsDocumentOpenInfo)
-NS_IMPL_THREADSAFE_RELEASE(nsDocumentOpenInfo)
+NS_IMPL_ADDREF(nsDocumentOpenInfo)
+NS_IMPL_RELEASE(nsDocumentOpenInfo)
NS_INTERFACE_MAP_BEGIN(nsDocumentOpenInfo)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
+ NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)
NS_INTERFACE_MAP_END_THREADSAFE
nsDocumentOpenInfo::nsDocumentOpenInfo()
@@ -267,6 +277,22 @@ NS_IMETHODIMP nsDocumentOpenInfo::OnStartRequest(nsIRequest *request, nsISupport
}
NS_IMETHODIMP
+nsDocumentOpenInfo::CheckListenerChain()
+{
+ NS_ASSERTION(NS_IsMainThread(), "Should be on the main thread!");
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
+ do_QueryInterface(m_targetStreamListener, &rv);
+ if (retargetableListener) {
+ rv = retargetableListener->CheckListenerChain();
+ }
+ LOG(("[0x%p] nsDocumentOpenInfo::CheckListenerChain %s listener %p rv %x",
+ this, (NS_SUCCEEDED(rv) ? "success" : "failure"),
+ (nsIStreamListener*)m_targetStreamListener, rv));
+ return rv;
+}
+
+NS_IMETHODIMP
nsDocumentOpenInfo::OnDataAvailable(nsIRequest *request, nsISupports * aCtxt,
nsIInputStream * inStr,
uint64_t sourceOffset, uint32_t count)
@@ -341,11 +367,26 @@ nsresult nsDocumentOpenInfo::DispatchContent(nsIRequest *request, nsISupports *
bool forceExternalHandling = false;
uint32_t disposition;
rv = aChannel->GetContentDisposition(&disposition);
- if (NS_SUCCEEDED(rv) && disposition == nsIChannel::DISPOSITION_ATTACHMENT)
+
+ bool allowContentDispositionToForceExternalHandling = true;
+
+#ifdef MOZ_B2G
+
+ // On B2G, OMA content files should never be handled by an external handler
+ // (even if the server specifies Content-Disposition: attachment) because the
+ // data should never be stored on an unencrypted form.
+ allowContentDispositionToForceExternalHandling =
+ !mContentType.LowerCaseEqualsASCII("application/vnd.oma.drm.message");
+
+#endif
+
+ if (NS_SUCCEEDED(rv) && (disposition == nsIChannel::DISPOSITION_ATTACHMENT) &&
+ allowContentDispositionToForceExternalHandling) {
forceExternalHandling = true;
+ }
LOG((" forceExternalHandling: %s", forceExternalHandling ? "yes" : "no"));
-
+
// We're going to try to find a contentListener that can handle our data
nsCOMPtr<nsIURIContentListener> contentListener;
// The type or data the contentListener wants.
@@ -497,6 +538,35 @@ nsresult nsDocumentOpenInfo::DispatchContent(nsIRequest *request, nsISupports *
// All attempts to dispatch this content have failed. Just pass it off to
// the helper app service.
//
+
+ //
+ // Optionally, we may want to disable background handling by the external
+ // helper application service.
+ //
+ if (mozilla::Preferences::GetBool(NS_PREF_DISABLE_BACKGROUND_HANDLING,
+ false)) {
+ // First, we will ensure that the parent docshell is in an active
+ // state as we will disallow all external application handling unless it is
+ // in the foreground.
+ nsCOMPtr<nsIDocShell> docShell(do_GetInterface(m_originalContext));
+ if (!docShell) {
+ // If we can't perform our security check we definitely don't want to go
+ // any further!
+ LOG(("Failed to get DocShell to ensure it is active before anding off to "
+ "helper app service. Aborting."));
+ return NS_ERROR_FAILURE;
+ }
+
+ // Ensure the DocShell is active before continuing.
+ bool isActive = false;
+ docShell->GetIsActive(&isActive);
+ if (!isActive) {
+ LOG((" Check for active DocShell returned false. Aborting hand off to "
+ "helper app service."));
+ return NS_ERROR_DOM_SECURITY_ERR;
+ }
+ }
+
nsCOMPtr<nsIExternalHelperAppService> helperAppService =
do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &rv);
if (helperAppService) {
@@ -518,6 +588,7 @@ nsresult nsDocumentOpenInfo::DispatchContent(nsIRequest *request, nsISupports *
request,
m_originalContext,
false,
+ nullptr,
getter_AddRefs(m_targetStreamListener));
if (NS_FAILED(rv)) {
request->SetLoadFlags(loadFlags);
@@ -558,7 +629,7 @@ nsDocumentOpenInfo::ConvertData(nsIRequest *request,
// stream is split up into multiple destination streams. This
// intermediate instance is used to target these "decoded" streams...
//
- nsCOMPtr<nsDocumentOpenInfo> nextLink =
+ nsRefPtr<nsDocumentOpenInfo> nextLink =
new nsDocumentOpenInfo(m_originalContext, mFlags, mURILoader);
if (!nextLink) return NS_ERROR_OUT_OF_MEMORY;
@@ -731,7 +802,7 @@ NS_IMETHODIMP nsURILoader::UnRegisterContentListener(nsIURIContentListener * aCo
}
NS_IMETHODIMP nsURILoader::OpenURI(nsIChannel *channel,
- bool aIsContentPreferred,
+ uint32_t aFlags,
nsIInterfaceRequestor *aWindowContext)
{
NS_ENSURE_ARG_POINTER(channel);
@@ -748,7 +819,7 @@ NS_IMETHODIMP nsURILoader::OpenURI(nsIChannel *channel,
nsCOMPtr<nsIStreamListener> loader;
nsresult rv = OpenChannel(channel,
- aIsContentPreferred ? IS_CONTENT_PREFERRED : 0,
+ aFlags,
aWindowContext,
false,
getter_AddRefs(loader));
@@ -812,7 +883,7 @@ nsresult nsURILoader::OpenChannel(nsIChannel* channel,
// we need to create a DocumentOpenInfo object which will go ahead and open
// the url and discover the content type....
- nsCOMPtr<nsDocumentOpenInfo> loader =
+ nsRefPtr<nsDocumentOpenInfo> loader =
new nsDocumentOpenInfo(aWindowContext, aFlags, this);
if (!loader) return NS_ERROR_OUT_OF_MEMORY;
diff --git a/uriloader/base/nsURILoader.h b/uriloader/base/nsURILoader.h
index 6c8bae6e5..79263b526 100644
--- a/uriloader/base/nsURILoader.h
+++ b/uriloader/base/nsURILoader.h
@@ -16,29 +16,26 @@
#include "nsIWeakReference.h"
#include "mozilla/Attributes.h"
-#ifdef MOZ_LOGGING
-// Uncomment the next line to force logging on in release builds
-// #define FORCE_PR_LOG
-#endif
#include "prlog.h"
class nsDocumentOpenInfo;
-class nsURILoader MOZ_FINAL : public nsIURILoader
+class nsURILoader final : public nsIURILoader
{
public:
NS_DECL_NSIURILOADER
NS_DECL_ISUPPORTS
nsURILoader();
- ~nsURILoader();
protected:
+ ~nsURILoader();
+
/**
* Equivalent to nsIURILoader::openChannel, but allows specifying whether the
* channel is opened already.
*/
- NS_HIDDEN_(nsresult) OpenChannel(nsIChannel* channel,
+ nsresult OpenChannel(nsIChannel* channel,
uint32_t aFlags,
nsIInterfaceRequestor* aWindowContext,
bool aChannelOpen,