From 817163a1bcff02285f763bcf72ff02e86f218cf8 Mon Sep 17 00:00:00 2001 From: Derek Jones Date: Sat, 11 Jul 2009 17:05:58 +0000 Subject: Modified show_error() to allow sending of HTTP server response codes. Added set_status_header() to the Common functions to allow use when the Output class is unavailable. Fixed a bug where the 400 status header sent with the 'disallowed URI characters' was not compatible with CGI environments. --- system/codeigniter/Common.php | 89 +++++++++++++++++++++++++++++++- system/libraries/Exceptions.php | 4 +- system/libraries/Output.php | 75 ++------------------------- system/libraries/URI.php | 3 +- user_guide/changelog.html | 7 +++ user_guide/general/common_functions.html | 17 ++++++ user_guide/general/errors.html | 3 +- user_guide/libraries/output.html | 2 +- 8 files changed, 121 insertions(+), 79 deletions(-) diff --git a/system/codeigniter/Common.php b/system/codeigniter/Common.php index c7f95688f..340be2454 100644 --- a/system/codeigniter/Common.php +++ b/system/codeigniter/Common.php @@ -203,10 +203,10 @@ function config_item($item) * @access public * @return void */ -function show_error($message) +function show_error($message, $status_code = 500) { $error =& load_class('Exceptions'); - echo $error->show_error('An Error Was Encountered', $message); + echo $error->show_error('An Error Was Encountered', $message, 'error_general', $status_code); exit; } @@ -252,6 +252,91 @@ function log_message($level = 'error', $message, $php_error = FALSE) $LOG->write_log($level, $message, $php_error); } + +/** + * Set HTTP Status Header + * + * @access public + * @param int the status code + * @param string + * @return void + */ +function set_status_header($code = 200, $text = '') +{ + $stati = array( + 200 => 'OK', + 201 => 'Created', + 202 => 'Accepted', + 203 => 'Non-Authoritative Information', + 204 => 'No Content', + 205 => 'Reset Content', + 206 => 'Partial Content', + + 300 => 'Multiple Choices', + 301 => 'Moved Permanently', + 302 => 'Found', + 304 => 'Not Modified', + 305 => 'Use Proxy', + 307 => 'Temporary Redirect', + + 400 => 'Bad Request', + 401 => 'Unauthorized', + 403 => 'Forbidden', + 404 => 'Not Found', + 405 => 'Method Not Allowed', + 406 => 'Not Acceptable', + 407 => 'Proxy Authentication Required', + 408 => 'Request Timeout', + 409 => 'Conflict', + 410 => 'Gone', + 411 => 'Length Required', + 412 => 'Precondition Failed', + 413 => 'Request Entity Too Large', + 414 => 'Request-URI Too Long', + 415 => 'Unsupported Media Type', + 416 => 'Requested Range Not Satisfiable', + 417 => 'Expectation Failed', + + 500 => 'Internal Server Error', + 501 => 'Not Implemented', + 502 => 'Bad Gateway', + 503 => 'Service Unavailable', + 504 => 'Gateway Timeout', + 505 => 'HTTP Version Not Supported' + ); + + if ($code == '' OR ! is_numeric($code)) + { + show_error('Status codes must be numeric', 500); + } + + if (isset($stati[$code]) AND $text == '') + { + $text = $stati[$code]; + } + + if ($text == '') + { + show_error('No status text available. Please check your status code number or supply your own message text.', 500); + } + + $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE; + + if (substr(php_sapi_name(), 0, 3) == 'cgi') + { + header("Status: {$code} {$text}", TRUE); + } + elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0') + { + header($server_protocol." {$code} {$text}", TRUE, $code); + } + else + { + header("HTTP/1.1 {$code} {$text}", TRUE, $code); + } +} + + /** * Exception Handler * diff --git a/system/libraries/Exceptions.php b/system/libraries/Exceptions.php index 902b574fc..1f99d01c3 100644 --- a/system/libraries/Exceptions.php +++ b/system/libraries/Exceptions.php @@ -113,8 +113,10 @@ class CI_Exceptions { * @param string the template name * @return string */ - function show_error($heading, $message, $template = 'error_general') + function show_error($heading, $message, $template = 'error_general', $status_code = 500) { + set_status_header($status_code); + $message = '

'.implode('

', ( ! is_array($message)) ? array($message) : $message).'

'; if (ob_get_level() > $this->ob_level + 1) diff --git a/system/libraries/Output.php b/system/libraries/Output.php index 6bfb9c7eb..4423ac726 100644 --- a/system/libraries/Output.php +++ b/system/libraries/Output.php @@ -116,7 +116,8 @@ class CI_Output { /** * Set HTTP Status Header - * + * moved to Common procedural functions in 1.7.2 + * * @access public * @param int the status code * @param string @@ -124,77 +125,7 @@ class CI_Output { */ function set_status_header($code = '200', $text = '') { - $stati = array( - '200' => 'OK', - '201' => 'Created', - '202' => 'Accepted', - '203' => 'Non-Authoritative Information', - '204' => 'No Content', - '205' => 'Reset Content', - '206' => 'Partial Content', - - '300' => 'Multiple Choices', - '301' => 'Moved Permanently', - '302' => 'Found', - '304' => 'Not Modified', - '305' => 'Use Proxy', - '307' => 'Temporary Redirect', - - '400' => 'Bad Request', - '401' => 'Unauthorized', - '403' => 'Forbidden', - '404' => 'Not Found', - '405' => 'Method Not Allowed', - '406' => 'Not Acceptable', - '407' => 'Proxy Authentication Required', - '408' => 'Request Timeout', - '409' => 'Conflict', - '410' => 'Gone', - '411' => 'Length Required', - '412' => 'Precondition Failed', - '413' => 'Request Entity Too Large', - '414' => 'Request-URI Too Long', - '415' => 'Unsupported Media Type', - '416' => 'Requested Range Not Satisfiable', - '417' => 'Expectation Failed', - - '500' => 'Internal Server Error', - '501' => 'Not Implemented', - '502' => 'Bad Gateway', - '503' => 'Service Unavailable', - '504' => 'Gateway Timeout', - '505' => 'HTTP Version Not Supported' - ); - - if ($code == '' OR ! is_numeric($code)) - { - show_error('Status codes must be numeric'); - } - - if (isset($stati[$code]) AND $text == '') - { - $text = $stati[$code]; - } - - if ($text == '') - { - show_error('No status text available. Please check your status code number or supply your own message text.'); - } - - $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE; - - if (substr(php_sapi_name(), 0, 3) == 'cgi') - { - header("Status: {$code} {$text}", TRUE); - } - elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0') - { - header($server_protocol." {$code} {$text}", TRUE, $code); - } - else - { - header("HTTP/1.1 {$code} {$text}", TRUE, $code); - } + set_status_header($code, $text); } // -------------------------------------------------------------------- diff --git a/system/libraries/URI.php b/system/libraries/URI.php index f09a5cd7c..efc7a18b3 100644 --- a/system/libraries/URI.php +++ b/system/libraries/URI.php @@ -188,8 +188,7 @@ class CI_URI { { if ( ! preg_match("|^[".preg_quote($this->config->item('permitted_uri_chars'))."]+$|i", $str)) { - header('HTTP/1.1 400 Bad Request'); - show_error('The URI you submitted has disallowed characters.'); + show_error('The URI you submitted has disallowed characters.', 400); } } diff --git a/user_guide/changelog.html b/user_guide/changelog.html index 323467b6e..e4199cd35 100644 --- a/user_guide/changelog.html +++ b/user_guide/changelog.html @@ -85,6 +85,12 @@ SVN Revision:

  • Modified directory_map() in the Directory helper to allow the inclusion of hidden files.
  • +
  • General + +
  • Bug fixes for 1.7.2

    @@ -102,6 +108,7 @@ SVN Revision:

  • Fixed a case sensitive string replacement in xss_clean()
  • Fixed a bug in form_prep() causing it to not preserve entities in the user's original input when called back into a form element
  • Fixed a bug in _protect_identifiers() where the swap prefix ($swap_pre) was not being observed.
  • +
  • Fixed a bug where the 400 status header sent with the 'disallowed URI characters' was not compatible with CGI environments.
  • Version 1.7.1

    diff --git a/user_guide/general/common_functions.html b/user_guide/general/common_functions.html index df5dfea6e..980a5a969 100644 --- a/user_guide/general/common_functions.html +++ b/user_guide/general/common_functions.html @@ -58,8 +58,11 @@ Auto-loading Resources

    Common Functions

    CodeIgniter uses a few functions for its operation that are globally defined, and are available to you at any point. These do not require loading any libraries or helpers.

    +

    is_really_writable('path/to/file')

    +

    is_writable() returns TRUE on Windows servers when you really can't write to the file as the OS reports to PHP as FALSE only if the read-only attribute is marked. This function determines if a file is actually writable by attempting to write to it first. Generally only recommended on platforms where this information may be unreliable.

    + if (is_really_writable('file.txt'))
    {
        echo "I could write to this if I wanted to";
    @@ -68,11 +71,25 @@ else
    {
        echo "File is not writable";
    }
    +

    config_item('item_key')

    The Config library is the preferred way of accessing configuration information, however config_item() can be used to retrieve single keys. See Config library documentation for more information.

    +

    show_error('message'), show_404('page'), log_message('level', 'message')

    These are each outlined on the Error Handling page.

    + +

    set_status_header(code, 'text');

    + +

    Permits you to manually set a server status header. Example:

    + +set_status_header(401);
    +// Sets the header as: Unauthorized
    + +

    See here for a full list of headers.

    + + + diff --git a/user_guide/general/errors.html b/user_guide/general/errors.html index c1bb69119..af1184593 100644 --- a/user_guide/general/errors.html +++ b/user_guide/general/errors.html @@ -71,9 +71,10 @@ about class/function scoping.

    The following functions let you generate errors:

    -

    show_error('message')

    +

    show_error('message' [, int $status_code= 500 ] )

    This function will display the error message supplied to it using the following error template:

    application/errors/error_general.php

    +

    The optional parameter $status_code determines what HTTP status code should be sent with the error.

    show_404('page')

    This function will display the 404 error message supplied to it using the following error template:

    diff --git a/user_guide/libraries/output.html b/user_guide/libraries/output.html index 6d75fe7b2..ba6a0d333 100644 --- a/user_guide/libraries/output.html +++ b/user_guide/libraries/output.html @@ -100,7 +100,7 @@ $this->output->set_header("Cache-Control: post-check=0, pre-check=0");
    $this->output->set_header("Pragma: no-cache"); -

    $this->output->set_status_header();

    +

    $this->output->set_status_header(code, 'text');

    Permits you to manually set a server status header. Example:

    -- cgit v1.2.3-24-g4f1b