Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
CRAP | |
0.00% |
0 / 1 |
| CurlHealthcheckClient | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
56 | |
0.00% |
0 / 1 |
| get | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
56 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace App\Domain\Notification\Service; |
| 6 | |
| 7 | use RuntimeException; |
| 8 | |
| 9 | /** |
| 10 | * cURL-backed transport for healthchecks.io pings. Plain GET with a |
| 11 | * short timeout; non-2xx responses raise so the caller can log them |
| 12 | * (the caller — {@see HealthcheckPinger} — swallows the exception). |
| 13 | */ |
| 14 | final readonly class CurlHealthcheckClient implements HealthcheckClientInterface |
| 15 | { |
| 16 | public function get(string $url, int $timeoutSeconds): void |
| 17 | { |
| 18 | $ch = curl_init($url); |
| 19 | if ($ch === false) { |
| 20 | throw new RuntimeException('Failed to initialise cURL handle'); |
| 21 | } |
| 22 | |
| 23 | curl_setopt_array($ch, [ |
| 24 | CURLOPT_RETURNTRANSFER => true, |
| 25 | CURLOPT_TIMEOUT => $timeoutSeconds, |
| 26 | CURLOPT_CONNECTTIMEOUT => $timeoutSeconds, |
| 27 | CURLOPT_FOLLOWLOCATION => false, |
| 28 | // Healthchecks.io presents a real cert; refusing to validate |
| 29 | // would defeat the point of using HTTPS. |
| 30 | CURLOPT_SSL_VERIFYPEER => true, |
| 31 | CURLOPT_SSL_VERIFYHOST => 2, |
| 32 | ]); |
| 33 | |
| 34 | $response = curl_exec($ch); |
| 35 | $statusCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); |
| 36 | $error = curl_error($ch); |
| 37 | curl_close($ch); |
| 38 | |
| 39 | if ($response === false || $error !== '') { |
| 40 | throw new RuntimeException(sprintf('Healthcheck transport error: %s', $error !== '' ? $error : 'unknown')); |
| 41 | } |
| 42 | |
| 43 | if ($statusCode < 200 || $statusCode >= 300) { |
| 44 | throw new RuntimeException(sprintf('Healthcheck returned non-2xx status %d', $statusCode)); |
| 45 | } |
| 46 | } |
| 47 | } |