зеркало из https://github.com/mozilla/pjs.git
Bug 546606 - Make redirect API async - part 2; r=honzab.moz,cbiesinger,bjarne,jst sr=jst
This commit is contained in:
Родитель
b64f460e63
Коммит
06924ec766
|
@ -95,6 +95,7 @@
|
|||
#include "nsIChromeRegistry.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
|
||||
|
||||
|
@ -3257,9 +3258,10 @@ nsScriptSecurityManager::CheckXPCPermissions(JSContext* cx,
|
|||
// Method implementing nsIChannelEventSink //
|
||||
/////////////////////////////////////////////
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::OnChannelRedirect(nsIChannel* oldChannel,
|
||||
nsIChannel* newChannel,
|
||||
PRUint32 redirFlags)
|
||||
nsScriptSecurityManager::AsyncOnChannelRedirect(nsIChannel* oldChannel,
|
||||
nsIChannel* newChannel,
|
||||
PRUint32 redirFlags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
nsCOMPtr<nsIPrincipal> oldPrincipal;
|
||||
GetChannelPrincipal(oldChannel, getter_AddRefs(oldPrincipal));
|
||||
|
@ -3278,7 +3280,12 @@ nsScriptSecurityManager::OnChannelRedirect(nsIChannel* oldChannel,
|
|||
if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
|
||||
rv = CheckLoadURIWithPrincipal(oldPrincipal, newOriginalURI, flags);
|
||||
}
|
||||
return rv;
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,6 +53,8 @@
|
|||
#include "nsIWritablePropertyBag2.h"
|
||||
#include "nsNetError.h"
|
||||
#include "nsChannelProperties.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsAsyncRedirectVerifyHelper.h"
|
||||
|
||||
/* Keeps track of whether or not CSP is enabled */
|
||||
PRBool CSPService::sCSPEnabled = PR_TRUE;
|
||||
|
@ -203,10 +205,13 @@ CSPService::ShouldProcess(PRUint32 aContentType,
|
|||
|
||||
/* nsIChannelEventSink implementation */
|
||||
NS_IMETHODIMP
|
||||
CSPService::OnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags)
|
||||
CSPService::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
nsAsyncRedirectAutoCallback autoCallback(callback);
|
||||
|
||||
// get the Content Security Policy and load type from the property bag
|
||||
nsCOMPtr<nsISupports> policyContainer;
|
||||
nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(oldChannel));
|
||||
|
@ -257,19 +262,22 @@ CSPService::OnChannelRedirect(nsIChannel *oldChannel,
|
|||
nsCAutoString newUriSpec("None");
|
||||
newUri->GetSpec(newUriSpec);
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
("CSPService::OnChannelRedirect called for %s", newUriSpec.get()));
|
||||
("CSPService::AsyncOnChannelRedirect called for %s",
|
||||
newUriSpec.get()));
|
||||
}
|
||||
if (aDecision == 1)
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
("CSPService::OnChannelRedirect ALLOWING request."));
|
||||
("CSPService::AsyncOnChannelRedirect ALLOWING request."));
|
||||
else
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
("CSPService::OnChannelRedirect CANCELLING request."));
|
||||
("CSPService::AsyncOnChannelRedirect CANCELLING request."));
|
||||
#endif
|
||||
|
||||
// if ShouldLoad doesn't accept the load, cancel the request
|
||||
if (aDecision != 1)
|
||||
if (aDecision != 1) {
|
||||
autoCallback.DontCallback();
|
||||
return NS_BINDING_FAILED;
|
||||
}
|
||||
|
||||
// the redirect is permitted, so propagate the Content Security Policy
|
||||
// and load type to the redirecting channel
|
||||
|
|
|
@ -162,6 +162,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
|||
#include "nsIUGenCategory.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIOfflineCacheUpdate.h"
|
||||
#include "nsCPrefetchService.h"
|
||||
|
@ -5149,14 +5150,14 @@ NS_IMPL_ISUPPORTS2(nsSameOriginChecker,
|
|||
nsIInterfaceRequestor)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSameOriginChecker::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsSameOriginChecker::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
|
||||
if (!nsContentUtils::GetSecurityManager()) {
|
||||
if (!nsContentUtils::GetSecurityManager())
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> oldPrincipal;
|
||||
nsContentUtils::GetSecurityManager()->
|
||||
|
@ -5173,7 +5174,12 @@ nsSameOriginChecker::OnChannelRedirect(nsIChannel *aOldChannel,
|
|||
if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
|
||||
rv = oldPrincipal->CheckMayLoad(newOriginalURI, PR_FALSE);
|
||||
}
|
||||
return rv;
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -52,8 +52,10 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "nsWhitespaceTokenizer.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsCharSeparatedTokenizer.h"
|
||||
#include "nsXMLHttpRequest.h"
|
||||
#include "nsAsyncRedirectVerifyHelper.h"
|
||||
|
||||
static PRBool gDisableCORS = PR_FALSE;
|
||||
static PRBool gDisableCORSPrivateData = PR_FALSE;
|
||||
|
@ -81,9 +83,9 @@ private:
|
|||
nsIChannel* mChannel;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS4(nsCrossSiteListenerProxy, nsIStreamListener,
|
||||
NS_IMPL_ISUPPORTS5(nsCrossSiteListenerProxy, nsIStreamListener,
|
||||
nsIRequestObserver, nsIChannelEventSink,
|
||||
nsIInterfaceRequestor)
|
||||
nsIInterfaceRequestor, nsIAsyncVerifyRedirectCallback)
|
||||
|
||||
/* static */
|
||||
void
|
||||
|
@ -370,11 +372,11 @@ nsCrossSiteListenerProxy::GetInterface(const nsIID & aIID, void **aResult)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCrossSiteListenerProxy::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsCrossSiteListenerProxy::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
nsChannelCanceller canceller(aOldChannel);
|
||||
nsresult rv;
|
||||
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
|
||||
rv = CheckRequestApproved(aOldChannel, PR_TRUE);
|
||||
|
@ -387,22 +389,57 @@ nsCrossSiteListenerProxy::OnChannelRedirect(nsIChannel *aOldChannel,
|
|||
RemoveEntries(oldURI, mRequestingPrincipal);
|
||||
}
|
||||
}
|
||||
aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
}
|
||||
|
||||
// Prepare to receive callback
|
||||
mRedirectCallback = cb;
|
||||
mOldRedirectChannel = aOldChannel;
|
||||
mNewRedirectChannel = aNewChannel;
|
||||
|
||||
nsCOMPtr<nsIChannelEventSink> outer =
|
||||
do_GetInterface(mOuterNotificationCallbacks);
|
||||
if (outer) {
|
||||
rv = outer->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = outer->AsyncOnChannelRedirect(aOldChannel, aNewChannel, aFlags, this);
|
||||
if (NS_FAILED(rv)) {
|
||||
aOldChannel->Cancel(rv); // is this necessary...?
|
||||
mRedirectCallback = nsnull;
|
||||
mOldRedirectChannel = nsnull;
|
||||
mNewRedirectChannel = nsnull;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = UpdateChannel(aNewChannel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
(void) OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
canceller.DontCancel();
|
||||
NS_IMETHODIMP
|
||||
nsCrossSiteListenerProxy::OnRedirectVerifyCallback(nsresult result)
|
||||
{
|
||||
NS_ASSERTION(mRedirectCallback, "mRedirectCallback not set in callback");
|
||||
NS_ASSERTION(mOldRedirectChannel, "mOldRedirectChannel not set in callback");
|
||||
NS_ASSERTION(mNewRedirectChannel, "mNewRedirectChannel not set in callback");
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
nsresult rv = UpdateChannel(mNewRedirectChannel);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsCrossSiteListenerProxy::OnRedirectVerifyCallback: "
|
||||
"UpdateChannel() returned failure");
|
||||
}
|
||||
result = rv;
|
||||
}
|
||||
|
||||
if (NS_FAILED(result)) {
|
||||
mOldRedirectChannel->Cancel(result);
|
||||
}
|
||||
|
||||
mOldRedirectChannel = nsnull;
|
||||
mNewRedirectChannel = nsnull;
|
||||
mRedirectCallback->OnRedirectVerifyCallback(result);
|
||||
mRedirectCallback = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "nsTArray.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
class nsIURI;
|
||||
class nsIParser;
|
||||
|
@ -56,7 +57,8 @@ IsValidHTTPToken(const nsCSubstring& aToken);
|
|||
|
||||
class nsCrossSiteListenerProxy : public nsIStreamListener,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIChannelEventSink
|
||||
public nsIChannelEventSink,
|
||||
public nsIAsyncVerifyRedirectCallback
|
||||
{
|
||||
public:
|
||||
nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
|
||||
|
@ -77,6 +79,7 @@ public:
|
|||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
|
||||
|
||||
// Must be called at startup.
|
||||
static void Startup();
|
||||
|
@ -100,6 +103,9 @@ private:
|
|||
nsCString mPreflightMethod;
|
||||
nsTArray<nsCString> mPreflightHeaders;
|
||||
nsTArray<PRUint32> mAllowedHTTPErrors;
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
|
||||
nsCOMPtr<nsIChannel> mOldRedirectChannel;
|
||||
nsCOMPtr<nsIChannel> mNewRedirectChannel;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
#include "nsIWebNavigationInfo.h"
|
||||
#include "nsIScriptChannel.h"
|
||||
#include "nsIBlocklistService.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
#include "nsPluginError.h"
|
||||
|
||||
|
@ -1025,9 +1026,10 @@ nsObjectLoadingContent::GetInterface(const nsIID & aIID, void **aResult)
|
|||
|
||||
// nsIChannelEventSink
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsObjectLoadingContent::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
// If we're already busy with a new load, cancel the redirect
|
||||
if (aOldChannel != mChannel) {
|
||||
|
@ -1035,6 +1037,7 @@ nsObjectLoadingContent::OnChannelRedirect(nsIChannel *aOldChannel,
|
|||
}
|
||||
|
||||
mChannel = aNewChannel;
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "nsIChannel.h"
|
||||
#include "nsIDOMLoadListener.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsString.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
@ -360,14 +361,16 @@ nsSyncLoader::Error(nsIDOMEvent* aEvent)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSyncLoader::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsSyncLoader::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
|
||||
|
||||
mChannel = aNewChannel;
|
||||
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
#include "nsIChannelPolicy.h"
|
||||
#include "nsChannelPolicy.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsAsyncRedirectVerifyHelper.h"
|
||||
|
||||
#define LOAD_STR "load"
|
||||
#define ERROR_STR "error"
|
||||
|
@ -486,13 +487,17 @@ nsACProxyListener::OnDataAvailable(nsIRequest *aRequest,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsACProxyListener::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsACProxyListener::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
// Only internal redirects allowed for now.
|
||||
return NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags) ?
|
||||
NS_OK : NS_ERROR_DOM_BAD_URI;
|
||||
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags))
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2988,13 +2993,60 @@ nsXMLHttpRequest::ChangeState(PRUint32 aState, PRBool aBroadcast)
|
|||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple helper class that just forwards the redirect callback back
|
||||
* to the nsXMLHttpRequest.
|
||||
*/
|
||||
class AsyncVerifyRedirectCallbackForwarder : public nsIAsyncVerifyRedirectCallback
|
||||
{
|
||||
public:
|
||||
AsyncVerifyRedirectCallbackForwarder(nsXMLHttpRequest *xhr)
|
||||
: mXHR(xhr)
|
||||
{
|
||||
}
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(AsyncVerifyRedirectCallbackForwarder)
|
||||
|
||||
// nsIAsyncVerifyRedirectCallback implementation
|
||||
NS_IMETHOD OnRedirectVerifyCallback(nsresult result)
|
||||
{
|
||||
mXHR->OnRedirectVerifyCallback(result);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsXMLHttpRequest> mXHR;
|
||||
};
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(AsyncVerifyRedirectCallbackForwarder)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AsyncVerifyRedirectCallbackForwarder)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mXHR, nsIDOMEventListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AsyncVerifyRedirectCallbackForwarder)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mXHR)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AsyncVerifyRedirectCallbackForwarder)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(AsyncVerifyRedirectCallbackForwarder)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(AsyncVerifyRedirectCallbackForwarder)
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// nsIChannelEventSink methods:
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsXMLHttpRequest::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsXMLHttpRequest::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
NS_PRECONDITION(aNewChannel, "Redirect without a channel?");
|
||||
|
||||
|
@ -3002,7 +3054,11 @@ nsXMLHttpRequest::OnChannelRedirect(nsIChannel *aOldChannel,
|
|||
|
||||
if (!NS_IsInternalSameURIRedirect(aOldChannel, aNewChannel, aFlags)) {
|
||||
rv = CheckChannelForCrossSiteRequest(aNewChannel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsXMLHttpRequest::OnChannelRedirect: "
|
||||
"CheckChannelForCrossSiteRequest returned failure");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Disable redirects for preflighted cross-site requests entirely for now
|
||||
// Note, do this after the call to CheckChannelForCrossSiteRequest
|
||||
|
@ -3012,20 +3068,44 @@ nsXMLHttpRequest::OnChannelRedirect(nsIChannel *aOldChannel,
|
|||
}
|
||||
}
|
||||
|
||||
// Prepare to receive callback
|
||||
mRedirectCallback = callback;
|
||||
mNewRedirectChannel = aNewChannel;
|
||||
|
||||
if (mChannelEventSink) {
|
||||
rv =
|
||||
mChannelEventSink->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
||||
nsRefPtr<AsyncVerifyRedirectCallbackForwarder> fwd =
|
||||
new AsyncVerifyRedirectCallbackForwarder(this);
|
||||
|
||||
rv = mChannelEventSink->AsyncOnChannelRedirect(aOldChannel,
|
||||
aNewChannel,
|
||||
aFlags, fwd);
|
||||
if (NS_FAILED(rv)) {
|
||||
mErrorLoad = PR_TRUE;
|
||||
return rv;
|
||||
mRedirectCallback = nsnull;
|
||||
mNewRedirectChannel = nsnull;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
mChannel = aNewChannel;
|
||||
|
||||
OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLHttpRequest::OnRedirectVerifyCallback(nsresult result)
|
||||
{
|
||||
NS_ASSERTION(mRedirectCallback, "mRedirectCallback not set in callback");
|
||||
NS_ASSERTION(mNewRedirectChannel, "mNewRedirectChannel not set in callback");
|
||||
|
||||
if (NS_SUCCEEDED(result))
|
||||
mChannel = mNewRedirectChannel;
|
||||
else
|
||||
mErrorLoad = PR_TRUE;
|
||||
|
||||
mNewRedirectChannel = nsnull;
|
||||
|
||||
mRedirectCallback->OnRedirectVerifyCallback(result);
|
||||
mRedirectCallback = nsnull;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
// nsIProgressEventSink methods:
|
||||
//
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "jsapi.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIHttpHeaderVisitor.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
|
@ -70,6 +71,7 @@
|
|||
#include "nsDOMEventTargetWrapperCache.h"
|
||||
|
||||
class nsILoadGroup;
|
||||
class AsyncVerifyRedirectCallbackForwarder;
|
||||
|
||||
class nsAccessControlLRUCache
|
||||
{
|
||||
|
@ -340,6 +342,9 @@ protected:
|
|||
|
||||
void StartProgressEventTimer();
|
||||
|
||||
friend class AsyncVerifyRedirectCallbackForwarder;
|
||||
void OnRedirectVerifyCallback(nsresult result);
|
||||
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
@ -413,6 +418,9 @@ protected:
|
|||
nsCOMPtr<nsITimer> mProgressNotifier;
|
||||
|
||||
PRPackedBool mFirstStartRequestSeen;
|
||||
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
|
||||
nsCOMPtr<nsIChannel> mNewRedirectChannel;
|
||||
};
|
||||
|
||||
// helper class to expose a progress DOM Event
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
#include "BasicLayers.h"
|
||||
#include <limits>
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
#ifdef MOZ_OGG
|
||||
#include "nsOggDecoder.h"
|
||||
|
@ -352,15 +353,19 @@ NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnDataAvailable(nsIRequest*
|
|||
return mNextListener->OnDataAvailable(aRequest, aContext, aStream, aOffset, aCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnChannelRedirect(nsIChannel* aOldChannel,
|
||||
nsIChannel* aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
nsIChannel* aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback* cb)
|
||||
{
|
||||
// TODO is this really correct?? See bug #579329.
|
||||
if (mElement)
|
||||
mElement->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
||||
nsCOMPtr<nsIChannelEventSink> sink = do_QueryInterface(mNextListener);
|
||||
if (sink)
|
||||
return sink->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
||||
return sink->AsyncOnChannelRedirect(aOldChannel, aNewChannel, aFlags, cb);
|
||||
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "nsDOMError.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsURILoader.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
#define HTTP_OK_CODE 200
|
||||
#define HTTP_PARTIAL_RESPONSE_CODE 206
|
||||
|
@ -126,13 +127,20 @@ nsMediaChannelStream::Listener::OnDataAvailable(nsIRequest* aRequest,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsMediaChannelStream::Listener::OnChannelRedirect(nsIChannel* aOldChannel,
|
||||
nsIChannel* aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsMediaChannelStream::Listener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
|
||||
nsIChannel* aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback* cb)
|
||||
{
|
||||
if (!mStream)
|
||||
return NS_OK;
|
||||
return mStream->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
||||
nsresult rv = NS_OK;
|
||||
if (mStream)
|
||||
rv = mStream->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#include "nsIAuthPrompt2.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsIUploadChannel.h"
|
||||
#include "nsISecurityEventSink.h"
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
|
@ -502,8 +503,9 @@ nsPingListener::GetInterface(const nsIID &iid, void **result)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPingListener::OnChannelRedirect(nsIChannel *oldChan, nsIChannel *newChan,
|
||||
PRUint32 flags)
|
||||
nsPingListener::AsyncOnChannelRedirect(nsIChannel *oldChan, nsIChannel *newChan,
|
||||
PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
newChan->GetURI(getter_AddRefs(newURI));
|
||||
|
@ -511,8 +513,10 @@ nsPingListener::OnChannelRedirect(nsIChannel *oldChan, nsIChannel *newChan,
|
|||
if (!CheckPingURI(newURI, mContent))
|
||||
return NS_ERROR_ABORT;
|
||||
|
||||
if (!mRequireSameHost)
|
||||
if (!mRequireSameHost) {
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXXbz should this be using something more like the nsContentUtils
|
||||
// same-origin checker?
|
||||
|
@ -523,6 +527,7 @@ nsPingListener::OnChannelRedirect(nsIChannel *oldChan, nsIChannel *newChan,
|
|||
if (!IsSameHost(oldURI, newURI))
|
||||
return NS_ERROR_ABORT;
|
||||
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsIProxyObjectManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIFileURL.h"
|
||||
|
@ -319,9 +320,10 @@ nsProgressNotificationProxy::OnStatus(nsIRequest* request,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProgressNotificationProxy::OnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags) {
|
||||
nsProgressNotificationProxy::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *cb) {
|
||||
// The 'old' channel should match the current one
|
||||
NS_ABORT_IF_FALSE(oldChannel == mChannel,
|
||||
"old channel doesn't match current!");
|
||||
|
@ -337,9 +339,13 @@ nsProgressNotificationProxy::OnChannelRedirect(nsIChannel *oldChannel,
|
|||
loadGroup,
|
||||
NS_GET_IID(nsIChannelEventSink),
|
||||
getter_AddRefs(target));
|
||||
if (!target)
|
||||
return NS_OK;
|
||||
return target->OnChannelRedirect(oldChannel, newChannel, flags);
|
||||
if (!target) {
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Delegate to |target| if set, reusing |cb|
|
||||
return target->AsyncOnChannelRedirect(oldChannel, newChannel, flags, cb);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
#include "nsIPrefBranch2.h"
|
||||
|
||||
#include "imgDiscardTracker.h"
|
||||
#include "nsAsyncRedirectVerifyHelper.h"
|
||||
|
||||
#define DISCARD_PREF "image.mem.discardable"
|
||||
#define DECODEONDRAW_PREF "image.mem.decodeondraw"
|
||||
|
@ -158,12 +159,13 @@ imgRequestPrefObserver::Observe(nsISupports *aSubject,
|
|||
PRLogModuleInfo *gImgLog = PR_NewLogModule("imgRequest");
|
||||
#endif
|
||||
|
||||
NS_IMPL_ISUPPORTS7(imgRequest,
|
||||
NS_IMPL_ISUPPORTS8(imgRequest,
|
||||
imgIDecoderObserver, imgIContainerObserver,
|
||||
nsIStreamListener, nsIRequestObserver,
|
||||
nsISupportsWeakReference,
|
||||
nsIChannelEventSink,
|
||||
nsIInterfaceRequestor)
|
||||
nsIInterfaceRequestor,
|
||||
nsIAsyncVerifyRedirectCallback)
|
||||
|
||||
imgRequest::imgRequest() :
|
||||
mCacheId(0), mValidator(nsnull), mImageSniffers("image-sniffing-services"),
|
||||
|
@ -1119,24 +1121,49 @@ imgRequest::GetInterface(const nsIID & aIID, void **aResult)
|
|||
}
|
||||
|
||||
/** nsIChannelEventSink methods **/
|
||||
|
||||
/* void onChannelRedirect (in nsIChannel oldChannel, in nsIChannel newChannel, in unsigned long flags); */
|
||||
NS_IMETHODIMP
|
||||
imgRequest::OnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel, PRUint32 flags)
|
||||
imgRequest::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel, PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
NS_ASSERTION(mRequest && mChannel, "Got an OnChannelRedirect after we nulled out mRequest!");
|
||||
NS_ASSERTION(mRequest && mChannel, "Got a channel redirect after we nulled out mRequest!");
|
||||
NS_ASSERTION(mChannel == oldChannel, "Got a channel redirect for an unknown channel!");
|
||||
NS_ASSERTION(newChannel, "Got a redirect to a NULL channel!");
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
// Prepare for callback
|
||||
mRedirectCallback = callback;
|
||||
mNewRedirectChannel = newChannel;
|
||||
|
||||
nsCOMPtr<nsIChannelEventSink> sink(do_GetInterface(mPrevChannelSink));
|
||||
if (sink) {
|
||||
rv = sink->OnChannelRedirect(oldChannel, newChannel, flags);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
nsresult rv = sink->AsyncOnChannelRedirect(oldChannel, newChannel, flags,
|
||||
this);
|
||||
if (NS_FAILED(rv)) {
|
||||
mRedirectCallback = nsnull;
|
||||
mNewRedirectChannel = nsnull;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
mChannel = newChannel;
|
||||
(void) OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
imgRequest::OnRedirectVerifyCallback(nsresult result)
|
||||
{
|
||||
NS_ASSERTION(mRedirectCallback, "mRedirectCallback not set in callback");
|
||||
NS_ASSERTION(mNewRedirectChannel, "mNewRedirectChannel not set in callback");
|
||||
|
||||
if (NS_FAILED(result)) {
|
||||
mRedirectCallback->OnRedirectVerifyCallback(result);
|
||||
mRedirectCallback = nsnull;
|
||||
mNewRedirectChannel = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mChannel = mNewRedirectChannel;
|
||||
mNewRedirectChannel = nsnull;
|
||||
|
||||
// Don't make any cache changes if we're going to point to the same thing. We
|
||||
// compare specs and not just URIs here because URIs that compare as
|
||||
|
@ -1149,17 +1176,23 @@ imgRequest::OnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel, PR
|
|||
// make sure we have a protocol that returns data rather than opens
|
||||
// an external application, e.g. mailto:
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
newChannel->GetURI(getter_AddRefs(uri));
|
||||
mChannel->GetURI(getter_AddRefs(uri));
|
||||
PRBool doesNotReturnData = PR_FALSE;
|
||||
rv = NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
|
||||
&doesNotReturnData);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
if (doesNotReturnData)
|
||||
return NS_ERROR_ABORT;
|
||||
nsresult rv =
|
||||
NS_URIChainHasFlags(uri, nsIProtocolHandler::URI_DOES_NOT_RETURN_DATA,
|
||||
&doesNotReturnData);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && doesNotReturnData)
|
||||
rv = NS_ERROR_ABORT;
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
mRedirectCallback->OnRedirectVerifyCallback(rv);
|
||||
mRedirectCallback = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
newChannel->GetOriginalURI(getter_AddRefs(newURI));
|
||||
mChannel->GetOriginalURI(getter_AddRefs(newURI));
|
||||
nsCAutoString newspec;
|
||||
if (newURI)
|
||||
newURI->GetSpec(newspec);
|
||||
|
@ -1186,5 +1219,7 @@ imgRequest::OnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel, PR
|
|||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
mRedirectCallback->OnRedirectVerifyCallback(NS_OK);
|
||||
mRedirectCallback = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "ImageErrors.h"
|
||||
#include "imgIRequest.h"
|
||||
#include "imgContainer.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
class imgCacheValidator;
|
||||
|
||||
|
@ -74,7 +75,8 @@ class imgRequest : public imgIDecoderObserver,
|
|||
public nsIStreamListener,
|
||||
public nsSupportsWeakReference,
|
||||
public nsIChannelEventSink,
|
||||
public nsIInterfaceRequestor
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIAsyncVerifyRedirectCallback
|
||||
{
|
||||
public:
|
||||
imgRequest();
|
||||
|
@ -182,6 +184,7 @@ public:
|
|||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
|
||||
|
||||
private:
|
||||
friend class imgMemoryReporter;
|
||||
|
@ -211,7 +214,8 @@ private:
|
|||
|
||||
imgCacheValidator *mValidator;
|
||||
nsCategoryCache<nsIContentSniffer> mImageSniffers;
|
||||
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
|
||||
nsCOMPtr<nsIChannel> mNewRedirectChannel;
|
||||
// Sometimes consumers want to do things before the image is ready. Let them,
|
||||
// and apply the action when the image becomes available.
|
||||
PRPackedBool mDecodeRequested : 1;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -20,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Honza Bambas <honzab@firemni.cz>
|
||||
* Bjarne Geir Herland <bjarne@runitsoft.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -39,8 +41,13 @@
|
|||
#define nsAsyncRedirectVerifyHelper_h
|
||||
|
||||
#include "nsIRunnable.h"
|
||||
|
||||
#include "nsIThread.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsIChannel;
|
||||
|
||||
|
@ -49,14 +56,27 @@ class nsIChannel;
|
|||
* the sink bound with the channel being redirected while the result of
|
||||
* redirect decision is returned through the callback.
|
||||
*/
|
||||
class nsAsyncRedirectVerifyHelper : public nsIRunnable
|
||||
class nsAsyncRedirectVerifyHelper : public nsIRunnable,
|
||||
public nsIAsyncVerifyRedirectCallback
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIRUNNABLE
|
||||
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
|
||||
|
||||
public:
|
||||
nsAsyncRedirectVerifyHelper();
|
||||
|
||||
/*
|
||||
* Calls AsyncOnChannelRedirect() on the given sink with the given
|
||||
* channels and flags. Keeps track of number of async callbacks to expect.
|
||||
*/
|
||||
nsresult DelegateOnChannelRedirect(nsIChannelEventSink *sink,
|
||||
nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags);
|
||||
|
||||
/**
|
||||
* Initialize and runs the chain of OnChannelRedirect calls. OldChannel
|
||||
* Initialize and run the chain of AsyncOnChannelRedirect calls. OldChannel
|
||||
* is QI'ed for nsIAsyncVerifyRedirectCallback. The result of the redirect
|
||||
* decision is passed through this interface back to the oldChannel.
|
||||
*
|
||||
|
@ -81,8 +101,57 @@ protected:
|
|||
nsCOMPtr<nsIChannel> mNewChan;
|
||||
PRUint32 mFlags;
|
||||
PRBool mWaitingForRedirectCallback;
|
||||
nsCOMPtr<nsIThread> mCallbackThread;
|
||||
PRBool mCallbackInitiated;
|
||||
PRInt32 mExpectedCallbacks;
|
||||
nsresult mResult; // value passed to callback
|
||||
|
||||
void Callback(nsresult result);
|
||||
void InitCallback();
|
||||
|
||||
/**
|
||||
* Calls back to |oldChan| as described in Init()
|
||||
*/
|
||||
void ExplicitCallback(nsresult result);
|
||||
|
||||
private:
|
||||
~nsAsyncRedirectVerifyHelper();
|
||||
|
||||
bool IsOldChannelCanceled();
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper to make the call-stack handle some control-flow for us
|
||||
*/
|
||||
class nsAsyncRedirectAutoCallback
|
||||
{
|
||||
public:
|
||||
nsAsyncRedirectAutoCallback(nsIAsyncVerifyRedirectCallback* aCallback)
|
||||
: mCallback(aCallback)
|
||||
{
|
||||
mResult = NS_OK;
|
||||
}
|
||||
~nsAsyncRedirectAutoCallback()
|
||||
{
|
||||
if (mCallback)
|
||||
mCallback->OnRedirectVerifyCallback(mResult);
|
||||
}
|
||||
/*
|
||||
* Call this is you want it to call back with a different result-code
|
||||
*/
|
||||
void SetResult(nsresult aRes)
|
||||
{
|
||||
mResult = aRes;
|
||||
}
|
||||
/*
|
||||
* Call this is you want to avoid the callback
|
||||
*/
|
||||
void DontCallback()
|
||||
{
|
||||
mCallback = nsnull;
|
||||
}
|
||||
private:
|
||||
nsIAsyncVerifyRedirectCallback* mCallback;
|
||||
nsresult mResult;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
* Gagan Saksena <gagan@netscape.com> (original author)
|
||||
* Darin Fisher <darin@netscape.com>
|
||||
* Christian Biesinger <cbiesinger@web.de>
|
||||
* Bjarne Geir Herland <bjarne@runitsoft.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -42,6 +43,7 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIChannel;
|
||||
interface nsIAsyncVerifyRedirectCallback;
|
||||
|
||||
/**
|
||||
* Implement this interface to receive control over various channel events.
|
||||
|
@ -49,10 +51,9 @@ interface nsIChannel;
|
|||
* notificationCallbacks or, if not available there, from the loadGroup's
|
||||
* notificationCallbacks.
|
||||
*
|
||||
* These methods are called before onStartRequest, and should be handled
|
||||
* SYNCHRONOUSLY.
|
||||
* These methods are called before onStartRequest.
|
||||
*/
|
||||
[scriptable, uuid(6757d790-2916-498e-aaca-6b668a956875)]
|
||||
[scriptable, uuid(a430d870-df77-4502-9570-d46a8de33154)]
|
||||
interface nsIChannelEventSink : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -82,7 +83,30 @@ interface nsIChannelEventSink : nsISupports
|
|||
|
||||
/**
|
||||
* Called when a redirect occurs. This may happen due to an HTTP 3xx status
|
||||
* code.
|
||||
* code. The purpose of this method is to notify the sink that a redirect
|
||||
* is about to happen, but also to give the sink the right to veto the
|
||||
* redirect by throwing or passing a failure-code in the callback.
|
||||
*
|
||||
* Note that vetoing the redirect simply means that |newChannel| will not
|
||||
* be opened. It is important to understand that |oldChannel| will continue
|
||||
* loading as if it received a HTTP 200, which includes notifying observers
|
||||
* and possibly display or process content attached to the HTTP response.
|
||||
* If the sink wants to prevent this loading it must explicitly deal with
|
||||
* it, e.g. by calling |oldChannel->Cancel()|
|
||||
*
|
||||
* There is a certain freedom in implementing this method:
|
||||
*
|
||||
* If the return-value indicates success, a callback on |callback| is
|
||||
* required. This callback can be done from within asyncOnChannelRedirect
|
||||
* (effectively making the call synchronous) or at some point later
|
||||
* (making the call asynchronous). Repeat: A callback must be done
|
||||
* if this method returns successfully.
|
||||
*
|
||||
* If the return value indicates error (method throws an exception)
|
||||
* the redirect is vetoed and no callback must be done. Repeat: No
|
||||
* callback must be done if this method throws!
|
||||
*
|
||||
* @see nsIAsyncVerifyRedirectCallback::onRedirectVerifyCallback()
|
||||
*
|
||||
* @param oldChannel
|
||||
* The channel that's being redirected.
|
||||
|
@ -93,11 +117,14 @@ interface nsIChannelEventSink : nsISupports
|
|||
* of flags from above.
|
||||
* One of REDIRECT_TEMPORARY and REDIRECT_PERMANENT will always be
|
||||
* set.
|
||||
* @param callback
|
||||
* Object to inform about the async result of this method
|
||||
*
|
||||
* @throw <any> Throwing an exception will cancel the load. No network
|
||||
* request for the new channel will be made.
|
||||
* @throw <any> Throwing an exception will cause the redirect to be
|
||||
* cancelled
|
||||
*/
|
||||
void onChannelRedirect(in nsIChannel oldChannel,
|
||||
in nsIChannel newChannel,
|
||||
in unsigned long flags);
|
||||
void asyncOnChannelRedirect(in nsIChannel oldChannel,
|
||||
in nsIChannel newChannel,
|
||||
in unsigned long flags,
|
||||
in nsIAsyncVerifyRedirectCallback callback);
|
||||
};
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -20,6 +21,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Honza Bambas <honzab@firemni.cz>
|
||||
* Bjarne Geir Herland <bjarnw@runitsoft.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -35,6 +37,7 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "prlog.h"
|
||||
#include "nsAsyncRedirectVerifyHelper.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
@ -44,15 +47,60 @@
|
|||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsAsyncRedirectVerifyHelper, nsIRunnable)
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo *gLog = PR_NewLogModule("nsRedirect");
|
||||
#define LOG(args) PR_LOG(gLog, PR_LOG_DEBUG, args)
|
||||
#else
|
||||
#define LOG(args)
|
||||
#endif
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsAsyncRedirectVerifyHelper,
|
||||
nsIAsyncVerifyRedirectCallback,
|
||||
nsIRunnable)
|
||||
|
||||
class nsAsyncVerifyRedirectCallbackEvent : public nsRunnable {
|
||||
public:
|
||||
nsAsyncVerifyRedirectCallbackEvent(nsIAsyncVerifyRedirectCallback *cb,
|
||||
nsresult result)
|
||||
: mCallback(cb), mResult(result) {
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
LOG(("nsAsyncVerifyRedirectCallbackEvent::Run() "
|
||||
"callback to %p with result %x",
|
||||
mCallback.get(), mResult));
|
||||
(void) mCallback->OnRedirectVerifyCallback(mResult);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mCallback;
|
||||
nsresult mResult;
|
||||
};
|
||||
|
||||
nsAsyncRedirectVerifyHelper::nsAsyncRedirectVerifyHelper()
|
||||
: mCallbackInitiated(PR_FALSE),
|
||||
mExpectedCallbacks(0),
|
||||
mResult(NS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
nsAsyncRedirectVerifyHelper::~nsAsyncRedirectVerifyHelper()
|
||||
{
|
||||
NS_ASSERTION(NS_FAILED(mResult) || mExpectedCallbacks == 0,
|
||||
"Did not receive all required callbacks!");
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAsyncRedirectVerifyHelper::Init(nsIChannel* oldChan, nsIChannel* newChan,
|
||||
PRUint32 flags, PRBool synchronize)
|
||||
{
|
||||
mOldChan = oldChan;
|
||||
mNewChan = newChan;
|
||||
mFlags = flags;
|
||||
LOG(("nsAsyncRedirectVerifyHelper::Init() "
|
||||
"oldChan=%p newChan=%p", oldChan, newChan));
|
||||
mOldChan = oldChan;
|
||||
mNewChan = newChan;
|
||||
mFlags = flags;
|
||||
mCallbackThread = do_GetCurrentThread();
|
||||
|
||||
if (synchronize)
|
||||
mWaitingForRedirectCallback = PR_TRUE;
|
||||
|
@ -73,55 +121,172 @@ nsAsyncRedirectVerifyHelper::Init(nsIChannel* oldChan, nsIChannel* newChan,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsAsyncRedirectVerifyHelper::Callback(nsresult result)
|
||||
NS_IMETHODIMP
|
||||
nsAsyncRedirectVerifyHelper::OnRedirectVerifyCallback(nsresult result)
|
||||
{
|
||||
// TODO E10S OnRedirectCallback has to be called on the original process
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> callback(do_QueryInterface(mOldChan));
|
||||
NS_ASSERTION(callback, "nsAsyncRedirectVerifyHelper: oldChannel doesn't"
|
||||
" implement nsIAsyncVerifyRedirectCallback");
|
||||
LOG(("nsAsyncRedirectVerifyHelper::OnRedirectVerifyCallback() "
|
||||
"result=%x expectedCBs=%u mResult=%x",
|
||||
result, mExpectedCallbacks, mResult));
|
||||
|
||||
if (callback)
|
||||
callback->OnRedirectVerifyCallback(result);
|
||||
--mExpectedCallbacks;
|
||||
|
||||
// If response indicates failure we may call back immediately
|
||||
if (NS_FAILED(result)) {
|
||||
// We chose to store the first failure-value (as opposed to the last)
|
||||
if (NS_SUCCEEDED(mResult))
|
||||
mResult = result;
|
||||
|
||||
// If InitCallback() has been called, just invoke the callback and
|
||||
// return. Otherwise it will be invoked from InitCallback()
|
||||
if (mCallbackInitiated) {
|
||||
ExplicitCallback(mResult);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// If the expected-counter is in balance and InitCallback() was called, all
|
||||
// sinks have agreed that the redirect is ok and we can invoke our callback
|
||||
if (mCallbackInitiated && mExpectedCallbacks == 0) {
|
||||
ExplicitCallback(mResult);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAsyncRedirectVerifyHelper::DelegateOnChannelRedirect(nsIChannelEventSink *sink,
|
||||
nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags)
|
||||
{
|
||||
LOG(("nsAsyncRedirectVerifyHelper::DelegateOnChannelRedirect() "
|
||||
"sink=%p expectedCBs=%u mResult=%x",
|
||||
sink, mExpectedCallbacks, mResult));
|
||||
|
||||
++mExpectedCallbacks;
|
||||
|
||||
if (IsOldChannelCanceled()) {
|
||||
LOG((" old channel has been canceled, cancel the redirect by "
|
||||
"emulating OnRedirectVerifyCallback..."));
|
||||
(void) OnRedirectVerifyCallback(NS_BINDING_ABORTED);
|
||||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
nsresult rv =
|
||||
sink->AsyncOnChannelRedirect(oldChannel, newChannel, flags, this);
|
||||
|
||||
LOG((" result=%x expectedCBs=%u", rv, mExpectedCallbacks));
|
||||
|
||||
// If the sink returns failure from this call the redirect is vetoed. We
|
||||
// emulate a callback from the sink in this case in order to perform all
|
||||
// the necessary logic.
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG((" emulating OnRedirectVerifyCallback..."));
|
||||
(void) OnRedirectVerifyCallback(rv);
|
||||
}
|
||||
|
||||
return rv; // Return the actual status since our caller may need it
|
||||
}
|
||||
|
||||
void
|
||||
nsAsyncRedirectVerifyHelper::ExplicitCallback(nsresult result)
|
||||
{
|
||||
LOG(("nsAsyncRedirectVerifyHelper::ExplicitCallback() "
|
||||
"result=%x expectedCBs=%u mCallbackInitiated=%u mResult=%x",
|
||||
result, mExpectedCallbacks, mCallbackInitiated, mResult));
|
||||
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback>
|
||||
callback(do_QueryInterface(mOldChan));
|
||||
|
||||
if (!callback || !mCallbackThread) {
|
||||
LOG(("nsAsyncRedirectVerifyHelper::ExplicitCallback() "
|
||||
"callback=%p mCallbackThread=%p", callback, mCallbackThread));
|
||||
return;
|
||||
}
|
||||
|
||||
mCallbackInitiated = PR_FALSE; // reset to ensure only one callback
|
||||
mWaitingForRedirectCallback = PR_FALSE;
|
||||
|
||||
// Now, dispatch the callback on the event-target which called Init()
|
||||
nsRefPtr<nsIRunnable> event =
|
||||
new nsAsyncVerifyRedirectCallbackEvent(callback, result);
|
||||
if (!event) {
|
||||
NS_WARNING("nsAsyncRedirectVerifyHelper::ExplicitCallback() "
|
||||
"failed creating callback event!");
|
||||
return;
|
||||
}
|
||||
nsresult rv = mCallbackThread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("nsAsyncRedirectVerifyHelper::ExplicitCallback() "
|
||||
"failed dispatching callback event!");
|
||||
} else {
|
||||
LOG(("nsAsyncRedirectVerifyHelper::ExplicitCallback() "
|
||||
"dispatched callback event=%p", event.get()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
nsAsyncRedirectVerifyHelper::InitCallback()
|
||||
{
|
||||
LOG(("nsAsyncRedirectVerifyHelper::InitCallback() "
|
||||
"expectedCBs=%d mResult=%x", mExpectedCallbacks, mResult));
|
||||
|
||||
mCallbackInitiated = PR_TRUE;
|
||||
|
||||
// Invoke the callback if we are done
|
||||
if (mExpectedCallbacks == 0)
|
||||
ExplicitCallback(mResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAsyncRedirectVerifyHelper::Run()
|
||||
{
|
||||
/* If the channel got canceled after it fired AsyncOnChannelRedirect
|
||||
* (bug 546606) and before we got here, mostly because docloader
|
||||
* load has been canceled, we must completely ignore this notification
|
||||
* and prevent any further notification.
|
||||
*
|
||||
* TODO Bug 546606, this must be checked before every single call!
|
||||
* and before we got here, mostly because docloader load has been canceled,
|
||||
* we must completely ignore this notification and prevent any further
|
||||
* notification.
|
||||
*/
|
||||
PRBool canceled;
|
||||
nsCOMPtr<nsIHttpChannelInternal> oldChannelInternal =
|
||||
do_QueryInterface(mOldChan);
|
||||
if (oldChannelInternal) {
|
||||
oldChannelInternal->GetCanceled(&canceled);
|
||||
if (canceled) {
|
||||
Callback(NS_BINDING_ABORTED);
|
||||
return NS_OK;
|
||||
}
|
||||
if (IsOldChannelCanceled()) {
|
||||
ExplicitCallback(NS_BINDING_ABORTED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// First, the global observer
|
||||
NS_ASSERTION(gIOService, "Must have an IO service at this point");
|
||||
nsresult rv = gIOService->OnChannelRedirect(mOldChan, mNewChan, mFlags);
|
||||
LOG(("nsAsyncRedirectVerifyHelper::Run() calling gIOService..."));
|
||||
nsresult rv = gIOService->AsyncOnChannelRedirect(mOldChan, mNewChan,
|
||||
mFlags, this);
|
||||
if (NS_FAILED(rv)) {
|
||||
Callback(rv);
|
||||
ExplicitCallback(rv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Now, the per-channel observers
|
||||
nsCOMPtr<nsIChannelEventSink> sink;
|
||||
NS_QueryNotificationCallbacks(mOldChan, sink);
|
||||
if (sink)
|
||||
rv = sink->OnChannelRedirect(mOldChan, mNewChan, mFlags);
|
||||
if (sink) {
|
||||
LOG(("nsAsyncRedirectVerifyHelper::Run() calling sink..."));
|
||||
rv = DelegateOnChannelRedirect(sink, mOldChan, mNewChan, mFlags);
|
||||
}
|
||||
|
||||
Callback(rv);
|
||||
// All invocations to AsyncOnChannelRedirect has been done - call
|
||||
// InitCallback() to flag this
|
||||
InitCallback();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsAsyncRedirectVerifyHelper::IsOldChannelCanceled()
|
||||
{
|
||||
PRBool canceled;
|
||||
nsCOMPtr<nsIHttpChannelInternal> oldChannelInternal =
|
||||
do_QueryInterface(mOldChan);
|
||||
if (oldChannelInternal) {
|
||||
oldChannelInternal->GetCanceled(&canceled);
|
||||
if (canceled)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -324,13 +324,15 @@ NS_IMPL_THREADSAFE_ISUPPORTS5(nsIOService,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
nsIOService::OnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
|
||||
PRUint32 flags)
|
||||
nsIOService::AsyncOnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
|
||||
PRUint32 flags,
|
||||
nsAsyncRedirectVerifyHelper *helper)
|
||||
{
|
||||
nsCOMPtr<nsIChannelEventSink> sink =
|
||||
do_GetService(NS_GLOBAL_CHANNELEVENTSINK_CONTRACTID);
|
||||
if (sink) {
|
||||
nsresult rv = sink->OnChannelRedirect(oldChan, newChan, flags);
|
||||
nsresult rv = helper->DelegateOnChannelRedirect(sink, oldChan,
|
||||
newChan, flags);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
@ -340,11 +342,11 @@ nsIOService::OnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
|
|||
mChannelEventSinks.GetEntries();
|
||||
PRInt32 len = entries.Count();
|
||||
for (PRInt32 i = 0; i < len; ++i) {
|
||||
nsresult rv = entries[i]->OnChannelRedirect(oldChan, newChan, flags);
|
||||
nsresult rv = helper->DelegateOnChannelRedirect(entries[i], oldChan,
|
||||
newChan, flags);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "nsIContentSniffer.h"
|
||||
#include "nsCategoryCache.h"
|
||||
#include "nsINetworkLinkService.h"
|
||||
#include "nsAsyncRedirectVerifyHelper.h"
|
||||
|
||||
#define NS_N(x) (sizeof(x)/sizeof(*x))
|
||||
|
||||
|
@ -95,8 +96,9 @@ public:
|
|||
|
||||
// Called by channels before a redirect happens. This notifies the global
|
||||
// redirect observers.
|
||||
nsresult OnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
|
||||
PRUint32 flags);
|
||||
nsresult AsyncOnChannelRedirect(nsIChannel* oldChan, nsIChannel* newChan,
|
||||
PRUint32 flags,
|
||||
nsAsyncRedirectVerifyHelper *helper);
|
||||
|
||||
// Gets the array of registered content sniffers
|
||||
const nsCOMArray<nsIContentSniffer>& GetContentSniffers() {
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsIRequestObserver.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIObserver.h"
|
||||
|
@ -126,6 +127,7 @@ class nsIncrementalDownload : public nsIIncrementalDownload
|
|||
, public nsIInterfaceRequestor
|
||||
, public nsIChannelEventSink
|
||||
, public nsSupportsWeakReference
|
||||
, public nsIAsyncVerifyRedirectCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -136,6 +138,7 @@ public:
|
|||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
|
||||
|
||||
nsIncrementalDownload();
|
||||
|
||||
|
@ -150,26 +153,28 @@ private:
|
|||
nsresult ReadCurrentSize();
|
||||
nsresult ClearRequestHeader(nsIHttpChannel *channel);
|
||||
|
||||
nsCOMPtr<nsIRequestObserver> mObserver;
|
||||
nsCOMPtr<nsISupports> mObserverContext;
|
||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mFinalURI;
|
||||
nsCOMPtr<nsILocalFile> mDest;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsAutoArrayPtr<char> mChunk;
|
||||
PRInt32 mChunkLen;
|
||||
PRInt32 mChunkSize;
|
||||
PRInt32 mInterval;
|
||||
nsInt64 mTotalSize;
|
||||
nsInt64 mCurrentSize;
|
||||
PRUint32 mLoadFlags;
|
||||
PRInt32 mNonPartialCount;
|
||||
nsresult mStatus;
|
||||
PRPackedBool mIsPending;
|
||||
PRPackedBool mDidOnStartRequest;
|
||||
PRTime mLastProgressUpdate;
|
||||
nsCOMPtr<nsIRequestObserver> mObserver;
|
||||
nsCOMPtr<nsISupports> mObserverContext;
|
||||
nsCOMPtr<nsIProgressEventSink> mProgressSink;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
nsCOMPtr<nsIURI> mFinalURI;
|
||||
nsCOMPtr<nsILocalFile> mDest;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsAutoArrayPtr<char> mChunk;
|
||||
PRInt32 mChunkLen;
|
||||
PRInt32 mChunkSize;
|
||||
PRInt32 mInterval;
|
||||
nsInt64 mTotalSize;
|
||||
nsInt64 mCurrentSize;
|
||||
PRUint32 mLoadFlags;
|
||||
PRInt32 mNonPartialCount;
|
||||
nsresult mStatus;
|
||||
PRPackedBool mIsPending;
|
||||
PRPackedBool mDidOnStartRequest;
|
||||
PRTime mLastProgressUpdate;
|
||||
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
|
||||
nsCOMPtr<nsIChannel> mNewRedirectChannel;
|
||||
};
|
||||
|
||||
nsIncrementalDownload::nsIncrementalDownload()
|
||||
|
@ -184,6 +189,8 @@ nsIncrementalDownload::nsIncrementalDownload()
|
|||
, mIsPending(PR_FALSE)
|
||||
, mDidOnStartRequest(PR_FALSE)
|
||||
, mLastProgressUpdate(0)
|
||||
, mRedirectCallback(nsnull)
|
||||
, mNewRedirectChannel(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -328,7 +335,7 @@ nsIncrementalDownload::ReadCurrentSize()
|
|||
|
||||
// nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS8(nsIncrementalDownload,
|
||||
NS_IMPL_ISUPPORTS9(nsIncrementalDownload,
|
||||
nsIIncrementalDownload,
|
||||
nsIRequest,
|
||||
nsIStreamListener,
|
||||
|
@ -336,7 +343,8 @@ NS_IMPL_ISUPPORTS8(nsIncrementalDownload,
|
|||
nsIObserver,
|
||||
nsIInterfaceRequestor,
|
||||
nsIChannelEventSink,
|
||||
nsISupportsWeakReference)
|
||||
nsISupportsWeakReference,
|
||||
nsIAsyncVerifyRedirectCallback)
|
||||
|
||||
// nsIRequest
|
||||
|
||||
|
@ -765,9 +773,10 @@ nsIncrementalDownload::ClearRequestHeader(nsIHttpChannel *channel)
|
|||
// nsIChannelEventSink
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIncrementalDownload::OnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags)
|
||||
nsIncrementalDownload::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
// In response to a redirect, we need to propagate the Range header. See bug
|
||||
// 311595. Any failure code returned from this function aborts the redirect.
|
||||
|
@ -792,16 +801,38 @@ nsIncrementalDownload::OnChannelRedirect(nsIChannel *oldChannel,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Prepare to receive callback
|
||||
mRedirectCallback = cb;
|
||||
mNewRedirectChannel = newChannel;
|
||||
|
||||
// Give the observer a chance to see this redirect notification.
|
||||
nsCOMPtr<nsIChannelEventSink> sink = do_GetInterface(mObserver);
|
||||
if (sink)
|
||||
rv = sink->OnChannelRedirect(oldChannel, newChannel, flags);
|
||||
if (sink) {
|
||||
rv = sink->AsyncOnChannelRedirect(oldChannel, newChannel, flags, this);
|
||||
if (NS_FAILED(rv)) {
|
||||
mRedirectCallback = nsnull;
|
||||
mNewRedirectChannel = nsnull;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
(void) OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIncrementalDownload::OnRedirectVerifyCallback(nsresult result)
|
||||
{
|
||||
NS_ASSERTION(mRedirectCallback, "mRedirectCallback not set in callback");
|
||||
NS_ASSERTION(mNewRedirectChannel, "mNewRedirectChannel not set in callback");
|
||||
|
||||
// Update mChannel, so we can Cancel the new channel.
|
||||
if (NS_SUCCEEDED(rv))
|
||||
mChannel = newChannel;
|
||||
if (NS_SUCCEEDED(result))
|
||||
mChannel = mNewRedirectChannel;
|
||||
|
||||
return rv;
|
||||
mRedirectCallback->OnRedirectVerifyCallback(result);
|
||||
mRedirectCallback = nsnull;
|
||||
mNewRedirectChannel = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
extern nsresult
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "nsAutoPtr.h"
|
||||
#include "nsCRT.h"
|
||||
#include "prmon.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -486,8 +487,14 @@ nsPACMan::GetInterface(const nsIID &iid, void **result)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPACMan::OnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel,
|
||||
PRUint32 flags)
|
||||
nsPACMan::AsyncOnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel,
|
||||
PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
return newChannel->GetURI(getter_AddRefs(mPACURI));
|
||||
nsresult rv = NS_OK;
|
||||
if (NS_FAILED((rv = newChannel->GetURI(getter_AddRefs(mPACURI)))))
|
||||
return rv;
|
||||
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsIHttpChannel.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -367,11 +368,13 @@ nsURIChecker::GetInterface(const nsIID & aIID, void **aResult)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsURIChecker::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsURIChecker::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
// We have a new channel
|
||||
mChannel = aNewChannel;
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -3044,6 +3044,7 @@ nsHttpChannel::ContinueProcessRedirectionAfterFallback(nsresult rv)
|
|||
nsresult
|
||||
nsHttpChannel::ContinueProcessRedirection(nsresult rv)
|
||||
{
|
||||
LOG(("ContinueProcessRedirection [rv=%x]\n", rv));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -4366,6 +4367,9 @@ nsHttpChannel::WaitForRedirectCallback()
|
|||
NS_IMETHODIMP
|
||||
nsHttpChannel::OnRedirectVerifyCallback(nsresult result)
|
||||
{
|
||||
LOG(("nsHttpChannel::OnRedirectVerifyCallback [this=%p] "
|
||||
"result=%x stack=%d mWaitingForRedirectCallback=%u\n",
|
||||
this, result, mRedirectFuncStack.Length(), mWaitingForRedirectCallback));
|
||||
NS_ASSERTION(mWaitingForRedirectCallback,
|
||||
"Someone forgot to call WaitForRedirectCallback() ?!");
|
||||
mWaitingForRedirectCallback = PR_FALSE;
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsIHttpHeaderVisitor.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIDNSService.h"
|
||||
|
@ -239,12 +240,14 @@ TestChannelEventSink::~TestChannelEventSink()
|
|||
NS_IMPL_ISUPPORTS1(TestChannelEventSink, nsIChannelEventSink)
|
||||
|
||||
NS_IMETHODIMP
|
||||
TestChannelEventSink::OnChannelRedirect(nsIChannel *channel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags)
|
||||
TestChannelEventSink::AsyncOnChannelRedirect(nsIChannel *channel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
LOG(("\n+++ TestChannelEventSink::OnChannelRedirect (with flags %x) +++\n",
|
||||
flags));
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -149,9 +149,10 @@ ChannelEventSink.prototype = {
|
|||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
onChannelRedirect: function(oldChannel, newChannel, flags) {
|
||||
if (this._flags & ES_ABORT_REDIRECT) {
|
||||
asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback) {
|
||||
if (this._flags & ES_ABORT_REDIRECT)
|
||||
throw Cr.NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
callback.onRedirectVerifyCallback(Cr.NS_OK);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ NotificationCallbacks.prototype = {
|
|||
{
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
onChannelRedirect: function(oldChan, newChan, flags)
|
||||
asyncOnChannelRedirect: function(oldChan, newChan, flags, callback)
|
||||
{
|
||||
do_check_eq(oldChan.URI.spec, this._origURI.spec);
|
||||
do_check_eq(oldChan.URI, this._origURI);
|
||||
|
|
|
@ -31,7 +31,7 @@ var eventsink = {
|
|||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
onChannelRedirect: function eventsink_onredir(oldChan, newChan, flags) {
|
||||
asyncOnChannelRedirect: function eventsink_onredir(oldChan, newChan, flags, callback) {
|
||||
// veto
|
||||
this.called = true;
|
||||
throw NS_BINDING_ABORTED;
|
||||
|
|
|
@ -125,6 +125,7 @@
|
|||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "rdfIDataSource.h"
|
||||
|
@ -901,32 +902,38 @@ RDFXMLDataSourceImpl::SetReadOnly(PRBool aIsReadOnly)
|
|||
// This code is copied from nsSameOriginChecker::OnChannelRedirect. See
|
||||
// bug 475940 on providing this code in a shared location.
|
||||
NS_IMETHODIMP
|
||||
RDFXMLDataSourceImpl::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
RDFXMLDataSourceImpl::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
|
||||
NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> oldPrincipal;
|
||||
secMan->GetChannelPrincipal(aOldChannel, getter_AddRefs(oldPrincipal));
|
||||
nsCOMPtr<nsIPrincipal> oldPrincipal;
|
||||
secMan->GetChannelPrincipal(aOldChannel, getter_AddRefs(oldPrincipal));
|
||||
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
aNewChannel->GetURI(getter_AddRefs(newURI));
|
||||
nsCOMPtr<nsIURI> newOriginalURI;
|
||||
aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
aNewChannel->GetURI(getter_AddRefs(newURI));
|
||||
nsCOMPtr<nsIURI> newOriginalURI;
|
||||
aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
|
||||
|
||||
NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI);
|
||||
NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI);
|
||||
|
||||
rv = oldPrincipal->CheckMayLoad(newURI, PR_FALSE);
|
||||
if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
|
||||
rv = oldPrincipal->CheckMayLoad(newOriginalURI, PR_FALSE);
|
||||
}
|
||||
return rv;
|
||||
rv = oldPrincipal->CheckMayLoad(newURI, PR_FALSE);
|
||||
if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
|
||||
rv = oldPrincipal->CheckMayLoad(newOriginalURI, PR_FALSE);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsNavHistory.h"
|
||||
#include "nsNavBookmarks.h"
|
||||
#include "nsFaviconService.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
|
@ -758,11 +759,13 @@ FetchNetworkIconStep::GetInterface(const nsIID& uuid,
|
|||
|
||||
|
||||
NS_IMETHODIMP
|
||||
FetchNetworkIconStep::OnChannelRedirect(nsIChannel* oldChannel,
|
||||
nsIChannel* newChannel,
|
||||
PRUint32 flags)
|
||||
FetchNetworkIconStep::AsyncOnChannelRedirect(nsIChannel* oldChannel,
|
||||
nsIChannel* newChannel,
|
||||
PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
mChannel = newChannel;
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -111,11 +111,12 @@ StreamListener.prototype = {
|
|||
},
|
||||
|
||||
// nsIChannelEventSink
|
||||
onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) {
|
||||
asyncOnChannelRedirect: function (aOldChannel, aNewChannel, aFlags, callback) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
ghist3.addDocumentRedirect(aOldChannel, aNewChannel, aFlags, true);
|
||||
// If redirecting, store the new channel
|
||||
this.mChannel = aNewChannel;
|
||||
callback.onRedirectVerifyCallback(Components.results.NS_OK);
|
||||
},
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
|
|
|
@ -219,9 +219,10 @@ ChannelListener.prototype = {
|
|||
},
|
||||
|
||||
// nsIChannelEventSink
|
||||
onChannelRedirect: function (aOldChannel, aNewChannel, aFlags) {
|
||||
asyncOnChannelRedirect: function (aOldChannel, aNewChannel, aFlags, callback) {
|
||||
print("onChannelRedirect");
|
||||
this._got_onchannelredirect = true;
|
||||
ghist3.addDocumentRedirect(aOldChannel, aNewChannel, aFlags, true);
|
||||
callback.onRedirectVerifyCallback(Components.results.NS_OK);
|
||||
},
|
||||
};
|
||||
|
|
|
@ -375,9 +375,10 @@ loadListener.prototype = {
|
|||
},
|
||||
|
||||
// nsIChannelEventSink
|
||||
onChannelRedirect: function SRCH_loadCRedirect(aOldChannel, aNewChannel,
|
||||
aFlags) {
|
||||
asyncOnChannelRedirect: function SRCH_loadCRedirect(aOldChannel, aNewChannel,
|
||||
aFlags, callback) {
|
||||
this._channel = aNewChannel;
|
||||
callback.onRedirectVerifyCallback(Components.results.NS_OK);
|
||||
},
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
|
|
|
@ -143,7 +143,7 @@ function BadCertHandler(aAllowNonBuiltInCerts) {
|
|||
BadCertHandler.prototype = {
|
||||
|
||||
// nsIChannelEventSink
|
||||
onChannelRedirect: function(oldChannel, newChannel, flags) {
|
||||
asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback) {
|
||||
if (this.allowNonBuiltInCerts)
|
||||
return;
|
||||
|
||||
|
@ -152,7 +152,9 @@ BadCertHandler.prototype = {
|
|||
// Don't call checkCert for internal redirects. See bug 569648.
|
||||
if (!(flags & Ci.nsIChannelEventSink.REDIRECT_INTERNAL))
|
||||
checkCert(oldChannel);
|
||||
},
|
||||
|
||||
callback.onRedirectVerifyCallback(Components.results.NS_OK);
|
||||
},
|
||||
|
||||
// Suppress any certificate errors
|
||||
notifyCertProblem: function(socketInfo, status, targetSite) {
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
static NS_DEFINE_CID(kThisImplCID, NS_THIS_DOCLOADER_IMPL_CID);
|
||||
|
||||
|
@ -1584,9 +1585,10 @@ PRInt64 nsDocLoader::CalculateMaxProgress()
|
|||
return max;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocLoader::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
NS_IMETHODIMP nsDocLoader::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
if (aOldChannel)
|
||||
{
|
||||
|
@ -1611,6 +1613,7 @@ NS_IMETHODIMP nsDocLoader::OnChannelRedirect(nsIChannel *aOldChannel,
|
|||
FireOnStateChange(this, aOldChannel, stateFlags, NS_OK);
|
||||
}
|
||||
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "prlog.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
static nsOfflineCacheUpdateService *gOfflineCacheUpdateService = nsnull;
|
||||
|
||||
|
@ -283,13 +284,16 @@ nsManifestCheck::GetInterface(const nsIID &aIID, void **aResult)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsManifestCheck::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsManifestCheck::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
// Redirects should cause the load (and therefore the update) to fail.
|
||||
if (aFlags & nsIChannelEventSink::REDIRECT_INTERNAL)
|
||||
if (aFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
aOldChannel->Cancel(NS_ERROR_ABORT);
|
||||
return NS_ERROR_ABORT;
|
||||
}
|
||||
|
@ -491,9 +495,10 @@ nsOfflineCacheUpdateItem::GetInterface(const nsIID &aIID, void **aResult)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOfflineCacheUpdateItem::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsOfflineCacheUpdateItem::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *cb)
|
||||
{
|
||||
if (!(aFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
|
||||
// Don't allow redirect in case of non-internal redirect and cancel
|
||||
|
@ -539,6 +544,7 @@ nsOfflineCacheUpdateItem::OnChannelRedirect(nsIChannel *aOldChannel,
|
|||
|
||||
mChannel = aNewChannel;
|
||||
|
||||
cb->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "prtime.h"
|
||||
#include "prlog.h"
|
||||
#include "plstr.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
|
@ -363,9 +364,10 @@ nsPrefetchNode::GetInterface(const nsIID &aIID, void **aResult)
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrefetchNode::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
nsPrefetchNode::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
nsCOMPtr<nsIURI> newURI;
|
||||
nsresult rv = aNewChannel->GetURI(getter_AddRefs(newURI));
|
||||
|
@ -395,6 +397,7 @@ nsPrefetchNode::OnChannelRedirect(nsIChannel *aOldChannel,
|
|||
|
||||
mChannel = aNewChannel;
|
||||
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#include "CertReader.h"
|
||||
|
||||
#include "nsEmbedCID.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
|
||||
#define PREF_XPINSTALL_ENABLED "xpinstall.enabled"
|
||||
#define PREF_XPINSTALL_CONFIRM_DLG "xpinstall.dialog.confirm"
|
||||
|
@ -1323,11 +1324,19 @@ nsXPInstallManager::GetInterface(const nsIID & eventSinkIID, void* *_retval)
|
|||
|
||||
// nsIChannelEventSink method
|
||||
NS_IMETHODIMP
|
||||
nsXPInstallManager::OnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel, PRUint32 flags)
|
||||
nsXPInstallManager::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIChannel *newChannel,
|
||||
PRUint32 flags,
|
||||
nsIAsyncVerifyRedirectCallback *callback)
|
||||
{
|
||||
// Chrome triggered installs need to have their certificates checked
|
||||
if (mFromChrome)
|
||||
return CheckCert(oldChannel);
|
||||
if (mFromChrome) {
|
||||
nsresult rv = CheckCert(oldChannel);
|
||||
if (NS_FAILED(rv()))
|
||||
return rv;
|
||||
}
|
||||
|
||||
callback->OnRedirectVerifyCallback(NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче