Bug 1175803 - Store redirect chain within loadInfo - part 2 (r=sicking,mayhemer)

This commit is contained in:
Christoph Kerschbaumer 2015-07-19 19:43:09 -07:00
parent c0cc3c5614
commit bcc6bfffb4
9 changed files with 36 additions and 102 deletions

View File

@ -86,7 +86,6 @@ XPIDL_SOURCES += [
'nsIProxyInfo.idl',
'nsIRandomGenerator.idl',
'nsIRedirectChannelRegistrar.idl',
'nsIRedirectHistory.idl',
'nsIRedirectResultListener.idl',
'nsIRequest.idl',
'nsIRequestObserver.idl',

View File

@ -5,10 +5,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsBaseChannel.h"
#include "nsContentUtils.h"
#include "nsURLHelper.h"
#include "nsNetCID.h"
#include "nsMimeTypes.h"
#include "nsIContentSniffer.h"
#include "nsIScriptSecurityManager.h"
#include "nsMimeTypes.h"
#include "nsIHttpEventSink.h"
#include "nsIHttpChannel.h"
@ -152,8 +154,15 @@ nsBaseChannel::ContinueRedirect()
if (mOpenRedirectChannel) {
nsresult rv = mRedirectChannel->AsyncOpen(mListener, mListenerContext);
if (NS_FAILED(rv))
return rv;
NS_ENSURE_SUCCESS(rv, rv);
// Append the initial uri of the channel to the redirectChain
// after the channel got openend successfully.
if (mLoadInfo) {
nsCOMPtr<nsIPrincipal> uriPrincipal;
nsIScriptSecurityManager *sm = nsContentUtils::GetSecurityManager();
sm->GetChannelURIPrincipal(this, getter_AddRefs(uriPrincipal));
mLoadInfo->AppendRedirectedPrincipal(uriPrincipal);
}
}
mRedirectChannel = nullptr;

View File

@ -1,25 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Allows keeping track of channel redirects. Currently nsHttpChannel is the
* only implementor.
*/
#include "nsISupports.idl"
interface nsIArray;
interface nsIPrincipal;
[scriptable, uuid(ab87eabf-d0c4-40a9-b4b2-a1191108d4c0)]
interface nsIRedirectHistory : nsISupports
{
/**
* An array of nsIPrincipal that store the redirects associated with this
* channel. This array is filled whether or not the channel has ever been
* opened. The last element of the array is associated with the most recent
* channel.
*/
readonly attribute nsIArray redirects;
};

View File

@ -188,7 +188,6 @@ NS_INTERFACE_MAP_BEGIN(HttpBaseChannel)
NS_INTERFACE_MAP_ENTRY(nsIHttpChannel)
NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)
NS_INTERFACE_MAP_ENTRY(nsIForcePendingChannel)
NS_INTERFACE_MAP_ENTRY(nsIRedirectHistory)
NS_INTERFACE_MAP_ENTRY(nsIUploadChannel)
NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2)
NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)
@ -1921,13 +1920,6 @@ HttpBaseChannel::SetResponseTimeoutEnabled(bool aEnable)
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::AddRedirect(nsIPrincipal *aRedirect)
{
mRedirects.AppendObject(aRedirect);
return NS_OK;
}
NS_IMETHODIMP
HttpBaseChannel::ForcePending(bool aForcePending)
{
@ -2094,24 +2086,6 @@ HttpBaseChannel::ShouldIntercept()
return shouldIntercept;
}
// nsIRedirectHistory
NS_IMETHODIMP
HttpBaseChannel::GetRedirects(nsIArray * *aRedirects)
{
nsresult rv;
nsCOMPtr<nsIMutableArray> redirects =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
for (int i = 0; i < mRedirects.Count(); ++i) {
rv = redirects->AppendElement(mRedirects[i], false);
NS_ENSURE_SUCCESS(rv, rv);
}
*aRedirects = redirects;
NS_IF_ADDREF(*aRedirects);
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsHttpChannel::nsITraceableChannel
//-----------------------------------------------------------------------------
@ -2379,28 +2353,6 @@ HttpBaseChannel::SetupReplacementChannel(nsIURI *newURI,
"[this=%p] transferring chain of redirect cache-keys", this));
httpInternal->SetCacheKeysRedirectChain(mRedirectedCachekeys.forget());
}
// Transfer existing redirect information. Add all of our existing
// redirects to the new channel.
for (int32_t i = 0; i < mRedirects.Count(); ++i) {
if (LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
mRedirects[i]->GetURI(getter_AddRefs(uri));
nsCString spec;
if (uri) {
uri->GetSpec(spec);
}
LOG(("HttpBaseChannel::SetupReplacementChannel adding redirect \'%s\' "
"[this=%p]", spec.get(), this));
}
httpInternal->AddRedirect(mRedirects[i]);
}
// Add our own principal to the redirect information on the new channel. If
// the redirect is vetoed, then newChannel->AsyncOpen won't be called.
// However, the new channel's redirect chain will still be complete.
nsCOMPtr<nsIPrincipal> principal = GetURIPrincipal();
httpInternal->AddRedirect(principal);
}
// transfer application cache information

View File

