FgcHttpClient   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 84.48%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
c 1
b 0
f 0
lcom 1
cbo 7
dl 0
loc 145
ccs 49
cts 58
cp 0.8448
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
C sendRequest() 0 80 10
1
<?php
2
3
/*
4
 * (c) Markus Lanthaler <[email protected]>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace ML\FgcClient;
11
12
use Http\Client\Exception\NetworkException;
13
use Http\Client\Exception\RequestException;
14
use Http\Message\MessageFactory;
15
use Http\Message\StreamFactory;
16
use Psr\Http\Message\RequestInterface;
17
use Psr\Http\Message\ResponseInterface;
18
19
/**
20
 * A file_get_contents-based HTTP client.
21
 *
22
 * @author Markus Lanthaler <[email protected]>
23
 *
24
 * @link http://httplug.io/
25
 */
26
class FgcHttpClient implements \Http\Client\HttpClient
27
{
28
    /**
29
     * The message factory
30
     *
31
     * @var MessageFactory
32
     */
33
    private $messageFactory;
34
35
    /**
36
     * The stream factory
37
     *
38
     * @var StreamFactory
39
     */
40
    private $streamFactory;
41
42
    /**
43
     * The request timeout.
44
     *
45
     * @var int
46
     */
47
    private $timeout = 30;
48
49
    /**
50
     * Should redirects be followed?
51
     *
52
     * @var bool
53
     */
54
    private $followRedirects = false;
55
56
    /**
57
     * Constructor
58
     *
59
     * @param MessageFactory $messageFactory  HTTP Message factory
60
     * @param StreamFactory  $streamFactory   HTTP Stream factory
61
     * @param int            $timeout         Request timeout in seconds
62
     * @param bool           $followRedirects If set to true, redirects are followed automatically
63
     *
64
     * @throws \InvalidArgumentException If an invalid IRI is passed.
65
     *
66
     * @api
67
     */
68 53
    public function __construct(
69
        MessageFactory $messageFactory,
70
        StreamFactory $streamFactory,
71
        $timeout = 30,
72
        $followRedirects = false
73
    ) {
74 53
        $this->messageFactory = $messageFactory;
75 53
        $this->streamFactory = $streamFactory;
76 53
        $this->timeout = $timeout;
77 53
        $this->followRedirects = $followRedirects;
78 53
    }
79
80
    /**
81
     * Sends a PSR-7 request.
82
     *
83
     * @param RequestInterface $request
84
     *
85
     * @return ResponseInterface
86
     *
87
     * @throws \Http\Client\Exception If an error happens during processing the request.
88
     * @throws \Exception             If processing the request is impossible (eg. bad configuration).
89
     */
90 53
    public function sendRequest(RequestInterface $request)
91
    {
92 53
        $body = (string) $request->getBody();
93
94 53
        $headers = [];
95 53
        foreach (array_keys($request->getHeaders()) as $headerName) {
96 53
            if (strtolower($headerName) === 'content-length') {
97 53
                $values = array(strlen($body));
98 53
            } else {
99 53
                $values = $request->getHeader($headerName);
100
            }
101 53
            foreach ($values as $value) {
102 53
                $headers[] = $headerName . ': ' . $value;
103 53
            }
104 53
        }
105
106
        $streamContextOptions = array(
107 53
            'protocol_version' => $request->getProtocolVersion(),
108 53
            'method'           => $request->getMethod(),
109 53
            'header'           => implode("\r\n", $headers),
110 53
            'timeout'          => $this->timeout,
111 53
            'ignore_errors'    => true,
112 53
            'follow_location'  => $this->followRedirects ? 1 : 0,
113
            'max_redirects'    => 100
114 53
        );
115
116 53
        if (strlen($body) > 0) {
117 20
            $streamContextOptions['content'] = $body;
118 20
        }
119
120 53
        $context = stream_context_create(array(
121 53
            'http' => $streamContextOptions,
122
            'https' => $streamContextOptions
123 53
        ));
124
125 53
        $httpHeadersOffset = 0;
126 53
        $finalUrl = (string) $request->getUri();
0 ignored issues
show
Unused Code introduced by
$finalUrl is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
127
128 53
        stream_context_set_params(
129 53
            $context,
130
            array('notification' =>
131 52
                function (
132
                    $code,
133
                    $severity,
134
                    $msg,
135
                    $msgCode,
136
                    $bytesTx,
137
                    $bytesMax
138
                ) use (
139
                    &$remoteDocument,
140
                    &$http_response_header,
141
                    &$httpHeadersOffset
142
                ) {
143 52
                    if ($code === STREAM_NOTIFY_REDIRECTED) {
144
                        $finalUrl = $msg;
0 ignored issues
show
Unused Code introduced by
$finalUrl is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
145
                        $httpHeadersOffset = count($http_response_header);
146
                    }
147 52
                }
148 53
            )
149 53
        );
150
151 53
        $response = $this->messageFactory->createResponse();
152 53
        if (false === ($responseBody = @file_get_contents((string) $request->getUri(), false, $context))) {
153 1
            if (!isset($http_response_header)) {
154 1
                throw new NetworkException(
155 1
                    'Unable to execute request',
156
                    $request
157 1
                );
158
            }
159
        } else {
160 52
            $response = $response->withBody($this->streamFactory->createStream($responseBody));
161
        }
162
163 52
        $parser = new HeaderParser();
164
        try {
165 52
            return $parser->parseArray(array_slice($http_response_header, $httpHeadersOffset), $response);
166
        } catch (\Exception $e) {
167
            throw new RequestException($e->getMessage(), $request, $e);
168
        }
169
    }
170
}
171