Bug 1319111 - Expose URI to make security check against on LoadInfo (no LOAD_REPLACE flag). r=bz

This commit is contained in:
Honza Bambas 2017-01-27 19:10:01 +01:00
Родитель 4b5525bbf7
Коммит a1b64b4694
40 изменённых файлов: 223 добавлений и 122 удалений

Просмотреть файл

@ -145,6 +145,7 @@ function testRegister(assert, text) {
var channel = ios.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
channel.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
return channel;
},
getURIFlags: function(aURI) {

Просмотреть файл

@ -172,27 +172,23 @@ AboutRedirector::NewChannel(nsIURI* aURI,
rv = NS_NewURI(getter_AddRefs(tempURI), url);
NS_ENSURE_SUCCESS(rv, rv);
// If tempURI links to an external URI (i.e. something other than
// chrome:// or resource://) then set the LOAD_REPLACE flag on the
// channel which forces the channel owner to reflect the displayed
// URL rather then being the systemPrincipal.
// If tempURI links to an internal URI (chrome://, resource://)
// then set the result principal URL on the channel's load info.
// Otherwise, we leave it null which forces the channel principal
// to reflect the displayed URL rather than being the systemPrincipal.
bool isUIResource = false;
rv = NS_URIChainHasFlags(tempURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
&isUIResource);
NS_ENSURE_SUCCESS(rv, rv);
nsLoadFlags loadFlags = isUIResource
? static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL)
: static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);
rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
tempURI,
aLoadInfo,
nullptr, // aLoadGroup
nullptr, // aCallbacks
loadFlags);
aLoadInfo);
NS_ENSURE_SUCCESS(rv, rv);
if (isUIResource) {
aLoadInfo->SetResultPrincipalURI(aURI);
}
tempChannel->SetOriginalURI(aURI);
NS_ADDREF(*result = tempChannel);

Просмотреть файл

