Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to set response headers on error pages #39

Merged
merged 4 commits into from
Dec 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 53 additions & 19 deletions kernel/error/view.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
$extraErrorParameters = $Params['ExtraParameters'];
$httpErrorCode = null;
$httpErrorName = null;
$Result = array();

$tpl->setVariable( 'parameters', $extraErrorParameters );

Expand Down Expand Up @@ -56,39 +57,53 @@

if ( $errorHandlerType != 'redirect' )
{
// Set apache error headers if error.ini tells us to
// Set response headers if error.ini tells us to
// $errorType is 'kernel' or 'shop'
if ( $errorINI->hasVariable( 'ErrorSettings-' . $errorType, 'HTTPError' ) )
{
$errorMap = $errorINI->variable( 'ErrorSettings-' . $errorType, 'HTTPError' );
if ( isset( $errorMap[$errorNumber] ) )
{
$httpErrorCode = $errorMap[$errorNumber];
if ( $errorINI->hasVariable( 'HTTPError-' . $httpErrorCode, 'HTTPName' ) )

$headers = kernelErrorGetHeaderList( $errorINI, $httpErrorCode );

if( !empty( $headers ) )
{
$httpErrorName = $errorINI->variable( 'HTTPError-' . $httpErrorCode, 'HTTPName' );
$httpErrorString = "$httpErrorCode $httpErrorName";
foreach( $headers as $name => $value )
{
// store header on $Result to get it into the content cache
$Result['responseHeaders'][] = $name . ': '. $value;

// Copy 'Status' header to a protocol header
// TODO: should use http_response_code()
if( $name == 'Status' )
{
$Result['responseHeaders'][] =
eZSys::serverVariable( 'SERVER_PROTOCOL' ) . " $httpErrorCode $value";
}
}

// apply header
foreach( $Result['responseHeaders'] as $header )
{
header( $header );
}

// This is triggered if the URL alias translator wants to redirect
// to another URL
// Not sure why it's wrapped in $errorINI->hasVariable( 'HTTPError-'...
if ( $errorNumber == eZError::KERNEL_MOVED )
{
$module->redirectTo( $extraErrorParameters['new_location'] );
$module->setRedirectStatus( $httpErrorString );
return array(); // $Result of this view
}
else
{
// we need to store the header so that they are listed in view cache data ()
$responseHeaders = array(
eZSys::serverVariable( 'SERVER_PROTOCOL' ) . " $httpErrorString",
"Status: $httpErrorString"
);
header( $responseHeaders[0] );
header( $responseHeaders[1] );
}
}
}
}
}

eZDebug::writeError( "Error ocurred using URI: " . $_SERVER['REQUEST_URI'] , "error/view.php" );
eZDebug::writeError( "Error occurred using URI: " . $_SERVER['REQUEST_URI'] , "error/view.php" );

if ( $errorHandlerType == 'redirect' )
{
Expand Down Expand Up @@ -179,7 +194,6 @@
$res = eZTemplateDesignResource::instance();
$res->setKeys( array( array( 'error_type', $errorType ), array( 'error_number', $errorNumber ) ) );

$Result = array();
$Result['content'] = $tpl->fetch( "design:error/$errorType/$errorNumber.tpl" );
$Result['path'] = array( array( 'text' => ezpI18n::tr( 'kernel/error', 'Error' ),
'url' => false ),
Expand All @@ -190,5 +204,25 @@
$Result['errorType'] = $errorType;
$Result['errorNumber'] = $errorNumber;

if ( isset( $responseHeaders ) )
$Result['responseHeaders'] = $responseHeaders;
/**
* @param eZINI $errorINI
* @param string $httpErrorCode
* @return array
*/
function kernelErrorGetHeaderList( $errorINI, $httpErrorCode )
{
$return = array();

if( $errorINI->hasVariable( 'HTTPError-' . $httpErrorCode, 'HeaderList' ) )
{
$return = $errorINI->variable( 'HTTPError-' . $httpErrorCode, 'HeaderList' );
}

// Make code backwards compatible - "HTTPName" is deprecated
if( $errorINI->hasVariable( 'HTTPError-' . $httpErrorCode, 'HTTPName' ) )
{
$return[ 'Status' ] = $errorINI->variable( 'HTTPError-' . $httpErrorCode, 'HTTPName' );
}

return $return;
}
19 changes: 13 additions & 6 deletions settings/error.ini
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,26 @@ HTTPError[1]=404
# Definition for the HTTP error code 404.
# It's possible to specify more error codes by creating a group called
# HTTPError followed by a - (dash) and the HTTP error code.
# The group most contain the HTTPName variable, if not the error code
# is not issued to the browser.
# Note: The HTTPName must be contain the correct string for the
# The HeaderList variable is a map of response header name to header value.
# The 'Status' header is special because it's also setting the response
# content.
#
# Note: The Status header must be contain the correct string for the
# specific HTTP error code.
[HTTPError-404]
HTTPName=Not Found
HeaderList[]
HeaderList[Status]=Not Found
HeaderList[Cache-Control]=public, must-revalidate, max-age=300

# Definition of the HTTP error code 301
# URL moved permanently
[HTTPError-301]
HTTPName=Moved Permanently
HeaderList[]
HeaderList[Status]=Moved Permanently
HeaderList[Cache-Control]=public, must-revalidate, max-age=300

# Definition of the HTTP error code 401
# Authorization Required
[HTTPError-401]
HTTPName=Authorization Required
HeaderList[]
HeaderList[Status]=Authorization Required