From e88c4931826fac9bcd14450a944e1fb6c7a85faa Mon Sep 17 00:00:00 2001 From: Kimapr Date: Sun, 27 Apr 2025 14:56:45 +0500 Subject: [PATCH] Hello --- .gitignore | 2 + index.js | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 5 +++ 3 files changed, 122 insertions(+) create mode 100644 .gitignore create mode 100755 index.js create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d502512 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/package-lock.json diff --git a/index.js b/index.js new file mode 100755 index 0000000..566c131 --- /dev/null +++ b/index.js @@ -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 +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]))) diff --git a/package.json b/package.json new file mode 100644 index 0000000..3864359 --- /dev/null +++ b/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "undici": "^7.8.0" + } +}