This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | namespace PCextreme\Cloudstack; |
||
6 | |||
7 | use GuzzleHttp\Client as HttpClient; |
||
8 | use GuzzleHttp\ClientInterface as HttpClientInterface; |
||
9 | use GuzzleHttp\Exception\BadResponseException; |
||
10 | use PCextreme\Cloudstack\RequestFactory; |
||
11 | use Psr\Http\Message\RequestInterface; |
||
12 | use Psr\Http\Message\ResponseInterface; |
||
13 | use UnexpectedValueException; |
||
14 | |||
15 | abstract class AbstractClient |
||
16 | { |
||
17 | /** |
||
18 | * @var string |
||
19 | */ |
||
20 | const METHOD_GET = 'GET'; |
||
21 | |||
22 | /** |
||
23 | * @var string |
||
24 | */ |
||
25 | const METHOD_POST = 'POST'; |
||
26 | |||
27 | /** |
||
28 | * @var RequestFactory |
||
29 | */ |
||
30 | protected $requestFactory; |
||
31 | |||
32 | /** |
||
33 | * @var HttpClientInterface |
||
34 | */ |
||
35 | protected $httpClient; |
||
36 | |||
37 | /** |
||
38 | * Constructs a new Cloudstack client instance. |
||
39 | * |
||
40 | * @param array $options |
||
41 | * An array of options to set on this client. |
||
42 | * @param array $collaborators |
||
43 | * An array of collaborators that may be used to override |
||
44 | * this provider's default behavior. Collaborators include |
||
45 | * `requestFactory` and `httpClient`. |
||
46 | */ |
||
47 | public function __construct(array $options = [], array $collaborators = []) |
||
48 | { |
||
49 | if (empty($collaborators['requestFactory'])) { |
||
50 | $collaborators['requestFactory'] = new RequestFactory(); |
||
51 | } |
||
52 | $this->setRequestFactory($collaborators['requestFactory']); |
||
53 | |||
54 | if (empty($collaborators['httpClient'])) { |
||
55 | $clientOptions = $this->getAllowedClientOptions($options); |
||
56 | |||
57 | $collaborators['httpClient'] = new HttpClient( |
||
58 | array_intersect_key($options, array_flip($clientOptions)) |
||
59 | ); |
||
60 | } |
||
61 | $this->setHttpClient($collaborators['httpClient']); |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * Return the list of options that can be passed to the HttpClient |
||
66 | * |
||
67 | * @param array $options |
||
68 | * @return array |
||
69 | */ |
||
70 | protected function getAllowedClientOptions(array $options) : array |
||
71 | { |
||
72 | $clientOptions = ['timeout', 'proxy']; |
||
73 | |||
74 | // Only allow turning off ssl verification is it's for a proxy |
||
75 | if (! empty($options['proxy'])) { |
||
76 | $clientOptions[] = 'verify'; |
||
77 | } |
||
78 | |||
79 | return $clientOptions; |
||
80 | } |
||
81 | |||
82 | /** |
||
83 | * Returns a PSR-7 request instance that is not authenticated. |
||
84 | * |
||
85 | * @param string $method |
||
86 | * @param string $url |
||
87 | * @param array $options |
||
88 | * @return RequestInterface |
||
89 | */ |
||
90 | public function getRequest(string $method, string $url, array $options = []) : RequestInterface |
||
91 | { |
||
92 | return $this->createRequest($method, $url, $options); |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * Creates a PSR-7 request instance. |
||
97 | * |
||
98 | * @param string $method |
||
99 | * @param string $url |
||
100 | * @param array $options |
||
101 | * @return RequestInterface |
||
102 | */ |
||
103 | protected function createRequest(string $method, string $url, array $options) : RequestInterface |
||
104 | { |
||
105 | $factory = $this->getRequestFactory(); |
||
106 | |||
107 | return $factory->getRequestWithOptions($method, $url, $options); |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Sends a request instance and returns a response instance. |
||
112 | * |
||
113 | * @param RequestInterface $request |
||
114 | * @return ResponseInterface |
||
115 | */ |
||
116 | protected function sendRequest(RequestInterface $request) : ResponseInterface |
||
117 | { |
||
118 | try { |
||
119 | $response = $this->getHttpClient()->send($request); |
||
120 | } catch (BadResponseException $e) { |
||
0 ignored issues
–
show
|
|||
121 | $response = $e->getResponse(); |
||
122 | } |
||
123 | |||
124 | return $response; |
||
125 | } |
||
126 | |||
127 | /** |
||
128 | * Sends a request and returns the parsed response. |
||
129 | * |
||
130 | * @param RequestInterface $request |
||
131 | * @return mixed |
||
132 | */ |
||
133 | public function getResponse(RequestInterface $request) |
||
134 | { |
||
135 | $response = $this->sendRequest($request); |
||
136 | $parsed = $this->parseResponse($response); |
||
137 | |||
138 | $this->checkResponse($response, $parsed); |
||
0 ignored issues
–
show
It seems like
$parsed defined by $this->parseResponse($response) on line 136 can also be of type null ; however, PCextreme\Cloudstack\Abs...Client::checkResponse() does only seem to accept array|string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
139 | |||
140 | return $parsed; |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * Attempts to parse a JSON response. |
||
145 | * |
||
146 | * @param string $content |
||
147 | * @return array |
||
148 | * @throws UnexpectedValueException |
||
149 | */ |
||
150 | protected function parseJson(string $content) : array |
||
151 | { |
||
152 | $content = json_decode($content, true); |
||
153 | |||
154 | if (json_last_error() !== JSON_ERROR_NONE) { |
||
155 | throw new UnexpectedValueException(sprintf( |
||
156 | "Failed to parse JSON response: %s", |
||
157 | json_last_error_msg() |
||
158 | )); |
||
159 | } |
||
160 | |||
161 | return $content; |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * Returns the content type header of a response. |
||
166 | * |
||
167 | * @param ResponseInterface $response |
||
168 | * @return string |
||
169 | */ |
||
170 | protected function getContentType(ResponseInterface $response) : string |
||
171 | { |
||
172 | return join(';', (array) $response->getHeader('content-type')); |
||
173 | } |
||
174 | |||
175 | /** |
||
176 | * Parses the response according to its content-type header. |
||
177 | * |
||
178 | * @param ResponseInterface $response |
||
179 | * @return mixed |
||
180 | * @throws UnexpectedValueException |
||
181 | */ |
||
182 | protected function parseResponse(ResponseInterface $response) |
||
183 | { |
||
184 | $content = (string) $response->getBody(); |
||
185 | $type = $this->getContentType($response); |
||
186 | |||
187 | if (strpos($type, 'urlencoded') !== false) { |
||
188 | parse_str($content, $parsed); |
||
189 | return $parsed; |
||
190 | } |
||
191 | |||
192 | // Attempt to parse the string as JSON regardless of content type, |
||
193 | // since some providers use non-standard content types. Only throw an |
||
194 | // exception if the JSON could not be parsed when it was expected to. |
||
195 | try { |
||
196 | return $this->parseJson($content); |
||
197 | } catch (UnexpectedValueException $e) { |
||
198 | if (strpos($type, 'json') !== false) { |
||
199 | throw $e; |
||
200 | } |
||
201 | |||
202 | return $content; |
||
203 | } |
||
204 | } |
||
205 | |||
206 | /** |
||
207 | * Checks a provider response for errors. |
||
208 | * |
||
209 | * @param ResponseInterface $response |
||
210 | * @param array|string $data |
||
211 | * @return void |
||
212 | * @throws \PCextreme\Cloudstack\Exception\ClientException |
||
213 | */ |
||
214 | abstract protected function checkResponse(ResponseInterface $response, $data); |
||
215 | |||
216 | /** |
||
217 | * Sets the request factory instance. |
||
218 | * |
||
219 | * @param RequestFactory $factory |
||
220 | * @return self |
||
221 | */ |
||
222 | public function setRequestFactory(RequestFactory $factory) : self |
||
223 | { |
||
224 | $this->requestFactory = $factory; |
||
225 | |||
226 | return $this; |
||
227 | } |
||
228 | |||
229 | /** |
||
230 | * Returns the request factory instance. |
||
231 | * |
||
232 | * @return RequestFactory |
||
233 | */ |
||
234 | public function getRequestFactory() : RequestFactory |
||
235 | { |
||
236 | return $this->requestFactory; |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * Sets the HTTP client instance. |
||
241 | * |
||
242 | * @param HttpClientInterface $client |
||
243 | * @return self |
||
244 | */ |
||
245 | public function setHttpClient(HttpClientInterface $client) : self |
||
246 | { |
||
247 | $this->httpClient = $client; |
||
248 | |||
249 | return $this; |
||
250 | } |
||
251 | |||
252 | /** |
||
253 | * Returns the HTTP client instance. |
||
254 | * |
||
255 | * @return HttpClientInterface |
||
256 | */ |
||
257 | public function getHttpClient() : HttpClientInterface |
||
258 | { |
||
259 | return $this->httpClient; |
||
260 | } |
||
261 | } |
||
262 |
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.