Bug 1311935 - P2. Process fullHashes.find response. r=francois
This patch includes following changes:
1. nsUrlClassifierHashCompleter.js
nsUrlClassifierHashCompleter.idl
- Add completionV4 interface for hashCompleter to pass response data to
DB service.
- Process response data includes negative cache duration, matched full
hashes and cache duration for each match. Full matches are passed through
nsIFullHashMatch interface.
- Change _requests.responses from array contains matched fullhashes to
dictionary so that it can store additional information likes negative cache
duration.
2. nsUrlClassifierDBService.cpp
- Implement CompletionV4 interface, store response data to CacheResultV4
object. Expired duration to expired time is handled here.
- Add CacheResultToTableUpdate function to convert V2 & V4 cache result
to TableUpdate object.
3. LookupCache.h
- Extend CacheResult to CacheResultV2 and CacheResultV4 so we can store
response data in CompletionV2 and CompletionV4.
4. HashStore.h
- Add API and member variable in TableUpdateV4 to store response data.
TableUpdate object is used by DB service to pass update data or gethash
response to Classifier, so we need to extend TableUpdateV4 to be able
to store fullHashes.find response.
6. Entry.h
- Define the structure about how we cache fullHashes.find response.
MozReview-Commit-ID: FV4yAl2SAc6
This commit is contained in:
@@ -149,6 +149,20 @@ function httpStatusToBucket(httpStatus) {
|
||||
return statusBucket;
|
||||
}
|
||||
|
||||
function FullHashMatch(table, hash, duration) {
|
||||
this.tableName = table;
|
||||
this.fullHash = hash;
|
||||
this.cacheDuration = duration;
|
||||
}
|
||||
|
||||
FullHashMatch.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFullHashMatch]),
|
||||
|
||||
tableName : null,
|
||||
fullHash : null,
|
||||
cacheDuration : null,
|
||||
};
|
||||
|
||||
function HashCompleter() {
|
||||
// The current HashCompleterRequest in flight. Once it is started, it is set
|
||||
// to null. It may be used by multiple calls to |complete| in succession to
|
||||
@@ -315,7 +329,8 @@ HashCompleterRequest.prototype = {
|
||||
this._requests.push({
|
||||
partialHash: aPartialHash,
|
||||
callback: aCallback,
|
||||
responses: []
|
||||
tableName: aTableName,
|
||||
response: { matches:[] },
|
||||
});
|
||||
|
||||
if (aTableName) {
|
||||
@@ -516,7 +531,7 @@ HashCompleterRequest.prototype = {
|
||||
httpChannel.requestMethod = "POST";
|
||||
},
|
||||
|
||||
// Parses the response body and eventually adds items to the |responses| array
|
||||
// Parses the response body and eventually adds items to the |response.matches| array
|
||||
// for elements of |this._requests|.
|
||||
handleResponse: function HCR_handleResponse() {
|
||||
if (this._response == "") {
|
||||
@@ -537,6 +552,8 @@ HashCompleterRequest.prototype = {
|
||||
|
||||
handleResponseV4: function HCR_handleResponseV4() {
|
||||
let callback = {
|
||||
// onCompleteHashFound will be called for each fullhash found in
|
||||
// FullHashResponse.
|
||||
onCompleteHashFound : (aCompleteHash,
|
||||
aTableNames,
|
||||
aPerHashCacheDuration) => {
|
||||
@@ -556,11 +573,16 @@ HashCompleterRequest.prototype = {
|
||||
log("WARNING: Got complete hash which has ambigious threat type.");
|
||||
}
|
||||
|
||||
this.handleItem(aCompleteHash, filteredTables[0], 0);
|
||||
|
||||
// TODO: Bug 1311935 - Implement v4 cache.
|
||||
this.handleItem({
|
||||
completeHash: aCompleteHash,
|
||||
tableName: filteredTables[0],
|
||||
cacheDuration: aPerHashCacheDuration
|
||||
});
|
||||
},
|
||||
|
||||
// onResponseParsed will be called no matter if there is match in
|
||||
// FullHashResponse, the callback is mainly used to pass negative cache
|
||||
// duration and minimum wait duration.
|
||||
onResponseParsed : (aMinWaitDuration,
|
||||
aNegCacheDuration) => {
|
||||
log("V4 fullhash response parsed callback: " +
|
||||
@@ -570,15 +592,22 @@ HashCompleterRequest.prototype = {
|
||||
let minWaitDuration = aMinWaitDuration;
|
||||
|
||||
if (aMinWaitDuration > MIN_WAIT_DURATION_MAX_VALUE) {
|
||||
log("WARNING: Minimum wait duration too large, clamping it down " +
|
||||
"to a reasonable value.");
|
||||
minWaitDuration = MIN_WAIT_DURATION_MAX_VALUE;
|
||||
} else if (aMinWaitDuration < 0) {
|
||||
log("WARNING: Minimum wait duration is negative, reset it to 0");
|
||||
minWaitDuration = 0;
|
||||
}
|
||||
|
||||
this._completer._nextGethashTimeMs[this.gethashUrl] =
|
||||
Date.now() + minWaitDuration;
|
||||
|
||||
// TODO: Bug 1311935 - Implement v4 cache.
|
||||
// A fullhash request may contain more than one prefix, so the negative
|
||||
// cache duration should be set for all the prefixes in the request.
|
||||
this._requests.forEach(request => {
|
||||
request.response.negCacheDuration = aNegCacheDuration;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -615,8 +644,11 @@ HashCompleterRequest.prototype = {
|
||||
|
||||
let data = body.substr(newlineIndex + 1, dataLength);
|
||||
for (let i = 0; i < (dataLength / COMPLETE_LENGTH); i++) {
|
||||
this.handleItem(data.substr(i * COMPLETE_LENGTH, COMPLETE_LENGTH), list,
|
||||
addChunk);
|
||||
this.handleItem({
|
||||
completeHash: data.substr(i * COMPLETE_LENGTH, COMPLETE_LENGTH),
|
||||
tableName: list,
|
||||
chunkId: addChunk
|
||||
});
|
||||
}
|
||||
|
||||
return aStart + newlineIndex + 1 + dataLength;
|
||||
@@ -624,15 +656,11 @@ HashCompleterRequest.prototype = {
|
||||
|
||||
// This adds a complete hash to any entry in |this._requests| that matches
|
||||
// the hash.
|
||||
handleItem: function HCR_handleItem(aData, aTableName, aChunkId) {
|
||||
handleItem: function HCR_handleItem(aData) {
|
||||
for (let i = 0; i < this._requests.length; i++) {
|
||||
let request = this._requests[i];
|
||||
if (aData.startsWith(request.partialHash)) {
|
||||
request.responses.push({
|
||||
completeHash: aData,
|
||||
tableName: aTableName,
|
||||
chunkId: aChunkId,
|
||||
});
|
||||
if (aData.completeHash.startsWith(request.partialHash)) {
|
||||
request.response.matches.push(aData);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -642,16 +670,32 @@ HashCompleterRequest.prototype = {
|
||||
// while notifyFailure only makes a |completionFinished| call with the error
|
||||
// code.
|
||||
notifySuccess: function HCR_notifySuccess() {
|
||||
for (let i = 0; i < this._requests.length; i++) {
|
||||
let request = this._requests[i];
|
||||
for (let j = 0; j < request.responses.length; j++) {
|
||||
let response = request.responses[j];
|
||||
request.callback.completion(response.completeHash, response.tableName,
|
||||
response.chunkId);
|
||||
}
|
||||
// V2 completion handler
|
||||
let completionV2 = (req) => {
|
||||
req.response.matches.forEach((m) => {
|
||||
req.callback.completionV2(m.completeHash, m.tableName, m.chunkId);
|
||||
});
|
||||
|
||||
request.callback.completionFinished(Cr.NS_OK);
|
||||
}
|
||||
req.callback.completionFinished(Cr.NS_OK);
|
||||
};
|
||||
|
||||
// V4 completion handler
|
||||
let completionV4 = (req) => {
|
||||
let matches = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
|
||||
|
||||
req.response.matches.forEach(m => {
|
||||
matches.appendElement(
|
||||
new FullHashMatch(m.tableName, m.completeHash, m.cacheDuration), false);
|
||||
});
|
||||
|
||||
req.callback.completionV4(req.partialHash, req.tableName,
|
||||
req.response.negCacheDuration, matches);
|
||||
|
||||
req.callback.completionFinished(Cr.NS_OK);
|
||||
};
|
||||
|
||||
let completion = this.isV4 ? completionV4 : completionV2;
|
||||
this._requests.forEach((req) => { completion(req); });
|
||||
},
|
||||
|
||||
notifyFailure: function HCR_notifyFailure(aStatus) {
|
||||
|
||||
Reference in New Issue
Block a user