update
This commit is contained in:
parent
77c0fdd0a4
commit
6e5c1f056b
2 changed files with 33 additions and 159 deletions
1
HHFWebsiteMonitor
Submodule
1
HHFWebsiteMonitor
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 77c0fdd0a4887e484ff053faf000e473313f49ab
|
191
monitor.php
191
monitor.php
|
@ -7,165 +7,38 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Strict error reporting
|
// Strict error reporting
|
||||||
error_reporting(E_ALL);
|
einclude('configuration.php');
|
||||||
ini_set('display_errors', 0);
|
|
||||||
ini_set('log_errors', 1);
|
|
||||||
|
|
||||||
// Validate and include configuration
|
$monitors = json_decode(file_get_contents(PATH.'/monitors.json'));
|
||||||
$configPath = __DIR__ . '/configuration.php';
|
|
||||||
if (!file_exists($configPath)) {
|
|
||||||
error_log('Configuration file not found');
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
require_once $configPath;
|
|
||||||
|
|
||||||
// Validate PATH constant
|
foreach($monitors as $name => $url) {
|
||||||
if (!defined('PATH') || !is_dir(PATH)) {
|
$response_data = array();
|
||||||
error_log('Invalid monitoring directory');
|
$timestamp = time();
|
||||||
exit(1);
|
$response_data[$timestamp]['timestamp'] = $timestamp;
|
||||||
}
|
$curl = curl_init($url);
|
||||||
|
curl_setopt($curl, CURLOPT_URL, $url);
|
||||||
// Secure monitors file path
|
curl_setopt($curl, CURLOPT_HEADER, true);
|
||||||
$monitorsFile = PATH . '/monitors.json';
|
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||||
if (!file_exists($monitorsFile)) {
|
$response = curl_exec($curl);
|
||||||
error_log('Monitors configuration file not found');
|
if(curl_exec($curl) === false) {
|
||||||
exit(1);
|
$response_data[$timestamp]['error'] = curl_error($curl);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
// Read and validate monitors
|
$info = curl_getinfo($curl);
|
||||||
$monitorsJson = file_get_contents($monitorsFile);
|
$http_code = $info['http_code'];
|
||||||
$monitors = json_decode($monitorsJson, true);
|
$ms = $info['total_time_us'] / 1000;
|
||||||
|
$response_data[$timestamp]['time'] = $ms;
|
||||||
if (json_last_error() !== JSON_ERROR_NONE || !is_array($monitors)) {
|
$response_data[$timestamp]['response'] = $http_code;
|
||||||
error_log('Invalid monitors JSON');
|
}
|
||||||
exit(1);
|
|
||||||
}
|
curl_close($curl);
|
||||||
|
if(file_exists(PATH.'/monitors/'.$name)) {
|
||||||
// Maximum number of historical records to keep
|
$data = json_decode(file_get_contents(PATH.'/monitors/'.$name), TRUE);
|
||||||
const MAX_HISTORY_RECORDS = 60;
|
}
|
||||||
|
else {
|
||||||
// Maximum execution time
|
$data = array();
|
||||||
set_time_limit(30);
|
}
|
||||||
|
$data = array_merge($data, $response_data);
|
||||||
/**
|
$data = array_slice($data, -60);
|
||||||
* Validate and sanitize URL
|
file_put_contents(PATH.'/monitors/'.$name, json_encode($data, JSON_PRETTY_PRINT));
|
||||||
*
|
|
||||||
* @param string $url URL to validate
|
|
||||||
* @return string|false Sanitized URL or false if invalid
|
|
||||||
*/
|
|
||||||
function validateUrl($url) {
|
|
||||||
// Trim and validate URL
|
|
||||||
$url = trim($url);
|
|
||||||
|
|
||||||
// Check if URL is valid
|
|
||||||
if (!filter_var($url, FILTER_VALIDATE_URL)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Additional URL schemes validation (optional)
|
|
||||||
$allowedSchemes = ['http', 'https'];
|
|
||||||
$urlParts = parse_url($url);
|
|
||||||
|
|
||||||
if (!isset($urlParts['scheme']) || !in_array($urlParts['scheme'], $allowedSchemes)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $url;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Safely fetch website response
|
|
||||||
*
|
|
||||||
* @param string $url URL to monitor
|
|
||||||
* @return array Response data
|
|
||||||
*/
|
|
||||||
function fetchWebsiteResponse($url) {
|
|
||||||
$response_data = [
|
|
||||||
'timestamp' => time(),
|
|
||||||
'error' => null,
|
|
||||||
'time' => null,
|
|
||||||
'response' => null
|
|
||||||
];
|
|
||||||
|
|
||||||
// Validate URL
|
|
||||||
$sanitizedUrl = validateUrl($url);
|
|
||||||
if (!$sanitizedUrl) {
|
|
||||||
$response_data['error'] = 'Invalid URL';
|
|
||||||
return $response_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize cURL with safe options
|
|
||||||
$curl = curl_init();
|
|
||||||
curl_setopt_array($curl, [
|
|
||||||
CURLOPT_URL => $sanitizedUrl,
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_HEADER => false,
|
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
|
||||||
CURLOPT_MAXREDIRS => 3,
|
|
||||||
CURLOPT_TIMEOUT => 10,
|
|
||||||
CURLOPT_CONNECTTIMEOUT => 5,
|
|
||||||
CURLOPT_SSL_VERIFYPEER => true,
|
|
||||||
CURLOPT_SSL_VERIFYHOST => 2
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Execute request
|
|
||||||
$response = curl_exec($curl);
|
|
||||||
|
|
||||||
// Check for cURL errors
|
|
||||||
if ($response === false) {
|
|
||||||
$response_data['error'] = curl_error($curl);
|
|
||||||
} else {
|
|
||||||
// Get connection info
|
|
||||||
$info = curl_getinfo($curl);
|
|
||||||
$response_data['time'] = round($info['total_time_us'] / 1000, 2);
|
|
||||||
$response_data['response'] = $info['http_code'];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close cURL resource
|
|
||||||
curl_close($curl);
|
|
||||||
|
|
||||||
return $response_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Safely write monitor data
|
|
||||||
*
|
|
||||||
* @param string $name Monitor name
|
|
||||||
* @param array $newData New response data
|
|
||||||
*/
|
|
||||||
function writeMonitorData($name, $newData) {
|
|
||||||
// Validate monitor name (prevent path traversal)
|
|
||||||
if (!preg_match('/^[a-zA-Z0-9_-]+$/', $name)) {
|
|
||||||
error_log("Invalid monitor name: $name");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$monitorFile = PATH . '/monitors/' . $name;
|
|
||||||
|
|
||||||
// Read existing data
|
|
||||||
$data = [];
|
|
||||||
if (file_exists($monitorFile)) {
|
|
||||||
$fileContent = file_get_contents($monitorFile);
|
|
||||||
$data = json_decode($fileContent, true) ?: [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Merge and limit historical data
|
|
||||||
$data[] = $newData;
|
|
||||||
$data = array_slice($data, -MAX_HISTORY_RECORDS);
|
|
||||||
|
|
||||||
// Securely write file
|
|
||||||
$jsonData = json_encode($data, JSON_PRETTY_PRINT);
|
|
||||||
if (file_put_contents($monitorFile, $jsonData) === false) {
|
|
||||||
error_log("Failed to write monitor data for: $name");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main monitoring loop
|
|
||||||
foreach ($monitors as $name => $url) {
|
|
||||||
try {
|
|
||||||
$responseData = fetchWebsiteResponse($url);
|
|
||||||
writeMonitorData($name, $responseData);
|
|
||||||
} catch (Exception $e) {
|
|
||||||
error_log("Monitoring error for $name: " . $e->getMessage());
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue