1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
<?php
declare(strict_types=1);
namespace Cepis\Tests;
use Cepis\NetworkException;
use Cepis\Response;
use Cepis\Transport;
/**
* A {@see Transport} over PHP streams rather than curl — roughly the shape a
* WordPress plugin's `wp_remote_get` implementation takes, and proof that the
* seam is implementable against a different HTTP stack in a few lines.
*/
final class StreamTransport implements Transport
{
public function get(string $url, array $headers, float $timeout): Response
{
$lines = '';
foreach ($headers as $name => $value) {
$lines .= $name . ': ' . $value . "\r\n";
}
$context = stream_context_create(['http' => [
'method' => 'GET',
'header' => $lines,
'timeout' => $timeout,
'ignore_errors' => true,
]]);
$body = @file_get_contents($url, false, $context);
if ($body === false) {
throw new NetworkException('could not reach ' . $url);
}
$status = 0;
$received = [];
foreach ($http_response_header ?? [] as $line) {
if (preg_match('#^HTTP/\S+\s+(\d{3})#', $line, $match) === 1) {
$status = (int) $match[1];
continue;
}
$parts = explode(':', $line, 2);
if (count($parts) === 2) {
$received[trim($parts[0])][] = trim($parts[1]);
}
}
return new Response($status, $received, $body);
}
}
|