Skip to content

Commit

Permalink
removed old curl request, improved url, query and body passing
Browse files Browse the repository at this point in the history
  • Loading branch information
hiqsol committed Jan 18, 2016
1 parent 1ddf7fd commit 122c1d3
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 203 deletions.
9 changes: 3 additions & 6 deletions src/Command.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,8 @@ class Command extends Component

/**
* Sends a request to the _search API and returns the result.
*
* @param array $options
*
* @throws ErrorResponseException
*
* @return mixed
*/
public function search($options = [])
Expand Down Expand Up @@ -107,11 +104,11 @@ public function update($index, $id, $data, $options = [])

/**
* @param $action
* @param array $options
* @param mixed $body request parameters
* @return mixed
*/
public function perform($action, $options = [])
public function perform($action, $body = [])
{
return $this->db->post($action, $options);
return $this->db->post($action, [], $body);
}
}
248 changes: 52 additions & 196 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,151 +144,143 @@ public function getQueryBuilder()

/**
* Performs GET HTTP request.
* @param string $url URL
* @param array $options URL options
* @param string $body request body
* @param bool $raw if response body contains JSON and should be decoded
* @param string $url URL
* @param array $query query options
* @param string $body request body
* @param bool $raw if response body contains JSON and should be decoded
* @throws HiArtException
* @throws \yii\base\InvalidConfigException
* @return mixed response
*/
public function get($url, $options = [], $body = null, $raw = false)
public function get($url, $query = [], $body = null, $raw = false)
{
return $this->makeRequest('GET', $url, $options, $body, $raw);
return $this->makeRequest('GET', $url, $query, $body, $raw);
}

/**
* Performs HEAD HTTP request.
* @param string $url URL
* @param array $options URL options
* @param string $body request body
* @param string $url URL
* @param array $query query options
* @param string $body request body
* @throws HiArtException
* @throws \yii\base\InvalidConfigException
* @return mixed response
*/
public function head($url, $options = [], $body = null)
public function head($url, $query = [], $body = null)
{
return $this->makeRequest('HEAD', $url, $options, $body, $raw);
return $this->makeRequest('HEAD', $url, $query, $body, $raw);
}

/**
* Performs POST HTTP request.
* @param string $url URL
* @param array $options URL options
* @param string $body request body
* @param bool $raw if response body contains JSON and should be decoded
* @param string $url URL
* @param array $query query options
* @param string $body request body
* @param bool $raw if response body contains JSON and should be decoded
* @throws HiArtException
* @throws \yii\base\InvalidConfigException
* @return mixed response
*/
public function post($url, $options = [], $body = null, $raw = false)
public function post($url, $query = [], $body = null, $raw = false)
{
return $this->makeRequest('POST', $url, $options, $body, $raw);
return $this->makeRequest('POST', $url, $query, $body, $raw);
}

/**
* Performs PUT HTTP request.
* @param string $url URL
* @param array $options URL options
* @param string $body request body
* @param bool $raw if response body contains JSON and should be decoded
* @param string $url URL
* @param array $query query options
* @param string $body request body
* @param bool $raw if response body contains JSON and should be decoded
* @throws HiArtException
* @throws \yii\base\InvalidConfigException
* @return mixed response
*/
public function put($url, $options = [], $body = null, $raw = false)
public function put($url, $query = [], $body = null, $raw = false)
{
return $this->makeRequest('PUT', $url, $options, $body, $raw);
return $this->makeRequest('PUT', $url, $query, $body, $raw);
}

/**
* Performs DELETE HTTP request.
* @param string $url URL
* @param array $options URL options
* @param string $body request body
* @param bool $raw if response body contains JSON and should be decoded
* @param string $url URL
* @param array $query query options
* @param string $body request body
* @param bool $raw if response body contains JSON and should be decoded
* @throws HiArtException
* @throws \yii\base\InvalidConfigException
* @return mixed response
*/
public function delete($url, $options = [], $body = null, $raw = false)
public function delete($url, $query = [], $body = null, $raw = false)
{
return $this->makeRequest('DELETE', $url, $options, $body, $raw);
return $this->makeRequest('DELETE', $url, $query, $body, $raw);
}

/**
* XXX To be removed in favour of post().
* XXX DEPRECATED in favour of post().
* @param $url
* @param array $options
* @param array $query
* @return mixed
*/
public function perform($url, $options = [])
public function perform($url, $body = [])
{
return $this->makeRequest('DELETE', $url, $options);
return $this->makeRequest('DELETE', $url, [], $body);
}