@ -253,6 +253,7 @@ FeedConverter.prototype = {
let aboutFeedsURI = ios.newURI("about:feeds");
chromeChannel = ios.newChannelFromURIWithLoadInfo(aboutFeedsURI, loadInfo);
chromeChannel.originalURI = result.uri;
loadInfo.resultPrincipalURI = result.uri;
// carry the origin attributes from the channel that loaded the feed.
chromeChannel.owner =
@ -560,10 +561,12 @@ GenericProtocolHandler.prototype = {
const schemeId = this._getTelemetrySchemeId();
Services.telemetry.getHistogramById("FEED_PROTOCOL_USAGE").add(schemeId);
if (channel instanceof Components.interfaces.nsIHttpChannel)
if (channel instanceof Components.interfaces.nsIHttpChannel) {
// Set this so we know this is supposed to be a feed
channel.setRequestHeader("X-Moz-Is-Feed", "1", false);
}
channel.originalURI = aUri;
aLoadInfo.resultPrincipalURI = aUri;
return channel;
},

Просмотреть файл

@ -26,6 +26,7 @@ let TestAboutPage = {
let channel = Services.io.newChannelFromURIWithLoadInfo(newURI,
aLoadInfo);
channel.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
return channel;
},

Просмотреть файл

@ -1003,6 +1003,7 @@ PdfStreamConverter.prototype = {
// Keep the URL the same so the browser sees it as the same.
channel.originalURI = aRequest.URI;
channel.loadInfo.resultPrincipalURI = aRequest.loadInfo.resultPrincipalURI;
channel.loadGroup = aRequest.loadGroup;
channel.loadInfo.originAttributes = aRequest.loadInfo.originAttributes;

Просмотреть файл

@ -40,6 +40,7 @@ AboutPage.prototype = {
let channel = Services.io.newChannelFromURIWithLoadInfo(newURI,
aLoadInfo);
channel.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
if (this.uriFlags & Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT) {
let principal = Services.scriptSecurityManager.getNoAppCodebasePrincipal(aURI);

Просмотреть файл

@ -168,12 +168,11 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI,
// Make sure that the channel remembers where it was
// originally loaded from.
nsLoadFlags loadFlags = 0;
result->GetLoadFlags(&loadFlags);
result->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE);
rv = result->SetOriginalURI(aURI);
if (NS_FAILED(rv)) return rv;
aLoadInfo->SetResultPrincipalURI(aURI);
// Get a system principal for content files and set the owner
// property of the result
nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);

Просмотреть файл

@ -26,6 +26,10 @@ AboutURL.prototype = {
newChannel: function (aURI, aLoadInfo) {
let chan = Services.io.newChannelFromURIWithLoadInfo(this.uri, aLoadInfo);
chan.owner = Services.scriptSecurityManager.getSystemPrincipal();
// Must set the result principal URI _after_ we've created the channel
// since the chrome protocol would overwrite it with a chrome:// URL.
aLoadInfo.resultPrincipalURI = aURI;
return chan;
},

Просмотреть файл

@ -174,10 +174,10 @@ nsAboutRedirector::NewChannel(nsIURI* aURI,
rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url);
NS_ENSURE_SUCCESS(rv, rv);
// If tempURI links to an external URI (i.e. something other than
// chrome:// or resource://) then set the LOAD_REPLACE flag on the
// channel which forces the channel owner to reflect the displayed
// URL rather then being the systemPrincipal.
// If tempURI links to an internal URI (chrome://, resource://, about:)
// then set the result principal URL on the channel's load info.
// Otherwise, we leave it null which forces the channel principal
// to reflect the displayed URL rather than being the systemPrincipal.
bool isUIResource = false;
rv = NS_URIChainHasFlags(tempURI, nsIProtocolHandler::URI_IS_UI_RESOURCE,
&isUIResource);
@ -185,18 +185,14 @@ nsAboutRedirector::NewChannel(nsIURI* aURI,
bool isAboutBlank = NS_IsAboutBlank(tempURI);
nsLoadFlags loadFlags = isUIResource || isAboutBlank
? static_cast<nsLoadFlags>(nsIChannel::LOAD_NORMAL)
: static_cast<nsLoadFlags>(nsIChannel::LOAD_REPLACE);
rv = NS_NewChannelInternal(getter_AddRefs(tempChannel),
tempURI,
aLoadInfo,
nullptr, // aLoadGroup
nullptr, // aCallbacks
loadFlags);
aLoadInfo);
NS_ENSURE_SUCCESS(rv, rv);
if (isUIResource || isAboutBlank) {
aLoadInfo->SetResultPrincipalURI(aURI);
}
tempChannel->SetOriginalURI(aURI);
tempChannel.forget(aResult);

Просмотреть файл

@ -11173,6 +11173,12 @@ nsDocShell::DoURILoad(nsIURI* aURI,
if (aOriginalURI) {
channel->SetOriginalURI(aOriginalURI);
// The LOAD_REPLACE flag and its handling here will be removed as part
// of bug 1319110. For now preserve its restoration here to not break
// any code expecting it being set specially on redirected channels.
// If the flag has originally been set to change result of
// NS_GetFinalChannelURI it won't have any effect and also won't cause
// any harm.
if (aLoadReplace) {
uint32_t loadFlags;
channel->GetLoadFlags(&loadFlags);

Просмотреть файл

@ -864,6 +864,8 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
}
channel->SetOriginalURI(uri);
aLoadInfo->SetResultPrincipalURI(uri);
channel->SetContentType(NS_ConvertUTF16toUTF8(contentType));
channel->SetContentLength(size);

Просмотреть файл

@ -2412,6 +2412,7 @@ nsHTMLDocument::CreateAndAddWyciwygChannel(void)
channel->SetLoadFlags(loadFlags);
channel->SetOriginalURI(wcwgURI);
loadInfo->SetResultPrincipalURI(wcwgURI);
rv = loadGroup->AddRequest(mWyciwygChannel, nullptr);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to add request to load group.");

Просмотреть файл

@ -123,6 +123,7 @@ AboutRedirector.prototype = {
}
channel.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
return channel;
}

Просмотреть файл

@ -38,6 +38,7 @@ AboutFlyWeb.prototype = Object.freeze({
let uri = Services.io.newURI("chrome://flyweb/content/aboutFlyWeb.xhtml");
let channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
channel.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
return channel;
}
});

Просмотреть файл

@ -269,6 +269,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
, mTriggeringPrincipal(rhs.mTriggeringPrincipal)
, mPrincipalToInherit(rhs.mPrincipalToInherit)
, mSandboxedLoadingPrincipal(rhs.mSandboxedLoadingPrincipal)
, mResultPrincipalURI(rhs.mResultPrincipalURI)
, mLoadingContext(rhs.mLoadingContext)
, mSecurityFlags(rhs.mSecurityFlags)
, mInternalContentPolicyType(rhs.mInternalContentPolicyType)
@ -936,5 +937,19 @@ LoadInfo::GetIsTopLevelLoad(bool *aResult)
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetResultPrincipalURI(nsIURI **aURI)
{
NS_IF_ADDREF(*aURI = mResultPrincipalURI);
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::SetResultPrincipalURI(nsIURI *aURI)
{
mResultPrincipalURI = aURI;
return NS_OK;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -128,6 +128,7 @@ private:
nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
nsCOMPtr<nsIPrincipal> mPrincipalToInherit;
nsCOMPtr<nsIPrincipal> mSandboxedLoadingPrincipal;
nsCOMPtr<nsIURI> mResultPrincipalURI;
nsWeakPtr mLoadingContext;
nsSecurityFlags mSecurityFlags;
nsContentPolicyType mInternalContentPolicyType;

Просмотреть файл

@ -10,6 +10,7 @@
interface nsIDOMDocument;
interface nsINode;
interface nsIPrincipal;
interface nsIURI;
%{C++
#include "nsTArray.h"
@ -740,6 +741,14 @@ interface nsILoadInfo : nsISupports
*/
[infallible] readonly attribute boolean isTopLevelLoad;
/**
* If this is non-null, this property represents two things: (1) the
* URI to be used for the principal if the channel with this loadinfo
* gets a principal based on URI and (2) the URI to use for a document
* created from the channel with this loadinfo.
*/
attribute nsIURI resultPrincipalURI;
/**
* Returns the null principal of the resulting resource if the SEC_SANDBOXED
* flag is set. Otherwise returns null. This is used by

Просмотреть файл

@ -189,13 +189,21 @@ NS_NewChannelInternal(nsIChannel **outChannel,
}
if (aLoadFlags != nsIRequest::LOAD_NORMAL) {
// Retain the LOAD_REPLACE load flag if set.
nsLoadFlags normalLoadFlags = 0;
channel->GetLoadFlags(&normalLoadFlags);
rv = channel->SetLoadFlags(aLoadFlags | (normalLoadFlags & nsIChannel::LOAD_REPLACE));
rv = channel->SetLoadFlags(aLoadFlags);
NS_ENSURE_SUCCESS(rv, rv);
}
#ifdef DEBUG
nsLoadFlags channelLoadFlags = 0;
channel->GetLoadFlags(&channelLoadFlags);
// Will be removed when we remove LOAD_REPLACE altogether
// This check is trying to catch protocol handlers that still
// try to set the LOAD_REPLACE flag. Only exception is when
// this flag is carried in the aLoadFlags argument (e.g. when
// cloning redirected channels for CORS preflight.)
MOZ_ASSERT(!((channelLoadFlags & ~aLoadFlags) & nsIChannel::LOAD_REPLACE));
#endif
channel.forget(outChannel);
return NS_OK;
}
@ -268,13 +276,21 @@ NS_NewChannelInternal(nsIChannel **outChannel,
}
if (aLoadFlags != nsIRequest::LOAD_NORMAL) {
// Retain the LOAD_REPLACE load flag if set.
nsLoadFlags normalLoadFlags = 0;
channel->GetLoadFlags(&normalLoadFlags);
rv = channel->SetLoadFlags(aLoadFlags | (normalLoadFlags & nsIChannel::LOAD_REPLACE));
rv = channel->SetLoadFlags(aLoadFlags);
NS_ENSURE_SUCCESS(rv, rv);
}
#ifdef DEBUG
nsLoadFlags channelLoadFlags = 0;
channel->GetLoadFlags(&channelLoadFlags);
// Will be removed when we remove LOAD_REPLACE altogether
// This check is trying to catch protocol handlers that still
// try to set the LOAD_REPLACE flag. Only exception is when
// this flag is carried in the aLoadFlags argument (e.g. when
// cloning redirected channels for CORS preflight.)
MOZ_ASSERT(!((channelLoadFlags & ~aLoadFlags) & nsIChannel::LOAD_REPLACE));
#endif
channel.forget(outChannel);
return NS_OK;
}
@ -1872,15 +1888,18 @@ nsresult
NS_GetFinalChannelURI(nsIChannel *channel, nsIURI **uri)
{
*uri = nullptr;
nsLoadFlags loadFlags = 0;
nsresult rv = channel->GetLoadFlags(&loadFlags);
NS_ENSURE_SUCCESS(rv, rv);
if (loadFlags & nsIChannel::LOAD_REPLACE) {
return channel->GetURI(uri);
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo) {
nsCOMPtr<nsIURI> resultPrincipalURI;
loadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
if (resultPrincipalURI) {
resultPrincipalURI.forget(uri);
return NS_OK;
}
}
return channel->GetOriginalURI(uri);
return channel->GetURI(uri);
}
nsresult

Просмотреть файл

@ -780,11 +780,9 @@ nsresult NS_URIChainHasFlags(nsIURI *uri,
already_AddRefed<nsIURI> NS_GetInnermostURI(nsIURI *aURI);
/**
* Get the "final" URI for a channel. This is either the same as GetURI or
* GetOriginalURI, depending on whether this channel has
* nsIChanel::LOAD_REPLACE set. For channels without that flag set, the final
* URI is the original URI, while for ones with the flag the final URI is the
* channel URI.
* Get the "final" URI for a channel. This is either channel's load info
* resultPrincipalURI, if set, or GetURI. In most cases (but not all) load
* info resultPrincipalURI, if set, corresponds to originalURI of the channel.
*/
nsresult NS_GetFinalChannelURI(nsIChannel *channel, nsIURI **uri);

Просмотреть файл

@ -290,9 +290,6 @@ nsFileChannel::nsFileChannel(nsIURI *uri)
SetURI(targetURI);
SetOriginalURI(uri);
nsLoadFlags loadFlags = 0;
GetLoadFlags(&loadFlags);
SetLoadFlags(loadFlags | nsIChannel::LOAD_REPLACE);
} else {
SetURI(uri);
}

Просмотреть файл

@ -2973,6 +2973,64 @@ void HttpBaseChannel::AssertPrivateBrowsingId()
}
#endif
already_AddRefed<nsILoadInfo>
HttpBaseChannel::CloneLoadInfoForRedirect(nsIURI * newURI, uint32_t redirectFlags)
{
// make a copy of the loadinfo, append to the redirectchain
// this will be set on the newly created channel for the redirect target.
if (!mLoadInfo) {
return nullptr;
}
nsCOMPtr<nsILoadInfo> newLoadInfo =
static_cast<mozilla::LoadInfo*>(mLoadInfo.get())->Clone();
nsContentPolicyType contentPolicyType = mLoadInfo->GetExternalContentPolicyType();
if (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
nsCOMPtr<nsIPrincipal> nullPrincipalToInherit = NullPrincipal::Create();
newLoadInfo->SetPrincipalToInherit(nullPrincipalToInherit);
}
// re-compute the origin attributes of the loadInfo if it's top-level load.
bool isTopLevelDoc =
newLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DOCUMENT;
if (isTopLevelDoc) {
nsCOMPtr<nsILoadContext> loadContext;
NS_QueryNotificationCallbacks(this, loadContext);
OriginAttributes docShellAttrs;
if (loadContext) {
loadContext->GetOriginAttributes(docShellAttrs);
}
OriginAttributes attrs = newLoadInfo->GetOriginAttributes();
MOZ_ASSERT(docShellAttrs.mUserContextId == attrs.mUserContextId,
"docshell and necko should have the same userContextId attribute.");
MOZ_ASSERT(docShellAttrs.mInIsolatedMozBrowser == attrs.mInIsolatedMozBrowser,
"docshell and necko should have the same inIsolatedMozBrowser attribute.");
MOZ_ASSERT(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId,
"docshell and necko should have the same privateBrowsingId attribute.");
attrs = docShellAttrs;
attrs.SetFirstPartyDomain(true, newURI);
newLoadInfo->SetOriginAttributes(attrs);
}
// Drop the target principal URI from the cloned load info because we want
// NS_GetFinalChannelURI to return either the URI of the target channel
// or anything that the target protocol handler potentially sets itself.
newLoadInfo->SetResultPrincipalURI(nullptr);
bool isInternalRedirect =
(redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
nsIChannelEventSink::REDIRECT_STS_UPGRADE));
newLoadInfo->AppendRedirectedPrincipal(GetURIPrincipal(), isInternalRedirect);
return newLoadInfo.forget();
}
//-----------------------------------------------------------------------------
// nsHttpChannel::nsITraceableChannel
//-----------------------------------------------------------------------------
@ -3161,57 +3219,6 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
}
}
// make a copy of the loadinfo, append to the redirectchain
// and set it on the new channel
if (mLoadInfo) {
nsCOMPtr<nsILoadInfo> newLoadInfo =
static_cast<mozilla::LoadInfo*>(mLoadInfo.get())->Clone();
nsContentPolicyType contentPolicyType = mLoadInfo->GetExternalContentPolicyType();
if (contentPolicyType == nsIContentPolicy::TYPE_DOCUMENT ||
contentPolicyType == nsIContentPolicy::TYPE_SUBDOCUMENT) {
nsCOMPtr<nsIPrincipal> nullPrincipalToInherit = NullPrincipal::Create();
newLoadInfo->SetPrincipalToInherit(nullPrincipalToInherit);
}
// re-compute the origin attributes of the loadInfo if it's top-level load.
bool isTopLevelDoc =
newLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DOCUMENT;
if (isTopLevelDoc) {
nsCOMPtr<nsILoadContext> loadContext;
NS_QueryNotificationCallbacks(this, loadContext);
OriginAttributes docShellAttrs;
if (loadContext) {
loadContext->GetOriginAttributes(docShellAttrs);
}
OriginAttributes attrs = newLoadInfo->GetOriginAttributes();
MOZ_ASSERT(docShellAttrs.mUserContextId == attrs.mUserContextId,
"docshell and necko should have the same userContextId attribute.");
MOZ_ASSERT(docShellAttrs.mInIsolatedMozBrowser == attrs.mInIsolatedMozBrowser,
"docshell and necko should have the same inIsolatedMozBrowser attribute.");
MOZ_ASSERT(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId,
"docshell and necko should have the same privateBrowsingId attribute.");
attrs = docShellAttrs;
attrs.SetFirstPartyDomain(true, newURI);
newLoadInfo->SetOriginAttributes(attrs);
}
bool isInternalRedirect =
(redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
nsIChannelEventSink::REDIRECT_STS_UPGRADE));
newLoadInfo->AppendRedirectedPrincipal(GetURIPrincipal(), isInternalRedirect);
newChannel->SetLoadInfo(newLoadInfo);
}
else {
// the newChannel was created with a dummy loadInfo, we should clear
// it in case the original channel does not have a loadInfo
newChannel->SetLoadInfo(nullptr);
}
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
if (!httpChannel)
return NS_OK; // no other options to set

