зеркало из https://github.com/mozilla/pjs.git
# User Michal Novotny <michal.novotny@gmail.com>
# Date 1272456176 -7200 Bug 549241 - Channel classifier should run in chrome process. r=biesi, sr=jst
This commit is contained in:
Родитель
d1441baf4a
Коммит
86c0119176
|
@ -500,9 +500,6 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
|
|||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
// We're done with the classifier
|
||||
mClassifier = nsnull;
|
||||
|
||||
AutoNotifier notifier(this, PR_TRUE);
|
||||
|
||||
if (!IsSuccessfulRequest(aRequest)) {
|
||||
|
@ -1033,10 +1030,6 @@ nsObjectLoadingContent::OnChannelRedirect(nsIChannel *aOldChannel,
|
|||
return NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
if (mClassifier) {
|
||||
mClassifier->OnRedirect(aOldChannel, aNewChannel);
|
||||
}
|
||||
|
||||
mChannel = aNewChannel;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1204,11 +1197,6 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
|||
if (mChannel) {
|
||||
LOG(("OBJLC [%p]: Cancelling existing load\n", this));
|
||||
|
||||
if (mClassifier) {
|
||||
mClassifier->Cancel();
|
||||
mClassifier = nsnull;
|
||||
}
|
||||
|
||||
// These three statements are carefully ordered:
|
||||
// - onStopRequest should get a channel whose status is the same as the
|
||||
// status argument
|
||||
|
@ -1436,7 +1424,8 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
|||
channelPolicy->SetLoadType(nsIContentPolicy::TYPE_OBJECT);
|
||||
}
|
||||
rv = NS_NewChannel(getter_AddRefs(chan), aURI, nsnull, group, this,
|
||||
nsIChannel::LOAD_CALL_CONTENT_SNIFFERS,
|
||||
nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
|
||||
nsIChannel::LOAD_CLASSIFY_URI,
|
||||
channelPolicy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -1477,12 +1466,6 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
LOG(("OBJLC [%p]: Channel opened.\n", this));
|
||||
|
||||
rv = CheckClassifier(chan);
|
||||
if (NS_FAILED(rv)) {
|
||||
chan->Cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
mChannel = chan;
|
||||
mType = eType_Loading;
|
||||
}
|
||||
|
@ -1924,22 +1907,6 @@ nsObjectLoadingContent::Instantiate(nsIObjectFrame* aFrame,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsObjectLoadingContent::CheckClassifier(nsIChannel *aChannel)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIChannelClassifier> classifier =
|
||||
do_CreateInstance(NS_CHANNELCLASSIFIER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = classifier->Start(aChannel, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mClassifier = classifier;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ PluginSupportState
|
||||
nsObjectLoadingContent::GetPluginSupportState(nsIContent* aContent,
|
||||
const nsCString& aContentType)
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIObjectLoadingContent.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsIChannelClassifier.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
class nsAsyncInstantiateEvent;
|
||||
|
@ -328,13 +327,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
*/
|
||||
nsresult Instantiate(nsIObjectFrame* aFrame, const nsACString& aMIMEType, nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* Check the channel load against the URI classifier service (if it
|
||||
* exists). The channel will be suspended until the classification is
|
||||
* complete.
|
||||
*/
|
||||
nsresult CheckClassifier(nsIChannel *aChannel);
|
||||
|
||||
/**
|
||||
* Get the plugin support state for the given content node and MIME type.
|
||||
* This is used for purposes of determining whether to fire PluginNotFound
|
||||
|
@ -394,11 +386,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
|||
// The data we were last asked to load
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
|
||||
/**
|
||||
* Suspends/resumes channels based on the URI classifier.
|
||||
*/
|
||||
nsCOMPtr<nsIChannelClassifier> mClassifier;
|
||||
|
||||
/**
|
||||
* Type of the currently-loaded content.
|
||||
*/
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
#include "nsContentErrors.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsIChannelClassifier.h"
|
||||
#include "nsDocShellCID.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "prlog.h"
|
||||
|
@ -305,8 +304,8 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType)
|
|||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
aRequest->mURI, nsnull, loadGroup,
|
||||
prompter, nsIRequest::LOAD_NORMAL,
|
||||
aRequest->mURI, nsnull, loadGroup, prompter,
|
||||
nsIRequest::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI,
|
||||
channelPolicy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -325,17 +324,6 @@ nsScriptLoader::StartLoad(nsScriptLoadRequest *aRequest, const nsAString &aType)
|
|||
rv = channel->AsyncOpen(loader, aRequest);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Check the load against the URI classifier
|
||||
nsCOMPtr<nsIChannelClassifier> classifier =
|
||||
do_CreateInstance(NS_CHANNELCLASSIFIER_CONTRACTID);
|
||||
if (classifier) {
|
||||
rv = classifier->Start(channel, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
channel->Cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,8 +74,6 @@ XPIDLSRCS = \
|
|||
nsIURIFixup.idl \
|
||||
nsIEditorDocShell.idl \
|
||||
nsIWebPageDescriptor.idl \
|
||||
nsIURIClassifier.idl \
|
||||
nsIChannelClassifier.idl \
|
||||
nsIDownloadHistory.idl \
|
||||
nsILoadContext.idl \
|
||||
$(NULL)
|
||||
|
|
|
@ -108,7 +108,6 @@
|
|||
#include "nsIView.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIScriptChannel.h"
|
||||
#include "nsIURIClassifier.h"
|
||||
#include "nsIOfflineCacheUpdate.h"
|
||||
#include "nsCPrefetchService.h"
|
||||
#include "nsJSON.h"
|
||||
|
@ -4043,11 +4042,6 @@ nsDocShell::Stop(PRUint32 aStopFlags)
|
|||
mRefreshURIList = nsnull;
|
||||
}
|
||||
|
||||
if (mClassifier) {
|
||||
mClassifier->Cancel();
|
||||
mClassifier = nsnull;
|
||||
}
|
||||
|
||||
// XXXbz We could also pass |this| to nsIURILoader::Stop. That will
|
||||
// just call Stop() on us as an nsIDocumentLoader... We need fewer
|
||||
// redundant apis!
|
||||
|
@ -5667,12 +5661,6 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
|
|||
if (!(aStateFlags & STATE_IS_DOCUMENT))
|
||||
return; // not a toplevel document
|
||||
|
||||
// If this load is being checked by the URI classifier, we need to
|
||||
// query the classifier again for the new URI.
|
||||
if (mClassifier) {
|
||||
mClassifier->OnRedirect(aOldChannel, aNewChannel);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalHistory3> history3(do_QueryInterface(mGlobalHistory));
|
||||
nsresult result = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (history3) {
|
||||
|
@ -5756,9 +5744,6 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress,
|
|||
//
|
||||
nsCOMPtr<nsIDocShell> kungFuDeathGrip(this);
|
||||
|
||||
// We're done with the URI classifier for this channel
|
||||
mClassifier = nsnull;
|
||||
|
||||
// Notify the ContentViewer that the Document has finished loading. This
|
||||
// will cause any OnLoad(...) and PopState(...) handlers to fire.
|
||||
if (!mEODForCurrentDocument && mContentViewer) {
|
||||
|
@ -8681,6 +8666,10 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel,
|
|||
break;
|
||||
}
|
||||
|
||||
if (!aBypassClassifier) {
|
||||
loadFlags |= nsIChannel::LOAD_CLASSIFY_URI;
|
||||
}
|
||||
|
||||
(void) aChannel->SetLoadFlags(loadFlags);
|
||||
|
||||
rv = aURILoader->OpenURI(aChannel,
|
||||
|
@ -8688,28 +8677,6 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel,
|
|||
this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!aBypassClassifier) {
|
||||
rv = CheckClassifier(aChannel);
|
||||
if (NS_FAILED(rv)) {
|
||||
aChannel->Cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocShell::CheckClassifier(nsIChannel *aChannel)
|
||||
{
|
||||
nsRefPtr<nsClassifierCallback> classifier = new nsClassifierCallback();
|
||||
if (!classifier) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = classifier->Start(aChannel, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mClassifier = classifier;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -10747,279 +10714,6 @@ nsDocShell::IsOKToLoadURI(nsIURI* aURI)
|
|||
NS_SUCCEEDED(secMan->CheckSameOriginURI(aURI, mLoadingURI, PR_FALSE));
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsClassifierCallback
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMPL_ISUPPORTS5(nsClassifierCallback,
|
||||
nsIChannelClassifier,
|
||||
nsIURIClassifierCallback,
|
||||
nsIRunnable,
|
||||
nsIChannelEventSink,
|
||||
nsIInterfaceRequestor)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClassifierCallback::Run()
|
||||
{
|
||||
if (!mChannel) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!mSuspendedChannel,
|
||||
"nsClassifierCallback::Run() called while a "
|
||||
"channel is still suspended.");
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
channel.swap(mChannel);
|
||||
|
||||
// Don't bother to run the classifier on a load that has already failed.
|
||||
// (this might happen after a redirect)
|
||||
PRUint32 status;
|
||||
channel->GetStatus(&status);
|
||||
if (NS_FAILED(status))
|
||||
return NS_OK;
|
||||
|
||||
// Don't bother to run the classifier on a cached load that was
|
||||
// previously classified.
|
||||
if (HasBeenClassified(channel)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = channel->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Don't bother checking certain types of URIs.
|
||||
PRBool hasFlags;
|
||||
rv = NS_URIChainHasFlags(uri,
|
||||
nsIProtocolHandler::URI_DANGEROUS_TO_LOAD,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
rv = NS_URIChainHasFlags(uri,
|
||||
nsIProtocolHandler::URI_IS_LOCAL_FILE,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
rv = NS_URIChainHasFlags(uri,
|
||||
nsIProtocolHandler::URI_IS_UI_RESOURCE,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
rv = NS_URIChainHasFlags(uri,
|
||||
nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIURIClassifier> uriClassifier =
|
||||
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
|
||||
if (rv == NS_ERROR_FACTORY_NOT_REGISTERED ||
|
||||
rv == NS_ERROR_NOT_AVAILABLE) {
|
||||
// no URI classifier, ignore this failure.
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool expectCallback;
|
||||
rv = uriClassifier->Classify(uri, this, &expectCallback);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (expectCallback) {
|
||||
// Suspend the channel, it will be resumed when we get the classifier
|
||||
// callback.
|
||||
rv = channel->Suspend();
|
||||
if (NS_FAILED(rv)) {
|
||||
// Some channels (including nsJSChannel) fail on Suspend. This
|
||||
// shouldn't be fatal, but will prevent malware from being
|
||||
// blocked on these channels.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mSuspendedChannel = channel;
|
||||
#ifdef DEBUG
|
||||
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
|
||||
("nsClassifierCallback[%p]: suspended channel %p",
|
||||
this, mSuspendedChannel.get()));
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Note in the cache entry that this URL was classified, so that future
|
||||
// cached loads don't need to be checked.
|
||||
void
|
||||
nsClassifierCallback::MarkEntryClassified(nsresult status)
|
||||
{
|
||||
nsCOMPtr<nsICachingChannel> cachingChannel =
|
||||
do_QueryInterface(mSuspendedChannel);
|
||||
if (!cachingChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> cacheToken;
|
||||
cachingChannel->GetCacheToken(getter_AddRefs(cacheToken));
|
||||
if (!cacheToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> cacheEntry =
|
||||
do_QueryInterface(cacheToken);
|
||||
if (!cacheEntry) {
|
||||
return;
|
||||
}
|
||||
|
||||
cacheEntry->SetMetaDataElement("docshell:classified",
|
||||
NS_SUCCEEDED(status) ? "1" : nsnull);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsClassifierCallback::HasBeenClassified(nsIChannel *aChannel)
|
||||
{
|
||||
nsCOMPtr<nsICachingChannel> cachingChannel =
|
||||
do_QueryInterface(aChannel);
|
||||
if (!cachingChannel) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Only check the tag if we are loading from the cache without
|
||||
// validation.
|
||||
PRBool fromCache;
|
||||
if (NS_FAILED(cachingChannel->IsFromCache(&fromCache)) || !fromCache) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> cacheToken;
|
||||
cachingChannel->GetCacheToken(getter_AddRefs(cacheToken));
|
||||
if (!cacheToken) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> cacheEntry =
|
||||
do_QueryInterface(cacheToken);
|
||||
if (!cacheEntry) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsXPIDLCString tag;
|
||||
cacheEntry->GetMetaDataElement("docshell:classified", getter_Copies(tag));
|
||||
return tag.EqualsLiteral("1");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClassifierCallback::OnClassifyComplete(nsresult aErrorCode)
|
||||
{
|
||||
if (mSuspendedChannel) {
|
||||
MarkEntryClassified(aErrorCode);
|
||||
|
||||
if (NS_FAILED(aErrorCode)) {
|
||||
#ifdef DEBUG
|
||||
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
|
||||
("nsClassifierCallback[%p]: cancelling channel %p with error code: %d",
|
||||
this, mSuspendedChannel.get(), aErrorCode));
|
||||
#endif
|
||||
mSuspendedChannel->Cancel(aErrorCode);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
|
||||
("nsClassifierCallback[%p]: resuming channel %p from OnClassifyComplete",
|
||||
this, mSuspendedChannel.get()));
|
||||
#endif
|
||||
mSuspendedChannel->Resume();
|
||||
mSuspendedChannel = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClassifierCallback::Start(nsIChannel *aChannel, PRBool aInstallListener)
|
||||
{
|
||||
mChannel = aChannel;
|
||||
|
||||
if (aInstallListener) {
|
||||
nsresult rv = aChannel->GetNotificationCallbacks
|
||||
(getter_AddRefs(mNotificationCallbacks));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aChannel->SetNotificationCallbacks
|
||||
(static_cast<nsIInterfaceRequestor*>(this));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return Run();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClassifierCallback::OnRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel)
|
||||
{
|
||||
mChannel = aNewChannel;
|
||||
|
||||
// we call the Run() from the main loop to give the channel a
|
||||
// chance to AsyncOpen() before we suspend it.
|
||||
NS_DispatchToCurrentThread(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClassifierCallback::Cancel()
|
||||
{
|
||||
if (mSuspendedChannel) {
|
||||
#ifdef DEBUG
|
||||
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
|
||||
("nsClassifierCallback[%p]: resuming channel %p from Cancel()",
|
||||
this, mSuspendedChannel.get()));
|
||||
#endif
|
||||
mSuspendedChannel->Resume();
|
||||
mSuspendedChannel = nsnull;
|
||||
}
|
||||
|
||||
if (mChannel) {
|
||||
mChannel = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClassifierCallback::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||
nsIChannel *aNewChannel,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
nsresult rv = OnRedirect(aOldChannel, aNewChannel);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mNotificationCallbacks) {
|
||||
nsCOMPtr<nsIChannelEventSink> sink =
|
||||
do_GetInterface(mNotificationCallbacks);
|
||||
if (sink) {
|
||||
return sink->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClassifierCallback::GetInterface(const nsIID &aIID, void **aResult)
|
||||
{
|
||||
if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
|
||||
NS_ADDREF_THIS();
|
||||
*aResult = static_cast<nsIChannelEventSink *>(this);
|
||||
return NS_OK;
|
||||
} else if (mNotificationCallbacks) {
|
||||
return mNotificationCallbacks->GetInterface(aIID, aResult);
|
||||
} else {
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Routines for selection and clipboard
|
||||
//
|
||||
|
|
|
@ -108,8 +108,6 @@
|
|||
#include "nsIObserver.h"
|
||||
#include "nsDocShellLoadTypes.h"
|
||||
#include "nsPIDOMEventTarget.h"
|
||||
#include "nsIURIClassifier.h"
|
||||
#include "nsIChannelClassifier.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIWebShellServices.h"
|
||||
|
@ -156,32 +154,6 @@ protected:
|
|||
virtual ~nsRefreshTimer();
|
||||
};
|
||||
|
||||
class nsClassifierCallback : public nsIChannelClassifier
|
||||
, public nsIURIClassifierCallback
|
||||
, public nsIRunnable
|
||||
, public nsIChannelEventSink
|
||||
, public nsIInterfaceRequestor
|
||||
{
|
||||
public:
|
||||
nsClassifierCallback() {}
|
||||
~nsClassifierCallback() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICHANNELCLASSIFIER
|
||||
NS_DECL_NSIURICLASSIFIERCALLBACK
|
||||
NS_DECL_NSIRUNNABLE
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsIChannel> mSuspendedChannel;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mNotificationCallbacks;
|
||||
|
||||
void MarkEntryClassified(nsresult status);
|
||||
PRBool HasBeenClassified(nsIChannel *aChannel);
|
||||
};
|
||||
|
||||
#define NS_ERROR_DOCSHELL_REQUEST_REJECTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_GENERAL,1001)
|
||||
|
||||
typedef enum {
|
||||
|
@ -353,11 +325,6 @@ protected:
|
|||
nsIURILoader * aURILoader,
|
||||
PRBool aBypassClassifier);
|
||||
|
||||
// Check the channel load against the URI classifier service (if it
|
||||
// exists). The channel will be suspended until the classification is
|
||||
// complete.
|
||||
nsresult CheckClassifier(nsIChannel *aChannel);
|
||||
|
||||
nsresult ScrollIfAnchor(nsIURI * aURI, PRBool * aWasAnchor,
|
||||
PRUint32 aLoadType, nscoord *cx, nscoord *cy,
|
||||
PRBool * aDoHashchange);
|
||||
|
@ -693,9 +660,6 @@ protected:
|
|||
// Secure browser UI object
|
||||
nsCOMPtr<nsISecureBrowserUI> mSecurityUI;
|
||||
|
||||
// Suspends/resumes channels based on the URI classifier.
|
||||
nsRefPtr<nsClassifierCallback> mClassifier;
|
||||
|
||||
// The URI we're currently loading. This is only relevant during the
|
||||
// firing of a pagehide/unload. The caller of FirePageHideNotification()
|
||||
// is responsible for setting it and unsetting it. It may be null if the
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: ft=cpp tw=78 sw=4 et ts=4 sts=4 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) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com>
|
||||
*
|
||||
* 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 nsIChannel;
|
||||
|
||||
/**
|
||||
* An nsIChannelClassifier object checks a channel's URI against the
|
||||
* URI classifier service, and cancels the channel before OnStartRequest
|
||||
* if it is found on a blacklist.
|
||||
*/
|
||||
[scriptable, uuid(1481c5b5-9f6e-4995-8fe3-2aad5c06440d)]
|
||||
interface nsIChannelClassifier : nsISupports
|
||||
{
|
||||
/**
|
||||
* Checks a channel against the URI classifier service (if it exists).
|
||||
*
|
||||
* The channel will be suspended while the classifier is checked. The
|
||||
* channel may be cancelled with an error code determined by the classifier
|
||||
* before it is resumed.
|
||||
*
|
||||
* If there is no URI classifier service, NS_ERROR_FACTORY_NOT_REGISTERED
|
||||
* will be returned.
|
||||
*
|
||||
* This method must be called immediately after AsyncOpen() has been called
|
||||
* on the channel.
|
||||
*
|
||||
* @param aChannel
|
||||
* The channel to suspend.
|
||||
* @param aInstallListener
|
||||
* If true, the classifier will install notification
|
||||
* callbacks to listen for redirects. The classifier will
|
||||
* pass all notifications on to the channel's existing
|
||||
* notification callbacks.
|
||||
*/
|
||||
void start(in nsIChannel aChannel, in boolean aInstallListener);
|
||||
|
||||
/**
|
||||
* Notify the classifier that the channel was redirected. The new channel
|
||||
* will be suspended pending a new classifier lookup.
|
||||
*
|
||||
* @param aOldChannel
|
||||
* The channel that's being redirected.
|
||||
* @param aNewChannel
|
||||
* The new channel. This channel is not opened yet.
|
||||
*/
|
||||
void onRedirect(in nsIChannel aOldChannel, in nsIChannel aNewChannel);
|
||||
|
||||
/**
|
||||
* Cancel an existing query. If a channel has been suspended, it will
|
||||
* be resumed.
|
||||
*/
|
||||
void cancel();
|
||||
};
|
|
@ -60,21 +60,6 @@
|
|||
#define NS_WEBNAVIGATION_INFO_CONTRACTID \
|
||||
"@mozilla.org/webnavigation-info;1"
|
||||
|
||||
/**
|
||||
* Contract ID for a service implementing nsIURIClassifier that identifies
|
||||
* phishing and malware sites.
|
||||
*/
|
||||
#define NS_URICLASSIFIERSERVICE_CONTRACTID "@mozilla.org/uriclassifierservice"
|
||||
|
||||
/**
|
||||
* Class and contract ID for an nsIChannelClassifier implementation for
|
||||
* checking a channel load against the URI classifier service.
|
||||
*/
|
||||
#define NS_CHANNELCLASSIFIER_CID \
|
||||
{ 0xce02d538, 0x0217, 0x47a3,{0xa5, 0x89, 0xb5, 0x17, 0x90, 0xfd, 0xd8, 0xce}}
|
||||
|
||||
#define NS_CHANNELCLASSIFIER_CONTRACTID "@mozilla.org/channelclassifier"
|
||||
|
||||
/**
|
||||
* Class and contract ID for the docshell. This is the container for a web
|
||||
* navigation context. It implements too many interfaces to count, and the
|
||||
|
|
|
@ -103,7 +103,6 @@ Shutdown(nsIModule* aSelf)
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDocShell, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDefaultURIFixup)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWebNavigationInfo, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsClassifierCallback)
|
||||
|
||||
// uriloader
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsURILoader)
|
||||
|
@ -144,12 +143,6 @@ static const nsModuleComponentInfo gDocShellModuleInfo[] = {
|
|||
NS_WEBNAVIGATION_INFO_CONTRACTID,
|
||||
nsWebNavigationInfoConstructor
|
||||
},
|
||||
{
|
||||
"Channel classifier",
|
||||
NS_CHANNELCLASSIFIER_CID,
|
||||
NS_CHANNELCLASSIFIER_CONTRACTID,
|
||||
nsClassifierCallbackConstructor
|
||||
},
|
||||
|
||||
// about redirector
|
||||
{ "about:about",
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include "nsIRequest.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIStreamLoader.h"
|
||||
#include "nsIChannelClassifier.h"
|
||||
|
||||
// Other includes
|
||||
#include "nsAutoLock.h"
|
||||
|
@ -526,7 +525,8 @@ nsDOMWorkerScriptLoader::RunInternal()
|
|||
ios,
|
||||
loadGroup,
|
||||
nsnull, // callbacks
|
||||
nsIRequest::LOAD_NORMAL, // loadFlags
|
||||
nsIRequest::LOAD_NORMAL |
|
||||
nsIChannel::LOAD_CLASSIFY_URI, // loadFlags
|
||||
channelPolicy); // CSP info
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -536,18 +536,6 @@ nsDOMWorkerScriptLoader::RunInternal()
|
|||
loadInfo.channel = nsnull;
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Check the load against the URI classifier
|
||||
nsCOMPtr<nsIChannelClassifier> classifier =
|
||||
do_CreateInstance(NS_CHANNELCLASSIFIER_CONTRACTID);
|
||||
if (classifier) {
|
||||
rv = classifier->Start(loadInfo.channel, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
loadInfo.channel->Cancel(rv);
|
||||
loadInfo.channel = nsnull;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -85,7 +85,6 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsDocShellCID.h"
|
||||
#include "nsIChannelClassifier.h"
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULPrototypeCache.h"
|
||||
|
@ -1537,8 +1536,9 @@ Loader::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState)
|
|||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_NewChannel(getter_AddRefs(channel),
|
||||
aLoadData->mURI, nsnull, loadGroup,
|
||||
nsnull, nsIChannel::LOAD_NORMAL, channelPolicy);
|
||||
aLoadData->mURI, nsnull, loadGroup, nsnull,
|
||||
nsIChannel::LOAD_NORMAL | nsIChannel::LOAD_CLASSIFY_URI,
|
||||
channelPolicy);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
#ifdef DEBUG
|
||||
|
@ -1596,20 +1596,6 @@ Loader::LoadSheet(SheetLoadData* aLoadData, StyleSheetState aSheetState)
|
|||
return rv;
|
||||
}
|
||||
|
||||
// Check the load against the URI classifier
|
||||
nsCOMPtr<nsIChannelClassifier> classifier =
|
||||
do_CreateInstance(NS_CHANNELCLASSIFIER_CONTRACTID);
|
||||
if (classifier) {
|
||||
rv = classifier->Start(channel, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG_ERROR((" Failed to classify URI"));
|
||||
aLoadData->mIsCancelled = PR_TRUE;
|
||||
channel->Cancel(rv);
|
||||
SheetComplete(aLoadData, rv);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mLoadingDatas.Put(&key, aLoadData)) {
|
||||
LOG_ERROR((" Failed to put data in loading table"));
|
||||
aLoadData->mIsCancelled = PR_TRUE;
|
||||
|
|
|
@ -135,6 +135,7 @@ XPIDLSRCS = \
|
|||
nsIProxiedChannel.idl \
|
||||
nsIRandomGenerator.idl \
|
||||
nsIURIWithPrincipal.idl \
|
||||
nsIURIClassifier.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
|
|
|
@ -213,7 +213,7 @@ interface nsIChannel : nsIRequest
|
|||
/**************************************************************************
|
||||
* Channel specific load flags:
|
||||
*
|
||||
* Bits 22-31 are reserved for future use by this interface or one of its
|
||||
* Bits 23-31 are reserved for future use by this interface or one of its
|
||||
* derivatives (e.g., see nsICachingChannel).
|
||||
*/
|
||||
|
||||
|
@ -268,4 +268,10 @@ interface nsIChannel : nsIRequest
|
|||
* should only do so with good reason.
|
||||
*/
|
||||
const unsigned long LOAD_CALL_CONTENT_SNIFFERS = 1 << 21;
|
||||
|
||||
/**
|
||||
* This flag tells the channel to use URI classifier service to check
|
||||
* the URI when opening the channel.
|
||||
*/
|
||||
const unsigned long LOAD_CLASSIFY_URI = 1 << 22;
|
||||
};
|
||||
|
|
|
@ -55,6 +55,7 @@ CPPSRCS = \
|
|||
nsBaseChannel.cpp \
|
||||
nsBaseContentStream.cpp \
|
||||
nsBufferedStreams.cpp \
|
||||
nsChannelClassifier.cpp \
|
||||
nsDirectoryIndexStream.cpp \
|
||||
nsDownloader.cpp \
|
||||
nsFileStreams.cpp \
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsIContentSniffer.h"
|
||||
#include "nsChannelClassifier.h"
|
||||
|
||||
static PLDHashOperator
|
||||
CopyProperties(const nsAString &key, nsIVariant *data, void *closure)
|
||||
|
@ -284,6 +285,24 @@ nsBaseChannel::HandleAsyncRedirect(nsIChannel* newChannel)
|
|||
CallbacksChanged();
|
||||
}
|
||||
|
||||
void
|
||||
nsBaseChannel::ClassifyURI()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (mLoadFlags & LOAD_CLASSIFY_URI) {
|
||||
nsRefPtr<nsChannelClassifier> classifier = new nsChannelClassifier();
|
||||
if (classifier) {
|
||||
rv = classifier->Start(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
}
|
||||
} else {
|
||||
Cancel(NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsBaseChannel::nsISupports
|
||||
|
||||
|
@ -513,7 +532,10 @@ nsBaseChannel::Open(nsIInputStream **result)
|
|||
} else if (rv == NS_ERROR_NOT_IMPLEMENTED)
|
||||
return NS_ImplementChannelOpen(this, result);
|
||||
|
||||
mWasOpened = NS_SUCCEEDED(rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mWasOpened = PR_TRUE;
|
||||
ClassifyURI();
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -561,6 +583,8 @@ nsBaseChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
|
|||
if (mLoadGroup)
|
||||
mLoadGroup->AddRequest(this, nsnull);
|
||||
|
||||
ClassifyURI();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -247,6 +247,9 @@ private:
|
|||
// returned success from AsyncOpen while posting a redirect runnable.
|
||||
void HandleAsyncRedirect(nsIChannel* newChannel);
|
||||
|
||||
// start URI classifier if requested
|
||||
void ClassifyURI();
|
||||
|
||||
class RedirectRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
/* ***** 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) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com>
|
||||
* Michal Novotny <michal.novotny@gmail.com>
|
||||
*
|
||||
* 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 "nsChannelClassifier.h"
|
||||
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
//
|
||||
// NSPR_LOG_MODULES=nsChannelClassifier:5
|
||||
//
|
||||
static PRLogModuleInfo *gChannelClassifierLog;
|
||||
#endif
|
||||
#define LOG(args) PR_LOG(gChannelClassifierLog, PR_LOG_DEBUG, args)
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsChannelClassifier,
|
||||
nsIURIClassifierCallback)
|
||||
|
||||
nsChannelClassifier::nsChannelClassifier()
|
||||
{
|
||||
#if defined(PR_LOGGING)
|
||||
if (!gChannelClassifierLog)
|
||||
gChannelClassifierLog = PR_NewLogModule("nsChannelClassifier");
|
||||
#endif
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsChannelClassifier::Start(nsIChannel *aChannel)
|
||||
{
|
||||
// Don't bother to run the classifier on a load that has already failed.
|
||||
// (this might happen after a redirect)
|
||||
PRUint32 status;
|
||||
aChannel->GetStatus(&status);
|
||||
if (NS_FAILED(status))
|
||||
return NS_OK;
|
||||
|
||||
// Don't bother to run the classifier on a cached load that was
|
||||
// previously classified.
|
||||
if (HasBeenClassified(aChannel)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Don't bother checking certain types of URIs.
|
||||
PRBool hasFlags;
|
||||
rv = NS_URIChainHasFlags(uri,
|
||||
nsIProtocolHandler::URI_DANGEROUS_TO_LOAD,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
rv = NS_URIChainHasFlags(uri,
|
||||
nsIProtocolHandler::URI_IS_LOCAL_FILE,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
rv = NS_URIChainHasFlags(uri,
|
||||
nsIProtocolHandler::URI_IS_UI_RESOURCE,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
rv = NS_URIChainHasFlags(uri,
|
||||
nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIURIClassifier> uriClassifier =
|
||||
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
|
||||
if (rv == NS_ERROR_FACTORY_NOT_REGISTERED ||
|
||||
rv == NS_ERROR_NOT_AVAILABLE) {
|
||||
// no URI classifier, ignore this failure.
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool expectCallback;
|
||||
rv = uriClassifier->Classify(uri, this, &expectCallback);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (expectCallback) {
|
||||
// Suspend the channel, it will be resumed when we get the classifier
|
||||
// callback.
|
||||
rv = aChannel->Suspend();
|
||||
if (NS_FAILED(rv)) {
|
||||
// Some channels (including nsJSChannel) fail on Suspend. This
|
||||
// shouldn't be fatal, but will prevent malware from being
|
||||
// blocked on these channels.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mSuspendedChannel = aChannel;
|
||||
#ifdef DEBUG
|
||||
LOG(("nsChannelClassifier[%p]: suspended channel %p",
|
||||
this, mSuspendedChannel.get()));
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Note in the cache entry that this URL was classified, so that future
|
||||
// cached loads don't need to be checked.
|
||||
void
|
||||
nsChannelClassifier::MarkEntryClassified(nsresult status)
|
||||
{
|
||||
nsCOMPtr<nsICachingChannel> cachingChannel =
|
||||
do_QueryInterface(mSuspendedChannel);
|
||||
if (!cachingChannel) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> cacheToken;
|
||||
cachingChannel->GetCacheToken(getter_AddRefs(cacheToken));
|
||||
if (!cacheToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> cacheEntry =
|
||||
do_QueryInterface(cacheToken);
|
||||
if (!cacheEntry) {
|
||||
return;
|
||||
}
|
||||
|
||||
cacheEntry->SetMetaDataElement("necko:classified",
|
||||
NS_SUCCEEDED(status) ? "1" : nsnull);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsChannelClassifier::HasBeenClassified(nsIChannel *aChannel)
|
||||
{
|
||||
nsCOMPtr<nsICachingChannel> cachingChannel =
|
||||
do_QueryInterface(aChannel);
|
||||
if (!cachingChannel) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Only check the tag if we are loading from the cache without
|
||||
// validation.
|
||||
PRBool fromCache;
|
||||
if (NS_FAILED(cachingChannel->IsFromCache(&fromCache)) || !fromCache) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> cacheToken;
|
||||
cachingChannel->GetCacheToken(getter_AddRefs(cacheToken));
|
||||
if (!cacheToken) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> cacheEntry =
|
||||
do_QueryInterface(cacheToken);
|
||||
if (!cacheEntry) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsXPIDLCString tag;
|
||||
cacheEntry->GetMetaDataElement("necko:classified", getter_Copies(tag));
|
||||
return tag.EqualsLiteral("1");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode)
|
||||
{
|
||||
if (mSuspendedChannel) {
|
||||
MarkEntryClassified(aErrorCode);
|
||||
|
||||
if (NS_FAILED(aErrorCode)) {
|
||||
#ifdef DEBUG
|
||||
LOG(("nsChannelClassifier[%p]: cancelling channel %p with error "
|
||||
"code: %x", this, mSuspendedChannel.get(), aErrorCode));
|
||||
#endif
|
||||
mSuspendedChannel->Cancel(aErrorCode);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
LOG(("nsChannelClassifier[%p]: resuming channel %p from "
|
||||
"OnClassifyComplete", this, mSuspendedChannel.get()));
|
||||
#endif
|
||||
mSuspendedChannel->Resume();
|
||||
mSuspendedChannel = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/* ***** 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) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@mozilla.com>
|
||||
* Michal Novotny <michal.novotny@gmail.com>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#ifndef nsChannelClassifier_h__
|
||||
#define nsChannelClassifier_h__
|
||||
|
||||
#include "nsIURIClassifier.h"
|
||||
#include "nsIRunnable.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsIChannel;
|
||||
|
||||
|
||||
class nsChannelClassifier : public nsIURIClassifierCallback
|
||||
{
|
||||
public:
|
||||
nsChannelClassifier();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURICLASSIFIERCALLBACK
|
||||
|
||||
nsresult Start(nsIChannel *aChannel);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIChannel> mSuspendedChannel;
|
||||
|
||||
~nsChannelClassifier() {}
|
||||
void MarkEntryClassified(nsresult status);
|
||||
PRBool HasBeenClassified(nsIChannel *aChannel);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -469,6 +469,13 @@
|
|||
#define NS_DEFAULTAUTHPROMPT_CONTRACTID \
|
||||
"@mozilla.org/network/default-auth-prompt;1"
|
||||
|
||||
/**
|
||||
* Contract ID for a service implementing nsIURIClassifier that identifies
|
||||
* phishing and malware sites.
|
||||
*/
|
||||
#define NS_URICLASSIFIERSERVICE_CONTRACTID \
|
||||
"@mozilla.org/uriclassifierservice"
|
||||
|
||||
/******************************************************************************
|
||||
* netwerk/cache/ classes
|
||||
*/
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
#include "nsAuthInformationHolder.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsDNSPrefetch.h"
|
||||
#include "nsChannelClassifier.h"
|
||||
|
||||
// True if the local cache should be bypassed when processing a request.
|
||||
#define BYPASS_LOCAL_CACHE(loadFlags) \
|
||||
|
@ -4496,6 +4497,20 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
|
|||
CloseCacheEntry(PR_TRUE);
|
||||
AsyncAbort(rv);
|
||||
}
|
||||
|
||||
if (mLoadFlags & LOAD_CLASSIFY_URI) {
|
||||
nsRefPtr<nsChannelClassifier> classifier = new nsChannelClassifier();
|
||||
if (!classifier) {
|
||||
Cancel(NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = classifier->Start(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -63,7 +63,6 @@
|
|||
#include "nsUrlClassifierStreamUpdater.h"
|
||||
#include "nsUrlClassifierUtils.h"
|
||||
#include "nsUrlClassifierHashCompleter.h"
|
||||
#include "nsDocShellCID.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_FEEDS
|
||||
|
|
Загрузка…
Ссылка в новой задаче