/**
* Make request and check for error.
* @param string $url URL
* @param array $options URL options
* @param string $body request body
* @param bool $raw if response body contains JSON and should be decoded
* @param string $url URL
* @param array $query query options, (GET parameters)
* @param string $body request body, (POST parameters)
* @param bool $raw if response body contains JSON and should be decoded
* @throws HiArtException
* @throws \yii\base\InvalidConfigException
* @return mixed response
*/
public function makeRequest($method, $url, $options = [], $body = null, $raw = false)
public function makeRequest($method, $url, $query = [], $body = null, $raw = false)
{
#$result = $this->curlRequest($method, $this->createUrl($url), http_build_query($options), $raw);
$result = $this->guzzleRequest($method, $this->createUrl($url), $options, $raw);
$result = $this->makeGuzzleRequest($method, $this->prepareUrl($url, $query), $body, $raw);

return $this->checkResponse($result, $url, $options);
return $this->checkResponse($result, $url, $query);
}

/**
* Creates URL.
* @param mixed $path path
* @param array $options URL options
* @param array $query query options
* @return array
*/
private function createUrl($path, array $options = [])
private function prepareUrl($path, array $query = [])
{
$options = array_merge($this->getAuth(), $options);
if (!is_string($path)) {
$url = urldecode(reset($path));
if (!empty($options)) {
$url .= '?' . http_build_query($options);
}
} else {
$url = $path;
if (!empty($options)) {
$url .= (strpos($url, '?') === false ? '?' : '&') . http_build_query($options);
}
$url = $path;
$query = array_merge($this->getAuth(), $query);
if (!empty($query)) {
$url .= (strpos($url, '?') === false ? '?' : '&') . http_build_query($query);
}

return [$this->config['api_url'], $url];
return $url;
}

/**
* Sends the request using guzzle, returns array or raw response content, if $raw is true.
*
* @param string $method POST, GET, etc
* @param string $url the URL for request
* @param string $url the URL for request, not including proto and site
* @param array|string $body the request body. When array - will be sent as POST params, otherwise - as RAW body.
* @param bool $raw Whether to decode data, when response is JSON.
* @return string|array
*/
protected function guzzleRequest($method, $url, $body = null, $raw = false)
protected function makeGuzzleRequest($method, $url, $body = null, $raw = false)
{
$method = strtoupper($method);
$profile = $method . ' ' . $url[1] . '#' . (is_array($body) ? http_build_query($body) : $body);
$profile = $method . ' ' . $url . '#' . (is_array($body) ? http_build_query($body) : $body);
$options = [(is_array($body) ? 'form_params' : 'body') => $body];
Yii::beginProfile($profile, __METHOD__);
$response = $this->getGuzzle()->request($method, $url[1], $options);
$response = $this->getGuzzle()->request($method, $url, $options);
Yii::endProfile($profile, __METHOD__);

$res = $response->getBody()->getContents();
if (!$raw && in_array('application/json', $response->getHeader('Content-Type'), true)) {
if (!$raw && preg_grep('|application/json|i', $response->getHeader('Content-Type'))) {
$res = Json::decode($res);
}

Expand All @@ -309,142 +301,6 @@ public function getGuzzle()
return static::$guzzle;
}

/**
* Performs HTTP request.
* @param string $method method name
* @param string $url URL
* @param string $requestBody request body
* @param bool $raw if response body contains JSON and should be decoded
* @throws ErrorResponseException
* @throws HiArtException
* @return mixed if request failed
*/
protected function curlRequest($method, $url, $requestBody = null, $raw = false)
{
$method = strtoupper($method);
// response body and headers
$headers = [];
$body = '';
$options = [
CURLOPT_URL => $url,
CURLOPT_USERAGENT => 'Yii Framework ' . Yii::getVersion() . ' (HiArt)',
//CURLOPT_ENCODING => 'UTF-8',
# CURLOPT_USERAGENT => 'curl/0.00 (php 5.x; U; en)',
CURLOPT_RETURNTRANSFER => false,
CURLOPT_HEADER => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 2,
// http://www.php.net/manual/en/function.curl-setopt.php#82418
CURLOPT_HTTPHEADER => ['Expect:'],
CURLOPT_WRITEFUNCTION => function ($curl, $data) use (&$body) {
$body .= $data;

return mb_strlen($data, '8bit');
},
CURLOPT_HEADERFUNCTION => function ($curl, $data) use (&$headers) {
foreach (explode("\r\n", $data) as $row) {
if (($pos = strpos($row, ':')) !== false) {
$headers[strtolower(substr($row, 0, $pos))] = trim(substr($row, $pos + 1));
}
}

return mb_strlen($data, '8bit');
},
CURLOPT_CUSTOMREQUEST => $method,
];
if ($this->connectionTimeout !== null) {
$options[CURLOPT_CONNECTTIMEOUT] = $this->connectionTimeout;
}
if ($this->dataTimeout !== null) {
$options[CURLOPT_TIMEOUT] = $this->dataTimeout;
}
if ($requestBody !== null) {
$options[CURLOPT_POSTFIELDS] = $requestBody;
}
if ($method === 'HEAD') {
$options[CURLOPT_NOBODY] = true;
unset($options[CURLOPT_WRITEFUNCTION]);
}
if (is_array($url)) {
list($host, $q) = $url;
if (strncmp($host, 'inet[', 5) === 0) {
$host = substr($host, 5, -1);
if (($pos = strpos($host, '/')) !== false) {
$host = substr($host, $pos + 1);
}
}
$profile = $method . ' ' . $q . '#' . $requestBody;
if (preg_match('@^https?://@', $host)) {
$url = $host . '/' . $q;
} else {
throw new HiArtException('Request failed: please specify the protocol (http, https) in reference to the API HiResource Core');
}
} else {
$profile = false;
}
$options[CURLOPT_URL] = $url;
Yii::trace("Sending request to node: $method $url\n$requestBody", __METHOD__);
if ($profile !== false) {
Yii::beginProfile($profile, __METHOD__);
}
$curl = $this->getHandler();
curl_setopt_array($curl, $options);
if (curl_exec($curl) === false) {
throw new HiArtException('Request failed: ' . curl_errno($curl) . ' - ' . curl_error($curl), [
'requestUrl' => $url,
'requestBody' => $requestBody,
'responseBody' => $this->decodeErrorBody($body),
'requestMethod' => $method,
'responseHeaders' => $headers,
]);
}

$responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
Yii::trace(curl_getinfo($curl));
if ($profile !== false) {
Yii::endProfile($profile, __METHOD__);
}
if ($responseCode >= 200 && $responseCode < 300) {
if ($method === 'HEAD') {
return true;
} else {
if (isset($headers['content-length']) && ($len = mb_strlen($body, '8bit')) < $headers['content-length']) {
throw new HiArtException("Incomplete data received: $len < {$headers['content-length']}", [
'requestMethod' => $method,
'requestUrl' => $url,
'requestBody' => $requestBody,
'responseCode' => $responseCode,
'responseHeaders' => $headers,
'responseBody' => $this->decodeErrorBody($body),
]);
}
if (isset($headers['content-type']) && !strncmp($headers['content-type'], 'application/json', 16)) {
return $raw ? $body : Json::decode($body);
} else {
return $body;
}
throw new HiArtException('Unsupported data received from Hiresource: ' . $headers['content-type'], [
'requestUrl' => $url,
'requestBody' => $requestBody,
'responseBody' => $this->decodeErrorBody($body),
'requestMethod' => $method,
'responseCode' => $responseCode,
'responseHeaders' => $headers,
]);
}
} elseif ($responseCode === 404) {
return false;
} else {
throw new HiArtException("Request request failed with code $responseCode.", [
'requestUrl' => $url,
'requestBody' => $requestBody,
'responseBody' => $this->decodeErrorBody($body),
'requestMethod' => $method,
'responseCode' => $responseCode,
'responseHeaders' => $headers,
]);
}
}

/**
* Try to decode error information if it is valid json, return it if not.
Expand Down
2 changes: 1 addition & 1 deletion src/DebugPanel.php
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ public function save()
{
$target = $this->module->logTarget;
$messages = $target->filterMessages($target->messages, Logger::LEVEL_PROFILE,
['hiqdev\hiart\Connection::guzzleRequest']);
['hiqdev\hiart\Connection::makeGuzzleRequest']);

return ['messages' => $messages];
}
Expand Down

0 comments on commit 122c1d3

Please sign in to comment.