This commit is contained in:
Kimapr 2025-04-27 14:56:45 +05:00
commit e88c493182
Signed by: kimapr
GPG key ID: 9F631B9803377CE4
3 changed files with 122 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/node_modules
/package-lock.json

115
index.js Executable file
View file

@ -0,0 +1,115 @@
#!/usr/bin/env node
var { Client } = require('undici');
var { parseArgs } = require('node:util');
var { values, positionals } = parseArgs({
options: {
help: {
type: 'boolean'
}
},
allowPositionals: true,
});
var help =
`Usage: webtimediff <URL>
Calculate system clock difference between this host and a web server.
--help display this help and exit
`;
if (values.help || positionals.length != 1) {
console.log(help);
return;
}
function sleep(ms) {
return new Promise((res, rej) => setTimeout(_ => res(), ms));
}
((async function(url) {
var conn = new Client(url.origin, {
pipelining: 1000,
headersTimeout: 10e3,
bodyTimeout: 10e3,
});
let step = 20;
let end = 2000;
let errors = [];
let resps = [];
let firstRemoteTime = undefined;
let foundChange = undefined;
await conn.request({
method: "HEAD",
path: url.pathname + url.search,
blocking: false,
idempotent: true,
});
for (let i = 0; (!foundChange) && i < end; i += step) {
if (errors.length > 0)
break;
let date = new Date();
let ii=i;
let res = conn.request({
method: "OPTIONS",
path: url.pathname + url.search,
blocking: false,
idempotent: true,
}).then(e => (
e.date = new Date(e.headers.date),
firstRemoteTime = firstRemoteTime ?? e.date,
e.madeAt = date,
e.doneAt = new Date(),
foundChange = foundChange ??
((firstRemoteTime && (firstRemoteTime.getTime() != e.date.getTime()))
? {
remoteTime: e.date.getTime()/1000,
beginTime: e.madeAt.getTime()/1000,
endTime: e.doneAt.getTime()/1000,
}
: foundChange),
e));
resps.push(res);
if (i + step < end)
await sleep(step);
}
if (errors.length > 0)
await Promise.all(errors);
Promise.all(resps).catch(e => {});
let firstReq = [await (resps[0])].map(res => ({
remoteTime: res.date.getTime()/1000,
beginTime: res.madeAt.getTime()/1000,
endTime: res.doneAt.getTime()/1000,
}))[0];
let reqEnds = (foundChange.endTime - firstReq.endTime);
let reqBegins = (foundChange.beginTime - firstReq.beginTime)
let lag = reqEnds / reqBegins;
if (!(lag < 1.08)) {
console.error("WARNING: Big Lag ("
+reqEnds+
"s / "
+reqBegins+
"s) detected, reported result may be inaccurate.");
}
if (!foundChange) {
throw new Error("The remote clock does not work.");
}
let diff = (foundChange.remoteTime - (foundChange.beginTime + foundChange.endTime) / 2);
console.log("remote_time = local_time "+(diff < 0 ? "-" : "+")+" " + Math.abs(diff)+ " s");
process.exit();
})(new URL(positionals[0])))

5
package.json Normal file
View file

@ -0,0 +1,5 @@
{
"dependencies": {
"undici": "^7.8.0"
}
}