Source for file HttpResponse.php
Documentation is available at HttpResponse.php
6: * Copyright (c) 2004, 2009 David Grudl (http://davidgrudl.com)
8: * This source file is subject to the "Nette license" that is bundled
9: * with this package in the file license.txt.
11: * For more information please see http://nettephp.com
13: * @copyright Copyright (c) 2004, 2009 David Grudl
14: * @license http://nettephp.com/license Nette license
15: * @link http://nettephp.com
22: require_once dirname(__FILE__) .
'/../Object.php';
24: require_once dirname(__FILE__) .
'/../Web/IHttpResponse.php';
29: * HttpResponse class.
31: * @author David Grudl
32: * @copyright Copyright (c) 2004, 2009 David Grudl
35: * @property int $code
36: * @property-read array $headers
37: * @property-read mixed $sent
41: /** @var bool Send invisible garbage for IE 6? */
42: private static $fixIE =
TRUE;
44: /** @var string The domain in which the cookie will be available */
47: /** @var string The path in which the cookie will be available */
50: /** @var string The path in which the cookie will be available */
53: /** @var int HTTP response code */
54: private $code =
self::S200_OK;
59: * Sets HTTP response code.
62: * @throws InvalidArgumentException if code is invalid
63: * @throws InvalidStateException if HTTP headers have been sent
69: static $allowed =
array(
70: 200=>
1, 201=>
1, 202=>
1, 203=>
1, 204=>
1, 205=>
1, 206=>
1,
71: 300=>
1, 301=>
1, 302=>
1, 303=>
1, 304=>
1, 307=>
1,
72: 400=>
1, 401=>
1, 403=>
1, 404=>
1, 406=>
1, 408=>
1, 410=>
1, 412=>
1, 415=>
1, 416=>
1,
73: 500=>
1, 501=>
1, 503=>
1, 505=>
1
76: if (!isset($allowed[$code])) {
77: throw new InvalidArgumentException("Bad HTTP response '
$code'.
");
79: } elseif (headers_sent($file, $line)) {
80: throw new InvalidStateException("Cannot set HTTP code after HTTP headers have been sent" .
($file ?
" (output started at
$file:
$line).
" :
"."));
84: $protocol =
isset($_SERVER['SERVER_PROTOCOL']) ?
$_SERVER['SERVER_PROTOCOL'] :
'HTTP/1.1';
85: header($protocol .
' ' .
$code, TRUE, $code);
92: * Returns HTTP response code.
103: * Sends a HTTP header and replaces a previous one.
104: * @param string header name
105: * @param string header value
107: * @throws InvalidStateException if HTTP headers have been sent
112: throw new InvalidStateException("Cannot send header after HTTP headers have been sent" .
($file ?
" (output started at $file:$line)." :
"."));
115: header($name .
': ' .
$value, TRUE, $this->code);
122: * @param string header name
123: * @param string header value
125: * @throws InvalidStateException if HTTP headers have been sent
130: throw new InvalidStateException("Cannot send header after HTTP headers have been sent" .
($file ?
" (output started at $file:$line)." :
"."));
133: header($name .
': ' .
$value, FALSE, $this->code);
139: * Sends a Content-type HTTP header.
140: * @param string mime-type
141: * @param string charset
143: * @throws InvalidStateException if HTTP headers have been sent
147: $this->setHeader('Content-Type', $type .
($charset ?
'; charset=' .
$charset :
''));
153: * Redirects to a new URL. Note: call exit() after it.
155: * @param int HTTP code
157: * @throws InvalidStateException if HTTP headers have been sent
159: public function redirect($url, $code =
self::S302_FOUND)
161: if (isset($_SERVER['SERVER_SOFTWARE']) &&
preg_match('#^Microsoft-IIS/[1-5]#', $_SERVER['SERVER_SOFTWARE']) &&
$this->getHeader('Set-Cookie') !==
NULL) {
168: echo "<h1>Redirect</h1>\n\n<p><a href=\"" .
htmlSpecialChars($url) .
"\">Please click here to continue</a>.</p>";
174: * Sets the number of seconds before a page cached on a browser expires.
175: * @param mixed timestamp or number of seconds
177: * @throws InvalidStateException if HTTP headers have been sent
189: $this->setHeader('Cache-Control', 'max-age=' .
($seconds -
time()).
',must-revalidate');
192: } else { // no cache
193: $this->setHeader('Expires', 'Mon, 23 Jan 1978 10:00:00 GMT');
194: $this->setHeader('Cache-Control', 's-maxage=0, max-age=0, must-revalidate');
201: * Checks if headers have been sent.
212: * Return the value of the HTTP header.
232: * Returns a list of headers to sent.
248: * Returns HTTP valid date format.
249: * @param int timestamp
252: public static function date($time =
NULL)
254: return gmdate('D, d M Y H:i:s \G\M\T', $time ===
NULL ?
time() :
$time);
260: * Enables compression. (warning: may not work)
268: return FALSE; // called twice
272: if ($ok ===
FALSE) {
273: return FALSE; // not allowed
292: // Sends invisible garbage for IE.
293: if (!isset($_SERVER['HTTP_USER_AGENT']) ||
strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE ') ===
FALSE) return;
294: if (!in_array($this->code, array(400, 403, 404, 405, 406, 408, 409, 410, 500, 501, 505), TRUE)) return;
295: if ($this->getHeader('Content-Type', 'text/html') !==
'text/html') return;
297: for ($i =
2e3; $i; $i--
) echo $s{rand(0, 3)};
298: self::$fixIE =
FALSE;
306: * @param string name of the cookie
307: * @param string value
308: * @param mixed expiration as unix timestamp or number of seconds; Value 0 means "until the browser is closed"
313: * @throws InvalidStateException if HTTP headers have been sent
315: public function setCookie($name, $value, $expire, $path =
NULL, $domain =
NULL, $secure =
NULL)
318: throw new InvalidStateException("Cannot set cookie after HTTP headers have been sent" .
($file ?
" (output started at $file:$line)." :
"."));
324: } elseif ($expire >
0 &&
$expire <=
Tools::YEAR) {
333: $domain ===
NULL ?
$this->cookieDomain : (string)
$domain, // . '; httponly'
335: TRUE // added in PHP 5.2.0.
343: * @param string name of the cookie.
348: * @throws InvalidStateException if HTTP headers have been sent
350: public function deleteCookie($name, $path =
NULL, $domain =
NULL, $secure =
NULL)
353: throw new InvalidStateException("Cannot delete cookie after HTTP headers have been sent" .
($file ?
" (output started at $file:$line)." :
"."));
361: $domain ===
NULL ?
$this->cookieDomain : (string)
$domain, // . '; httponly'
363: TRUE // added in PHP 5.2.0.