Просмотреть файл

@ -424,6 +424,8 @@ protected:
void AssertPrivateBrowsingId();
#endif
already_AddRefed<nsILoadInfo> CloneLoadInfoForRedirect(nsIURI *newURI, uint32_t redirectFlags);
friend class PrivateBrowsingChannel<HttpBaseChannel>;
friend class InterceptFailedOnStop;

Просмотреть файл

@ -1493,9 +1493,10 @@ HttpChannelChild::SetupRedirect(nsIURI* uri,
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> newChannel;
nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(uri, redirectFlags);
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
uri,
mLoadInfo,
redirectLoadInfo,
nullptr, // aLoadGroup
nullptr, // aCallbacks
nsIRequest::LOAD_NORMAL,

Просмотреть файл

@ -2617,6 +2617,8 @@ nsHttpChannel::StartRedirectChannelToURI(nsIURI *upgradedURI, uint32_t flags)
LOG(("nsHttpChannel::StartRedirectChannelToURI()\n"));
nsCOMPtr<nsIChannel> newChannel;
nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(upgradedURI,
flags);
nsCOMPtr<nsIIOService> ioService;
rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
@ -2624,7 +2626,7 @@ nsHttpChannel::StartRedirectChannelToURI(nsIURI *upgradedURI, uint32_t flags)
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
upgradedURI,
mLoadInfo,
redirectLoadInfo,
nullptr, // aLoadGroup
nullptr, // aCallbacks
nsIRequest::LOAD_NORMAL,
@ -5474,22 +5476,23 @@ nsHttpChannel::ContinueProcessRedirectionAfterFallback(nsresult rv)
rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIChannel> newChannel;
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
mRedirectURI,
mLoadInfo,
nullptr, // aLoadGroup
nullptr, // aCallbacks
nsIRequest::LOAD_NORMAL,
ioService);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t redirectFlags;
if (nsHttp::IsPermanentRedirect(mRedirectType))
redirectFlags = nsIChannelEventSink::REDIRECT_PERMANENT;
else
redirectFlags = nsIChannelEventSink::REDIRECT_TEMPORARY;
nsCOMPtr<nsIChannel> newChannel;
nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(mRedirectURI, redirectFlags);
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
mRedirectURI,
redirectLoadInfo,
nullptr, // aLoadGroup
nullptr, // aCallbacks
nsIRequest::LOAD_NORMAL,
ioService);
NS_ENSURE_SUCCESS(rv, rv);
rv = SetupReplacementChannel(mRedirectURI, newChannel,
!rewriteToGET, redirectFlags);
if (NS_FAILED(rv)) return rv;

