* fixed #194 PHP 5.6 error * - closed #102 added "set waypoint/destination" context menu to route finder module - update "Select2" 4.0.0 -> 4.0.3 - update "Font Awesome" 4.6.1 -> 4.6.3 * - added *.js files for develop branch * - closed #195 fixed "BASE" dir for subDir installations - fixed "Home" menu link * - #195 improved js load path * - added "clear cache" function for manually cache clearing to /setup #200 #105 #158 - added cache size information to /setup - added current pathfinder "VERSION" to /setup - updated "requireJs" 2.1.20 ->2.2.0 - removed unnecessary page cache timings from static templates (page cache) * - added "document_root", "port", "protocol" and "PHP framework version" to /setup page - added new "shattered" wormhole types to "signature table", closed #182, #179 * - added new "delete old signatures" option to "signature reader" dialog, closed #95 * - added new housekeeping cronjob für cached files, closed #200 - added new cache size information to /setup page * - fixed signature groupId/typeId "overwriting" for already known signatures. closed #207 - improved system search dialog. Added trim(); before "api/signatures-> search" request * updated README.me * fixed PHP error "default object from empty value", closed #209 * reduced image file size * - added local storage (IndexedDB) - added local storage for map scroll position. closed #69 * - added "notice" panel for upcoming release information - improved layout for "release dialog" (GitHub API) - improved pagespeed (removed render blocking javascripts) - improved map scrollbar configuration - improved Chrome browser custom scrollbar layout - removed "sign up" buttons from "map panels", closed #214 * - fixed some session and cookie bugs * - added new requirement check for `max_input_vars` to /setup URL, closed #224 * - fixed isWormhole(); bug * -v1.1.1 added js build files * - removed IGB support #206 - removed location tracking by IGB * - added build files for upcoming version 1.1.2 - improved ajax authentication check and "logout" notification | closed #198 - improved logging, added missing log file configuration to pathfinder.ini - added logging for "unauthorized" requests | closed #198 - updated js "jQuery" 1.11.3 -> 3.0.0 | #206 - updated js "datatables" plugin 1.10.7 -> 1.10.12 | #206 - updated js "mCustomScrollbar" 3.1.14 -> 3.1.4 | #206 * - fixed some minor bugs in signature table module * - fixed type "Cataclysmic", closed #241 * - added new setup DB indexing for "system_neighbour" table to /setup route, #125 - fixed system "TrueSec" rounding in "routes module", closed #109 * - fixed system "TrueSec" rounding in "routes module", closed #109 * - added new wormhole statics for "Thera", closed #240 * - fixed missing statics for constellation "21000062" , closed #232 * - added "static" wormholes for "shattered" systems , closed #180 - added im/export function for "index" tables (*.csv import), as an alternative to the *.sql import, closed #125 * - added new system tooltip for "region name", closed #236 - updated "Bootstrap" JS-library 3.3.0 -> 3.3.5 * - removed console.log(),,, * minor bugfixes in /setup page * - added basic support for Russian signatures, closed #256 - added warning notification for invalid signature stings * - added basic support for Russian signatures, closed #256 * - added requirement check for "PDO", "PDO_MYSQL" to "/setup" route - imrpved DB PDO connection (added "TIMEOUT", forced "ERRMODE") - fixed broken "system alias" renaming dialog * - fixed "system graph" module rendering if there was no data available - improved "image gallery" initialization on landing page - added navigation to /setup page - updated "blueImpGallery" (fixed some bugs after jQuery 3.0 upgrade) 1.15.2 -> 2.21.3 - updated "blueImpGalleryBootstrap" (fixed some bugs after jQuery 3.0 upgrade) 3.1.1 -> 3.4.2 * - JS build files vor 1.1.2 * Updated pathfinder.css
233 lines
6.8 KiB
PHP
233 lines
6.8 KiB
PHP
<?php
|
|
/**
|
|
* Created by PhpStorm.
|
|
* User: Exodus
|
|
* Date: 12.03.2016
|
|
* Time: 12:28
|
|
*/
|
|
|
|
namespace Lib;
|
|
|
|
use controller\LogController;
|
|
|
|
class Web extends \Web {
|
|
|
|
const ERROR_STATUS_LOG = 'HTTP %s: \'%s\' | url: %s \'%s\'%s';
|
|
|
|
/**
|
|
* max number of CREST curls for a single endpoint until giving up...
|
|
* this is because CREST is not very stable
|
|
*/
|
|
const RETRY_COUNT_MAX = 3;
|
|
|
|
/**
|
|
* end of line
|
|
* @var string
|
|
*/
|
|
private $eol = "\r\n";
|
|
|
|
/**
|
|
* get status code from Header data array
|
|
* @param array $headers
|
|
* @return int
|
|
*/
|
|
protected function getStatusCodeFromHeaders($headers = []){
|
|
$statusCode = 0;
|
|
|
|
if(
|
|
preg_match(
|
|
'/HTTP\/1\.\d (\d{3}?)/',
|
|
implode($this->eol, $headers),
|
|
$matches
|
|
)
|
|
){
|
|
$statusCode = (int)$matches[1];
|
|
}
|
|
return $statusCode;
|
|
}
|
|
|
|
/**
|
|
* get cache time in seconds from Header data array
|
|
* @param array $headers
|
|
* @return int
|
|
*/
|
|
protected function getCacheTimeFromHeaders($headers = []){
|
|
$cacheTime = 0;
|
|
|
|
if(
|
|
preg_match(
|
|
'/Cache-Control:(.*?)max-age=([0-9]+)/',
|
|
implode($this->eol, $headers),
|
|
$matches
|
|
)
|
|
){
|
|
$cacheTime = (int)$matches[2];
|
|
}elseif(
|
|
preg_match(
|
|
'/Access-Control-Max-Age: ([0-9]+)/',
|
|
implode($this->eol, $headers),
|
|
$matches
|
|
)
|
|
){
|
|
$cacheTime = (int)$matches[1];
|
|
}
|
|
return $cacheTime;
|
|
}
|
|
|
|
/**
|
|
* get a unique cache kay for a request
|
|
* @param $url
|
|
* @param null $options
|
|
* @return string
|
|
*/
|
|
protected function getCacheKey($url, $options = null){
|
|
$f3 = \Base::instance();
|
|
|
|
$headers = isset($options['header']) ? implode($this->eol, (array) $options['header']) : '';
|
|
|
|
return $f3->hash(
|
|
$options['method'] . ' '
|
|
. $url . ' '
|
|
. $headers
|
|
) . 'url';
|
|
}
|
|
|
|
/**
|
|
* perform curl() request
|
|
* -> caches response by returned HTTP Cache header data
|
|
* @param string $url
|
|
* @param array|null $options
|
|
* @param array $additionalOptions
|
|
* @param int $retryCount request counter for failed crest call
|
|
* @return array|FALSE|mixed
|
|
*/
|
|
public function request($url,array $options = null, $additionalOptions = [], $retryCount = 0 ) {
|
|
$f3 = \Base::instance();
|
|
|
|
if( !$f3->exists( $hash = $this->getCacheKey($url, $options) ) ){
|
|
// retry same request until request limit is reached
|
|
$retry = false;
|
|
|
|
$result = parent::request($url, $options);
|
|
$result['timeout'] = false;
|
|
$statusCode = $this->getStatusCodeFromHeaders( $result['headers'] );
|
|
|
|
switch($statusCode){
|
|
case 100:
|
|
case 200:
|
|
// request succeeded -> check if response should be cached
|
|
$ttl = $this->getCacheTimeFromHeaders( $result['headers'] );
|
|
|
|
if(
|
|
$ttl > 0 &&
|
|
!empty( json_decode( $result['body'], true ) )
|
|
){
|
|
$f3->set($hash, $result, $ttl);
|
|
}
|
|
break;
|
|
case 401:
|
|
case 415:
|
|
// unauthorized
|
|
$errorMsg = $this->getErrorMessageFromJsonResponse(
|
|
$statusCode,
|
|
$options['method'],
|
|
$url,
|
|
json_decode($result['body'])
|
|
);
|
|
LogController::getLogger('ERROR')->write($errorMsg);
|
|
break;
|
|
case 500:
|
|
case 501:
|
|
case 502:
|
|
case 503:
|
|
case 505:
|
|
$retry = true;
|
|
|
|
if( $retryCount == self::RETRY_COUNT_MAX ){
|
|
$errorMsg = $this->getErrorMessageFromJsonResponse(
|
|
$statusCode,
|
|
$options['method'],
|
|
$url,
|
|
json_decode($result['body'])
|
|
);
|
|
LogController::getLogger('ERROR')->write($errorMsg);
|
|
|
|
// trigger error
|
|
$f3->error($statusCode, $errorMsg);
|
|
}
|
|
break;
|
|
case 504:
|
|
case 0:
|
|
$retry = true;
|
|
|
|
if( $retryCount == self::RETRY_COUNT_MAX ){
|
|
// timeout -> response should not be cached
|
|
$result['timeout'] = true;
|
|
|
|
$errorMsg = $this->getErrorMessageFromJsonResponse(
|
|
504,
|
|
$options['method'],
|
|
$url,
|
|
json_decode($result['body'])
|
|
);
|
|
|
|
// log error
|
|
LogController::getLogger('ERROR')->write($errorMsg);
|
|
|
|
if($additionalOptions['suppressTimeoutErrors'] !== true){
|
|
// trigger error
|
|
$f3->error(504, $errorMsg);
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
// unknown status
|
|
$errorMsg = $this->getErrorMessageFromJsonResponse(
|
|
$statusCode,
|
|
$options['method'],
|
|
$url
|
|
);
|
|
|
|
LogController::getLogger('ERROR')->write($errorMsg);
|
|
break;
|
|
}
|
|
|
|
if(
|
|
$retry &&
|
|
$retryCount < self::RETRY_COUNT_MAX
|
|
){
|
|
$retryCount++;
|
|
$this->request($url, $options, $additionalOptions, $retryCount);
|
|
}
|
|
|
|
}else{
|
|
$result = $f3->get($hash);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* get error message from response object
|
|
* @param int $code
|
|
* @param string $method
|
|
* @param string $url
|
|
* @param null|\stdClass $responseBody
|
|
* @return string
|
|
*/
|
|
protected function getErrorMessageFromJsonResponse($code, $method, $url, $responseBody = null){
|
|
if( empty($responseBody->message) ){
|
|
$message = @constant('Base::HTTP_' . $code);
|
|
}else{
|
|
$message = $responseBody->message;
|
|
}
|
|
|
|
$body = '';
|
|
if( !is_null($responseBody) ){
|
|
$body = ' | body: ' . print_r($responseBody, true);
|
|
}
|
|
|
|
return sprintf(self::ERROR_STATUS_LOG, $code, $message, $method, $url, $body);
|
|
}
|
|
|
|
} |