Bug 1165816 - Cancel remote application reputation requests after a certain timeout. r=gcp

This commit is contained in:
Francois Marier 2015-06-10 17:35:18 +12:00
Родитель e9debda7c4
Коммит 197c33cfb2
2 изменённых файлов: 36 добавлений и 7 удалений

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

@ -975,6 +975,7 @@ pref("browser.safebrowsing.enabled", true);
pref("browser.safebrowsing.malware.enabled", true);
pref("browser.safebrowsing.downloads.enabled", true);
pref("browser.safebrowsing.downloads.remote.enabled", true);
pref("browser.safebrowsing.downloads.remote.timeout_ms", 10000);
pref("browser.safebrowsing.debug", false);
pref("browser.safebrowsing.updateURL", "https://safebrowsing.google.com/safebrowsing/downloads?client=SAFEBROWSING_ID&appver=%VERSION%&pver=2.2&key=%GOOGLE_API_KEY%");

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

@ -18,6 +18,7 @@
#include "nsIScriptSecurityManager.h"
#include "nsIStreamListener.h"
#include "nsIStringStream.h"
#include "nsITimer.h"
#include "nsIUploadChannel2.h"
#include "nsIURI.h"
#include "nsIUrlClassifierDBService.h"
@ -60,6 +61,7 @@ using safe_browsing::ClientDownloadRequest_SignatureInfo;
#define PREF_SB_MALWARE_ENABLED "browser.safebrowsing.malware.enabled"
#define PREF_SB_DOWNLOADS_ENABLED "browser.safebrowsing.downloads.enabled"
#define PREF_SB_DOWNLOADS_REMOTE_ENABLED "browser.safebrowsing.downloads.remote.enabled"
#define PREF_SB_DOWNLOADS_REMOTE_TIMEOUT "browser.safebrowsing.downloads.remote.timeout_ms"
#define PREF_GENERAL_LOCALE "general.useragent.locale"
#define PREF_DOWNLOAD_BLOCK_TABLE "urlclassifier.downloadBlockTable"
#define PREF_DOWNLOAD_ALLOW_TABLE "urlclassifier.downloadAllowTable"
@ -75,12 +77,14 @@ class PendingDBLookup;
// nsIApplicationReputationQuery and an nsIApplicationReputationCallback. Once
// created by ApplicationReputationService, it is guaranteed to call mCallback.
// This class is private to ApplicationReputationService.
class PendingLookup final : public nsIStreamListener
class PendingLookup final : public nsIStreamListener,
public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSITIMERCALLBACK
// Constructor and destructor.
PendingLookup(nsIApplicationReputationQuery* aQuery,
@ -125,6 +129,12 @@ private:
// When we started this query
TimeStamp mStartTime;
// The channel used to talk to the remote lookup server
nsCOMPtr<nsIChannel> mChannel;
// Timer to abort this lookup if it takes too long
nsCOMPtr<nsITimer> mTimeoutTimer;
// A protocol buffer for storing things we need in the remote request. We
// store the resource chain (redirect information) as well as signature
// information extracted using the Windows Authenticode API, if the binary is
@ -741,6 +751,11 @@ PendingLookup::DoLookupInternal()
nsresult
PendingLookup::OnComplete(bool shouldBlock, nsresult rv)
{
if (mTimeoutTimer) {
mTimeoutTimer->Cancel();
mTimeoutTimer = nullptr;
}
Accumulate(mozilla::Telemetry::APPLICATION_REPUTATION_SHOULD_BLOCK,
shouldBlock);
double t = (TimeStamp::Now() - mStartTime).ToMilliseconds();
@ -929,7 +944,6 @@ PendingLookup::SendRemoteQueryInternal()
NS_ENSURE_SUCCESS(rv, rv);
// Set up the channel to transmit the request to the service.
nsCOMPtr<nsIChannel> channel;
nsCOMPtr<nsIIOService> ios = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
rv = ios->NewChannel2(serviceUrl,
nullptr,
@ -939,14 +953,14 @@ PendingLookup::SendRemoteQueryInternal()
nullptr, // aTriggeringPrincipal
nsILoadInfo::SEC_NORMAL,
nsIContentPolicy::TYPE_OTHER,
getter_AddRefs(channel));
getter_AddRefs(mChannel));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel, &rv));
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel, &rv));
NS_ENSURE_SUCCESS(rv, rv);
// Upload the protobuf to the application reputation service.
nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(channel, &rv);
nsCOMPtr<nsIUploadChannel2> uploadChannel = do_QueryInterface(mChannel, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = uploadChannel->ExplicitSetUploadStream(sstream,
@ -958,15 +972,29 @@ PendingLookup::SendRemoteQueryInternal()
// sent with this request. See bug 897516.
nsCOMPtr<nsIInterfaceRequestor> loadContext =
new mozilla::LoadContext(NECKO_SAFEBROWSING_APP_ID);
rv = channel->SetNotificationCallbacks(loadContext);
rv = mChannel->SetNotificationCallbacks(loadContext);
NS_ENSURE_SUCCESS(rv, rv);
rv = channel->AsyncOpen(this, nullptr);
uint32_t timeoutMs = Preferences::GetUint(PREF_SB_DOWNLOADS_REMOTE_TIMEOUT, 10000);
mTimeoutTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
mTimeoutTimer->InitWithCallback(this, timeoutMs, nsITimer::TYPE_ONE_SHOT);
rv = mChannel->AsyncOpen(this, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
PendingLookup::Notify(nsITimer* aTimer)
{
LOG(("Remote lookup timed out [this = %p]", this));
MOZ_ASSERT(aTimer == mTimeoutTimer);
mChannel->Cancel(NS_ERROR_NET_TIMEOUT);
mTimeoutTimer->Cancel();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
//// nsIStreamListener
static NS_METHOD