зеркало из https://github.com/mozilla/gecko-dev.git
Bug 457153. Introduce an nsILoadContext interface so that consumers can get load context information from a channel/loadgroup without having to depend on getInterface of docshell stuff. r=dwitte for cookie part, r=jst for rest, sr=jst, a=beltzner for CLOSED TREE
This commit is contained in:
Родитель
2e8581a986
Коммит
a2b28f6144
|
@ -162,11 +162,8 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
|
|||
#include "nsIDocumentLoaderFactory.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIXMLContentSink.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsContentErrors.h"
|
||||
#include "nsIXULDocument.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsISecurityEventSink.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIPropertyBag2.h"
|
||||
|
||||
|
@ -1137,30 +1134,58 @@ nsExternalResourceMap::PendingLoad::StartLoad(nsIURI* aURI,
|
|||
NS_IMPL_ISUPPORTS1(nsExternalResourceMap::LoadgroupCallbacks,
|
||||
nsIInterfaceRequestor)
|
||||
|
||||
#define IMPL_SHIM(_i) \
|
||||
NS_IMPL_ISUPPORTS1(nsExternalResourceMap::LoadgroupCallbacks::_i##Shim, _i)
|
||||
|
||||
IMPL_SHIM(nsILoadContext)
|
||||
IMPL_SHIM(nsIProgressEventSink);
|
||||
IMPL_SHIM(nsIChannelEventSink);
|
||||
IMPL_SHIM(nsISecurityEventSink);
|
||||
IMPL_SHIM(nsIApplicationCacheContainer);
|
||||
|
||||
#undef IMPL_SHIM
|
||||
|
||||
#define IID_IS(_i) aIID.Equals(NS_GET_IID(_i))
|
||||
|
||||
#define TRY_SHIM(_i) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (IID_IS(_i)) { \
|
||||
nsCOMPtr<_i> real = do_GetInterface(mCallbacks); \
|
||||
if (!real) { \
|
||||
return NS_NOINTERFACE; \
|
||||
} \
|
||||
nsCOMPtr<_i> shim = new _i##Shim(this, real); \
|
||||
if (!shim) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
*aSink = shim.forget().get(); \
|
||||
return NS_OK; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExternalResourceMap::LoadgroupCallbacks::GetInterface(const nsIID & aIID,
|
||||
void **aSink)
|
||||
{
|
||||
#define IID_IS(_i) aIID.Equals(NS_GET_IID(_i))
|
||||
if (mCallbacks &&
|
||||
(IID_IS(nsIProgressEventSink) ||
|
||||
IID_IS(nsIChannelEventSink) ||
|
||||
IID_IS(nsISecurityEventSink) ||
|
||||
IID_IS(nsIPrompt) ||
|
||||
IID_IS(nsIAuthPrompt) ||
|
||||
IID_IS(nsIAuthPrompt2) ||
|
||||
IID_IS(nsIApplicationCacheContainer) ||
|
||||
// XXXbz evil hack for cookies for now
|
||||
IID_IS(nsIDOMWindow) ||
|
||||
IID_IS(nsIDocShellTreeItem))) {
|
||||
(IID_IS(nsIPrompt) || IID_IS(nsIAuthPrompt) || IID_IS(nsIAuthPrompt2))) {
|
||||
return mCallbacks->GetInterface(aIID, aSink);
|
||||
}
|
||||
#undef IID_IS
|
||||
|
||||
*aSink = nsnull;
|
||||
|
||||
TRY_SHIM(nsILoadContext);
|
||||
TRY_SHIM(nsIProgressEventSink);
|
||||
TRY_SHIM(nsIChannelEventSink);
|
||||
TRY_SHIM(nsISecurityEventSink);
|
||||
TRY_SHIM(nsIApplicationCacheContainer);
|
||||
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
#undef TRY_SHIM
|
||||
#undef IID_IS
|
||||
|
||||
nsExternalResourceMap::ExternalResource::~ExternalResource()
|
||||
{
|
||||
if (mViewer) {
|
||||
|
|
|
@ -110,6 +110,10 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsIDocumentViewer.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsISecurityEventSink.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
|
||||
#define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0)
|
||||
#define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1)
|
||||
|
@ -496,7 +500,42 @@ protected:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
private:
|
||||
// The only reason it's safe to hold a strong ref here without leaking is
|
||||
// that the notificationCallbacks on a loadgroup aren't the docshell itself
|
||||
// but a shim that holds a weak reference to the docshell.
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
|
||||
// Use shims for interfaces that docshell implements directly so that we
|
||||
// don't hand out references to the docshell. The shims should all allow
|
||||
// getInterface back on us, but other than that each one should only
|
||||
// implement one interface.
|
||||
|
||||
// XXXbz I wish we could just derive the _allcaps thing from _i
|
||||
#define DECL_SHIM(_i, _allcaps) \
|
||||
class _i##Shim : public nsIInterfaceRequestor, \
|
||||
public _i \
|
||||
{ \
|
||||
public: \
|
||||
_i##Shim(nsIInterfaceRequestor* aIfreq, _i* aRealPtr) \
|
||||
: mIfReq(aIfreq), mRealPtr(aRealPtr) \
|
||||
{ \
|
||||
NS_ASSERTION(mIfReq, "Expected non-null here"); \
|
||||
NS_ASSERTION(mRealPtr, "Expected non-null here"); \
|
||||
} \
|
||||
NS_DECL_ISUPPORTS \
|
||||
NS_FORWARD_NSIINTERFACEREQUESTOR(mIfReq->); \
|
||||
NS_FORWARD_##_allcaps(mRealPtr->); \
|
||||
private: \
|
||||
nsCOMPtr<nsIInterfaceRequestor> mIfReq; \
|
||||
nsCOMPtr<_i> mRealPtr; \
|
||||
};
|
||||
|
||||
DECL_SHIM(nsILoadContext, NSILOADCONTEXT)
|
||||
DECL_SHIM(nsIProgressEventSink, NSIPROGRESSEVENTSINK)
|
||||
DECL_SHIM(nsIChannelEventSink, NSICHANNELEVENTSINK)
|
||||
DECL_SHIM(nsISecurityEventSink, NSISECURITYEVENTSINK)
|
||||
DECL_SHIM(nsIApplicationCacheContainer, NSIAPPLICATIONCACHECONTAINER)
|
||||
#undef DECL_SHIM
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -116,7 +116,8 @@ XPIDLSRCS = \
|
|||
nsIWebPageDescriptor.idl \
|
||||
nsIURIClassifier.idl \
|
||||
nsIChannelClassifier.idl \
|
||||
nsIDownloadHistory.idl \
|
||||
nsIDownloadHistory.idl \
|
||||
nsILoadContext.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = nsDocShellLoadTypes.h
|
||||
|
|
|
@ -436,6 +436,7 @@ NS_INTERFACE_MAP_BEGIN(nsDocShell)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIWebPageDescriptor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsILoadContext)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDocLoader)
|
||||
|
||||
///*****************************************************************************
|
||||
|
@ -9534,6 +9535,52 @@ nsDocShell::Observe(nsISupports *aSubject, const char *aTopic,
|
|||
return rv;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsDocShell::nsILoadContext
|
||||
//*****************************************************************************
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetAssociatedWindow(nsIDOMWindow** aWindow)
|
||||
{
|
||||
return CallGetInterface(this, aWindow);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetTopWindow(nsIDOMWindow** aWindow)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDOMWindow> win = do_GetInterface(GetAsSupports(this), &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return win->GetTop(aWindow);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::IsAppOfType(PRUint32 aAppType, PRBool *aIsOfType)
|
||||
{
|
||||
nsCOMPtr<nsIDocShell> shell = this;
|
||||
while (shell) {
|
||||
PRUint32 type;
|
||||
shell->GetAppType(&type);
|
||||
if (type == aAppType) {
|
||||
*aIsOfType = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(shell);
|
||||
nsCOMPtr<nsIDocShellTreeItem> parent;
|
||||
item->GetParent(getter_AddRefs(parent));
|
||||
shell = do_QueryInterface(parent);
|
||||
}
|
||||
|
||||
*aIsOfType = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetIsContent(PRBool *aIsContent)
|
||||
{
|
||||
*aIsContent = (mItemType == typeContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsDocShell::URIInheritsSecurityContext(nsIURI* aURI, PRBool* aResult)
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
#include "nsPIDOMEventTarget.h"
|
||||
#include "nsIURIClassifier.h"
|
||||
#include "nsIChannelClassifier.h"
|
||||
#include "nsILoadContext.h"
|
||||
|
||||
class nsIScrollableView;
|
||||
class nsDocShell;
|
||||
|
@ -185,7 +186,8 @@ class nsDocShell : public nsDocLoader,
|
|||
public nsIEditorDocShell,
|
||||
public nsIWebPageDescriptor,
|
||||
public nsIAuthPromptProvider,
|
||||
public nsIObserver
|
||||
public nsIObserver,
|
||||
public nsILoadContext
|
||||
{
|
||||
friend class nsDSURIContentListener;
|
||||
|
||||
|
@ -214,6 +216,7 @@ public:
|
|||
NS_DECL_NSIWEBPAGEDESCRIPTOR
|
||||
NS_DECL_NSIAUTHPROMPTPROVIDER
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSILOADCONTEXT
|
||||
|
||||
NS_IMETHOD Stop() {
|
||||
// Need this here because otherwise nsIWebNavigation::Stop
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: ft=cpp tw=78 sw=2 et ts=2 sts=2 cin
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Boris Zbarsky <bzbarsky@mit.edu> (original author)
|
||||
*
|
||||
* 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
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIDOMWindow;
|
||||
|
||||
/**
|
||||
* An nsILoadContext represents the context of a load. This interface
|
||||
* can be queried for various information about where the load is
|
||||
* happening.
|
||||
*/
|
||||
[scriptable, uuid(314d8a54-1caf-4721-94d7-f6c82d9b82ed)]
|
||||
interface nsILoadContext : nsISupports
|
||||
{
|
||||
/**
|
||||
* associatedWindow is the window with which the load is associated, if any.
|
||||
* Note that the load may be triggered by a document which is different from
|
||||
* the document in associatedWindow, and in fact the source of the load need
|
||||
* not be same-origin with the document in associatedWindow. This attribute
|
||||
* may be null if there is no associated window.
|
||||
*/
|
||||
readonly attribute nsIDOMWindow associatedWindow;
|
||||
|
||||
/**
|
||||
* topWindow is the top window which is of same type as associatedWindow.
|
||||
* This is equivalent to associatedWindow.top, but is provided here as a
|
||||
* convenience. All the same caveats as associatedWindow of apply, of
|
||||
* course. This attribute may be null if there is no associated window.
|
||||
*/
|
||||
readonly attribute nsIDOMWindow topWindow;
|
||||
|
||||
/**
|
||||
* Check whether the load is happening in a particular type of application.
|
||||
*
|
||||
* @param an application type. For now, the constants to be passed here are
|
||||
* the nsIDocShell APP_TYPE_* constants.
|
||||
*
|
||||
* @return whether there is some ancestor of the associatedWindow that is of
|
||||
* the given app type.
|
||||
*/
|
||||
boolean isAppOfType(in unsigned long appType);
|
||||
|
||||
/**
|
||||
* True if the load context is content (as opposed to chrome). This is
|
||||
* determined based on the type of window the load is performed in, NOT based
|
||||
* on any URIs that might be around.
|
||||
*/
|
||||
readonly attribute boolean isContent;
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
// vim:ts=2:sw=2:et:
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:ts=2:sw=2:et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -49,15 +50,15 @@
|
|||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
|
||||
/****************************************************************
|
||||
************************ nsCookiePermission ********************
|
||||
|
@ -91,6 +92,7 @@ static const char kPermissionType[] = "cookie";
|
|||
|
||||
#ifdef MOZ_MAIL_NEWS
|
||||
// returns PR_TRUE if URI appears to be the URI of a mailnews protocol
|
||||
// XXXbz this should be a protocol flag, not a scheme list, dammit!
|
||||
static PRBool
|
||||
IsFromMailNews(nsIURI *aURI)
|
||||
{
|
||||
|
@ -208,35 +210,21 @@ nsCookiePermission::CanAccess(nsIURI *aURI,
|
|||
// disable cookies in mailnews if user's prefs say so
|
||||
if (mCookiesDisabledForMailNews) {
|
||||
//
|
||||
// try to examine the "app type" of the docshell owning this request. if
|
||||
// we find a docshell in the heirarchy of type APP_TYPE_MAIL, then assume
|
||||
// this URI is being loaded from within mailnews.
|
||||
//
|
||||
// XXX this is a pretty ugly hack at the moment since cookies really
|
||||
// shouldn't have to talk to the docshell directly. ultimately, we want
|
||||
// to talk to some more generic interface, which the docshell would also
|
||||
// implement. but, the basic mechanism here of leveraging the channel's
|
||||
// (or loadgroup's) notification callbacks attribute seems ideal as it
|
||||
// avoids the problem of having to modify all places in the code which
|
||||
// kick off network requests.
|
||||
//
|
||||
PRUint32 appType = nsIDocShell::APP_TYPE_UNKNOWN;
|
||||
// try to examine the "app type" of the window owning this request. if it
|
||||
// or some ancestor is of type APP_TYPE_MAIL, then assume this URI is being
|
||||
// loaded from within mailnews.
|
||||
PRBool isMail = PR_FALSE;
|
||||
if (aChannel) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item, parent;
|
||||
NS_QueryNotificationCallbacks(aChannel, parent);
|
||||
if (parent) {
|
||||
do {
|
||||
item = parent;
|
||||
nsCOMPtr<nsIDocShell> docshell = do_QueryInterface(item);
|
||||
if (docshell)
|
||||
docshell->GetAppType(&appType);
|
||||
} while (appType != nsIDocShell::APP_TYPE_MAIL &&
|
||||
NS_SUCCEEDED(item->GetParent(getter_AddRefs(parent))) &&
|
||||
parent);
|
||||
nsCOMPtr<nsILoadContext> ctx;
|
||||
NS_QueryNotificationCallbacks(aChannel, ctx);
|
||||
if (ctx) {
|
||||
PRBool temp;
|
||||
isMail =
|
||||
NS_FAILED(ctx->IsAppOfType(nsIDocShell::APP_TYPE_MAIL, &temp)) ||
|
||||
temp;
|
||||
}
|
||||
}
|
||||
if ((appType == nsIDocShell::APP_TYPE_MAIL) ||
|
||||
IsFromMailNews(aURI)) {
|
||||
if (isMail || IsFromMailNews(aURI)) {
|
||||
*aResult = ACCESS_DENY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -350,8 +338,13 @@ nsCookiePermission::CanSetCookie(nsIURI *aURI,
|
|||
|
||||
// try to get a nsIDOMWindow from the channel...
|
||||
nsCOMPtr<nsIDOMWindow> parent;
|
||||
if (aChannel)
|
||||
NS_QueryNotificationCallbacks(aChannel, parent);
|
||||
if (aChannel) {
|
||||
nsCOMPtr<nsILoadContext> ctx;
|
||||
NS_QueryNotificationCallbacks(aChannel, ctx);
|
||||
if (ctx) {
|
||||
ctx->GetAssociatedWindow(getter_AddRefs(parent));
|
||||
}
|
||||
}
|
||||
|
||||
// get some useful information to present to the user:
|
||||
// whether a previous cookie already exists, and how many cookies this host
|
||||
|
@ -426,35 +419,27 @@ nsCookiePermission::GetOriginatingURI(nsIChannel *aChannel,
|
|||
nsIURI **aURI)
|
||||
{
|
||||
/* to find the originating URI, we use the loadgroup of the channel to obtain
|
||||
* the docshell owning the load, and from there, we find the root content
|
||||
* docshell and its URI. there are several possible cases:
|
||||
* the window owning the load, and from there, we find the top same-type
|
||||
* window and its URI. there are several possible cases:
|
||||
*
|
||||
* 1) no channel. this will occur for plugins using the nsICookieStorage
|
||||
* interface, since they have none to provide. other consumers should
|
||||
* have a channel.
|
||||
*
|
||||
* 2) a channel, but no docshell. this can occur when the consumer kicking
|
||||
* 2) a channel, but no window. this can occur when the consumer kicking
|
||||
* off the load doesn't provide one to the channel, and should be limited
|
||||
* to loads of certain types of resources (e.g. favicons).
|
||||
* to loads of certain types of resources.
|
||||
*
|
||||
* 3) a non-content docshell. this occurs for loads kicked off from chrome,
|
||||
* where no content docshell exists (favicons can also fall into this
|
||||
* category).
|
||||
* 3) a window equal to the top window of same type, with the channel its
|
||||
* document channel. this covers the case of a freshly kicked-off load
|
||||
* (e.g. the user typing something in the location bar, or clicking on a
|
||||
* bookmark), where the window's URI hasn't yet been set, and will be
|
||||
* bogus. we return the channel URI in this case.
|
||||
*
|
||||
* 4) a content docshell equal to the root content docshell, with channel
|
||||
* loadflags LOAD_DOCUMENT_URI. this covers the case of a freshly kicked-
|
||||
* off load (e.g. the user typing something in the location bar, or
|
||||
* clicking on a bookmark), where the currentURI hasn't yet been set,
|
||||
* and will be bogus. we return the channel URI in this case. note that
|
||||
* we could also allow non-content docshells here, but that goes against
|
||||
* the philosophy of having an audit trail back to a URI the user typed
|
||||
* or clicked on.
|
||||
*
|
||||
* 5) a root content docshell. this covers most cases for an ordinary page
|
||||
* load from the location bar, and will catch nested frames within
|
||||
* a page, image loads, etc. we return the URI of the docshell's principal
|
||||
* 4) Anything else. this covers most cases for an ordinary page load from
|
||||
* the location bar, and will catch nested frames within a page, image
|
||||
* loads, etc. we return the URI of the root window's document's principal
|
||||
* in this case.
|
||||
*
|
||||
*/
|
||||
|
||||
*aURI = nsnull;
|
||||
|
@ -463,27 +448,29 @@ nsCookiePermission::GetOriginatingURI(nsIChannel *aChannel,
|
|||
if (!aChannel)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// find the docshell and its root
|
||||
nsCOMPtr<nsIDocShellTreeItem> docshell, root;
|
||||
NS_QueryNotificationCallbacks(aChannel, docshell);
|
||||
if (docshell)
|
||||
docshell->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
// find the associated window and its top window
|
||||
nsCOMPtr<nsILoadContext> ctx;
|
||||
NS_QueryNotificationCallbacks(aChannel, ctx);
|
||||
nsCOMPtr<nsIDOMWindow> topWin, ourWin;
|
||||
if (ctx) {
|
||||
ctx->GetTopWindow(getter_AddRefs(topWin));
|
||||
ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
|
||||
}
|
||||
|
||||
PRInt32 type;
|
||||
if (root)
|
||||
root->GetItemType(&type);
|
||||
|
||||
// cases 2) and 3)
|
||||
if (!root || type != nsIDocShellTreeItem::typeContent)
|
||||
// case 2)
|
||||
if (!topWin)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// case 4)
|
||||
if (docshell == root) {
|
||||
// case 3)
|
||||
if (ourWin == topWin) {
|
||||
// Check whether this is the document channel for this window (representing
|
||||
// a load of a new page). This is a bit of a nasty hack, but we will
|
||||
// hopefully flag these channels better later.
|
||||
nsLoadFlags flags;
|
||||
aChannel->GetLoadFlags(&flags);
|
||||
|
||||
if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
|
||||
// get the channel URI - the docshell's will be bogus
|
||||
// get the channel URI - the window's will be bogus
|
||||
aChannel->GetURI(aURI);
|
||||
if (!*aURI)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
@ -492,15 +479,14 @@ nsCookiePermission::GetOriginatingURI(nsIChannel *aChannel,
|
|||
}
|
||||
}
|
||||
|
||||
// case 5) - get the originating URI from the docshell's principal
|
||||
nsCOMPtr<nsIWebNavigation> webnav = do_QueryInterface(root);
|
||||
if (webnav) {
|
||||
nsCOMPtr<nsIDOMDocument> doc;
|
||||
webnav->GetDocument(getter_AddRefs(doc));
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(doc);
|
||||
if (node)
|
||||
node->NodePrincipal()->GetURI(aURI);
|
||||
}
|
||||
// case 4) - get the originating URI from the top window's principal
|
||||
nsCOMPtr<nsIScriptObjectPrincipal> scriptObjPrin = do_QueryInterface(topWin);
|
||||
NS_ENSURE_TRUE(scriptObjPrin, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsIPrincipal* prin = scriptObjPrin->GetPrincipal();
|
||||
NS_ENSURE_TRUE(prin, NS_ERROR_UNEXPECTED);
|
||||
|
||||
prin->GetURI(aURI);
|
||||
|
||||
if (!*aURI)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
|
Загрузка…
Ссылка в новой задаче