@ -20,7 +20,6 @@
#include "nsHttpHandler.h"
#include "nsIHttpChannelInternal.h"
#include "nsIForcePendingChannel.h"
#include "nsIRedirectHistory.h"
#include "nsIUploadChannel.h"
#include "nsIUploadChannel2.h"
#include "nsIProgressEventSink.h"
@ -62,7 +61,6 @@ class HttpBaseChannel : public nsHashPropertyBag
, public nsIEncodedChannel
, public nsIHttpChannel
, public nsIHttpChannelInternal
, public nsIRedirectHistory
, public nsIUploadChannel
, public nsIUploadChannel2
, public nsISupportsPriority
@ -82,7 +80,6 @@ public:
NS_DECL_NSIUPLOADCHANNEL2
NS_DECL_NSITRACEABLECHANNEL
NS_DECL_NSITIMEDCHANNEL
NS_DECL_NSIREDIRECTHISTORY
HttpBaseChannel();
@ -188,7 +185,6 @@ public:
NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable) override;
NS_IMETHOD GetNetworkInterfaceId(nsACString& aNetworkInterfaceId) override;
NS_IMETHOD SetNetworkInterfaceId(const nsACString& aNetworkInterfaceId) override;
NS_IMETHOD AddRedirect(nsIPrincipal *aRedirect) override;
NS_IMETHOD ForcePending(bool aForcePending) override;
NS_IMETHOD GetLastModifiedTime(PRTime* lastModifiedTime) override;
NS_IMETHOD ForceNoIntercept() override;
@ -387,8 +383,6 @@ protected:
nsCOMPtr<nsIURI> mAPIRedirectToURI;
nsAutoPtr<nsTArray<nsCString> > mRedirectedCachekeys;
// Redirects added by previous channels.
nsCOMArray<nsIPrincipal> mRedirects;
uint32_t mProxyResolveFlags;
nsCOMPtr<nsIURI> mProxyURI;

View File

@ -205,6 +205,11 @@ AutoRedirectVetoNotifier::ReportRedirectResult(bool succeeded)
if (!mChannel)
return;
// Append the initial uri of the channel to the redirectChain
if (succeeded && mChannel->mLoadInfo) {
mChannel->mLoadInfo->AppendRedirectedPrincipal(mChannel->GetURIPrincipal());
}
mChannel->mRedirectChannel = nullptr;
nsCOMPtr<nsIRedirectResultListener> vetoHook;

View File

@ -38,7 +38,7 @@ interface nsIHttpUpgradeListener : nsISupports
* using any feature exposed by this interface, be aware that this interface
* will change and you will be broken. You have been warned.
*/
[scriptable, uuid(c025c35a-dda3-4a1d-9e6c-e02d7149ac79)]
[scriptable, uuid(4c9e681e-efd8-4ed2-b57f-20d48c9b3c3b)]
interface nsIHttpChannelInternal : nsISupports
{
@ -213,12 +213,6 @@ interface nsIHttpChannelInternal : nsISupports
*/
attribute boolean allowAltSvc;
/**
* Add a new nsIPrincipal to the redirect chain. This is the only way to
* write to nsIRedirectHistory.redirects.
*/
void addRedirect(in nsIPrincipal aPrincipal);
readonly attribute PRTime lastModifiedTime;
/**

View File

@ -34,10 +34,12 @@ function contentHandler(request, response)
function finish_test(request, buffer)
{
do_check_eq(buffer, responseBody);
let chan = request.QueryInterface(Ci.nsIRedirectHistory);
do_check_eq(numRedirects - 1, chan.redirects.length);
let chan = request.QueryInterface(Ci.nsIChannel);
let redirectChain = chan.loadInfo.redirectChain;
do_check_eq(numRedirects - 1, redirectChain.length);
for (let i = 0; i < numRedirects - 1; ++i) {
let principal = chan.redirects.queryElementAt(i, Ci.nsIPrincipal);
let principal = redirectChain[i];
do_check_eq(URL + redirects[i], principal.URI.spec);
}
httpServer.stop(do_test_finished);

View File

@ -21,7 +21,6 @@
#include "nsIFile.h"
#include "nsIFileURL.h"
#include "nsIChannel.h"
#include "nsIRedirectHistory.h"
#include "nsIDirectoryService.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsICategoryManager.h"
@ -1986,14 +1985,20 @@ nsExternalAppHandler::OnSaveComplete(nsIBackgroundFileSaver *aSaver,
mSaver = nullptr;
// Save the redirect information.
nsCOMPtr<nsIRedirectHistory> history = do_QueryInterface(mRequest);
if (history) {
(void)history->GetRedirects(getter_AddRefs(mRedirects));
uint32_t length = 0;
mRedirects->GetLength(&length);
LOG(("nsExternalAppHandler: Got %u redirects\n", length));
} else {
LOG(("nsExternalAppHandler: No redirects\n"));
nsCOMPtr<nsIChannel> channel = do_QueryInterface(mRequest);
if (channel) {
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo) {
nsresult rv = NS_OK;
nsCOMPtr<nsIMutableArray> redirectChain =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
LOG(("nsExternalAppHandler: Got %u redirects\n", loadInfo->RedirectChain().Length()));
for (nsIPrincipal* principal : loadInfo->RedirectChain()) {
redirectChain->AppendElement(principal, false);
}
mRedirects = redirectChain;
}
}
if (NS_FAILED(aStatus)) {
@ -2006,7 +2011,6 @@ nsExternalAppHandler::OnSaveComplete(nsIBackgroundFileSaver *aSaver,
// for us, we'll fall back to using the prompt service if we absolutely
// have to.
if (!mTransfer) {
nsCOMPtr<nsIChannel> channel = do_QueryInterface(mRequest);
// We don't care if this fails.
CreateFailedTransfer(channel && NS_UsePrivateBrowsing(channel));
}