Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 28 additions & 24 deletions modules/analyze.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,41 +19,45 @@ function analyzeURL(req, res) {
}

const hostname = url.parse(urlToAnalyze).hostname;
const options = {
method: 'HEAD',
timeout: 5000,
};

const start = now();

makeHttpRequest(urlToAnalyze, options, (response, httpRequestError) => {
if (httpRequestError) {
console.error(`Failed to request ${urlToAnalyze}: ${httpRequestError}`);
return res.json({ isUp: false, ipAddress: null, uptime: 0, responseTime: 0 });
makeHttpRequest(urlToAnalyze, {}, (responseDetails, latencyMs, httpRequestError) => {
if (httpRequestError || !responseDetails) {
console.error(`Failed to request ${urlToAnalyze}: ${httpRequestError || 'Unknown error'}`);
return res.json({ isUp: false, ipAddress: null, uptime: 0, latencyMs: 0, dnsLookupMs: 0 });
}

const isUp = response.statusCode >= 200 && response.statusCode < 400;
const isUp =
responseDetails.statusCode >= 200 && responseDetails.statusCode < 400;
if (!isUp) {
return res.json({ isUp: false, ipAddress: null, uptime: 0, responseTime: 0 });
return res.json({
isUp: false,
ipAddress: null,
uptime: 0,
latencyMs,
dnsLookupMs: 0,
statusCode: responseDetails.statusCode,
});
}

performDnsLookup(hostname, (ipAddress, dnsLookupError) => {
performDnsLookup(hostname, ({ ipAddress, lookupMs, error: dnsLookupError }) => {
if (dnsLookupError) {
console.error(`Failed to lookup IP address for ${urlToAnalyze}: ${dnsLookupError}`);
return res.status(500).json({ error: 'Internal server error' });
}

// Calculate responseTime
const end = now();
const responseTime = ((end - start) / 1000).toFixed(2);

// calculate uptime
const totalSeconds = (end - start) / 1000; // convert to seconds
const availableSeconds = totalSeconds - (totalSeconds * 0.01); // assuming 99.99% uptime
const uptime = ((availableSeconds / totalSeconds) * 100).toFixed(2);
// Calculate uptime baseline on successful check
const uptime = 100;

console.log(`isUp: ${isUp}, ipAddress: ${ipAddress}, uptime: ${uptime}%, responseTime: ${responseTime}s`);
return res.json({ isUp: true, ipAddress, uptime, responseTime });
console.log(
`isUp: ${isUp}, ipAddress: ${ipAddress}, uptime: ${uptime}%, latencyMs: ${latencyMs}, dnsLookupMs: ${lookupMs}`
);
return res.json({
isUp: true,
ipAddress,
uptime,
latencyMs,
dnsLookupMs: lookupMs,
statusCode: responseDetails.statusCode,
});
});
});
} catch (error) {
Expand Down
7 changes: 5 additions & 2 deletions modules/dnsLookup.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
const dns = require('dns');
const now = require('performance-now');

function performDnsLookup(hostname, callback) {
const start = now();
dns.lookup(hostname, (error, ipAddress) => {
const lookupMs = Number((now() - start).toFixed(2));
if (error) {
callback(null, error);
callback({ error, lookupMs });
} else {
callback(ipAddress);
callback({ ipAddress, lookupMs });
}
});
}
Expand Down
31 changes: 27 additions & 4 deletions modules/httpRequest.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
const http = require('http');
const https = require('https');
const now = require('performance-now');

function makeHttpRequest(urlToAnalyze, options, callback) {
function makeHttpRequest(urlToAnalyze, options = {}, callback) {
const protocol = urlToAnalyze.startsWith('https://') ? https : http;
const requestOptions = {
method: 'GET',
timeout: 8000,
...options,
};

const request = protocol.request(urlToAnalyze, options, (response) => {
callback(response);
const start = now();
const request = protocol.request(urlToAnalyze, requestOptions, (response) => {
// consume the response to ensure the 'end' event fires for timing accuracy
response.on('data', () => {});

response.on('end', () => {
const latencyMs = Number((now() - start).toFixed(2));
callback(
{
statusCode: response.statusCode,
headers: response.headers,
},
latencyMs
);
});
});

request.on('timeout', () => {
request.destroy(new Error('Request timed out'));
});

request.on('error', (error) => {
callback(null, error);
callback(null, 0, error);
});

request.end();
Expand Down
Loading