Просмотреть файл

@ -33,6 +33,10 @@ protected:
const nsACString& aPathname,
nsACString& aResult) override;
// |result| is an inout param. On entry to this function, *result
// is expected to be non-null and already addrefed. This function
// may release the object stored in *result on entry and write
// a new pointer to an already addrefed channel to *result.
virtual MOZ_MUST_USE nsresult SubstituteChannel(nsIURI* uri,
nsILoadInfo* aLoadInfo,
nsIChannel** result) override;

Просмотреть файл

@ -257,12 +257,21 @@ SubstitutingProtocolHandler::NewChannel2(nsIURI* uri,
rv = NS_NewChannelInternal(result, newURI, aLoadInfo);
NS_ENSURE_SUCCESS(rv, rv);
nsLoadFlags loadFlags = 0;
(*result)->GetLoadFlags(&loadFlags);
(*result)->SetLoadFlags(loadFlags & ~nsIChannel::LOAD_REPLACE);
rv = (*result)->SetOriginalURI(uri);
NS_ENSURE_SUCCESS(rv, rv);
// We must set result principal URL prior to calling SubstituteChannel
// because it may call NS_GetFinalChannelURI and the correct result
// (in this case |uri|) is already expected.
//
// We don't want to reset the result principal URL to |uri| after calling
// SubstituteChannel since whatever substituting protocol handler(s) set
// has to override anything we set here.
if (aLoadInfo) {
rv = aLoadInfo->SetResultPrincipalURI(uri);
NS_ENSURE_SUCCESS(rv, rv);
}
return SubstituteChannel(uri, aLoadInfo, result);
}

