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 https://nette.org
13: * @copyright Copyright (c) 2004, 2009 David Grudl
14: * @license https://nette.org/license Nette license
15: * @link https://nette.org
23: require_once dirname(__FILE__) .
'/../Object.php';
25: require_once dirname(__FILE__) .
'/../Web/IHttpResponse.php';
30: * HttpResponse class.
32: * @author David Grudl
33: * @copyright Copyright (c) 2004, 2009 David Grudl
38: /** @var bool Send invisible garbage for IE 6? */
39: private static $fixIE =
TRUE;
41: /** @var string The domain in which the cookie will be available */
44: /** @var string The path in which the cookie will be available */
47: /** @var string The path in which the cookie will be available */
50: /** @var int HTTP response code */
51: private $code =
self::S200_OK;
56: * Sets HTTP response code.
59: * @throws InvalidArgumentException if code is invalid
60: * @throws InvalidStateException if HTTP headers have been sent
66: static $allowed =
array(
67: 200=>
1, 201=>
1, 202=>
1, 203=>
1, 204=>
1, 205=>
1, 206=>
1,
68: 300=>
1, 301=>
1, 302=>
1, 303=>
1, 304=>
1, 307=>
1,
69: 400=>
1, 401=>
1, 403=>
1, 404=>
1, 406=>
1, 408=>
1, 410=>
1, 412=>
1, 415=>
1, 416=>
1,
70: 500=>
1, 501=>
1, 503=>
1, 505=>
1
73: if (!isset($allowed[$code])) {
74: throw new InvalidArgumentException("Bad HTTP response '
$code'.
");
76: } elseif (headers_sent($file, $line)) {
77: throw new InvalidStateException("Cannot set HTTP code after HTTP headers have been sent" .
($file ?
" (output started at
$file:
$line).
" :
"."));
81: $protocol =
isset($_SERVER['SERVER_PROTOCOL']) ?
$_SERVER['SERVER_PROTOCOL'] :
'HTTP/1.1';
82: header($protocol .
' ' .
$code, TRUE, $code);
90: * Returns HTTP response code.
101: * Sends a HTTP header and replaces a previous one.
102: * @param string header name
103: * @param string header value
105: * @throws InvalidStateException if HTTP headers have been sent
110: throw new InvalidStateException("Cannot send header after HTTP headers have been sent" .
($file ?
" (output started at $file:$line)." :
"."));
113: header($name .
': ' .
$value, $replace, $this->code);
120: * @param string header name
121: * @param string header value
123: * @throws InvalidStateException if HTTP headers have been sent
128: throw new InvalidStateException("Cannot send header after HTTP headers have been sent" .
($file ?
" (output started at $file:$line)." :
"."));
131: header($name .
': ' .
$value, FALSE, $this->code);
137: * Sends a Content-type HTTP header.
138: * @param string mime-type
139: * @param string charset
141: * @throws InvalidStateException if HTTP headers have been sent
145: $this->setHeader('Content-Type', $type .
($charset ?
'; charset=' .
$charset :
''));
151: * Redirects to a new URL. Note: call exit() after it.
153: * @param int HTTP code
155: * @throws InvalidStateException if HTTP headers have been sent
157: public function redirect($url, $code =
self::S302_FOUND)
161: $url =
htmlSpecialChars($url);
162: echo "<h1>Redirect</h1>\n\n<p><a href=\"$url\">Please click here to continue</a>.</p>";
168: * Sets the number of seconds before a page cached on a browser expires.
169: * @param int timestamp or number of seconds
171: * @throws InvalidStateException if HTTP headers have been sent
179: $this->setHeader('Cache-Control', 'max-age=' .
($time -
time()).
',must-revalidate');
182: } else { // no cache
183: $this->setHeader('Expires', 'Mon, 23 Jan 1978 10:00:00 GMT');
184: $this->setHeader('Cache-Control', 's-maxage=0, max-age=0, must-revalidate');
191: * Checks if headers have been sent.
202: * Returns a list of headers to sent.
218: * Returns HTTP valid date format.
219: * @param int timestamp
222: public static function date($time =
NULL)
224: return gmdate('D, d M Y H:i:s \G\M\T', $time ===
NULL ?
time() :
$time);
230: * Enables compression. (warning: may not work)
238: if (isset($headers['Content-Encoding'])) {
239: return FALSE; // called twice
243: if ($ok ===
FALSE) {
244: return FALSE; // not allowed
263: // Sends invisible garbage for IE.
264: if (!isset($_SERVER['HTTP_USER_AGENT']) ||
strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE ') ===
FALSE) return;
265: if (!in_array($this->code, array(400, 403, 404, 405, 406, 408, 409, 410, 500, 501, 505), TRUE)) return;
267: if (isset($headers['Content-Type']) &&
$headers['Content-Type'] !==
'text/html') return;
269: for ($i =
2e3; $i; $i--
) echo $s{rand(0, 3)};
270: self::$fixIE =
FALSE;
278: * @param string name of the cookie
279: * @param string value
280: * @param int expiration as unix timestamp or number of seconds; Value 0 means "until the browser is closed"
285: * @throws InvalidStateException if HTTP headers have been sent
287: public function setCookie($name, $value, $expire, $path =
NULL, $domain =
NULL, $secure =
NULL)
290: throw new InvalidStateException("Cannot set cookie after HTTP headers have been sent" .
($file ?
" (output started at $file:$line)." :
"."));
296: $expire >
0 &&
$expire <=
Tools::YEAR ?
$expire +
time() :
$expire,
298: $domain ===
NULL ?
$this->cookieDomain : (string)
$domain, // . '; httponly'
300: TRUE // added in PHP 5.2.0.
308: * @param string name of the cookie.
313: * @throws InvalidStateException if HTTP headers have been sent
315: public function deleteCookie($name, $path =
NULL, $domain =
NULL, $secure =
NULL)
318: throw new InvalidStateException("Cannot delete cookie after HTTP headers have been sent" .
($file ?
" (output started at $file:$line)." :
"."));
326: $domain ===
NULL ?
$this->cookieDomain : (string)
$domain, // . '; httponly'
328: TRUE // added in PHP 5.2.0.