Skip to content
Snippets Groups Projects
Commit e59a092b authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

Merge branch '7512-php83-update' into 'master'

Php 8.3 update

See merge request !4
parents 919602f7 faa3e562
No related branches found
No related tags found
1 merge request!4Php 8.3 update
# ======================================================================
#
# GENERATED BY init.sh - template: ./templates/dot_env - e2cde05722688ff85d3a93e9cd55787e
# GENERATED BY init.sh - template: templates/dot_env - e2cde05722688ff85d3a93e9cd55787e
# values to be used in docker-composer.yml
#
# ======================================================================
......
#
# GENERATED BY init.sh - template: ./templates/web-server-Dockerfile - 42dce773c83597a7d05af398bdd66d15
# GENERATED BY init.sh - template: templates/web-server-Dockerfile - 42dce773c83597a7d05af398bdd66d15
#
FROM php:8.2-apache
FROM php:8.3-apache
# install packages
RUN apt-get update && apt-get install -y git unzip zip
......
#
# GENERATED BY init.sh - template: ./templates/vhost_app.conf - 50f337db404bc73530e3340a8f2f1af9
# GENERATED BY init.sh - template: templates/vhost_app.conf - 50f337db404bc73530e3340a8f2f1af9
#
<VirtualHost *:80>
DocumentRoot /var/www/my_new_app/public_html
......
;
; GENERATED BY init.sh - template: ./templates/extra-php-config.ini - 9dce36d285d5b21d70e015c074c196c2
; GENERATED BY init.sh - template: templates/extra-php-config.ini - 9dce36d285d5b21d70e015c074c196c2
;
[PHP]
......
#
# GENERATED BY init.sh - template: ./templates/docker-compose.yml - fc2f1d55926abdb9c54f65afd0571d7b
# GENERATED BY init.sh - template: templates/docker-compose.yml - fc2f1d55926abdb9c54f65afd0571d7b
#
# ======================================================================
#
......@@ -19,7 +19,7 @@ services:
build:
context: .
dockerfile: ./containers/web-server/Dockerfile
image: "php:8.2-apache"
image: "php:8.3-apache"
container_name: 'my_new_app-server'
ports:
- '${APP_PORT}:80'
......
This diff is collapsed.
......@@ -17,7 +17,7 @@ APP_APT_PACKAGES="git unzip zip"
#APP_APACHE_MODULES="rewrite"
APP_APACHE_MODULES=""
APP_PHP_VERSION=8.2
APP_PHP_VERSION=8.3
# APP_PHP_MODULES="curl pdo_mysql mbstring xml zip xdebug"
# APP_PHP_MODULES="curl mbstring xml zip xdebug"
APP_PHP_MODULES="xdebug"
......
## Requirements
* PHP 7+ (up to PHP 8.2)
* PHP 8 (up to PHP 8.3)
* Webserver (docs describe usage for Apache httpd)
## Features
......
......@@ -18,6 +18,7 @@ require_once 'redirect.class.php';
* 2022-05-23 v1.6 ah add http head check+render output;
* 2022-05-31 v1.7 ah optical changes
* 2023-08-28 v1.8 ah remove php warning if there is no config yet
* 2024-10-03 v1.9 ah php8 only: typed variables
*/
/**
......@@ -25,37 +26,44 @@ require_once 'redirect.class.php';
*
* @author axel
*/
class redirectadmin extends redirect {
class redirectadmin extends redirect
{
protected function _getCurlOptions(){
$aReturn=array(
/**
* Get default curl options
* @return array
*/
protected function _getCurlOptions(): array
{
$aReturn = [
CURLOPT_HEADER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERAGENT => strip_tags($this->sAbout),
CURLOPT_VERBOSE => false,
CURLOPT_ENCODING => 'gzip, deflate', // to fetch encoding
CURLOPT_HTTPHEADER => array(
CURLOPT_HTTPHEADER => [
'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language: en',
'DNT: 1',
),
],
// TODO: this is unsafe .. better: let the user configure it
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_TIMEOUT => 5,
);
];
return $aReturn;
}
/**
* make a single http(s) get request and return the response body
* Make a single http(s) get request and return the response body
* @param string $url url to fetch
* @param boolean $bHeaderOnly optional: true=make HEAD request; default: false (=GET)
* @return string
*/
public function httpGet($url, $bHeaderOnly = false) {
public function httpGet(string $url, bool $bHeaderOnly = false): bool|string
{
$ch = curl_init($url);
foreach ($this->_getCurlOptions() as $sCurlOption => $sCurlValue) {
curl_setopt($ch, $sCurlOption, $sCurlValue);
......@@ -69,7 +77,14 @@ class redirectadmin extends redirect {
return ($res);
}
public function renderHttpResponseHeader($sHeader){
/**
* Get html code for a response header of a request
*
* @param string $sHeader
* @return string
*/
public function renderHttpResponseHeader(string $sHeader): string
{
$sReturn = $sHeader;
if (!$sReturn) {
$sReturn = '<pre><span class="status status-error">Request failed. </span><br>'
......@@ -111,40 +126,45 @@ class redirectadmin extends redirect {
}
/**
* check if admin is enabled
* Check if admin is enabled
*
* @return bool
*/
public function isEnabled(){
public function isEnabled(): bool
{
$sFile2Enable = __DIR__ . '/' . basename(__FILE__) . '_enabled.txt';
return file_exists($sFile2Enable);
}
/**
* get ip address of a given hostname as ip (string) or false
* Get ip address of a given hostname as ip (string) or false
* @return string|bool
*/
protected function _getIp($sHostname){
protected function _getIp(string $sHostname): string
{
$sIp = gethostbyname($sHostname);
return $sIp===$sHostname ? false : $sIp;
return $sIp === $sHostname ? '' : $sIp;
}
/**
* get an array with all config entries in all json files
* Get an array with all config entries in all json files
* including some error checking
*
* @return array
*/
public function getHosts(){
$aReturn = array();
$aErrors = array();
public function getHosts(): array
{
$aReturn = [];
$aErrors = [];
foreach (glob($this->sConfigDir . '/redirects_*.json') as $sFilename) {
$sMyHost= str_replace(array('redirects_', '.json'), array('',''), basename($sFilename));
$aReturn[$sMyHost]=array(
$sMyHost = str_replace(['redirects_', '.json'], ['', ''], basename($sFilename));
$aReturn[$sMyHost] = [
'type' => 'config',
'file' => $sFilename,
'ip' => $this->_getIp($sMyHost),
'aliases'=>array(),
'aliases' => [],
'redirects' => json_decode(file_get_contents($sFilename), 1),
);
];
if (!$aReturn[$sMyHost]['ip']) {
$aErrors[] = basename($sFilename) . ': The hostname was not found in DNS: ' . $sMyHost;
}
......@@ -159,11 +179,11 @@ class redirectadmin extends redirect {
$aErrors[] = "alias.json: [$sAlias] points to a non existing host [$sConfig] - a file redirects_$sConfig.yml does not exist.";
} else {
$aReturn[$sConfig]['aliases'][] = $sAlias;
$aReturn[$sAlias]=array(
$aReturn[$sAlias] = [
'type' => 'alias',
'target' => $sConfig,
'ip' => $this->_getIp($sAlias),
);
];
if (!$aReturn[$sAlias]['ip']) {
$aErrors[] = 'alias.json: The hostname was not found in DNS: ' . $sAlias;
}
......@@ -176,6 +196,5 @@ class redirectadmin extends redirect {
return $aReturn;
}
}
......@@ -24,6 +24,7 @@
* 2020-05-06 v1.3 ah added aliases for multiple domains with the same config
* 2020-05-06 v1.4 ah rewrite as class
* 2023-08-28 v1.5 ah fix loop over config with missing regex section.
* 2024-10-03 v1.6 ah php8 only: typed variables
*/
/**
......@@ -31,30 +32,85 @@
*
* @author axel
*/
class redirect {
class redirect
{
// ----------------------------------------------------------------------
// CONFIG
// ----------------------------------------------------------------------
protected $bDebug = false;
protected $sConfigDir = __DIR__ . '/../../config';
protected $sAbout = 'IML redirect <small>v1.4</small>';
/**
* Flag: debug is enabled?
* @var bool
*/
protected bool $bDebug = false;
/**
* configuration dir
* @var string
*/
protected string $sConfigDir = __DIR__ . '/../../config';
/**
* About message
* @var string
*/
protected string $sAbout = 'IML redirect <small>v1.4</small>';
protected $sHostname = false;
protected $sRequest = false;
/**
* Hostname
* @var string
*/
protected string $sHostname = '';
protected $sCfgfile = false;
protected $aConfig = false;
protected $aRedirect = false;
/**
* Request to handle and to redirect to aconfigured target url
* @var string
*/
protected string $sRequest = '';
public $urlRepo='https://git-repo.iml.unibe.ch/iml-open-source/redirect-handler';
public $urlDocs='https://os-docs.iml.unibe.ch/redirect-handler/';
/**
* Config file
* @var
*/
protected string $sCfgfile = '';
/**
* Config data for the current hostname
* @var
*/
protected array $aConfig = [];
/**
* Redirect data for the current request
* @var array
*/
protected array $aRedirect = [];
/**
* URL to the repository of this project
* @var string
*/
public string $urlRepo = 'https://git-repo.iml.unibe.ch/iml-open-source/redirect-handler';
/**
* Url to the docs
* @var string
*/
public string $urlDocs = 'https://os-docs.iml.unibe.ch/redirect-handler/';
// ----------------------------------------------------------------------
// CONSTRUCTOR
// ----------------------------------------------------------------------
public function __constructor($sHostname=false, $sRequest=false) {
/**
* Constructor
* @param string $sHostname hostname
* @param string $sRequest request to proces
* @return void
*/
public function __constructor(string $sHostname = '', string $sRequest = '')
{
if ($sHostname) {
$this->setHost($sHostname);
}
......@@ -62,7 +118,6 @@ class redirect {
$this->setRequest($sRequest);
}
return true;
}
......@@ -71,43 +126,59 @@ class redirect {
// ----------------------------------------------------------------------
/**
* write a debug message into the header
* Write a debug message into the http response header
*
* @global boolean $bDebug flag: show debug infos?
* @staticvar int $i counter
*
* @param string $sDebugMessage message to show
* @return boolean
*/
protected function _wd($sDebugMessage) {
protected function _wd(string $sDebugMessage): bool
{
if (!$this->bDebug) {
return false;
}
static $i;
$i++;
header('X-DEBUG-' . $i . ': ' . $sDebugMessage);
header("X-DEBUG-$i: $sDebugMessage");
return true;
}
// ----------------------------------------------------------------------
// SET INTERNAL VARS
// ----------------------------------------------------------------------
/**
* get a string with full path of a config file with aliases
* Get a string with full path of a config file with aliases
* @return string
*/
protected function _generateAliasfile() {
protected function _generateAliasfile(): string
{
return $this->sConfigDir . '/aliases.json';
}
/**
* get a string with full path of a config file based on hostname
* @param string $sHostname
* Get a string with full path of a config file based on hostname
*
* @param string $sHostname hostname/ fqdn
* @return string
*/
protected function _generateCfgfile($sHostname) {
protected function _generateCfgfile(string $sHostname): string
{
return $this->sConfigDir . '/redirects_' . $sHostname . '.json';
}
protected function _getAliases(){
/**
* Get Aliases from aliases.json
* It returns false if no alias was found
*
* @return bool|array
*/
protected function _getAliases(): bool|array
{
$sAliasfile = $this->_generateAliasfile();
$this->_wd('check alias file ' . $sAliasfile);
if (!file_exists($sAliasfile)) {
......@@ -120,34 +191,36 @@ class redirect {
}
/**
* get an array with redirect config based on a given hostname
* @param string $sHostname hostname
* @param boolean $bAbort flag: true = do not scan aliases (used for loop detection)
* @return array
* Get an array with redirect config based on a given hostname.
* @return bool
*/
protected function _getConfig() {
$this->aConfig=false;
$this->aRedirect=false;
protected function _getConfig(): bool
{
$this->aConfig = [];
$this->aRedirect = [];
$this->_getEffectiveConfigfile();
if ($this->sCfgfile) {
$aConfig = json_decode(file_get_contents($this->sCfgfile), 1);
if (!is_array($aConfig) || !count($aConfig)) {
$this->_wd('no config available');
// $this->sendBody(500, '<h1>Internal Server Error</h1>Errorcode 02');
}
} else {
$this->aConfig = $aConfig;
}
}
return true;
}
/**
* get an array with redirect config based on a given hostname
* Get filename of config file based on a given hostname
* or detection in the alias config
*
* @param string $sHostname hostname
* @param boolean $bAbort flag: true = do not scan aliases (used for loop detection)
* @return array
* @return bool|string
*/
protected function _getEffectiveConfigfile($sHostname=false, $bAbort=false) {
protected function _getEffectiveConfigfile(string $sHostname = '', bool $bAbort = false): bool|string
{
if (!$sHostname) {
$sHostname = $this->sHostname;
}
......@@ -176,31 +249,34 @@ class redirect {
/**
* enable/ disable debug
* Enable/ disable debug
* @param boolean $bEnable
*/
public function setDebug($bEnable){
public function setDebug(bool $bEnable): bool
{
$this->bDebug = !!$bEnable;
return true;
}
/**
* set hostname; internally it detects the config too
* @param type $sHostname
* Set hostname; internally it detects the config too
* @param string $sHostname
* @return boolean
*/
public function setHost($sHostname){
public function setHost(string $sHostname): bool
{
$this->sHostname = $sHostname;
$this->_getConfig();
return true;
}
/**
* set the request
* @param type $sRequest
* Set the request
* @param string $sRequest
* @return boolean
*/
public function setRequest($sRequest){
public function setRequest(string $sRequest): bool
{
$this->sRequest = $sRequest;
$this->aRedirect = false;
return true;
......@@ -211,16 +287,18 @@ class redirect {
// ----------------------------------------------------------------------
/**
* get an array with the matching redirect; it returns false if none was
* Get an array with the matching redirect; it returns false if none was
* detected
*
* @return array
*/
public function getRedirect(){
public function getRedirect(): array
{
if (is_array($this->aRedirect)) {
return $this->aRedirect;
}
$aRedirect = false;
$aRedirect = [];
// remark:
// $this->aConfig is set in setHost() with $this->_getConfig();
......@@ -245,17 +323,28 @@ class redirect {
return $aRedirect;
}
public function getRedirectCode($iNone=false){
/**
* Get 30x redirect code
* @param integer $iNone fallback value if no redirect status code was found
* @return integer
*/
public function getRedirectCode($iNone = 307): int
{
$aRedirect = $this->getRedirect();
return isset($aRedirect['code']) ? $aRedirect['code'] : $iNone;
}
public function getRedirectTarget(){
/**
* Get Target url of redirect
* @return string
*/
public function getRedirectTarget(): string
{
$aRedirect = $this->getRedirect();
return isset($aRedirect['target']) ? $aRedirect['target'] : false;
return $aRedirect['target'] ?? '';
}
// ----------------------------------------------------------------------
// FUNCTIONS - SEND DATA
// ----------------------------------------------------------------------
......@@ -264,14 +353,15 @@ class redirect {
* make the redirect if it was found ... or a 404
* @return true
*/
public function makeRedirect(){
public function makeRedirect(): bool
{
$sTarget = $this->getRedirectTarget();
if (!$sTarget) {
$this->_wd('send a not found');
$this->sendBody(404, '<h1>404 Not found</h1>');
} else {
$iCode = $this->getRedirectCode();
$this->_wd("Redirect with http status [" . $iCode . "] to new Location: " . $sTarget);
$this->_wd("Redirect with http status [$iCode] to new Location: $sTarget");
$this->sendHttpStatusheader($iCode);
header("Location: " . $sTarget);
}
......@@ -283,8 +373,9 @@ class redirect {
* @param integer $iCode http code
* @return boolean
*/
public function sendHttpStatusheader($iCode) {
$aHeaders = array(
public function sendHttpStatusheader(int $iCode): bool
{
$aHeaders = [
301 => 'Moved Permanently',
302 => 'Found', // (Moved Temporarily)
303 => 'See other', // redirect with GET
......@@ -293,7 +384,7 @@ class redirect {
404 => 'Not found',
410 => 'Gone',
500 => 'Internal Server Error',
);
];
$iCode = (int) $iCode;
if (!isset($aHeaders[$iCode])) {
......@@ -308,9 +399,11 @@ class redirect {
* @see sendHttpStatusheader()
*
* @param integer $iCode http status code
* @param stringg $sBody message text as html code
* @param string $sBody message text as html code
* @return void
*/
public function sendBody($iCode, $sBody) {
public function sendBody(int $iCode, string $sBody): void
{
$this->sendHttpStatusheader($iCode);
die('<!doctype html><html><head>'
. '<title>Redirect</title>'
......@@ -330,6 +423,5 @@ class redirect {
);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment