|
6 | 6 | use BasicHttpClient\Request\Base\RequestInterface; |
7 | 7 | use BasicHttpClient\Request\Message\Base\MessageInterface; |
8 | 8 | use BasicHttpClient\Request\Transport\Base\TransportInterface; |
| 9 | +use BasicHttpClient\Request\Transport\HttpsTransport; |
9 | 10 | use BasicHttpClient\Request\Transport\HttpTransport; |
| 11 | +use BasicHttpClient\Response\Response; |
10 | 12 | use BasicHttpClient\Util\UrlUtil; |
| 13 | +use CommonException\NetworkException\Base\NetworkException; |
| 14 | +use CommonException\NetworkException\ConnectionTimeoutException; |
11 | 15 |
|
12 | 16 | /** |
13 | 17 | * Class Request |
@@ -59,6 +63,11 @@ class Request implements RequestInterface |
59 | 63 | */ |
60 | 64 | private $message; |
61 | 65 |
|
| 66 | + /** |
| 67 | + * @var Response |
| 68 | + */ |
| 69 | + private $response; |
| 70 | + |
62 | 71 | /** |
63 | 72 | * Request constructor. |
64 | 73 | */ |
@@ -115,6 +124,14 @@ public function getPort() |
115 | 124 | return $this->port; |
116 | 125 | } |
117 | 126 |
|
| 127 | + /** |
| 128 | + * @return bool |
| 129 | + */ |
| 130 | + public function hasPort() |
| 131 | + { |
| 132 | + return !is_null($this->port); |
| 133 | + } |
| 134 | + |
118 | 135 | /** |
119 | 136 | * @param int $port |
120 | 137 | * @return $this |
@@ -265,47 +282,89 @@ public function configureCurl($curl) |
265 | 282 | curl_setopt($curl, CURLINFO_HEADER_OUT, true); |
266 | 283 | curl_setopt($curl, CURLOPT_USERAGENT, $this->getUserAgent()); |
267 | 284 | curl_setopt($curl, CURLOPT_URL, $this->getEndpoint()); |
268 | | - // Setup request method |
| 285 | + if ($this->hasPort()) { |
| 286 | + curl_setopt($curl, CURLOPT_PORT, $this->getPort()); |
| 287 | + } |
| 288 | + // Request method |
| 289 | + curl_setopt($curl, CURLOPT_HTTPGET, true); |
| 290 | + if ($this->getMethod() != self::REQUEST_METHOD_GET) { |
| 291 | + curl_setopt($curl, CURLOPT_HTTPGET, false); |
| 292 | + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->getMethod()); |
| 293 | + } |
| 294 | + // Request body |
269 | 295 | switch ($this->getMethod()) { |
270 | 296 | case self::REQUEST_METHOD_GET: |
271 | 297 | case self::REQUEST_METHOD_HEAD: |
272 | | - curl_setopt($curl, CURLOPT_HTTPGET, true); |
273 | 298 | // Modify the URL using the body as query string |
274 | 299 | break; |
275 | 300 | case self::REQUEST_METHOD_POST: |
276 | | - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); |
277 | 301 | // curl_setopt($curl, CURLOPT_POSTFIELDS, $requestBody); |
278 | 302 | break; |
279 | 303 | case self::REQUEST_METHOD_PUT: |
280 | | - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT'); |
281 | 304 | // curl_setopt($curl, CURLOPT_POSTFIELDS, $requestBody); |
282 | 305 | break; |
283 | 306 | case self::REQUEST_METHOD_PATCH: |
284 | | - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PATCH'); |
285 | 307 | // curl_setopt($curl, CURLOPT_POSTFIELDS, $requestBody); |
286 | 308 | break; |
287 | | - case self::REQUEST_METHOD_DELETE: |
288 | | - curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); |
289 | | - break; |
290 | 309 | } |
291 | 310 | return $this; |
292 | 311 | } |
293 | 312 |
|
294 | 313 | /** |
295 | 314 | * @return $this |
| 315 | + * @throws ConnectionTimeoutException |
| 316 | + * @throws NetworkException |
| 317 | + * @throws \Exception |
296 | 318 | */ |
297 | 319 | public function perform() |
298 | 320 | { |
| 321 | + // Reset former result |
| 322 | + $this->response = null; |
| 323 | + // Perform hook |
| 324 | + $this->prePerform(); |
299 | 325 | // Curl basic setup |
300 | 326 | $curl = curl_init(); |
301 | 327 | $this->configureCurl($curl); |
302 | 328 | $this->getTransport()->configureCurl($curl); |
303 | 329 | $this->getMessage()->configureCurl($curl); |
304 | 330 | // Execute request |
305 | 331 | $responseBody = curl_exec($curl); |
306 | | - // TODO: Parse the response body |
| 332 | + $curlErrorCode = curl_errno($curl); |
| 333 | + $curlErrorMessage = curl_error($curl); |
| 334 | + if ($curlErrorCode === CURLE_OK) { |
| 335 | + $this->response = new Response(); |
| 336 | + $this->response->populateFromCurlResult($curl, $responseBody); |
| 337 | + return $this; |
| 338 | + } |
307 | 339 | curl_close($curl); |
308 | | - return $this; |
| 340 | + switch ($curlErrorCode) { |
| 341 | + case CURLE_OPERATION_TIMEOUTED: |
| 342 | + throw new ConnectionTimeoutException('The request timed out with message: ' . $curlErrorMessage); |
| 343 | + break; |
| 344 | + default: |
| 345 | + throw new NetworkException('The request failed with message: ' . $curlErrorMessage); |
| 346 | + break; |
| 347 | + } |
| 348 | + } |
| 349 | + |
| 350 | + /** |
| 351 | + * @return Response |
| 352 | + */ |
| 353 | + public function getResponse() |
| 354 | + { |
| 355 | + return $this->response; |
| 356 | + } |
| 357 | + |
| 358 | + /** |
| 359 | + * @throws \Exception |
| 360 | + * @return void |
| 361 | + */ |
| 362 | + protected function prePerform() |
| 363 | + { |
| 364 | + $urlUtil = new UrlUtil(); |
| 365 | + if ($urlUtil->getScheme($this->getEndpoint()) == 'HTTPS' && !$this->getTransport() instanceof HttpsTransport) { |
| 366 | + throw new \Exception('Transport misconfiguration. Use HttpsTransport for HTTPS requests.'); |
| 367 | + } |
309 | 368 | } |
310 | 369 |
|
311 | 370 | } |
0 commit comments