Просмотреть файл

@ -116,6 +116,12 @@ nsViewSourceHandler::NewChannel2(nsIURI* uri,
return rv;
}
if (aLoadInfo) {
// The underlying channel is created for a different URI.
// Original URI on the resulting channel has been set to |uri|.
aLoadInfo->SetResultPrincipalURI(uri);
}
*result = static_cast<nsIViewSourceChannel*>(channel);
return NS_OK;
}
@ -141,6 +147,12 @@ nsViewSourceHandler::NewSrcdocChannel(nsIURI *aURI,
return rv;
}
if (aLoadInfo) {
// The underlying channel is created for a different URI.
// Original URI on the resulting channel has been set to |aURI|.
aLoadInfo->SetResultPrincipalURI(aURI);
}
*outChannel = static_cast<nsIViewSourceChannel*>(channel.forget().take());
return NS_OK;
}

Просмотреть файл

@ -217,6 +217,11 @@ WyciwygChannelParent::RecvAsyncOpen(const URIParams& aOriginal,
return IPC_OK();
}
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
if (loadInfo) {
loadInfo->SetResultPrincipalURI(original);
}
rv = mChannel->SetLoadFlags(aLoadFlags);
if (NS_FAILED(rv)) {
if (!SendCancelEarly(rv)) {
@ -237,7 +242,6 @@ WyciwygChannelParent::RecvAsyncOpen(const URIParams& aOriginal,
return IPC_OK();
}
nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
if (loadInfo && loadInfo->GetEnforceSecurity()) {
rv = mChannel->AsyncOpen2(this);
}

Просмотреть файл

@ -877,6 +877,10 @@ nsMultiMixedConv::SendStart()
mPartChannel->SetContentDisposition(mContentDisposition);
// Each part of a multipart/replace response can be used
// for the top level document. We must inform upper layers
// about this by setting the LOAD_REPLACE flag so that certain
// state assertions are evaluated as positive.
nsLoadFlags loadFlags = 0;
mPartChannel->GetLoadFlags(&loadFlags);
loadFlags |= nsIChannel::LOAD_REPLACE;

Просмотреть файл

@ -232,9 +232,6 @@ function test_load_replace() {
file = do_get_file("data/system_root.lnk", false);
var chan = new_file_channel(file);
// The LOAD_REPLACE flag should be set
do_check_eq(chan.loadFlags & chan.LOAD_REPLACE, chan.LOAD_REPLACE);
// The original URI path should differ from the URI path
do_check_neq(chan.URI.path, chan.originalURI.path);

Просмотреть файл

@ -161,6 +161,7 @@ AboutWeaveLog.prototype = {
let channel = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
channel.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
// Ensure that the about page has the same privileges as a regular directory
// view. That way links to files can be opened. make sure we use the correct

Просмотреть файл

@ -26,6 +26,7 @@ AboutPage.prototype = {
let channel = Services.io.newChannelFromURIWithLoadInfo(newURI,
aLoadInfo);
channel.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
if (this.uriFlags & Ci.nsIAboutModule.URI_SAFE_FOR_UNTRUSTED_CONTENT) {
channel.owner = null;

Просмотреть файл

@ -14,6 +14,7 @@ class TabSwitchAboutModule {
let uri = Services.io.newURI(CHROME_URI);
let chan = Services.io.newChannelFromURIWithLoadInfo(uri, aLoadInfo);
chan.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
return chan;
}

Просмотреть файл

@ -4,7 +4,7 @@
<em:id>tab-switch-test@lassey.us</em:id>
<em:type>2</em:type>
<em:name>Tab Switch Test</em:name>
<em:version>1.0.3</em:version>
<em:version>1.0.4</em:version>
<em:optionsType>2</em:optionsType>
<em:optionsURL>chrome://tabswitch/content/options.xul</em:optionsURL>
<em:bootstrap>true</em:bootstrap>

Двоичный файл не отображается.

Просмотреть файл

@ -32,7 +32,6 @@ mozProtocolHandler.prototype = {
newChannel2(uri, loadInfo) {
let realURL = NetUtil.newURI(this.urlToLoad);
let channel = Services.io.newChannelFromURIWithLoadInfo(realURL, loadInfo)
channel.loadFlags |= Ci.nsIChannel.LOAD_REPLACE;
return channel;
},

Просмотреть файл

@ -38,6 +38,7 @@ function* registerConverter() {
loadUsingSystemPrincipal: true,
});
channel.originalURI = aRequest.QueryInterface(Ci.nsIChannel).URI;
channel.loadInfo.resultPrincipalURI = channel.originalURI;
channel.loadGroup = aRequest.loadGroup;
channel.owner = Services.scriptSecurityManager
.createCodebasePrincipal(channel.URI, {});

Просмотреть файл

@ -17,6 +17,7 @@ function makeDefaultFaviconChannel(uri, loadInfo) {
let channel = Services.io.newChannelFromURIWithLoadInfo(
PlacesUtils.favicons.defaultFavicon, loadInfo);
channel.originalURI = uri;
loadInfo.resultPrincipalURI = uri;
return channel;
}

Просмотреть файл

@ -88,6 +88,7 @@ Protocol.prototype = {
let fileuri = Services.io.newFileURI(file);
let channel = Services.io.newChannelFromURIWithLoadInfo(fileuri, aLoadInfo);
channel.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
return channel;
},

Просмотреть файл

@ -24,6 +24,7 @@ var CustomChromeProtocol = {
let url = Services.io.newURI("chrome:" + aURI.path);
let ch = Services.io.newChannelFromURIWithLoadInfo(url, aLoadInfo);
ch.originalURI = aURI;
aLoadInfo.resultPrincipalURI = aURI;
return ch;
},