no message

This commit is contained in:
BarboraFleg
2019-04-04 18:34:40 +02:00
commit ce48ca4a21
589 changed files with 82184 additions and 0 deletions
+322
View File
@@ -0,0 +1,322 @@
<?php
/**
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*/
namespace Nette\Http;
use Nette;
use Nette\Utils\DateTime;
/**
* HttpResponse class.
*
* @property-read array $headers
*/
class Response implements IResponse
{
use Nette\SmartObject;
/** @var string The domain in which the cookie will be available */
public $cookieDomain = '';
/** @var string The path in which the cookie will be available */
public $cookiePath = '/';
/** @var bool Whether the cookie is available only through HTTPS */
public $cookieSecure = false;
/** @var bool Whether the cookie is hidden from client-side */
public $cookieHttpOnly = true;
/** @var bool Whether warn on possible problem with data in output buffer */
public $warnOnBuffer = true;
/** @var bool Send invisible garbage for IE 6? */
private static $fixIE = true;
/** @var int HTTP response code */
private $code = self::S200_OK;
public function __construct()
{
if (is_int($code = http_response_code())) {
$this->code = $code;
}
}
/**
* Sets HTTP response code.
* @param int
* @param string
* @return static
* @throws Nette\InvalidArgumentException if code is invalid
* @throws Nette\InvalidStateException if HTTP headers have been sent
*/
public function setCode($code, $reason = null)
{
$code = (int) $code;
if ($code < 100 || $code > 599) {
throw new Nette\InvalidArgumentException("Bad HTTP response '$code'.");
}
self::checkHeaders();
$this->code = $code;
static $hasReason = [ // hardcoded in PHP
100, 101,
200, 201, 202, 203, 204, 205, 206,
300, 301, 302, 303, 304, 305, 307, 308,
400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 426, 428, 429, 431,
500, 501, 502, 503, 504, 505, 506, 511,
];
if ($reason || !in_array($code, $hasReason, true)) {
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
header("$protocol $code " . ($reason ?: 'Unknown status'));
} else {
http_response_code($code);
}
return $this;
}
/**
* Returns HTTP response code.
* @return int
*/
public function getCode()
{
return $this->code;
}
/**
* Sends a HTTP header and replaces a previous one.
* @param string header name
* @param string header value
* @return static
* @throws Nette\InvalidStateException if HTTP headers have been sent
*/
public function setHeader($name, $value)
{
self::checkHeaders();
if ($value === null) {
header_remove($name);
} elseif (strcasecmp($name, 'Content-Length') === 0 && ini_get('zlib.output_compression')) {
// ignore, PHP bug #44164
} else {
header($name . ': ' . $value, true, $this->code);
}
return $this;
}
/**
* Adds HTTP header.
* @param string header name
* @param string header value
* @return static
* @throws Nette\InvalidStateException if HTTP headers have been sent
*/
public function addHeader($name, $value)
{
self::checkHeaders();
header($name . ': ' . $value, false, $this->code);
return $this;
}
/**
* Sends a Content-type HTTP header.
* @param string mime-type
* @param string charset
* @return static
* @throws Nette\InvalidStateException if HTTP headers have been sent
*/
public function setContentType($type, $charset = null)
{
$this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
return $this;
}
/**
* Redirects to a new URL. Note: call exit() after it.
* @param string URL
* @param int HTTP code
* @return void
* @throws Nette\InvalidStateException if HTTP headers have been sent
*/
public function redirect($url, $code = self::S302_FOUND)
{
$this->setCode($code);
$this->setHeader('Location', $url);
if (preg_match('#^https?:|^\s*+[a-z0-9+.-]*+[^:]#i', $url)) {
$escapedUrl = htmlspecialchars($url, ENT_IGNORE | ENT_QUOTES, 'UTF-8');
echo "<h1>Redirect</h1>\n\n<p><a href=\"$escapedUrl\">Please click here to continue</a>.</p>";
}
}
/**
* Sets the number of seconds before a page cached on a browser expires.
* @param string|int|\DateTimeInterface time, value 0 means "must-revalidate"
* @return static
* @throws Nette\InvalidStateException if HTTP headers have been sent
*/
public function setExpiration($time)
{
$this->setHeader('Pragma', null);
if (!$time) { // no cache
$this->setHeader('Cache-Control', 's-maxage=0, max-age=0, must-revalidate');
$this->setHeader('Expires', 'Mon, 23 Jan 1978 10:00:00 GMT');
return $this;
}
$time = DateTime::from($time);
$this->setHeader('Cache-Control', 'max-age=' . ($time->format('U') - time()));
$this->setHeader('Expires', Helpers::formatDate($time));
return $this;
}
/**
* Checks if headers have been sent.
* @return bool
*/
public function isSent()
{
return headers_sent();
}
/**
* Returns value of an HTTP header.
* @param string
* @param string|null
* @return string|null
*/
public function getHeader($header, $default = null)
{
$header .= ':';
$len = strlen($header);
foreach (headers_list() as $item) {
if (strncasecmp($item, $header, $len) === 0) {
return ltrim(substr($item, $len));
}
}
return $default;
}
/**
* Returns a list of headers to sent.
* @return array (name => value)
*/
public function getHeaders()
{
$headers = [];
foreach (headers_list() as $header) {
$a = strpos($header, ':');
$headers[substr($header, 0, $a)] = (string) substr($header, $a + 2);
}
return $headers;
}
/**
* @deprecated
*/
public static function date($time = null)
{
trigger_error('Method date() is deprecated, use Nette\Http\Helpers::formatDate() instead.', E_USER_DEPRECATED);
return Helpers::formatDate($time);
}
public function __destruct()
{
if (
self::$fixIE
&& isset($_SERVER['HTTP_USER_AGENT'])
&& strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE ') !== false
&& in_array($this->code, [400, 403, 404, 405, 406, 408, 409, 410, 500, 501, 505], true)
&& preg_match('#^text/html(?:;|$)#', $this->getHeader('Content-Type'))
) {
echo Nette\Utils\Random::generate(2e3, " \t\r\n"); // sends invisible garbage for IE
self::$fixIE = false;
}
}
/**
* Sends a cookie.
* @param string name of the cookie
* @param string value
* @param string|int|\DateTimeInterface expiration time, value 0 means "until the browser is closed"
* @param string
* @param string
* @param bool
* @param bool
* @param string
* @return static
* @throws Nette\InvalidStateException if HTTP headers have been sent
*/
public function setCookie($name, $value, $time, $path = null, $domain = null, $secure = null, $httpOnly = null, $sameSite = null)
{
self::checkHeaders();
$options = [
'expires' => $time ? (int) DateTime::from($time)->format('U') : 0,
'path' => $path === null ? $this->cookiePath : (string) $path,
'domain' => $domain === null ? $this->cookieDomain : (string) $domain,
'secure' => $secure === null ? $this->cookieSecure : (bool) $secure,
'httponly' => $httpOnly === null ? $this->cookieHttpOnly : (bool) $httpOnly,
'samesite' => (string) $sameSite,
];
if (PHP_VERSION_ID >= 70300) {
setcookie($name, $value, $options);
} else {
setcookie(
$name,
$value,
$options['expires'],
$options['path'] . ($sameSite ? "; SameSite=$sameSite" : ''),
$options['domain'],
$options['secure'],
$options['httponly']
);
}
return $this;
}
/**
* Deletes a cookie.
* @param string name of the cookie.
* @param string
* @param string
* @param bool
* @return void
* @throws Nette\InvalidStateException if HTTP headers have been sent
*/
public function deleteCookie($name, $path = null, $domain = null, $secure = null)
{
$this->setCookie($name, false, 0, $path, $domain, $secure);
}
private function checkHeaders()
{
if (PHP_SAPI === 'cli') {
} elseif (headers_sent($file, $line)) {
throw new Nette\InvalidStateException('Cannot send header after HTTP headers have been sent' . ($file ? " (output started at $file:$line)." : '.'));
} elseif ($this->warnOnBuffer && ob_get_length() && !array_filter(ob_get_status(true), function ($i) { return !$i['chunk_size']; })) {
trigger_error('Possible problem: you are sending a HTTP header while already having some data in output buffer. Try Tracy\OutputDebugger or start session earlier.');
}
}
}