-
Notifications
You must be signed in to change notification settings - Fork 21
/
heuristic.js
105 lines (92 loc) · 3.05 KB
/
heuristic.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
* Copyright (c) 2015 Adobe Systems Incorporated. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var URL = require("url");
module.exports = function (entries, request) {
var topPoints = 0;
var topEntry = null;
var entry;
for (var i = 0; i < entries.length; i++) {
entry = entries[i];
if (!entry.request.parsedUrl) {
entry.request.parsedUrl = URL.parse(entry.request.url, true);
}
if (!entry.request.indexedHeaders) {
entry.request.indexedHeaders = indexHeaders(entry.request.headers);
}
var points = rate(entry.request, request);
if (points > topPoints) {
topPoints = points;
topEntry = entry;
}
}
return topEntry;
};
function rate(entryRequest, request) {
var points = 0;
var name;
// method, host and pathname must match
if (
entryRequest.method !== request.method ||
(request.parsedUrl.host !== null && entryRequest.parsedUrl.host !== request.parsedUrl.host) ||
entryRequest.parsedUrl.pathname !== request.parsedUrl.pathname
) {
return 0;
}
// One point for matching above requirements
points += 1;
// each query
var entryQuery = entryRequest.parsedUrl.query;
var requestQuery = request.parsedUrl.query;
if (entryQuery && requestQuery) {
for (name in requestQuery) {
if (entryQuery[name] === undefined) {
points -= 0.5;
} else {
points += stripProtocol(entryQuery[name]) === stripProtocol(requestQuery[name]) ? 1 : 0;
}
}
for (name in entryQuery) {
if (requestQuery[name] === undefined) {
points -= 0.5;
}
}
}
// each header
var entryHeaders = entryRequest.indexedHeaders;
var requestHeaders = request.headers;
for (name in requestHeaders) {
if (entryHeaders[name]) {
points += stripProtocol(entryHeaders[name]) === stripProtocol(requestHeaders[name]) ? 1 : 0;
}
// TODO handle missing headers and adjust score appropriately
}
return points;
}
function stripProtocol(string) {
if (typeof string === "string") {
return string.replace(/^https?/, "");
} else {
return string;
}
}
function indexHeaders(entryHeaders) {
var headers = {};
entryHeaders.forEach(function (header) {
headers[header.name.toLowerCase()] = header.value;
// TODO handle multiple of the same named header
});
return headers;
}