/** * Send the given request and return its response * * @param RestApiRequest $request * * @return RestApiResponse * * @throws RestApiException In case an error occured while handling the request */ public function request(RestApiRequest $request) { $scheme = strpos($this->host, '://') !== false ? '' : 'http://'; $path = '/' . join('/', array_map('rawurlencode', explode('/', ltrim($request->getPath(), '/')))); $query = $request->getParams()->isEmpty() ? '' : '?' . (string) $request->getParams(); $curl = $this->getConnection(); curl_setopt($curl, CURLOPT_HTTPHEADER, $request->getHeaders()); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getMethod()); curl_setopt($curl, CURLOPT_URL, $scheme . $this->host . $path . $query); curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getPayload()); $result = curl_exec($curl); if ($result === false) { $restApiException = new RestApiException(curl_error($curl)); $restApiException->setErrorCode(curl_errno($curl)); throw $restApiException; } $header = substr($result, 0, curl_getinfo($curl, CURLINFO_HEADER_SIZE)); $result = substr($result, curl_getinfo($curl, CURLINFO_HEADER_SIZE)); $statusCode = 0; foreach (explode("\r\n", $header) as $headerLine) { // The headers are inspected manually because curl_getinfo($curl, CURLINFO_HTTP_CODE) // returns only the first status code. (e.g. 100 instead of 200) $matches = array(); if (preg_match('/^HTTP\\/[0-9.]+ ([0-9]+)/', $headerLine, $matches)) { $statusCode = (int) $matches[1]; } } $response = new RestApiResponse($statusCode); if ($result) { $response->setPayload($result); $response->setContentType(curl_getinfo($curl, CURLINFO_CONTENT_TYPE)); } return $response; }