Completed
Push — master ( 979ecb...d86fa2 )
by smiley
01:38
created

CurlClient::request()   B

Complexity

Conditions 9
Paths 16

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
nc 16
nop 5
dl 0
loc 31
rs 8.0555
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class HTTPClient
4
 *
5
 * @filesource   HTTPClient.php
6
 * @created      27.08.2018
7
 * @package      chillerlan\HTTP
8
 * @author       smiley <[email protected]>
9
 * @copyright    2018 smiley
10
 * @license      MIT
11
 */
12
13
namespace chillerlan\HTTP;
14
15
use chillerlan\HTTP\Psr17\{RequestFactory, ResponseFactory, StreamFactory};
16
use chillerlan\Settings\SettingsContainerInterface;
17
use Psr\Http\Message\{RequestFactoryInterface, RequestInterface, ResponseFactoryInterface, ResponseInterface, StreamFactoryInterface};
18
use Http\Client\Exception\{NetworkException, RequestException};
19
20
class CurlClient implements HTTPClientInterface{
21
	use HTTPRequestTrait;
22
23
	/**
24
	 * @var \chillerlan\HTTP\HTTPOptions
25
	 */
26
	protected $options;
27
28
	/**
29
	 * @var \Psr\Http\Message\RequestFactoryInterface
30
	 */
31
	protected $requestFactory;
32
33
	/**
34
	 * @var \Psr\Http\Message\ResponseFactoryInterface
35
	 */
36
	protected $responseFactory;
37
38
	/**
39
	 * @var \Psr\Http\Message\StreamFactoryInterface
40
	 */
41
	protected $streamFactory;
42
43
	/**
44
	 * CurlClient constructor.
45
	 *
46
	 * @param \chillerlan\Settings\SettingsContainerInterface|null $options
47
	 * @param \Psr\Http\Message\RequestFactoryInterface|null       $requestFactory
48
	 * @param \Psr\Http\Message\ResponseFactoryInterface|null      $responseFactory
49
	 * @param \Psr\Http\Message\StreamFactoryInterface|null        $streamFactory
50
	 */
51
	public function __construct(
52
		SettingsContainerInterface $options = null,
53
		RequestFactoryInterface $requestFactory = null,
54
		ResponseFactoryInterface $responseFactory = null,
55
		StreamFactoryInterface $streamFactory = null
56
	){
57
		$this->options         = $options ?? new HTTPOptions;
0 ignored issues
show
Documentation Bug introduced by
$options ?? new \chillerlan\HTTP\HTTPOptions() is of type object<chillerlan\Settin...ingsContainerInterface>, but the property $options was declared to be of type object<chillerlan\HTTP\HTTPOptions>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
58
		$this->requestFactory  = $requestFactory ?? new RequestFactory;
59
		$this->responseFactory = $responseFactory ?? new ResponseFactory;
60
		$this->streamFactory   = $streamFactory ?? new StreamFactory;
61
	}
62
63
	/**
64
	 * Sends a PSR-7 request.
65
	 *
66
	 * @param \Psr\Http\Message\RequestInterface $request
67
	 *
68
	 * @return \Psr\Http\Message\ResponseInterface
69
	 *
70
	 * @throws \Http\Client\Exception If an error happens during processing the request.
71
	 * @throws \Exception             If processing the request is impossible (eg. bad configuration).
72
	 */
73
	public function sendRequest(RequestInterface $request):ResponseInterface{
74
		$handle = new CurlHandle($request, $this->responseFactory->createResponse(), $this->options);
75
		$handle->init();
76
77
		curl_exec($handle->ch);
78
79
		$errno = curl_errno($handle->ch);
80
81
		if($errno !== CURLE_OK){
82
			$error = curl_error($handle->ch);
83
84
			$network_errors = [
85
				CURLE_COULDNT_RESOLVE_PROXY,
86
				CURLE_COULDNT_RESOLVE_HOST,
87
				CURLE_COULDNT_CONNECT,
88
				CURLE_OPERATION_TIMEOUTED,
89
				CURLE_SSL_CONNECT_ERROR,
90
				CURLE_GOT_NOTHING,
91
			];
92
93
			if(in_array($errno, $network_errors, true)){
94
				throw new NetworkException($error, $request);
95
			}
96
97
			throw new RequestException($error, $request);
98
		}
99
100
		$handle->close();
101
		$handle->response->getBody()->rewind();
102
103
		return $handle->response;
104
105
	}
106
107
}
108