зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1199049 - Part 7: Remove entries from the CORS preflight cache in the parent process when a CORS check in the child process fails; r=jduell
This is necessary because it's possible for one request triggered from a child to start a CORS preflight in the parent process and get an entry into the preflight cache, and then a CORS check for the same URL to fail in the child process later on. In this case, we need to tell the parent process to clear its CORS preflight cache entry.
This commit is contained in:
Родитель
d1029ccc78
Коммит
c9ef5ad84e
|
@ -2173,6 +2173,26 @@ NS_IMETHODIMP HttpChannelChild::GetClientSetRequestHeaders(RequestHeaderTuples *
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::RemoveCorsPreflightCacheEntry(nsIURI* aURI,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
URIParams uri;
|
||||
SerializeURI(aURI, uri);
|
||||
PrincipalInfo principalInfo;
|
||||
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
bool result = false;
|
||||
// Be careful to not attempt to send a message to the parent after the
|
||||
// actor has been destroyed.
|
||||
if (mIPCOpen) {
|
||||
result = SendRemoveCorsPreflightCacheEntry(uri, principalInfo);
|
||||
}
|
||||
return result ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HttpChannelChild::nsIDivertableChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "nsIHttpHeaderVisitor.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "nsCORSListenerProxy.h"
|
||||
|
||||
using mozilla::BasePrincipal;
|
||||
using mozilla::OriginAttributes;
|
||||
|
@ -939,6 +940,24 @@ HttpChannelParent::DivertComplete()
|
|||
mParentListener = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
HttpChannelParent::RecvRemoveCorsPreflightCacheEntry(const URIParams& uri,
|
||||
const mozilla::ipc::PrincipalInfo& requestingPrincipal)
|
||||
{
|
||||
nsCOMPtr<nsIURI> deserializedURI = DeserializeURI(uri);
|
||||
if (!deserializedURI) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
PrincipalInfoToPrincipal(requestingPrincipal);
|
||||
if (!principal) {
|
||||
return false;
|
||||
}
|
||||
nsCORSListenerProxy::RemoveFromCorsPreflightCache(deserializedURI,
|
||||
principal);
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// HttpChannelParent::nsIRequestObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -141,6 +141,8 @@ protected:
|
|||
const uint32_t& count) override;
|
||||
virtual bool RecvDivertOnStopRequest(const nsresult& statusCode) override;
|
||||
virtual bool RecvDivertComplete() override;
|
||||
virtual bool RecvRemoveCorsPreflightCacheEntry(const URIParams& uri,
|
||||
const mozilla::ipc::PrincipalInfo& requestingPrincipal) override;
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
// Supporting function for ADivertableParentChannel.
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
include protocol PNecko;
|
||||
include InputStreamParams;
|
||||
include URIParams;
|
||||
include PBackgroundSharedTypes;
|
||||
|
||||
include protocol PBlob; //FIXME: bug #792908
|
||||
|
||||
|
@ -79,6 +80,11 @@ parent:
|
|||
// Child has no more events/messages to divert to the parent.
|
||||
DivertComplete();
|
||||
|
||||
// Child has detected a CORS check failure, so needs to tell the parent
|
||||
// to remove any matching entry from the CORS preflight cache.
|
||||
RemoveCorsPreflightCacheEntry(URIParams uri,
|
||||
PrincipalInfo requestingPrincipal);
|
||||
|
||||
__delete__();
|
||||
|
||||
child:
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nsCORSListenerProxy.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIHttpChannelChild.h"
|
||||
#include "nsIHttpChannelInternal.h"
|
||||
#include "nsError.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -501,15 +502,24 @@ nsCORSListenerProxy::OnStartRequest(nsIRequest* aRequest,
|
|||
nsresult rv = CheckRequestApproved(aRequest);
|
||||
mRequestApproved = NS_SUCCEEDED(rv);
|
||||
if (!mRequestApproved) {
|
||||
if (sPreflightCache) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
if (channel) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_GetFinalChannelURI(channel, getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
if (channel) {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_GetFinalChannelURI(channel, getter_AddRefs(uri));
|
||||
if (uri) {
|
||||
if (sPreflightCache) {
|
||||
// OK to use mRequestingPrincipal since preflights never get
|
||||
// redirected.
|
||||
sPreflightCache->RemoveEntries(uri, mRequestingPrincipal);
|
||||
} else {
|
||||
nsCOMPtr<nsIHttpChannelChild> httpChannelChild =
|
||||
do_QueryInterface(channel);
|
||||
if (httpChannelChild) {
|
||||
rv = httpChannelChild->RemoveCorsPreflightCacheEntry(uri, mRequestingPrincipal);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -732,13 +742,22 @@ nsCORSListenerProxy::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
|
|||
!NS_IsHSTSUpgradeRedirect(aOldChannel, aNewChannel, aFlags)) {
|
||||
rv = CheckRequestApproved(aOldChannel);
|
||||
if (NS_FAILED(rv)) {
|
||||
if (sPreflightCache) {
|
||||
nsCOMPtr<nsIURI> oldURI;
|
||||
NS_GetFinalChannelURI(aOldChannel, getter_AddRefs(oldURI));
|
||||
if (oldURI) {
|
||||
nsCOMPtr<nsIURI> oldURI;
|
||||
NS_GetFinalChannelURI(aOldChannel, getter_AddRefs(oldURI));
|
||||
if (oldURI) {
|
||||
if (sPreflightCache) {
|
||||
// OK to use mRequestingPrincipal since preflights never get
|
||||
// redirected.
|
||||
sPreflightCache->RemoveEntries(oldURI, mRequestingPrincipal);
|
||||
} else {
|
||||
nsCOMPtr<nsIHttpChannelChild> httpChannelChild =
|
||||
do_QueryInterface(aOldChannel);
|
||||
if (httpChannelChild) {
|
||||
rv = httpChannelChild->RemoveCorsPreflightCacheEntry(oldURI, mRequestingPrincipal);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
|
||||
|
@ -1260,6 +1279,16 @@ nsCORSPreflightListener::GetInterface(const nsIID & aIID, void **aResult)
|
|||
return QueryInterface(aIID, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
nsCORSListenerProxy::RemoveFromCorsPreflightCache(nsIURI* aURI,
|
||||
nsIPrincipal* aRequestingPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
if (sPreflightCache) {
|
||||
sPreflightCache->RemoveEntries(aURI, aRequestingPrincipal);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_StartCORSPreflight(nsIChannel* aRequestChannel,
|
||||
nsIStreamListener* aListener,
|
||||
|
|
|
@ -33,6 +33,12 @@ NS_StartCORSPreflight(nsIChannel* aRequestChannel,
|
|||
nsTArray<nsCString>& aACUnsafeHeaders,
|
||||
nsIChannel** aPreflightChannel);
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
class HttpChannelParent;
|
||||
}
|
||||
}
|
||||
|
||||
enum class DataURIHandling
|
||||
{
|
||||
Allow,
|
||||
|
@ -73,6 +79,12 @@ public:
|
|||
void SetInterceptController(nsINetworkInterceptController* aInterceptController);
|
||||
|
||||
private:
|
||||
// Only HttpChannelParent can call RemoveFromCorsPreflightCache
|
||||
friend class mozilla::net::HttpChannelParent;
|
||||
|
||||
static void RemoveFromCorsPreflightCache(nsIURI* aURI,
|
||||
nsIPrincipal* aRequestingPrincipal);
|
||||
|
||||
~nsCORSListenerProxy();
|
||||
|
||||
nsresult UpdateChannel(nsIChannel* aChannel, DataURIHandling aAllowDataURI);
|
||||
|
|
|
@ -7,7 +7,10 @@
|
|||
|
||||
[ptr] native RequestHeaderTuples(mozilla::net::RequestHeaderTuples);
|
||||
|
||||
[uuid(3842c5e9-b5b1-400c-8eb7-936a3316ff21)]
|
||||
interface nsIPrincipal;
|
||||
interface nsIURI;
|
||||
|
||||
[uuid(81acb360-edd2-428e-935f-300a32efb649)]
|
||||
interface nsIHttpChannelChild : nsISupports
|
||||
{
|
||||
void addCookiesToRequest();
|
||||
|
@ -18,4 +21,8 @@ interface nsIHttpChannelChild : nsISupports
|
|||
|
||||
// Headers that the channel client has set via SetRequestHeader.
|
||||
readonly attribute RequestHeaderTuples clientSetRequestHeaders;
|
||||
|
||||
// This method is called by nsCORSListenerProxy if we need to remove
|
||||
// an entry from the CORS preflight cache in the parent process.
|
||||
void removeCorsPreflightCacheEntry(in nsIURI aURI, in nsIPrincipal aRequestingPrincipal);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче