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
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 0);
|
||||
ini_set('log_errors', 1);
|
||||
einclude('configuration.php');
|
||||
|
||||
// Validate and include configuration
|
||||
$configPath = __DIR__ . '/configuration.php';
|
||||
if (!file_exists($configPath)) {
|
||||
error_log('Configuration file not found');
|
||||
exit(1);
|
||||
}
|
||||
require_once $configPath;
|
||||
$monitors = json_decode(file_get_contents(PATH.'/monitors.json'));
|
||||
|
||||
// Validate PATH constant
|
||||
if (!defined('PATH') || !is_dir(PATH)) {
|
||||
error_log('Invalid monitoring directory');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Secure monitors file path
|
||||
$monitorsFile = PATH . '/monitors.json';
|
||||
if (!file_exists($monitorsFile)) {
|
||||
error_log('Monitors configuration file not found');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Read and validate monitors
|
||||
$monitorsJson = file_get_contents($monitorsFile);
|
||||
$monitors = json_decode($monitorsJson, true);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE || !is_array($monitors)) {
|
||||
error_log('Invalid monitors JSON');
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Maximum number of historical records to keep
|
||||
const MAX_HISTORY_RECORDS = 60;
|
||||
|
||||
// Maximum execution time
|
||||
set_time_limit(30);
|
||||
|
||||
/**
|
||||
* Validate and sanitize URL
|
||||
*
|
||||
* @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());
|
||||
}
|
||||
foreach($monitors as $name => $url) {
|
||||
$response_data = array();
|
||||
$timestamp = time();
|
||||
$response_data[$timestamp]['timestamp'] = $timestamp;
|
||||
$curl = curl_init($url);
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_HEADER, true);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
$response = curl_exec($curl);
|
||||
if(curl_exec($curl) === false) {
|
||||
$response_data[$timestamp]['error'] = curl_error($curl);
|
||||
}
|
||||
else {
|
||||
$info = curl_getinfo($curl);
|
||||
$http_code = $info['http_code'];
|
||||
$ms = $info['total_time_us'] / 1000;
|
||||
$response_data[$timestamp]['time'] = $ms;
|
||||
$response_data[$timestamp]['response'] = $http_code;
|
||||
}
|
||||
|
||||
curl_close($curl);
|
||||
if(file_exists(PATH.'/monitors/'.$name)) {
|
||||
$data = json_decode(file_get_contents(PATH.'/monitors/'.$name), TRUE);
|
||||
}
|
||||
else {
|
||||
$data = array();
|
||||
}
|
||||
$data = array_merge($data, $response_data);
|
||||
$data = array_slice($data, -60);
|
||||
file_put_contents(PATH.'/monitors/'.$name, json_encode($data, JSON_PRETTY_PRINT));
|
||||
}
|
Loading…
Reference in a new issue