Skip to content

Commit a2b2c0a

Browse files
authored
Merge pull request #303 from Lissy93/feat/ui-result-accuracy
UI result accuracy
2 parents fcb596c + c4f65e4 commit a2b2c0a

30 files changed

Lines changed: 427 additions & 234 deletions

api/_common/http.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ const wrapNetworkError = (error) => {
6161
return error;
6262
};
6363

64-
const UA = 'web-check/1.0 (https://web-check.xyz)';
64+
export const UA =
65+
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) ' +
66+
'Chrome/120.0.0.0 Safari/537.36 (compatible; web-check/1.0; +https://web-check.xyz)';
6567

6668
const send = async (method, url, body, opts = {}) => {
6769
const finalUrl = appendParams(url, opts.params);

api/archives.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,32 +47,32 @@ const getScanFrequency = (firstScan, lastScan, totalScans, changeCount) => {
4747
};
4848

4949
const wayBackHandler = async (url) => {
50-
const cdxUrl = `https://web.archive.org/cdx/search/cdx?url=${url}&output=json&fl=timestamp,statuscode,digest,length,offset`;
50+
// collapse=timestamp:8 returns one row per archived day, slashing payloads
51+
// (Wikipedia: 25MB/373k rows -> 428KB/6k rows) without losing first/last/change counts
52+
const cdxUrl =
53+
`https://web.archive.org/cdx/search/cdx?url=${encodeURIComponent(url)}` +
54+
`&output=json&fl=timestamp,statuscode,digest,length&collapse=timestamp:8`;
5155

5256
try {
5357
const { data } = await httpGet(cdxUrl);
5458

55-
// Check there's data
5659
if (!data || !Array.isArray(data) || data.length <= 1) {
5760
return { skipped: 'Site has never before been archived via the Wayback Machine' };
5861
}
5962

60-
// Remove the header row
6163
data.shift();
6264

63-
// Process and return the results
6465
const firstScan = convertTimestampToDate(data[0][0]);
6566
const lastScan = convertTimestampToDate(data[data.length - 1][0]);
66-
const totalScans = data.length;
67+
const daysArchived = data.length;
6768
const changeCount = countPageChanges(data);
6869
return {
6970
firstScan,
7071
lastScan,
71-
totalScans,
72+
daysArchived,
7273
changeCount,
7374
averagePageSize: getAveragePageSize(data),
74-
scanFrequency: getScanFrequency(firstScan, lastScan, totalScans, changeCount),
75-
scans: data,
75+
scanFrequency: getScanFrequency(firstScan, lastScan, daysArchived, changeCount),
7676
scanUrl: url,
7777
};
7878
} catch (err) {

api/carbon.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import middleware from './_common/middleware.js';
2+
import { UA } from './_common/http.js';
23
import { createLogger } from './_common/logger.js';
34

45
const log = createLogger('carbon');
56

67
const TIMEOUT = 8000;
78
const MAX_BYTES = 10 * 1024 * 1024;
8-
const USER_AGENT = 'Mozilla/5.0 (compatible; WebCheck/2.0; +https://web-check.xyz)';
99

1010
// Sustainable Web Design model v3 constants, matches websitecarbon.com formula
1111
const KWH_PER_GB = 0.81;
@@ -33,7 +33,7 @@ const fetchByteCount = async (url) => {
3333
const r = await fetch(url, {
3434
signal: AbortSignal.timeout(TIMEOUT),
3535
redirect: 'follow',
36-
headers: { 'user-agent': USER_AGENT, accept: 'text/html,*/*;q=0.1' },
36+
headers: { 'user-agent': UA, accept: 'text/html,*/*;q=0.1' },
3737
});
3838
if (!r.ok) throw new Error(`status ${r.status}`);
3939
if (!r.body) return 0;

api/dnssec.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const queryDns = async (domain, type) => {
77
const res = await httpGet('https://dns.google/resolve', {
88
params: { name: domain, type },
99
headers: { Accept: 'application/dns-json' },
10-
timeout: 5000,
1110
});
1211
return res.data;
1312
};

api/hsts.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,12 @@ const evaluate = (header) => {
2222
return verdict('Site is compatible with the HSTS preload list!', true, header);
2323
};
2424

25-
const REQUEST_TIMEOUT = 5000;
26-
2725
const hstsHandler = async (url) =>
2826
new Promise((resolve) => {
2927
const req = https.request(url, (res) => {
3028
resolve(evaluate(res.headers['strict-transport-security']));
3129
res.resume();
3230
});
33-
req.setTimeout(REQUEST_TIMEOUT, () => {
34-
req.destroy();
35-
resolve({ error: 'HSTS check timed out' });
36-
});
3731
req.on('error', (e) => resolve({ error: `HSTS check failed: ${e.message}` }));
3832
req.end();
3933
});

api/quality.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const qualityHandler = async (url) => {
88
const endpoint =
99
`https://www.googleapis.com/pagespeedonline/v5/runPagespeed?` +
1010
`url=${encodeURIComponent(url)}&category=PERFORMANCE&category=ACCESSIBILITY` +
11-
`&category=BEST_PRACTICES&category=SEO&category=PWA&strategy=mobile` +
11+
`&category=BEST_PRACTICES&category=SEO&strategy=mobile` +
1212
`&key=${auth.value}`;
1313

1414
let data;

api/rank.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ const rankHandler = async (url) => {
1010
? { auth: { username: TRANCO_USERNAME, password: TRANCO_API_KEY } }
1111
: {};
1212
try {
13-
const response = await httpGet(`https://tranco-list.eu/api/ranks/domain/${domain}`, {
14-
timeout: 5000,
15-
...auth,
16-
});
13+
const response = await httpGet(`https://tranco-list.eu/api/ranks/domain/${domain}`, auth);
1714
if (!response.data?.ranks?.length) {
1815
return {
1916
skipped: `${domain} isn't ranked in the top 1 million sites yet`,

api/redirects.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import middleware from './_common/middleware.js';
2+
import { UA } from './_common/http.js';
23
import { upstreamError } from './_common/upstream.js';
34

45
const MAX_REDIRECTS = 12;
56
const TIMEOUT_MS = 10000;
6-
const USER_AGENT = 'Mozilla/5.0 (compatible; WebCheck/2.0; +https://web-check.xyz)';
77

88
// Walks the redirect chain manually, recording each Location header as got did
99
const redirectsHandler = async (url) => {
@@ -14,7 +14,7 @@ const redirectsHandler = async (url) => {
1414
const response = await fetch(current, {
1515
redirect: 'manual',
1616
signal: AbortSignal.timeout(TIMEOUT_MS),
17-
headers: { 'user-agent': USER_AGENT },
17+
headers: { 'user-agent': UA },
1818
});
1919
if (response.status < 300 || response.status >= 400) {
2020
if (response.status >= 400) {

api/robots-txt.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ const robotsHandler = async (url) => {
2222
const parsed = parseRobotsTxt(res.data || '');
2323
return parsed.robots.length ? parsed : { skipped: 'No robots.txt rules found for this host' };
2424
} catch (error) {
25-
if (error.response?.status === 404) {
25+
const status = error.response?.status;
26+
if (status >= 400 && status < 500) {
2627
return { skipped: 'No robots.txt file present on this host' };
2728
}
2829
return upstreamError(error, 'robots.txt fetch');

api/shodan.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ const shodanHandler = async (url) => {
99
if (auth.skipped) return auth;
1010
const { hostname } = parseTarget(url);
1111
try {
12-
const res = await httpGet(`https://api.shodan.io/shodan/host/${hostname}?key=${auth.value}`, {
13-
timeout: 8000,
14-
});
12+
const res = await httpGet(`https://api.shodan.io/shodan/host/${hostname}?key=${auth.value}`);
1513
return res.data;
1614
} catch (error) {
1715
return upstreamError(error, 'Shodan lookup');

0 commit comments

Comments
 (0)