2016-04-12 19:31:39 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace b8;
|
|
|
|
|
|
|
|
class HttpClient
|
|
|
|
{
|
2016-04-20 12:30:26 +02:00
|
|
|
protected $_base = '';
|
|
|
|
protected $_params = [];
|
|
|
|
protected $_headers = [];
|
|
|
|
|
|
|
|
public function __construct($base = null)
|
|
|
|
{
|
|
|
|
$settings = Config::getInstance()->get('b8.http.client', ['base_url' => '', 'params' => []]);
|
|
|
|
$this->_base = $settings['base_url'];
|
|
|
|
$this->_params = isset($settings['params']) && is_array($settings['params']) ? $settings['params'] : [];
|
|
|
|
$this->_headers = ['Content-Type: application/x-www-form-urlencoded'];
|
|
|
|
|
|
|
|
if (!is_null($base)) {
|
|
|
|
$this->_base = $base;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setHeaders(array $headers)
|
|
|
|
{
|
|
|
|
$this->_headers = $headers;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function request($method, $uri, $params = [])
|
|
|
|
{
|
|
|
|
// Clean incoming:
|
|
|
|
$method = strtoupper($method);
|
|
|
|
$getParams = $this->_params;
|
|
|
|
|
|
|
|
if ($method == 'GET' || $method == 'DELETE') {
|
|
|
|
$getParams = array_merge($getParams, $params);
|
|
|
|
} else {
|
|
|
|
$bodyParams = is_array($params) ? http_build_query($params) : $params;
|
|
|
|
}
|
|
|
|
|
|
|
|
$getParams = http_build_query($getParams);
|
|
|
|
|
|
|
|
if (substr($uri, 0, 1) != '/' && !empty($this->_base)) {
|
|
|
|
$uri = '/' . $uri;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build HTTP context array:
|
|
|
|
$context = [];
|
|
|
|
$context['http']['user_agent'] = 'b8/1.0';
|
|
|
|
$context['http']['timeout'] = 30;
|
|
|
|
$context['http']['method'] = $method;
|
|
|
|
$context['http']['ignore_errors'] = true;
|
|
|
|
$context['http']['header'] = implode(PHP_EOL, $this->_headers);
|
|
|
|
|
|
|
|
if (in_array($method, ['PUT', 'POST'])) {
|
|
|
|
$context['http']['content'] = $bodyParams;
|
|
|
|
}
|
|
|
|
|
|
|
|
$uri .= '?' . $getParams;
|
|
|
|
|
|
|
|
$context = stream_context_create($context);
|
|
|
|
$result = file_get_contents($this->_base . $uri, false, $context);
|
|
|
|
|
|
|
|
$res = [];
|
|
|
|
$res['headers'] = $http_response_header;
|
|
|
|
$res['code'] = (int)preg_replace('/HTTP\/1\.[0-1] ([0-9]+)/', '$1', $res['headers'][0]);
|
|
|
|
$res['success'] = false;
|
2017-01-13 16:35:41 +01:00
|
|
|
$res['body'] = $this->decodeResponse($result);
|
2016-04-20 12:30:26 +02:00
|
|
|
|
|
|
|
if ($res['code'] >= 200 && $res['code'] < 300) {
|
|
|
|
$res['success'] = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle JSON responses:
|
|
|
|
foreach ($res['headers'] as $header) {
|
|
|
|
if (stripos($header, 'Content-Type') !== false || stripos($header, 'b8-Type') !== false) {
|
|
|
|
if (stripos($header, 'application/json') !== false) {
|
|
|
|
$res['text_body'] = $res['body'];
|
|
|
|
$res['body'] = json_decode($res['body'], true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $res;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function get($uri, $params = [])
|
|
|
|
{
|
|
|
|
return $this->request('GET', $uri, $params);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function put($uri, $params = [])
|
|
|
|
{
|
|
|
|
return $this->request('PUT', $uri, $params);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function post($uri, $params = [])
|
|
|
|
{
|
|
|
|
return $this->request('POST', $uri, $params);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function delete($uri, $params = [])
|
|
|
|
{
|
|
|
|
return $this->request('DELETE', $uri, $params);
|
|
|
|
}
|
|
|
|
|
2017-01-13 16:35:41 +01:00
|
|
|
protected function decodeResponse($originalResponse)
|
2016-04-20 12:30:26 +02:00
|
|
|
{
|
|
|
|
$response = $originalResponse;
|
|
|
|
$body = '';
|
|
|
|
|
|
|
|
do {
|
2017-01-13 16:35:41 +01:00
|
|
|
$line = $this->readChunk($response);
|
2016-04-20 12:30:26 +02:00
|
|
|
|
|
|
|
if ($line == PHP_EOL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$length = hexdec(trim($line));
|
|
|
|
|
|
|
|
if (!is_int($length) || empty($response) || $line === false || $length < 1) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
do {
|
2017-01-13 16:35:41 +01:00
|
|
|
$data = $this->readChunk($response, $length);
|
2016-04-20 12:30:26 +02:00
|
|
|
|
|
|
|
// remove the amount received from the total length on the next loop
|
|
|
|
// it'll attempt to read that much less data
|
|
|
|
$length -= strlen($data);
|
|
|
|
|
|
|
|
// store in string for later use
|
|
|
|
$body .= $data;
|
|
|
|
|
|
|
|
// zero or less or end of connection break
|
|
|
|
if ($length <= 0 || empty($response)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (true);
|
|
|
|
} while (true);
|
|
|
|
|
|
|
|
if (empty($body)) {
|
|
|
|
$body = $originalResponse;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $body;
|
|
|
|
}
|
|
|
|
|
2017-01-13 16:35:41 +01:00
|
|
|
protected function readChunk(&$string, $len = 4096)
|
2016-04-20 12:30:26 +02:00
|
|
|
{
|
|
|
|
$rtn = '';
|
|
|
|
for ($i = 0; $i <= $len; $i++) {
|
|
|
|
if (empty($string)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$char = $string[0];
|
|
|
|
$string = substr($string, 1);
|
|
|
|
$rtn .= $char;
|
|
|
|
|
|
|
|
if ($char == PHP_EOL) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $rtn;
|
|
|
|
}
|
2016-04-21 19:05:32 +02:00
|
|
|
}
|