mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
add HTTP Head request
This commit is contained in:
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@@ -86,7 +86,7 @@
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/Probe",
|
||||
"name": "Dashboard API: Debug with Docker",
|
||||
"name": "Probe: Debug with Docker",
|
||||
"port": 9655,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
@@ -335,20 +335,6 @@
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"address": "127.0.0.1",
|
||||
"localRoot": "${workspaceFolder}/probe",
|
||||
"name": "Probe: Debug with Docker",
|
||||
"port": 9238,
|
||||
"remoteRoot": "/usr/src/app",
|
||||
"request": "attach",
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"type": "node",
|
||||
"restart": true,
|
||||
"autoAttachChildProcesses": true
|
||||
},
|
||||
{
|
||||
"name": "CommonServer: Debug Tests",
|
||||
"type": "node",
|
||||
|
||||
@@ -3,6 +3,7 @@ enum HTTPMethod {
|
||||
POST = 'POST',
|
||||
DELETE = 'DELETE',
|
||||
PUT = 'PUT',
|
||||
HEAD = 'HEAD',
|
||||
}
|
||||
|
||||
export default HTTPMethod;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import axios, { AxiosResponse } from 'axios';
|
||||
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
import Headers from './API/Headers';
|
||||
import URL from './API/URL';
|
||||
import HTML from './Html';
|
||||
import HTTPMethod from './API/HTTPMethod';
|
||||
|
||||
export interface WebsiteResponse {
|
||||
url: URL;
|
||||
@@ -13,18 +14,32 @@ export interface WebsiteResponse {
|
||||
}
|
||||
|
||||
export default class WebsiteRequest {
|
||||
public static async get(
|
||||
public static async fetch(
|
||||
url: URL,
|
||||
options: {
|
||||
headers?: Headers | undefined;
|
||||
timeout?: number | undefined;
|
||||
isHeadRequest?: boolean | undefined;
|
||||
}
|
||||
): Promise<WebsiteResponse> {
|
||||
// use axios to fetch an HTML page
|
||||
const response: AxiosResponse = await axios.get(url.toString(), {
|
||||
headers: options.headers || {},
|
||||
const axiosOptions: AxiosRequestConfig = {
|
||||
timeout: options.timeout || 5000,
|
||||
});
|
||||
method: HTTPMethod.GET,
|
||||
};
|
||||
|
||||
if (options.headers) {
|
||||
axiosOptions.headers = options.headers;
|
||||
}
|
||||
|
||||
if (options.isHeadRequest) {
|
||||
axiosOptions.method = HTTPMethod.HEAD;
|
||||
}
|
||||
|
||||
// use axios to fetch an HTML page
|
||||
const response: AxiosResponse = await axios(
|
||||
url.toString(),
|
||||
axiosOptions
|
||||
);
|
||||
|
||||
// return the response
|
||||
return {
|
||||
|
||||
@@ -16,6 +16,8 @@ import ApiMonitor, { APIResponse } from './MonitorTypes/ApiMonitor';
|
||||
import JSONFunctions from 'Common/Types/JSONFunctions';
|
||||
import logger from 'CommonServer/Utils/Logger';
|
||||
import ProbeUtil from '../Probe';
|
||||
import MonitorCriteriaInstance from 'Common/Types/Monitor/MonitorCriteriaInstance';
|
||||
import { CheckOn, CriteriaFilter } from 'Common/Types/Monitor/CriteriaFilter';
|
||||
|
||||
export default class MonitorUtil {
|
||||
public static async probeMonitor(
|
||||
@@ -63,6 +65,47 @@ export default class MonitorUtil {
|
||||
return results;
|
||||
}
|
||||
|
||||
public static isHeadRequest(monitorStep: MonitorStep): boolean {
|
||||
// If its not GET requestm it cannot be a head request
|
||||
if (
|
||||
monitorStep.data?.requestType &&
|
||||
monitorStep.data?.requestType !== HTTPMethod.GET
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if monitor step has any criteria with needs request body. If no, then return true otherwise return false.
|
||||
|
||||
if (
|
||||
monitorStep.data?.monitorCriteria.data
|
||||
?.monitorCriteriaInstanceArray &&
|
||||
monitorStep.data?.monitorCriteria.data?.monitorCriteriaInstanceArray
|
||||
.length > 0
|
||||
) {
|
||||
const criteriaArray: Array<MonitorCriteriaInstance> =
|
||||
monitorStep.data?.monitorCriteria.data
|
||||
?.monitorCriteriaInstanceArray;
|
||||
|
||||
for (const criteria of criteriaArray) {
|
||||
if (
|
||||
criteria.data?.filters &&
|
||||
criteria.data?.filters.length > 0
|
||||
) {
|
||||
const filters: Array<CriteriaFilter> =
|
||||
criteria.data?.filters;
|
||||
|
||||
for (const filter of filters) {
|
||||
if (filter.checkOn === CheckOn.ResponseBody) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async probeMonitorStep(
|
||||
monitorStep: MonitorStep,
|
||||
monitor: Monitor
|
||||
@@ -91,7 +134,10 @@ export default class MonitorUtil {
|
||||
|
||||
if (monitor.monitorType === MonitorType.Website) {
|
||||
const response: ProbeWebsiteResponse = await WebsiteMonitor.ping(
|
||||
monitorStep.data?.monitorDestination as URL
|
||||
monitorStep.data?.monitorDestination as URL,
|
||||
{
|
||||
isHeadRequest: MonitorUtil.isHeadRequest(monitorStep),
|
||||
}
|
||||
);
|
||||
|
||||
result.isOnline = response.isOnline;
|
||||
@@ -117,6 +163,7 @@ export default class MonitorUtil {
|
||||
{
|
||||
requestHeaders: monitorStep.data?.requestHeaders || {},
|
||||
requestBody: requestBody || undefined,
|
||||
isHeadRequest: MonitorUtil.isHeadRequest(monitorStep),
|
||||
requestType:
|
||||
monitorStep.data?.requestType || HTTPMethod.GET,
|
||||
}
|
||||
|
||||
@@ -28,16 +28,25 @@ export default class ApiMonitor {
|
||||
requestHeaders?: Headers | undefined;
|
||||
requestBody?: JSONObject | undefined;
|
||||
requestType?: HTTPMethod | undefined;
|
||||
},
|
||||
retry?: number | undefined
|
||||
isHeadRequest?: boolean | undefined;
|
||||
retry?: number | undefined;
|
||||
}
|
||||
): Promise<APIResponse> {
|
||||
let requestType: HTTPMethod = options.requestType || HTTPMethod.GET;
|
||||
|
||||
if (options.isHeadRequest) {
|
||||
requestType = HTTPMethod.HEAD;
|
||||
}
|
||||
|
||||
try {
|
||||
logger.info(`API Monitor - Pinging ${url.toString()}`);
|
||||
logger.info(
|
||||
`API Monitor - Pinging ${requestType} ${url.toString()}`
|
||||
);
|
||||
|
||||
const startTime: [number, number] = process.hrtime();
|
||||
const result: HTTPResponse<JSONObject> | HTTPErrorResponse =
|
||||
await API.fetch(
|
||||
options.requestType || HTTPMethod.GET,
|
||||
requestType,
|
||||
url,
|
||||
options.requestBody || undefined,
|
||||
options.requestHeaders || undefined
|
||||
@@ -61,27 +70,23 @@ export default class ApiMonitor {
|
||||
};
|
||||
|
||||
logger.info(
|
||||
`API Monitor - Pinging ${url.toString()} Success - Response: ${JSON.stringify(
|
||||
`API Monitor - Pinging ${requestType} ${url.toString()} Success - Response: ${JSON.stringify(
|
||||
apiResponse
|
||||
)}`
|
||||
);
|
||||
|
||||
return apiResponse;
|
||||
} catch (err) {
|
||||
logger.error(
|
||||
`API Monitor - Pinging ${url.toString()} - Error: ${err}`
|
||||
);
|
||||
|
||||
if (!retry) {
|
||||
retry = 0; // default value
|
||||
if (!options.retry) {
|
||||
options.retry = 0; // default value
|
||||
}
|
||||
|
||||
if (retry < 5) {
|
||||
retry++;
|
||||
return await this.ping(url, options, retry);
|
||||
if (options.retry < 5) {
|
||||
options.retry++;
|
||||
return await this.ping(url, options);
|
||||
}
|
||||
|
||||
return {
|
||||
const apiResponse: APIResponse = {
|
||||
url: url,
|
||||
isOnline: false,
|
||||
requestBody: options.requestBody || {},
|
||||
@@ -92,6 +97,14 @@ export default class ApiMonitor {
|
||||
responseBody: '',
|
||||
responseHeaders: {},
|
||||
};
|
||||
|
||||
logger.error(
|
||||
`API Monitor - Pinging ${requestType} ${url.toString()} - ERROR: ${err} Response: ${JSON.stringify(
|
||||
apiResponse
|
||||
)}`
|
||||
);
|
||||
|
||||
return apiResponse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import Protocol from 'Common/Types/API/Protocol';
|
||||
import WebsiteRequest, { WebsiteResponse } from 'Common/Types/WebsiteRequest';
|
||||
import HTML from 'Common/Types/Html';
|
||||
import { AxiosError } from 'axios';
|
||||
import logger from 'CommonServer/Utils/Logger';
|
||||
import HTTPMethod from 'Common/Types/API/HTTPMethod';
|
||||
|
||||
export interface ProbeWebsiteResponse {
|
||||
url: URL;
|
||||
@@ -20,17 +22,33 @@ export interface ProbeWebsiteResponse {
|
||||
export default class WebsiteMonitor {
|
||||
public static async ping(
|
||||
url: URL,
|
||||
retry?: number | undefined
|
||||
options: {
|
||||
retry?: number | undefined;
|
||||
isHeadRequest?: boolean | undefined;
|
||||
}
|
||||
): Promise<ProbeWebsiteResponse> {
|
||||
let requestType: HTTPMethod = HTTPMethod.GET;
|
||||
|
||||
if (options.isHeadRequest) {
|
||||
requestType = HTTPMethod.HEAD;
|
||||
}
|
||||
|
||||
try {
|
||||
logger.info(
|
||||
`Website Monitor - Pinging ${requestType} ${url.toString()}`
|
||||
);
|
||||
|
||||
const startTime: [number, number] = process.hrtime();
|
||||
const result: WebsiteResponse = await WebsiteRequest.get(url, {});
|
||||
const result: WebsiteResponse = await WebsiteRequest.fetch(url, {
|
||||
isHeadRequest: options.isHeadRequest,
|
||||
});
|
||||
|
||||
const endTime: [number, number] = process.hrtime(startTime);
|
||||
const responseTimeInMS: PositiveNumber = new PositiveNumber(
|
||||
(endTime[0] * 1000000000 + endTime[1]) / 1000000
|
||||
);
|
||||
|
||||
return {
|
||||
const probeWebsiteResponse: ProbeWebsiteResponse = {
|
||||
url: url,
|
||||
requestHeaders: {},
|
||||
isOnline: true,
|
||||
@@ -40,18 +58,33 @@ export default class WebsiteMonitor {
|
||||
responseBody: result.responseBody,
|
||||
responseHeaders: result.responseHeaders,
|
||||
};
|
||||
|
||||
logger.info(
|
||||
`Website Monitor - Pinging ${requestType} ${url.toString()} Success - Response: ${JSON.stringify(
|
||||
probeWebsiteResponse
|
||||
)}`
|
||||
);
|
||||
|
||||
return probeWebsiteResponse;
|
||||
} catch (err) {
|
||||
if (!retry) {
|
||||
retry = 0; // default value
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
if (retry < 5) {
|
||||
retry++;
|
||||
return await this.ping(url, retry);
|
||||
if (!options.retry) {
|
||||
options.retry = 0; // default value
|
||||
}
|
||||
|
||||
if (options.retry < 5) {
|
||||
options.retry++;
|
||||
return await this.ping(url, options);
|
||||
}
|
||||
|
||||
let probeWebisteResponse: ProbeWebsiteResponse | undefined =
|
||||
undefined;
|
||||
|
||||
if (err instanceof AxiosError) {
|
||||
return {
|
||||
probeWebisteResponse = {
|
||||
url: url,
|
||||
isOnline: Boolean(err.response),
|
||||
requestHeaders: {},
|
||||
@@ -61,18 +94,26 @@ export default class WebsiteMonitor {
|
||||
responseBody: err.response?.data,
|
||||
responseHeaders: (err.response?.headers as Headers) || {},
|
||||
};
|
||||
} else {
|
||||
probeWebisteResponse = {
|
||||
url: url,
|
||||
isOnline: false,
|
||||
requestHeaders: {},
|
||||
isSecure: url.protocol === Protocol.HTTPS,
|
||||
responseTimeInMS: new PositiveNumber(0),
|
||||
statusCode: undefined,
|
||||
responseBody: undefined,
|
||||
responseHeaders: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
url: url,
|
||||
isOnline: false,
|
||||
requestHeaders: {},
|
||||
isSecure: url.protocol === Protocol.HTTPS,
|
||||
responseTimeInMS: new PositiveNumber(0),
|
||||
statusCode: undefined,
|
||||
responseBody: undefined,
|
||||
responseHeaders: undefined,
|
||||
};
|
||||
logger.error(
|
||||
`Website Monitor - Pinging ${requestType} ${url.toString()} - ERROR: ${err} Response: ${JSON.stringify(
|
||||
probeWebisteResponse
|
||||
)}`
|
||||
);
|
||||
|
||||
return probeWebisteResponse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user