From dfc1ebc82cec3fac7e8f724735e5d1e8b3daf802 Mon Sep 17 00:00:00 2001 From: Marcin Haba Date: Sun, 19 Nov 2017 18:22:40 +0100 Subject: [PATCH] baculum: Use api client version and introduce api server version --- .../protected/API/Class/BaculumAPIServer.php | 23 +++++- .../protected/Web/Class/BaculumAPIClient.php | 75 +++++++++++++++++-- 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/gui/baculum/protected/API/Class/BaculumAPIServer.php b/gui/baculum/protected/API/Class/BaculumAPIServer.php index feb15e11fc..8216a564d9 100644 --- a/gui/baculum/protected/API/Class/BaculumAPIServer.php +++ b/gui/baculum/protected/API/Class/BaculumAPIServer.php @@ -38,6 +38,11 @@ Prado::using('Application.API.Class.OAuth2.TokenRecord'); */ abstract class BaculumAPIServer extends TPage { + /** + * API server version (used in HTTP header) + */ + const API_SERVER_VERSION = 0.1; + /** * Storing output from API commands in numeric array. */ @@ -208,7 +213,9 @@ abstract class BaculumAPIServer extends TPage { * Set output headers to send in response. */ private function setOutputHeaders() { - $this->getResponse()->setContentType('application/json'); + $response = $this->getResponse(); + $response->setContentType('application/json'); + $response->appendHeader('Baculum-API-Version: ' . strval(self::API_SERVER_VERSION)); } /** @@ -345,5 +352,19 @@ abstract class BaculumAPIServer extends TPage { public function getModule($name) { return $this->Application->getModule($name); } + + /** + * Get Baculum web client version. + * + * @return float client version + */ + public function getClientVersion() { + $version = 0; + $headers = $this->getRequest()->getHeaders(CASE_LOWER); + if (array_key_exists('x-baculum-api', $headers)) { + $version = floatval($headers['x-baculum-api']); + } + return $version; + } } ?> diff --git a/gui/baculum/protected/Web/Class/BaculumAPIClient.php b/gui/baculum/protected/Web/Class/BaculumAPIClient.php index 6e7ce35bb3..5f85e18b85 100644 --- a/gui/baculum/protected/Web/Class/BaculumAPIClient.php +++ b/gui/baculum/protected/Web/Class/BaculumAPIClient.php @@ -35,9 +35,12 @@ Prado::using('Application.Web.Class.HostRecord'); class BaculumAPIClient extends WebModule { /** - * API version (used in HTTP header) + * API client version (used in HTTP header) + * + * 0.2 - + * 0.3 - sending config as json instead of serialized array */ - const API_VERSION = '0.2'; + const API_CLIENT_VERSION = 0.3; /** * OAuth2 authorization endpoints @@ -45,6 +48,16 @@ class BaculumAPIClient extends WebModule { const OAUTH2_AUTH_URL = 'api/auth/'; const OAUTH2_TOKEN_URL = 'api/token/'; + /** + * API server version for current request. + */ + public $api_server_version = 0; + + /** + * Single request response headers. + */ + public $response_headers = array(); + /** * Session params to put in URLs. * @@ -83,6 +96,7 @@ class BaculumAPIClient extends WebModule { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_COOKIE, 'PHPSESSID=' . md5(session_id())); + curl_setopt($ch, CURLOPT_HEADER, true); return $ch; } @@ -94,7 +108,7 @@ class BaculumAPIClient extends WebModule { */ private function getAPIHeaders($host = null, $host_cfg = array()) { $headers = array( - 'X-Baculum-API: ' . self::API_VERSION, + 'X-Baculum-API: ' . strval(self::API_CLIENT_VERSION), 'Accept: application/json' ); if (count($host_cfg) > 0 && !is_null($host) && $host_cfg['auth_type'] === 'oauth2') { @@ -279,8 +293,12 @@ class BaculumAPIClient extends WebModule { $result = curl_exec($ch); $error = curl_error($ch); $errno = curl_errno($ch); + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); curl_close($ch); - $ret = $this->preParseOutput($result, $error, $errno, $show_error); + $header = substr($result, 0, $header_size); + $body = substr($result, $header_size); + $this->parseHeader($header); + $ret = $this->preParseOutput($body, $error, $errno, $show_error); if ($use_cache === true && $ret->error === 0) { $this->setSessionCache($host, $params, $ret); } @@ -321,8 +339,12 @@ class BaculumAPIClient extends WebModule { $result = curl_exec($ch); $error = curl_error($ch); $errno = curl_errno($ch); + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); curl_close($ch); - return $this->preParseOutput($result, $error, $errno, $show_error); + $header = substr($result, 0, $header_size); + $body = substr($result, $header_size); + $this->parseHeader($header); + return $this->preParseOutput($body, $error, $errno, $show_error); } /** @@ -354,8 +376,12 @@ class BaculumAPIClient extends WebModule { $result = curl_exec($ch); $error = curl_error($ch); $errno = curl_errno($ch); + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); curl_close($ch); - return $this->preParseOutput($result, $error, $errno, $show_error); + $header = substr($result, 0, $header_size); + $body = substr($result, $header_size); + $this->parseHeader($header); + return $this->preParseOutput($body, $error, $errno, $show_error); } /** @@ -384,8 +410,12 @@ class BaculumAPIClient extends WebModule { $result = curl_exec($ch); $error = curl_error($ch); $errno = curl_errno($ch); + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); curl_close($ch); - return $this->preParseOutput($result, $error, $errno, $show_error); + $header = substr($result, 0, $header_size); + $body = substr($result, $header_size); + $this->parseHeader($header); + return $this->preParseOutput($body, $error, $errno, $show_error); } /** @@ -434,6 +464,23 @@ class BaculumAPIClient extends WebModule { return $resource; } + /** + * Parse and set response headers. + * Note, header names are lower case. + * + * @return none + */ + public function parseHeader($header) { + $headers = array(); + $heads = explode("\r\n", $header); + for ($i = 0; $i < count($heads); $i++) { + if (preg_match('/^(?P[^:]+):(?P[\S\s]+)$/', $heads[$i], $match) === 1) { + $headers[strtolower($match['name'])] = trim($match['value']); + } + } + $this->response_headers = $headers; + } + /** * Initialize session cache. * @@ -563,5 +610,19 @@ class BaculumAPIClient extends WebModule { HostRecord::deleteByPk($st['host']); } } + + /** + * Get Baculum web server version. + * Value available after receiving response. + * + * @return float server version + */ + public function getServerVersion() { + $version = 0; + if (array_key_exists('baculum-api-version', $this->response_headers)) { + $version = floatval($this->response_headers['baculum-api-version']); + } + return $version; + } } ?> -- 2.39.5