diff --git a/README.md b/README.md index 80ac90a..06f627d 100644 --- a/README.md +++ b/README.md @@ -112,8 +112,12 @@ return [ 'enabled' => env('NETWATCH_PROBE_DATABASE_TCP_ENABLED', false), 'probe' => [ TcpPingProbe::class => [ - parse_url((string) env('DB_HOST'), PHP_URL_HOST) ?? env('DB_HOST'), - (int) env('DB_PORT', 3306), + parse_url((string) env('DB_HOST'), PHP_URL_HOST) ?: env('DB_HOST'), + (int) (env('DB_PORT') ?: match (env('DB_CONNECTION')) { + 'pgsql' => 5432, + 'sqlsrv' => 1433, + default => 3306, + }), ], ], ], @@ -133,8 +137,8 @@ return [ 'enabled' => env('NETWATCH_PROBE_REDIS_TCP_ENABLED', false), 'probe' => [ TcpPingProbe::class => [ - parse_url((string) env('REDIS_HOST'), PHP_URL_HOST) ?? env('REDIS_HOST'), - (int) env('REDIS_PORT', 6379), + parse_url((string) env('REDIS_HOST'), PHP_URL_HOST) ?: env('REDIS_HOST'), + (int) (env('REDIS_PORT') ?: 6379), ], ], ], @@ -331,7 +335,7 @@ NETWATCH_PROBE_APP_WARN_MS=500 NETWATCH_PROBE_APP_CRIT_MS=1000 NETWATCH_PROBE_CLOUDFLARE_DNS_WARN_MS=35 NETWATCH_PROBE_CLOUDFLARE_DNS_CRIT_MS=50 -NETWATCH_PROBE_GOOGLE_DNS_WARN_MS=25 +NETWATCH_PROBE_GOOGLE_DNS_WARN_MS=35 NETWATCH_PROBE_GOOGLE_DNS_CRIT_MS=50 ``` diff --git a/src/Laravel/Http/Middleware/Authorize.php b/src/Laravel/Http/Middleware/Authorize.php index ce997ea..bc0c465 100644 --- a/src/Laravel/Http/Middleware/Authorize.php +++ b/src/Laravel/Http/Middleware/Authorize.php @@ -13,8 +13,9 @@ class Authorize public function handle(Request $request, Closure $next) { $token = config('netwatch.health_route.token'); + $requestToken = $request->query('token'); - if ($token && $request->query('token') && hash_equals($token, $request->query('token'))) { + if ($token && is_string($requestToken) && $requestToken !== '' && hash_equals($token, $requestToken)) { return $next($request); } diff --git a/src/Laravel/config/netwatch.php b/src/Laravel/config/netwatch.php index fc65277..979c3ab 100644 --- a/src/Laravel/config/netwatch.php +++ b/src/Laravel/config/netwatch.php @@ -76,8 +76,12 @@ ], 'probe' => [ TcpPingProbe::class => [ - parse_url((string) env('DB_HOST'), PHP_URL_HOST) ?? env('DB_HOST'), - (int) env('DB_PORT', 3306), + parse_url((string) env('DB_HOST'), PHP_URL_HOST) ?: env('DB_HOST'), + (int) (env('DB_PORT') ?: match (env('DB_CONNECTION')) { + 'pgsql' => 5432, + 'sqlsrv' => 1433, + default => 3306, + }), ], ], ], @@ -105,8 +109,8 @@ ], 'probe' => [ TcpPingProbe::class => [ - parse_url((string) env('REDIS_HOST'), PHP_URL_HOST) ?? env('REDIS_HOST'), - (int) env('REDIS_PORT', 6379), + parse_url((string) env('REDIS_HOST'), PHP_URL_HOST) ?: env('REDIS_HOST'), + (int) (env('REDIS_PORT') ?: 6379), ], ], ], diff --git a/src/Probe/TcpPingProbe.php b/src/Probe/TcpPingProbe.php index 7b512bb..c979458 100644 --- a/src/Probe/TcpPingProbe.php +++ b/src/Probe/TcpPingProbe.php @@ -10,13 +10,23 @@ class TcpPingProbe implements ProbeInterface { public function __construct( - private readonly string $host, + private readonly ?string $host, private readonly int $port, private readonly float $timeout = 3.0, ) {} public function probe(): ProbeResult { + if ($this->host === null || $this->host === '') { + return new ProbeResult( + connectMs: 0, + requestMs: 0, + totalMs: 0, + success: false, + error: 'TCP connect failed: no host configured', + ); + } + $start = hrtime(true); $errno = 0; diff --git a/tests/Laravel/AuthorizeTokenTest.php b/tests/Laravel/AuthorizeTokenTest.php index 0e4c7dc..7910a37 100644 --- a/tests/Laravel/AuthorizeTokenTest.php +++ b/tests/Laravel/AuthorizeTokenTest.php @@ -105,6 +105,13 @@ ->assertForbidden(); }); +test('array token query param is rejected instead of erroring', function () { + config(['netwatch.health_route.token' => 'secret-token']); + + $this->get('/netwatch/health?token[]=secret-token', ['Accept' => 'application/json']) + ->assertForbidden(); +}); + test('token not configured ignores query param and uses regular auth', function () { config(['netwatch.health_route.token' => null]); diff --git a/tests/Probe/TcpPingProbeTest.php b/tests/Probe/TcpPingProbeTest.php index 07d3bff..b54381a 100644 --- a/tests/Probe/TcpPingProbeTest.php +++ b/tests/Probe/TcpPingProbeTest.php @@ -9,6 +9,22 @@ expect($probe->name())->toBe('tcp://example.com:443'); }); +test('probe fails gracefully when host is null', function () { + $probe = new TcpPingProbe(null, 3306); + $result = $probe->probe(); + + expect($result->success)->toBeFalse() + ->and($result->error)->toBe('TCP connect failed: no host configured'); +}); + +test('probe fails gracefully when host is empty', function () { + $probe = new TcpPingProbe('', 6379); + $result = $probe->probe(); + + expect($result->success)->toBeFalse() + ->and($result->error)->toBe('TCP connect failed: no host configured'); +}); + test('probe fails on unreachable host', function () { $probe = new TcpPingProbe('192.0.2.1', 9999, timeout: 0.5); $result = $probe->probe();