зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1274112 - Part 1: Make update request v4. r=francois
MozReview-Commit-ID: NgV4QYbDll --HG-- extra : rebase_source : 0c6c000e81e73617c6616dfa39fa868e35a43f9c
This commit is contained in:
Родитель
8ce157e06f
Коммит
019c6a51fd
|
@ -5133,7 +5133,7 @@ pref("browser.safebrowsing.provider.google.reportURL", "https://safebrowsing.goo
|
|||
// Prefs for v4.
|
||||
pref("browser.safebrowsing.provider.google4.pver", "4");
|
||||
pref("browser.safebrowsing.provider.google4.lists", "goog-phish-proto,googpub-phish-proto,goog-malware-proto,goog-unwanted-proto");
|
||||
pref("browser.safebrowsing.provider.google4.updateURL", "https://safebrowsing.googleapis.com/v4/threatListUpdates:fetch?$req=%REQUEST_BASE64%&$ct=application/x-protobuf&key=%GOOGLE_API_KEY%");
|
||||
pref("browser.safebrowsing.provider.google4.updateURL", "https://safebrowsing.googleapis.com/v4/threatListUpdates:fetch?$ct=application/x-protobuf&key=%GOOGLE_API_KEY%");
|
||||
pref("browser.safebrowsing.provider.google4.gethashURL", "https://safebrowsing.googleapis.com/v4/fullHashes:find?$req=%REQUEST_BASE64%&$ct=application/x-protobuf&key=%GOOGLE_API_KEY%");
|
||||
pref("browser.safebrowsing.provider.google4.reportURL", "https://safebrowsing.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ add_test(function test_safebrowsing_update() {
|
|||
}
|
||||
|
||||
streamUpdater.downloadUpdates("test-phish-simple,test-malware-simple", "",
|
||||
URL + safebrowsingUpdatePath, onSuccess, onUpdateError, onDownloadError);
|
||||
true, URL + safebrowsingUpdatePath, onSuccess, onUpdateError, onDownloadError);
|
||||
});
|
||||
|
||||
add_test(function test_non_safebrowsing_cookie() {
|
||||
|
|
|
@ -220,6 +220,7 @@ add_test(function test_local_list() {
|
|||
streamUpdater.downloadUpdates(
|
||||
"goog-downloadwhite-digest256,goog-badbinurl-shavar",
|
||||
"goog-downloadwhite-digest256,goog-badbinurl-shavar;\n",
|
||||
true, // isPostRequest.
|
||||
"http://localhost:4444/downloads",
|
||||
updateSuccess, handleError, handleError);
|
||||
});
|
||||
|
|
|
@ -197,6 +197,7 @@ function waitForUpdates() {
|
|||
streamUpdater.downloadUpdates(
|
||||
"goog-downloadwhite-digest256",
|
||||
"goog-downloadwhite-digest256;\n",
|
||||
true,
|
||||
"http://localhost:4444/downloads",
|
||||
updateSuccess, handleError, handleError);
|
||||
return deferred.promise;
|
||||
|
|
|
@ -297,6 +297,7 @@ function waitForUpdates() {
|
|||
streamUpdater.downloadUpdates(
|
||||
"goog-downloadwhite-digest256",
|
||||
"goog-downloadwhite-digest256;\n",
|
||||
true,
|
||||
"http://localhost:4444/downloads",
|
||||
updateSuccess, handleError, handleError);
|
||||
return deferred.promise;
|
||||
|
|
|
@ -12,7 +12,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||
//
|
||||
// There is a single listmanager for the whole application.
|
||||
//
|
||||
// TODO more comprehensive update tests, for example add unittest check
|
||||
// TODO more comprehensive update tests, for example add unittest check
|
||||
// that the listmanagers tables are properly written on updates
|
||||
|
||||
// Lower and upper limits on the server-provided polling frequency
|
||||
|
@ -352,8 +352,13 @@ PROT_ListManager.prototype.makeUpdateRequest_ = function(updateUrl, tableData) {
|
|||
// tableNames: map of tables that need updating,
|
||||
// request: list of tables and existing chunk ranges from tableData
|
||||
// }
|
||||
var streamerMap = { tableList: null, tableNames: {}, request: "" };
|
||||
var streamerMap = { tableList: null,
|
||||
tableNames: {},
|
||||
requestPayload: "",
|
||||
isPostRequest: true };
|
||||
|
||||
let useProtobuf = false;
|
||||
let onceThru = false;
|
||||
for (var tableName in this.tablesData) {
|
||||
// Skip tables not matching this update url
|
||||
if (this.tablesData[tableName].updateUrl != updateUrl) {
|
||||
|
@ -364,11 +369,13 @@ PROT_ListManager.prototype.makeUpdateRequest_ = function(updateUrl, tableData) {
|
|||
// We use the table name 'goog-*-proto' and an additional provider "google4"
|
||||
// to describe the v4 settings.
|
||||
let isCurTableProto = tableName.endsWith('-proto');
|
||||
if (useProtobuf && !isCurTableProto) {
|
||||
log('ERROR: Tables for the same updateURL should all be "proto" or none. ' +
|
||||
'Check "browser.safebrowsing.provider.google4.lists"');
|
||||
if (!onceThru) {
|
||||
useProtobuf = isCurTableProto;
|
||||
onceThru = true;
|
||||
} else if (useProtobuf !== isCurTableProto) {
|
||||
log('ERROR: Cannot mix "proto" tables with other types ' +
|
||||
'within the same provider.');
|
||||
}
|
||||
useProtobuf = isCurTableProto;
|
||||
|
||||
if (this.needsUpdate_[this.tablesData[tableName].updateUrl][tableName]) {
|
||||
streamerMap.tableNames[tableName] = true;
|
||||
|
@ -381,8 +388,24 @@ PROT_ListManager.prototype.makeUpdateRequest_ = function(updateUrl, tableData) {
|
|||
}
|
||||
|
||||
if (useProtobuf) {
|
||||
// TODO: Bug 1275507 - XPCOM API to build v4 update request.
|
||||
streamerMap.request = "";
|
||||
let tableArray = streamerMap.tableList.split(',');
|
||||
|
||||
// The state is a byte stream which server told us from the
|
||||
// last table update. The state would be used to do the partial
|
||||
// update and the empty string means the table has
|
||||
// never been downloaded. See Bug 1287058 for supporting
|
||||
// partial update.
|
||||
let stateArray = [];
|
||||
tableArray.forEach(() => stateArray.push(''));
|
||||
|
||||
let urlUtils = Cc["@mozilla.org/url-classifier/utils;1"]
|
||||
.getService(Ci.nsIUrlClassifierUtils);
|
||||
let requestPayload = urlUtils.makeUpdateRequestV4(tableArray,
|
||||
stateArray,
|
||||
tableArray.length);
|
||||
// Use a base64-encoded request.
|
||||
streamerMap.requestPayload = btoa(requestPayload);
|
||||
streamerMap.isPostRequest = false;
|
||||
} else {
|
||||
// Build the request. For each table already in the database, include the
|
||||
// chunk data from the database
|
||||
|
@ -391,23 +414,26 @@ PROT_ListManager.prototype.makeUpdateRequest_ = function(updateUrl, tableData) {
|
|||
var fields = lines[i].split(";");
|
||||
var name = fields[0];
|
||||
if (streamerMap.tableNames[name]) {
|
||||
streamerMap.request += lines[i] + "\n";
|
||||
streamerMap.requestPayload += lines[i] + "\n";
|
||||
delete streamerMap.tableNames[name];
|
||||
}
|
||||
}
|
||||
// For each requested table that didn't have chunk data in the database,
|
||||
// request it fresh
|
||||
for (let tableName in streamerMap.tableNames) {
|
||||
streamerMap.request += tableName + ";\n";
|
||||
streamerMap.requestPayload += tableName + ";\n";
|
||||
}
|
||||
|
||||
streamerMap.isPostRequest = true;
|
||||
}
|
||||
|
||||
log("update request: " + JSON.stringify(streamerMap, undefined, 2) + "\n");
|
||||
|
||||
// Don't send an empty request.
|
||||
if (streamerMap.request.length > 0) {
|
||||
if (streamerMap.requestPayload.length > 0) {
|
||||
this.makeUpdateRequestForEntry_(updateUrl, streamerMap.tableList,
|
||||
streamerMap.request);
|
||||
streamerMap.requestPayload,
|
||||
streamerMap.isPostRequest);
|
||||
} else {
|
||||
// We were disabled between kicking off getTables and now.
|
||||
log("Not sending empty request");
|
||||
|
@ -416,8 +442,9 @@ PROT_ListManager.prototype.makeUpdateRequest_ = function(updateUrl, tableData) {
|
|||
|
||||
PROT_ListManager.prototype.makeUpdateRequestForEntry_ = function(updateUrl,
|
||||
tableList,
|
||||
request) {
|
||||
log("makeUpdateRequestForEntry_: request " + request +
|
||||
requestPayload,
|
||||
isPostRequest) {
|
||||
log("makeUpdateRequestForEntry_: requestPayload " + requestPayload +
|
||||
" update: " + updateUrl + " tablelist: " + tableList + "\n");
|
||||
var streamer = Cc["@mozilla.org/url-classifier/streamupdater;1"]
|
||||
.getService(Ci.nsIUrlClassifierStreamUpdater);
|
||||
|
@ -426,7 +453,8 @@ PROT_ListManager.prototype.makeUpdateRequestForEntry_ = function(updateUrl,
|
|||
|
||||
if (!streamer.downloadUpdates(
|
||||
tableList,
|
||||
request,
|
||||
requestPayload,
|
||||
isPostRequest,
|
||||
updateUrl,
|
||||
BindToObject(this.updateSuccess_, this, tableList, updateUrl),
|
||||
BindToObject(this.updateError_, this, tableList, updateUrl),
|
||||
|
|
|
@ -20,7 +20,9 @@ interface nsIUrlClassifierStreamUpdater : nsISupports
|
|||
* as well as in testing.
|
||||
* @param aRequestTables Comma-separated list of tables included in this
|
||||
* update.
|
||||
* @param aRequestBody The body for the request.
|
||||
* @param aRequestPayload The payload for the request.
|
||||
* @param aIsPostRequest Whether the request should be sent by POST method.
|
||||
* Should be 'true' for v2 usage.
|
||||
* @param aUpdateUrl The plaintext url from which to request updates.
|
||||
* @param aSuccessCallback Called after a successful update.
|
||||
* @param aUpdateErrorCallback Called for problems applying the update
|
||||
|
@ -28,7 +30,8 @@ interface nsIUrlClassifierStreamUpdater : nsISupports
|
|||
* connection refused error.
|
||||
*/
|
||||
boolean downloadUpdates(in ACString aRequestTables,
|
||||
in ACString aRequestBody,
|
||||
in ACString aRequestPayload,
|
||||
in boolean aIsPostRequest,
|
||||
in ACString aUpdateUrl,
|
||||
in nsIUrlClassifierCallback aSuccessCallback,
|
||||
in nsIUrlClassifierCallback aUpdateErrorCallback,
|
||||
|
|
|
@ -103,7 +103,8 @@ nsUrlClassifierStreamUpdater::DownloadDone()
|
|||
|
||||
nsresult
|
||||
nsUrlClassifierStreamUpdater::FetchUpdate(nsIURI *aUpdateUrl,
|
||||
const nsACString & aRequestBody,
|
||||
const nsACString & aRequestPayload,
|
||||
bool aIsPostRequest,
|
||||
const nsACString & aStreamTable)
|
||||
{
|
||||
|
||||
|
@ -111,7 +112,7 @@ nsUrlClassifierStreamUpdater::FetchUpdate(nsIURI *aUpdateUrl,
|
|||
{
|
||||
nsCString spec;
|
||||
aUpdateUrl->GetSpec(spec);
|
||||
LOG(("Fetching update %s from %s", aRequestBody.Data(), spec.get()));
|
||||
LOG(("Fetching update %s from %s", aRequestPayload.Data(), spec.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -134,9 +135,26 @@ nsUrlClassifierStreamUpdater::FetchUpdate(nsIURI *aUpdateUrl,
|
|||
|
||||
mBeganStream = false;
|
||||
|
||||
// If aRequestBody is empty, construct it for the test.
|
||||
if (!aRequestBody.IsEmpty()) {
|
||||
rv = AddRequestBody(aRequestBody);
|
||||
if (!aIsPostRequest) {
|
||||
// We use POST method to send our request in v2. In v4, the request
|
||||
// needs to be embedded to the URL and use GET method to send.
|
||||
// However, from the Chromium source code, a extended HTTP header has
|
||||
// to be sent along with the request to make the request succeed.
|
||||
// The following description is from Chromium source code:
|
||||
//
|
||||
// "The following header informs the envelope server (which sits in
|
||||
// front of Google's stubby server) that the received GET request should be
|
||||
// interpreted as a POST."
|
||||
//
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(mChannel, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = httpChannel->SetRequestHeader(NS_LITERAL_CSTRING("X-HTTP-Method-Override"),
|
||||
NS_LITERAL_CSTRING("POST"),
|
||||
false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else if (!aRequestPayload.IsEmpty()) {
|
||||
rv = AddRequestBody(aRequestPayload);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
|
@ -176,13 +194,19 @@ nsUrlClassifierStreamUpdater::FetchUpdate(nsIURI *aUpdateUrl,
|
|||
|
||||
nsresult
|
||||
nsUrlClassifierStreamUpdater::FetchUpdate(const nsACString & aUpdateUrl,
|
||||
const nsACString & aRequestBody,
|
||||
const nsACString & aRequestPayload,
|
||||
bool aIsPostRequest,
|
||||
const nsACString & aStreamTable)
|
||||
{
|
||||
LOG(("(pre) Fetching update from %s\n", PromiseFlatCString(aUpdateUrl).get()));
|
||||
|
||||
nsCString updateUrl(aUpdateUrl);
|
||||
if (!aIsPostRequest) {
|
||||
updateUrl.AppendPrintf("&$req=%s", nsCString(aRequestPayload).get());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aUpdateUrl);
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), updateUrl);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoCString urlSpec;
|
||||
|
@ -190,13 +214,14 @@ nsUrlClassifierStreamUpdater::FetchUpdate(const nsACString & aUpdateUrl,
|
|||
|
||||
LOG(("(post) Fetching update from %s\n", urlSpec.get()));
|
||||
|
||||
return FetchUpdate(uri, aRequestBody, aStreamTable);
|
||||
return FetchUpdate(uri, aRequestPayload, aIsPostRequest, aStreamTable);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUrlClassifierStreamUpdater::DownloadUpdates(
|
||||
const nsACString &aRequestTables,
|
||||
const nsACString &aRequestBody,
|
||||
const nsACString &aRequestPayload,
|
||||
bool aIsPostRequest,
|
||||
const nsACString &aUpdateUrl,
|
||||
nsIUrlClassifierCallback *aSuccessCallback,
|
||||
nsIUrlClassifierCallback *aUpdateErrorCallback,
|
||||
|
@ -208,12 +233,13 @@ nsUrlClassifierStreamUpdater::DownloadUpdates(
|
|||
NS_ENSURE_ARG(aDownloadErrorCallback);
|
||||
|
||||
if (mIsUpdating) {
|
||||
LOG(("Already updating, queueing update %s from %s", aRequestBody.Data(),
|
||||
LOG(("Already updating, queueing update %s from %s", aRequestPayload.Data(),
|
||||
aUpdateUrl.Data()));
|
||||
*_retval = false;
|
||||
PendingRequest *request = mPendingRequests.AppendElement();
|
||||
request->mTables = aRequestTables;
|
||||
request->mRequest = aRequestBody;
|
||||
request->mRequestPayload = aRequestPayload;
|
||||
request->mIsPostRequest = aIsPostRequest;
|
||||
request->mUrl = aUpdateUrl;
|
||||
request->mSuccessCallback = aSuccessCallback;
|
||||
request->mUpdateErrorCallback = aUpdateErrorCallback;
|
||||
|
@ -248,11 +274,12 @@ nsUrlClassifierStreamUpdater::DownloadUpdates(
|
|||
rv = mDBService->BeginUpdate(this, aRequestTables);
|
||||
if (rv == NS_ERROR_NOT_AVAILABLE) {
|
||||
LOG(("Service busy, already updating, queuing update %s from %s",
|
||||
aRequestBody.Data(), aUpdateUrl.Data()));
|
||||
aRequestPayload.Data(), aUpdateUrl.Data()));
|
||||
*_retval = false;
|
||||
PendingRequest *request = mPendingRequests.AppendElement();
|
||||
request->mTables = aRequestTables;
|
||||
request->mRequest = aRequestBody;
|
||||
request->mRequestPayload = aRequestPayload;
|
||||
request->mIsPostRequest = aIsPostRequest;
|
||||
request->mUrl = aUpdateUrl;
|
||||
request->mSuccessCallback = aSuccessCallback;
|
||||
request->mUpdateErrorCallback = aUpdateErrorCallback;
|
||||
|
@ -272,9 +299,8 @@ nsUrlClassifierStreamUpdater::DownloadUpdates(
|
|||
*_retval = true;
|
||||
|
||||
LOG(("FetchUpdate: %s", aUpdateUrl.Data()));
|
||||
//LOG(("requestBody: %s", aRequestBody.Data()));
|
||||
|
||||
return FetchUpdate(aUpdateUrl, aRequestBody, EmptyCString());
|
||||
return FetchUpdate(aUpdateUrl, aRequestPayload, aIsPostRequest, EmptyCString());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -318,7 +344,9 @@ nsUrlClassifierStreamUpdater::FetchNext()
|
|||
|
||||
PendingUpdate &update = mPendingUpdates[0];
|
||||
LOG(("Fetching update url: %s\n", update.mUrl.get()));
|
||||
nsresult rv = FetchUpdate(update.mUrl, EmptyCString(),
|
||||
nsresult rv = FetchUpdate(update.mUrl,
|
||||
EmptyCString(),
|
||||
true, // This method is for v2 and v2 is always a POST.
|
||||
update.mTable);
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("Error fetching update url: %s\n", update.mUrl.get()));
|
||||
|
@ -349,7 +377,8 @@ nsUrlClassifierStreamUpdater::FetchNextRequest()
|
|||
bool dummy;
|
||||
DownloadUpdates(
|
||||
request.mTables,
|
||||
request.mRequest,
|
||||
request.mRequestPayload,
|
||||
request.mIsPostRequest,
|
||||
request.mUrl,
|
||||
request.mSuccessCallback,
|
||||
request.mUpdateErrorCallback,
|
||||
|
|
|
@ -54,11 +54,13 @@ private:
|
|||
|
||||
// Fetches an update for a single table.
|
||||
nsresult FetchUpdate(nsIURI *aURI,
|
||||
const nsACString &aRequestBody,
|
||||
const nsACString &aRequest,
|
||||
bool aIsPostRequest,
|
||||
const nsACString &aTable);
|
||||
// Dumb wrapper so we don't have to create URIs.
|
||||
nsresult FetchUpdate(const nsACString &aURI,
|
||||
const nsACString &aRequestBody,
|
||||
const nsACString &aRequest,
|
||||
bool aIsPostRequest,
|
||||
const nsACString &aTable);
|
||||
|
||||
// Fetches the next table, from mPendingUpdates.
|
||||
|
@ -78,7 +80,8 @@ private:
|
|||
|
||||
struct PendingRequest {
|
||||
nsCString mTables;
|
||||
nsCString mRequest;
|
||||
nsCString mRequestPayload;
|
||||
bool mIsPostRequest;
|
||||
nsCString mUrl;
|
||||
nsCOMPtr<nsIUrlClassifierCallback> mSuccessCallback;
|
||||
nsCOMPtr<nsIUrlClassifierCallback> mUpdateErrorCallback;
|
||||
|
|
|
@ -211,6 +211,9 @@ static const struct {
|
|||
{ "googpub-phish-proto", SOCIAL_ENGINEERING_PUBLIC}, // 2
|
||||
{ "goog-unwanted-proto", UNWANTED_SOFTWARE}, // 3
|
||||
{ "goog-phish-proto", SOCIAL_ENGINEERING}, // 5
|
||||
|
||||
// For testing purpose.
|
||||
{ "test-phish-proto", SOCIAL_ENGINEERING_PUBLIC}, // 2
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -200,7 +200,7 @@ function doStreamUpdate(updateText, success, failure, downloadFailure) {
|
|||
downloadFailure = failure;
|
||||
}
|
||||
|
||||
streamUpdater.downloadUpdates(allTables, "",
|
||||
streamUpdater.downloadUpdates(allTables, "", true,
|
||||
dataUpdate, success, failure, downloadFailure);
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,7 @@ add_test(function test_update() {
|
|||
streamUpdater.downloadUpdates(
|
||||
"goog-downloadwhite-digest256",
|
||||
"goog-downloadwhite-digest256;\n",
|
||||
true,
|
||||
"http://localhost:4444/downloads",
|
||||
updateSuccess, handleError, handleError);
|
||||
});
|
||||
|
|
|
@ -31,31 +31,36 @@ const TEST_TABLE_DATA_LIST = [
|
|||
}
|
||||
];
|
||||
|
||||
// This table has a different update URL.
|
||||
const TEST_TABLE_DATA_ANOTHER = {
|
||||
tableName: "test-listmanageranother-digest256",
|
||||
providerName: "google",
|
||||
updateUrl: "http://localhost:5555/safebrowsing/update",
|
||||
gethashUrl: "http://localhost:5555/safebrowsing/gethash-another",
|
||||
// This table has a different update URL (for v4).
|
||||
const TEST_TABLE_DATA_V4 = {
|
||||
tableName: "test-phish-proto",
|
||||
providerName: "google4",
|
||||
updateUrl: "http://localhost:5555/safebrowsing/update?",
|
||||
gethashUrl: "http://localhost:5555/safebrowsing/gethash-v4",
|
||||
};
|
||||
|
||||
const PREF_NEXTUPDATETIME = "browser.safebrowsing.provider.google.nextupdatetime";
|
||||
const PREF_NEXTUPDATETIME_V4 = "browser.safebrowsing.provider.google4.nextupdatetime";
|
||||
|
||||
let gListManager = Cc["@mozilla.org/url-classifier/listmanager;1"]
|
||||
.getService(Ci.nsIUrlListManager);
|
||||
|
||||
let gUrlUtils = Cc["@mozilla.org/url-classifier/utils;1"]
|
||||
.getService(Ci.nsIUrlClassifierUtils);
|
||||
|
||||
// Global test server for serving safebrowsing updates.
|
||||
let gHttpServ = null;
|
||||
let gUpdateResponse = "";
|
||||
let gExpectedUpdateRequest = "";
|
||||
let gExpectedQueryV4 = "";
|
||||
|
||||
// Handles request for TEST_TABLE_DATA_ANOTHER.
|
||||
let gHttpServAnother = null;
|
||||
// Handles request for TEST_TABLE_DATA_V4.
|
||||
let gHttpServV4 = null;
|
||||
|
||||
// These two variables are used to synchronize the last two racing updates
|
||||
// (in terms of "update URL") in test_update_all_tables().
|
||||
let gUpdatedCntForTableData = 0; // For TEST_TABLE_DATA_LIST.
|
||||
let gIsAnotherUpdated = false; // For TEST_TABLE_DATA_ANOTHER.
|
||||
let gIsV4Updated = false; // For TEST_TABLE_DATA_V4.
|
||||
|
||||
prefBranch.setBoolPref("browser.safebrowsing.debug", true);
|
||||
|
||||
|
@ -66,10 +71,11 @@ TEST_TABLE_DATA_LIST.forEach(function(t) {
|
|||
t.updateUrl,
|
||||
t.gethashUrl);
|
||||
});
|
||||
gListManager.registerTable(TEST_TABLE_DATA_ANOTHER.tableName,
|
||||
TEST_TABLE_DATA_ANOTHER.providerName,
|
||||
TEST_TABLE_DATA_ANOTHER.updateUrl,
|
||||
TEST_TABLE_DATA_ANOTHER.gethashUrl);
|
||||
|
||||
gListManager.registerTable(TEST_TABLE_DATA_V4.tableName,
|
||||
TEST_TABLE_DATA_V4.providerName,
|
||||
TEST_TABLE_DATA_V4.updateUrl,
|
||||
TEST_TABLE_DATA_V4.gethashUrl);
|
||||
|
||||
const SERVER_INVOLVED_TEST_CASE_LIST = [
|
||||
// - Do table0 update.
|
||||
|
@ -110,17 +116,26 @@ const SERVER_INVOLVED_TEST_CASE_LIST = [
|
|||
function test_update_all_tables() {
|
||||
disableAllUpdates();
|
||||
|
||||
// Enable all tables including TEST_TABLE_DATA_ANOTHER!
|
||||
// Enable all tables including TEST_TABLE_DATA_V4!
|
||||
TEST_TABLE_DATA_LIST.forEach(function(t) {
|
||||
gListManager.enableUpdate(t.tableName);
|
||||
});
|
||||
gListManager.enableUpdate(TEST_TABLE_DATA_ANOTHER.tableName);
|
||||
gListManager.enableUpdate(TEST_TABLE_DATA_V4.tableName);
|
||||
|
||||
// Expected results for v2.
|
||||
gExpectedUpdateRequest = TEST_TABLE_DATA_LIST[0].tableName + ";a:5:s:2-12\n" +
|
||||
TEST_TABLE_DATA_LIST[1].tableName + ";\n" +
|
||||
TEST_TABLE_DATA_LIST[2].tableName + ";\n";
|
||||
gUpdateResponse = "n:1000\n";
|
||||
|
||||
// We test the request against the query string since v4 request
|
||||
// would be appened to the query string. The request is generated
|
||||
// by protobuf API (binary) then encoded to base64 format.
|
||||
let requestV4 = gUrlUtils.makeUpdateRequestV4([TEST_TABLE_DATA_V4.tableName],
|
||||
[""],
|
||||
1);
|
||||
gExpectedQueryV4 = "&$req=" + btoa(requestV4);
|
||||
|
||||
forceTableUpdate();
|
||||
},
|
||||
|
||||
|
@ -133,8 +148,8 @@ add_test(function test_getGethashUrl() {
|
|||
TEST_TABLE_DATA_LIST.forEach(function (t) {
|
||||
equal(gListManager.getGethashUrl(t.tableName), t.gethashUrl);
|
||||
});
|
||||
equal(gListManager.getGethashUrl(TEST_TABLE_DATA_ANOTHER.tableName),
|
||||
TEST_TABLE_DATA_ANOTHER.gethashUrl);
|
||||
equal(gListManager.getGethashUrl(TEST_TABLE_DATA_V4.tableName),
|
||||
TEST_TABLE_DATA_V4.gethashUrl);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
|
@ -165,36 +180,43 @@ function run_test() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (gIsAnotherUpdated) {
|
||||
if (gIsV4Updated) {
|
||||
run_next_test(); // All tests are done. Just finish.
|
||||
return;
|
||||
}
|
||||
|
||||
do_print("Waiting for TEST_TABLE_DATA_ANOTHER to be tested ...");
|
||||
do_print("Waiting for TEST_TABLE_DATA_V4 to be tested ...");
|
||||
});
|
||||
|
||||
gHttpServ.start(4444);
|
||||
|
||||
// Setup another testing server for the different update URL.
|
||||
gHttpServAnother = new HttpServer();
|
||||
gHttpServAnother.registerDirectory("/", do_get_cwd());
|
||||
// Setup v4 testing server for the different update URL.
|
||||
gHttpServV4 = new HttpServer();
|
||||
gHttpServV4.registerDirectory("/", do_get_cwd());
|
||||
|
||||
gHttpServAnother.registerPathHandler("/safebrowsing/update", function(request, response) {
|
||||
let body = NetUtil.readInputStreamToString(request.bodyInputStream,
|
||||
request.bodyInputStream.available());
|
||||
gHttpServV4.registerPathHandler("/safebrowsing/update", function(request, response) {
|
||||
// V4 update request body should be empty.
|
||||
equal(request.bodyInputStream.available(), 0);
|
||||
|
||||
// Verify if the request is as expected.
|
||||
equal(body, TEST_TABLE_DATA_ANOTHER.tableName + ";\n");
|
||||
// Not on the spec. Found in Chromium source code...
|
||||
equal(request.getHeader("X-HTTP-Method-Override"), "POST");
|
||||
|
||||
// Respond with no chunk control.
|
||||
// V4 update request uses GET.
|
||||
equal(request.method, "GET");
|
||||
|
||||
// V4 append the base64 encoded request to the query string.
|
||||
equal(request.queryString, gExpectedQueryV4);
|
||||
|
||||
// Respond a V2 compatible content for now. In the future we can
|
||||
// send a meaningful response to test Bug 1284178 to see if the
|
||||
// update is successfully stored to database.
|
||||
response.setHeader("Content-Type",
|
||||
"application/vnd.google.safebrowsing-update", false);
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
|
||||
let content = "n:1000\n";
|
||||
response.bodyOutputStream.write(content, content.length);
|
||||
|
||||
gIsAnotherUpdated = true;
|
||||
gIsV4Updated = true;
|
||||
|
||||
if (gUpdatedCntForTableData === SERVER_INVOLVED_TEST_CASE_LIST.length) {
|
||||
// All tests are done!
|
||||
|
@ -205,7 +227,7 @@ function run_test() {
|
|||
do_print("Wait for all sever-involved tests to be done ...");
|
||||
});
|
||||
|
||||
gHttpServAnother.start(5555);
|
||||
gHttpServV4.start(5555);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
@ -214,12 +236,13 @@ function run_test() {
|
|||
// call disableAllUpdates() first to clean up the updateCheckers in listmanager.
|
||||
function forceTableUpdate() {
|
||||
prefBranch.setCharPref(PREF_NEXTUPDATETIME, "1");
|
||||
prefBranch.setCharPref(PREF_NEXTUPDATETIME_V4, "1");
|
||||
gListManager.maybeToggleUpdateChecking();
|
||||
}
|
||||
|
||||
function disableAllUpdates() {
|
||||
TEST_TABLE_DATA_LIST.forEach(t => gListManager.disableUpdate(t.tableName));
|
||||
gListManager.disableUpdate(TEST_TABLE_DATA_ANOTHER.tableName);
|
||||
gListManager.disableUpdate(TEST_TABLE_DATA_V4.tableName);
|
||||
}
|
||||
|
||||
// Since there's no public interface on listmanager to know the update success,
|
||||
|
@ -243,3 +266,11 @@ function readFileToString(aFilename) {
|
|||
let buf = NetUtil.readInputStreamToString(stream, stream.available());
|
||||
return buf;
|
||||
}
|
||||
|
||||
function buildUpdateRequestV4InBase64() {
|
||||
|
||||
let request = urlUtils.makeUpdateRequestV4([TEST_TABLE_DATA_V4.tableName],
|
||||
[""],
|
||||
1);
|
||||
return btoa(request);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче