You Are Here : /var/www/virtual/tvarditsa.org/classes/ |
Current File : /var/www/virtual/tvarditsa.org/classes/httpresponse.class.php |
<?php /** * VSite Framework for PHP * * This product includes PHP, freely available from * <{@link http://www.php.net/ http://www.php.net/}> * * @package VSite_Framework * @subpackage HTTP * @copyright Copyright (c) 2003-2004, Valentin Sheiretsky * @license http://www.vsite.org/license.txt BSD-style license */ if (!defined("_VSITE_HTTP_RESPONSE_CLASS_")) { /** * @ignore */ define("_VSITE_HTTP_RESPONSE_CLASS_", 1); if (!defined("_VSITECONF_CLASS_")) include (dirname(__FILE__) . '/vsiteconf.class.php'); /** * Encapsulates HTTP response information * * @version 1.0.2 * @author Valentin Sheiretsky <valio@vsite.org> * @package VSite_Framework */ class httpResponse { /**#@+ * @access private */ var $_cfg = null; var $_cfg_httpResponse = array ( 'show_errors' => TRUE, 'http_version' => '1.1', 'default_mimetype' => 'text/html', 'default_charset' => NULL, ); var $_status_code = 200; var $_status_codes = array ( 100 => "Continue", 101 => "Switching Protocols", 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", 303 => "See Other", 304 => "Not Modified", 305 => "Use Proxy", 307 => "Temporary Redirect", 400 => "Bad Request", 401 => "Unauthorized", 402 => "Payment Required", 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", ); var $_charset = NULL; var $_mime_type = NULL; var $_output_buffering = FALSE; var $_output_handlers = array(); var $_compression = 0; // 0 = no compression, -1 = unknown level var $_compression_handler = NULL; var $_zlib_compression = FALSE; var $_implicit_flush = NULL; var $_uri_regexp = "|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|"; var $_last_error_no = 0; var $_last_error_msg = ''; var $_last_error_line = 0; var $_last_error_file = ''; var $_errors = array( 0 => 'no error', 1 => 'cannot add header information - headers already sent', 2 => 'failed to open stream: No such file or directory', 3 => 'supplied argument is not a valid stream resource', 4 => 'output is already compressed', 5 => 'invalid call back function', 6 => 'this callback is already set', 7 => 'cannot compress output', ); var $_header_error = "Cannot add header information - headers already sent"; /**#@-*/ /** * Constructor */ function __construct($cfname = 'httpresponse') { $c = new VsiteConf(); $this->_cfg = $c->join_conf ($this->_cfg, $this->_cfg_httpResponse); $this->_cfg = $c->read_conf ($cfname, $this->_cfg); $this->_mime_type = trim(ini_get('default_mimetype')); $this->_charset = trim(ini_get('default_charset')); $this->_charset = trim(ini_get('default_charset')); $this->_output_buffering = (bool)trim(ini_get('output_buffering')); $this->_implicit_flush = trim(ini_get('implicit_flush')); if (function_exists('apache_get_modules')) { $apache_output_handler = FALSE; $apache_modules = apache_get_modules(); if (is_array($apache_modules)) foreach ($apache_modules as $apache_module_name) if (stristr($apache_module_name, 'mod_gzip')) $apache_output_handler = 'mod_gzip'; elseif (stristr($apache_module_name, 'mod_deflate')) $apache_output_handler = 'mod_deflate'; if ($apache_output_handler) { $this->_compression_handler = 'apache_'.$apache_output_handler; $this->_output_handlers[0] = $this->_compression_handler; $this->_compression = -1; } } $zlib_output_compression = trim(ini_get('zlib.output_compression')); if ($zlib_output_compression > 0) { $this->_zlib_compression = TRUE; $this->_compression = intval(ini_get('zlib.output_compression_level')); $this->_compression_handler = 'zlib:'.trim(ini_get('zlib.output_handler')); $this->_output_handlers[] = $this->_compression_handler; $this->_output_buffering = TRUE; } else { $ini_output_handler = trim(ini_get('output_handler')); if ($ini_output_handler != '') { if ($ini_output_handler == 'ob_gzhandler') { $this->_compression_handler = $ini_output_handler; $this->_compression = -1; } $this->_output_handlers[] = $ini_output_handler; } } if ($this->_mime_type == "") $this->ContentType ($this->_cfg['default_mimetype']); if ($this->_charset == "") $this->Charset ($this->_cfg['default_charset']); } /** * @ignore */ function httpResponse ($cfname = 'httpresponse') { $this->__construct($cfname); } /** * Gets or sets a value indicating whether to buffer output * and send it after the entire page is finished processing * * @param boolean output callback function name * @param int compression level */ function BufferOutput ($output_callback = NULL, $compression = 0) { if ($output_callback == NULL) return $this->_output_buffering; $this->_trigger_error(); if (($compression > 0) && ($this->_compression != 0)) { $this->_trigger_error(4, 'BufferOutput', E_USER_WARNING); return FALSE; } if ($output_callback == TRUE) { ob_start (); $this->_output_handlers[] = 'output_buffer'; return $this->_output_buffering = TRUE; } if (!function_exists($output_callback)) { $this->_trigger_error(5, 'BufferOutput', E_USER_WARNING); return FALSE; } $last = end($this->_output_handlers); if (($last != 'output_buffer') && ($last == $output_callback)){ $this->_trigger_error(6, 'BufferOutput', E_USER_WARNING); return FALSE; } ob_start ($output_callback); $this->_output_handlers[] = $output_callback; if ($compression != 0) $this->_compression = $compression; return $this->_output_buffering = TRUE; } /** * Gets or sets a value indicating whether to compress entire output * * @param boolean output callback function name * @param int compression level */ function Compression ($level = NULL) { if ($level == NULL) return $this->_compression; $level = intval($level); if ($level <= 0) return TRUE; if ($level > 9) $level = 9; $this->_trigger_error(); if ($this->_compression != 0) { $this->_trigger_error(4, 'Compression', E_USER_WARNING); return FALSE; } if ( stristr($_SERVER['HTTP_ACCEPT_ENCODING'], 'deflate') && function_exists('gzdeflate') ) { if (!$this->AppendHeader ("Content-Encoding: deflate")) return FALSE; $GLOBALS['response_ob_compress_level'] = $level; $this->_compression = $level; $this->_output_handlers[] = 'ob_responsedeflate'; ob_start("ob_responsedeflate"); return $this->_output_buffering = TRUE; } elseif ( stristr($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') && function_exists('gzencode') ) { if (!$this->AppendHeader ("Content-Encoding: gzip")) return FALSE; if ((float)PHP_VERSION < 4.2) { $GLOBALS['response_ob_compress_level'] = 0; $this->_compression = -1; } else { $GLOBALS['response_ob_compress_level'] = $level; $this->_compression = $level; } $this->_output_handlers[] = 'ob_responsegzip'; ob_start("ob_responsegzip"); return $this->_output_buffering = TRUE; } elseif (function_exists('ob_gzhandler')) { $this->_compression = -1; $this->_output_handlers[] = 'ob_gzhandler'; ob_start('ob_gzhandler'); return $this->_output_buffering = TRUE; } $this->_trigger_error(7, 'Compression', E_USER_WARNING); return FALSE; } /** * Returns compression handler name */ function CompressionHandler () { return $this->_compression_handler; } /** * AppendHeader - Alias * * @param string header */ function AddHeader ($uri) { $this->AppendHeader ($header); } /** * Adds an HTTP header to the output stream * * @param string header */ function AppendHeader ($header) { $this->_trigger_error(); if (!headers_sent($this->_last_error_file, $this->_last_error_line)) { header($header); return TRUE; } $this->_trigger_error(1, 'AppendHeader', E_USER_WARNING); return FALSE; } /** * ClearContent - Alias */ function Clear () { $this->ClearContent(); } /** * Clears all content output from the buffer stream */ function ClearContent () { while (@ob_end_clean()); if (substr($this->_output_handlers[0], 0, 6) == 'apache') { $handler = $this->_output_handlers[0]; $this->_output_handlers = array(); $this->_output_handlers[0] = $handler; return; } $this->_output_handlers = array(); } /** * ClearContent - Alias */ function Flush () { $this->FlushContent(); } /** * Sends all currently buffered output to the client */ function FlushContent () { while (@ob_end_flush()); } /** * Writes information to an HTTP output content stream */ function Write ($content) { print($content); } /** * Writes the specified file directly to an HTTP content output stream */ function WriteFile ($FileName, $StartPos = 0, $FileSize = 0) { $this->_trigger_error(); if (is_string($FileName)) { if (!($FileHandle = @fopen($FileName, 'r'))) { $this->_trigger_error(1, 'WriteFile('.$FileName.')', E_USER_ERROR); return FALSE; } } else { $FileHandle = $FileName; } if (!@rewind ($FileHandle)) { $this->_trigger_error(1, 'WriteFile', E_USER_ERROR); return FALSE; } $BufferLenght = 8192; $BufferCounter = 0; while (!feof($FileHandle)) { $buffer = fread($FileHandle, $BufferLenght); if ($StartPos > 0) { if ($StartPos > $BufferLenght) { $StartPos -= $BufferLenght; continue; } else { $buffer = substr($buffer, $StartPos); $StartPos = 0; $BufferCounter += $BufferLenght - $StartPos; } } else { $BufferCounter += $BufferLenght; } if (($FileSize > 0) && ($BufferCounter > $FileSize)) $buffer = substr($buffer, 0, $BufferLenght + $FileSize - $BufferCounter); $this->Write($buffer); } } /** * Close - Alias */ function End () { $this->Close(); } /** * Sends all currently buffered output to the client and stops execution of the page */ function Close () { $this->FlushContent(); exit(); } /** * Get Status Code * * @return string Status Code */ function StatusCode () { return $this->_status_code; } /** * Get Status Description * * @return string Status Description */ function StatusDescription () { return $this->_status_codes[$this->_status_code]; } /** * Gets or sets the Status line that is returned to the client. * * @param string Status Code */ function Status ($code = NULL) { if ($code == NULL) return $this->StatusCode()." ".$this->StatusDescription (); $code = intval($code); if (!isset($this->_status_codes[$code])) return FALSE; if ($this->_status_code == $code) return TRUE; $this->_status_code = $code; $header = "HTTP/".$this->_cfg['http_version']." ". $code." ".$this->_status_codes[$code]; return $this->AppendHeader($header); } /** * Charset - Alias * * @param string character set */ function ContentEncoding ($charset = NULL) { return $this->Charset($charset); } /** * Gets or sets the HTTP character set of the output stream * * @param string character set */ function Charset ($charset = NULL) { if ($charset == NULL) return $this->_charset; $this->_charset = $charset; $header = "Content-type: ".$this->_mime_type; if (trim($this->_charset) != "") $header .= "; charset=".$this->_charset; return $this->AppendHeader($header); } /** * Gets or sets the HTTP MIME type of the output stream * * @param string MIME type */ function ContentType ($mime_type = NULL) { if ($mime_type == NULL) return $this->_mime_type; $this->_mime_type = $mime_type; $header = "Content-type: ".$this->_mime_type; if (trim($this->_charset) != "") $header .= "; charset=".$this->_charset; return $this->AppendHeader($header); } /** * RedirectLocation - Alias * * @param string URL * @param boolean show error if cannot redirect */ function Redirect ($uri, $show_error = NULL) { $this->RedirectLocation ($uri, $show_error); } /** * Redirect to URL * * @param string URL */ function RedirectLocation ($uri) { $uri = $this->RelativeToAbsoluteUri ($uri); if ($this->AppendHeader('Location: ' . $uri)){ $this->ClearContent (); echo '<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">'."\r\n". '<HTML><HEAD>'."\r\n". '<TITLE>302 Found</TITLE>'."\r\n". '</HEAD><BODY>'."\r\n". '<H1>Found</H1>'."\r\n". 'The document has moved <A HREF="'.$uri.'">here</A>.<P>'."\r\n". '<HR>'."\r\n". $_SERVER["SERVER_SIGNATURE"]."\r\n". '</BODY></HTML>'."\r\n"; $this->Close(); } if (!$this->_cfg['show_errors']) { $this->ClearContent (); echo "\r\n". '<SCR'.'IPT LANGUAGE="JavaScript">'."\r\n". 'window.location="'.$uri.'";'."\r\n". '// -->'."\r\n". '</SCR'.'IPT>'."\r\n"; $this->Close(); } return FALSE; } /** * Set Cookie * * @param string Name of the variable * @param string Value of the variable * @return boolean */ function SetCookies ( $varName, $varValue = NULL, $lifetime = 0, $path = NULL, $domain = NULL ) { $this->_trigger_error(); if (!headers_sent($this->_last_error_file, $this->_last_error_line)) { if (is_string ($varName)) { setcookie($varName, $varValue, $lifetime, $path, $domain); return TRUE; } if (is_array ($varName)) { foreach ($varName as $varNameX => $varValue) setcookie($varNameX, $varValue, $lifetime, $path, $domain); return TRUE; } } $this->_trigger_error(1, 'AppendHeader', E_USER_WARNING); return FALSE; } /** * Convert Relative URI to Absolute URI * * @param string Realtive URI */ function RelativeToAbsoluteUri ($rel_uri) { if (preg_match($this->_uri_regexp,$rel_uri,$uri_parts)) return $rel_uri; if ($rel_uri{0} == '/') { return "http://".$_SERVER['HTTP_HOST'].$rel_uri; } return "http://".$_SERVER['HTTP_HOST']. dirname($_SERVER['PHP_SELF'])."/".$rel_uri; } /** * Returns the text of the last error */ function ErrorMsg() { return $this->_last_error_msg; } /** * Returns the numerical value of the last error */ function ErrorNo() { return $this->_last_error_no; } /** * Trigger Error * * @access private */ function _trigger_error($code = 0, $function = NULL, $type = E_USER_WARNING) { if ($code == 0) { $this->_last_error_no = 0; $this->_last_error_msg = ''; $this->_last_error_line = 0; $this->_last_error_file = ''; return; } if (!isset($this->_errors[$code])) return; $this->_last_error_no = $code; if ($function != '') $ErrMsg = "httpResponse.".$function.": ".$this->_errors[$code]; else $ErrMsg = "httpResponse: ".$this->_errors[$code]; if ($this->_last_error_line > 0) { $ErrMsg .= " by (output started at ". $this->_last_error_file.":".$this->_last_error_line.")"; } $this->_last_error_msg = $ErrMsg; if ($this->_cfg['show_errors']) trigger_error ($ErrMsg, $type); } /** * Destructor */ function __destruct() { $this->Close(); } } /** * gzip compression handler */ function ob_responsegzip($output) { if ($GLOBALS['response_ob_compress_level'] > 0) return gzencode($output, $GLOBALS['response_ob_compress_level']); else return gzencode($output); } /** * deflate compression handler */ function ob_responsedeflate($output) { if ($GLOBALS['response_ob_compress_level'] > 0) return gzdeflate($output, $GLOBALS['response_ob_compress_level']); else return gzdeflate($output); } } // END VSITE_HTTP_RESPONSE_CLASS ?>