mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 1478171 - [1.0] Forward channel redirect to nsILoadURIDelegate to allow external handling. r=smaug,snorp
This commit is contained in:
parent
d3673a24f2
commit
ee984e1e49
@ -52,6 +52,13 @@ interface nsIChannelEventSink : nsISupports
|
|||||||
*/
|
*/
|
||||||
const unsigned long REDIRECT_STS_UPGRADE = 1 << 3;
|
const unsigned long REDIRECT_STS_UPGRADE = 1 << 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This redirect has already been presented to the nsILoadURIDelegate
|
||||||
|
* for possible handling; if this flag is set we may safely skip checking
|
||||||
|
* if the nsILoadURIDelegate will handle the redirect.
|
||||||
|
*/
|
||||||
|
const unsigned long REDIRECT_DELEGATES_CHECKED = 1 << 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a redirect occurs. This may happen due to an HTTP 3xx status
|
* Called when a redirect occurs. This may happen due to an HTTP 3xx status
|
||||||
* code. The purpose of this method is to notify the sink that a redirect
|
* code. The purpose of this method is to notify the sink that a redirect
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "nspr.h"
|
#include "nspr.h"
|
||||||
#include "mozilla/Logging.h"
|
#include "mozilla/Logging.h"
|
||||||
#include "mozilla/IntegerPrintfMacros.h"
|
#include "mozilla/IntegerPrintfMacros.h"
|
||||||
|
#include "mozilla/dom/Promise.h"
|
||||||
|
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||||
|
|
||||||
#include "nsDocLoader.h"
|
#include "nsDocLoader.h"
|
||||||
#include "nsCURILoader.h"
|
#include "nsCURILoader.h"
|
||||||
@ -34,6 +36,8 @@
|
|||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsPresContext.h"
|
#include "nsPresContext.h"
|
||||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||||
|
#include "nsILoadURIDelegate.h"
|
||||||
|
#include "nsIBrowserDOMWindow.h"
|
||||||
|
|
||||||
using mozilla::DebugOnly;
|
using mozilla::DebugOnly;
|
||||||
using mozilla::LogLevel;
|
using mozilla::LogLevel;
|
||||||
@ -1421,11 +1425,106 @@ int64_t nsDocLoader::CalculateMaxProgress()
|
|||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LoadURIDelegateRedirectHandler final : public mozilla::dom::PromiseNativeHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS(LoadURIDelegateRedirectHandler)
|
||||||
|
|
||||||
|
LoadURIDelegateRedirectHandler(nsDocLoader* aDocLoader,
|
||||||
|
nsIChannel* aOldChannel,
|
||||||
|
nsIChannel* aNewChannel,
|
||||||
|
uint32_t aFlags,
|
||||||
|
nsIAsyncVerifyRedirectCallback* aCallback)
|
||||||
|
: mDocLoader(aDocLoader)
|
||||||
|
, mOldChannel(aOldChannel)
|
||||||
|
, mNewChannel(aNewChannel)
|
||||||
|
, mFlags(aFlags)
|
||||||
|
, mCallback(aCallback)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void
|
||||||
|
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
|
||||||
|
{
|
||||||
|
if (aValue.isBoolean() && aValue.toBoolean()) {
|
||||||
|
// The app handled the redirect, notify the callback
|
||||||
|
mCallback->OnRedirectVerifyCallback(NS_ERROR_ABORT);
|
||||||
|
} else {
|
||||||
|
UnhandledCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
|
||||||
|
{
|
||||||
|
UnhandledCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
~LoadURIDelegateRedirectHandler()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void UnhandledCallback()
|
||||||
|
{
|
||||||
|
// If the redirect wasn't handled by the nsILoadURIDelegate, let Gecko
|
||||||
|
// handle it.
|
||||||
|
mFlags |= nsIChannelEventSink::REDIRECT_DELEGATES_CHECKED;
|
||||||
|
mDocLoader->AsyncOnChannelRedirect(mOldChannel, mNewChannel, mFlags,
|
||||||
|
mCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<nsDocLoader> mDocLoader;
|
||||||
|
nsCOMPtr<nsIChannel> mOldChannel;
|
||||||
|
nsCOMPtr<nsIChannel> mNewChannel;
|
||||||
|
uint32_t mFlags;
|
||||||
|
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION(LoadURIDelegateRedirectHandler, mDocLoader,
|
||||||
|
mOldChannel, mNewChannel, mCallback)
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(LoadURIDelegateRedirectHandler)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||||
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(LoadURIDelegateRedirectHandler)
|
||||||
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(LoadURIDelegateRedirectHandler)
|
||||||
|
|
||||||
NS_IMETHODIMP nsDocLoader::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
NS_IMETHODIMP nsDocLoader::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
||||||
nsIChannel *aNewChannel,
|
nsIChannel *aNewChannel,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
nsIAsyncVerifyRedirectCallback *cb)
|
nsIAsyncVerifyRedirectCallback *cb)
|
||||||
{
|
{
|
||||||
|
if ((aFlags &
|
||||||
|
(nsIChannelEventSink::REDIRECT_TEMPORARY |
|
||||||
|
nsIChannelEventSink::REDIRECT_PERMANENT)) &&
|
||||||
|
!(aFlags & nsIChannelEventSink::REDIRECT_DELEGATES_CHECKED)) {
|
||||||
|
nsCOMPtr<nsIDocShell> docShell =
|
||||||
|
do_QueryInterface(static_cast<nsIRequestObserver*>(this));
|
||||||
|
|
||||||
|
nsCOMPtr<nsILoadURIDelegate> delegate;
|
||||||
|
docShell->GetLoadURIDelegate(getter_AddRefs(delegate));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> newURI;
|
||||||
|
aNewChannel->GetURI(getter_AddRefs(newURI));
|
||||||
|
|
||||||
|
if (newURI && delegate) {
|
||||||
|
RefPtr<mozilla::dom::Promise> promise;
|
||||||
|
const int where = nsIBrowserDOMWindow::OPEN_CURRENTWINDOW;
|
||||||
|
nsresult rv = delegate->LoadURI(newURI, where, /* flags */ 0,
|
||||||
|
/* triggering principal */ nullptr,
|
||||||
|
getter_AddRefs(promise));
|
||||||
|
if (NS_SUCCEEDED(rv) && promise) {
|
||||||
|
RefPtr<LoadURIDelegateRedirectHandler> handler =
|
||||||
|
new LoadURIDelegateRedirectHandler(this, aOldChannel, aNewChannel,
|
||||||
|
aFlags, cb);
|
||||||
|
|
||||||
|
promise->AppendNativeHandler(handler);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (aOldChannel)
|
if (aOldChannel)
|
||||||
{
|
{
|
||||||
nsLoadFlags loadFlags = 0;
|
nsLoadFlags loadFlags = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user