ResponseReader   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 5

Test Coverage

Coverage 90.91%

Importance

Changes 0
Metric Value
wmc 12
lcom 0
cbo 5
dl 0
loc 83
ccs 30
cts 33
cp 0.9091
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A createStream() 0 10 2
B readResponse() 0 51 10
1
<?php
2
3
namespace Http\Client\Socket;
4
5
use Http\Client\Socket\Exception\BrokenPipeException;
6
use Http\Client\Socket\Exception\TimeoutException;
7
use Http\Message\ResponseFactory;
8
use Nyholm\Psr7\Response;
9
use Psr\Http\Message\RequestInterface;
10
use Psr\Http\Message\ResponseInterface;
11
12
/**
13
 * Method for reading response.
14
 *
15
 * Mainly used by SocketHttpClient
16
 *
17
 * @author Joel Wurtz <[email protected]>
18
 */
19
trait ResponseReader
20
{
21
    /**
22
     * @var ResponseFactory For creating response
23
     */
24
    protected $responseFactory;
25
26
    /**
27
     * Read a response from a socket.
28
     *
29
     * @param resource $socket
30
     *
31
     * @throws TimeoutException    When the socket timed out
32
     * @throws BrokenPipeException When the response cannot be read
33
     */
34 59
    protected function readResponse(RequestInterface $request, $socket): ResponseInterface
35
    {
36 59
        $headers = [];
37 59
        $reason = null;
38
39 59
        while (false !== ($line = fgets($socket))) {
40 58
            if ('' === rtrim($line)) {
41 58
                break;
42
            }
43 58
            $headers[] = trim($line);
44
        }
45
46 59
        $metadatas = stream_get_meta_data($socket);
47
48 59
        if (array_key_exists('timed_out', $metadatas) && true === $metadatas['timed_out']) {
49
            throw new TimeoutException('Error while reading response, stream timed out', $request, null);
50
        }
51
52 59
        $parts = explode(' ', array_shift($headers), 3);
53
54 59
        if (count($parts) <= 1) {
55 1
            throw new BrokenPipeException('Cannot read the response', $request);
56
        }
57
58 58
        $protocol = substr($parts[0], -3);
59 58
        $status = $parts[1];
60
61 58
        if (isset($parts[2])) {
62 58
            $reason = $parts[2];
63
        }
64
65
        // Set the size on the stream if it was returned in the response
66 58
        $responseHeaders = [];
67
68 58
        foreach ($headers as $header) {
69 58
            $headerParts = explode(':', $header, 2);
70
71 58
            if (!array_key_exists(trim($headerParts[0]), $responseHeaders)) {
72 58
                $responseHeaders[trim($headerParts[0])] = [];
73
            }
74
75 58
            $responseHeaders[trim($headerParts[0])][] = isset($headerParts[1])
76 58
                ? trim($headerParts[1])
77
                : '';
78
        }
79
80 58
        $response = new Response($status, $responseHeaders, null, $protocol, $reason);
81 58
        $stream = $this->createStream($socket, $request, $response);
82
83 58
        return $response->withBody($stream);
84
    }
85
86
    /**
87
     * Create the stream.
88
     *
89
     * @param resource $socket
90
     */
91 58
    protected function createStream($socket, RequestInterface $request, ResponseInterface $response): Stream
92
    {
93 58
        $size = null;
94
95 58
        if ($response->hasHeader('Content-Length')) {
96
            $size = (int) $response->getHeaderLine('Content-Length');
97
        }
98
99 58
        return new Stream($request, $socket, $size);
100
    }
101
}
102