Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
CurlHealthcheckClient
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
56
0.00% covered (danger)
0.00%
0 / 1
 get
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2
3declare(strict_types=1);
4
5namespace App\Domain\Notification\Service;
6
7use 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 */
14final 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}