php-censor/src/B8Framework/HttpClient.php
2017-01-14 16:12:53 +07:00

168 lines
4.6 KiB
PHP

<?php
namespace b8;
class HttpClient
{
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;
$res['body'] = $this->decodeResponse($result);
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);
}
protected function decodeResponse($originalResponse)
{
$response = $originalResponse;
$body = '';
do {
$line = $this->readChunk($response);
if ($line == PHP_EOL) {
continue;
}
$length = hexdec(trim($line));
if (!is_int($length) || empty($response) || $line === false || $length < 1) {
break;
}
do {
$data = $this->readChunk($response, $length);
// 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;
}
protected function readChunk(&$string, $len = 4096)
{
$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;
}
}