2014-06-22 13:49:21 +02:00
|
|
|
<?php
|
2016-02-08 15:41:00 +01:00
|
|
|
/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
|
2014-06-22 13:49:21 +02:00
|
|
|
|
|
|
|
namespace Icinga\Web;
|
|
|
|
|
|
|
|
use Zend_Controller_Response_Http;
|
2014-07-04 12:35:33 +02:00
|
|
|
use Icinga\Application\Icinga;
|
2015-09-07 13:24:21 +02:00
|
|
|
use Icinga\Web\Response\JsonResponse;
|
2014-06-22 13:49:21 +02:00
|
|
|
|
2015-11-27 15:44:40 +01:00
|
|
|
/**
|
|
|
|
* A HTTP response
|
|
|
|
*/
|
2014-06-22 13:49:21 +02:00
|
|
|
class Response extends Zend_Controller_Response_Http
|
|
|
|
{
|
2016-01-27 09:14:11 +01:00
|
|
|
/**
|
|
|
|
* Auto-refresh interval
|
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
|
|
|
protected $autoRefreshInterval;
|
|
|
|
|
2015-11-27 15:51:38 +01:00
|
|
|
/**
|
|
|
|
* Set of cookies which are to be sent to the client
|
|
|
|
*
|
|
|
|
* @var CookieSet
|
|
|
|
*/
|
|
|
|
protected $cookies;
|
|
|
|
|
2015-07-29 15:08:36 +02:00
|
|
|
/**
|
|
|
|
* Redirect URL
|
|
|
|
*
|
|
|
|
* @var Url|null
|
|
|
|
*/
|
|
|
|
protected $redirectUrl;
|
|
|
|
|
2015-07-29 14:20:39 +02:00
|
|
|
/**
|
|
|
|
* Request
|
|
|
|
*
|
|
|
|
* @var Request
|
|
|
|
*/
|
|
|
|
protected $request;
|
|
|
|
|
2015-11-27 15:44:40 +01:00
|
|
|
/**
|
|
|
|
* Whether to instruct client side script code to reload CSS
|
|
|
|
*
|
|
|
|
* @var bool
|
|
|
|
*/
|
|
|
|
protected $reloadCss;
|
|
|
|
|
2015-07-29 14:39:45 +02:00
|
|
|
/**
|
|
|
|
* Whether to send the rerender layout header on XHR
|
|
|
|
*
|
|
|
|
* @var bool
|
|
|
|
*/
|
|
|
|
protected $rerenderLayout = false;
|
|
|
|
|
2016-10-14 16:12:47 +02:00
|
|
|
/**
|
|
|
|
* Content type of this response
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $contentType = 'text/html';
|
|
|
|
|
2016-01-27 09:14:11 +01:00
|
|
|
/**
|
|
|
|
* Get the auto-refresh interval
|
|
|
|
*
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
public function getAutoRefreshInterval()
|
|
|
|
{
|
|
|
|
return $this->autoRefreshInterval;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the auto-refresh interval
|
|
|
|
*
|
|
|
|
* @param int $autoRefreshInterval
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setAutoRefreshInterval($autoRefreshInterval)
|
|
|
|
{
|
|
|
|
$this->autoRefreshInterval = $autoRefreshInterval;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2015-11-27 15:51:38 +01:00
|
|
|
/**
|
|
|
|
* Get the set of cookies which are to be sent to the client
|
|
|
|
*
|
|
|
|
* @return CookieSet
|
|
|
|
*/
|
|
|
|
public function getCookies()
|
|
|
|
{
|
|
|
|
if ($this->cookies === null) {
|
|
|
|
$this->cookies = new CookieSet();
|
|
|
|
}
|
|
|
|
return $this->cookies;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the cookie with the given name from the set of cookies which are to be sent to the client
|
|
|
|
*
|
|
|
|
* @param string $name The name of the cookie
|
|
|
|
*
|
|
|
|
* @return Cookie|null The cookie with the given name or null if the cookie does not exist
|
|
|
|
*/
|
|
|
|
public function getCookie($name)
|
|
|
|
{
|
|
|
|
return $this->getCookies()->get($name);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the given cookie for sending it to the client
|
|
|
|
*
|
|
|
|
* @param Cookie $cookie The cookie to send to the client
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setCookie(Cookie $cookie)
|
|
|
|
{
|
|
|
|
$this->getCookies()->add($cookie);
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2015-07-29 15:08:36 +02:00
|
|
|
/**
|
|
|
|
* Get the redirect URL
|
|
|
|
*
|
|
|
|
* @return Url|null
|
|
|
|
*/
|
|
|
|
protected function getRedirectUrl()
|
|
|
|
{
|
|
|
|
return $this->redirectUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the redirect URL
|
|
|
|
*
|
|
|
|
* Unlike {@link setRedirect()} this method only sets a redirect URL on the response for later usage.
|
|
|
|
* {@link prepare()} will take care of the correct redirect handling and HTTP headers on XHR and "normal" browser
|
|
|
|
* requests.
|
|
|
|
*
|
|
|
|
* @param string|Url $redirectUrl
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
protected function setRedirectUrl($redirectUrl)
|
|
|
|
{
|
|
|
|
if (! $redirectUrl instanceof Url) {
|
|
|
|
$redirectUrl = Url::fromPath((string) $redirectUrl);
|
|
|
|
}
|
|
|
|
$redirectUrl->getParams()->setSeparator('&');
|
|
|
|
$this->redirectUrl = $redirectUrl;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2015-07-29 14:20:39 +02:00
|
|
|
/**
|
|
|
|
* Get the request
|
|
|
|
*
|
|
|
|
* @return Request
|
|
|
|
*/
|
|
|
|
public function getRequest()
|
|
|
|
{
|
|
|
|
if ($this->request === null) {
|
2015-07-30 14:02:44 +02:00
|
|
|
$this->request = Icinga::app()->getRequest();
|
2015-07-29 14:20:39 +02:00
|
|
|
}
|
|
|
|
return $this->request;
|
|
|
|
}
|
|
|
|
|
2015-11-27 15:44:40 +01:00
|
|
|
/**
|
|
|
|
* Get whether to instruct client side script code to reload CSS
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function isReloadCss()
|
|
|
|
{
|
|
|
|
return $this->reloadCss;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set whether to instruct client side script code to reload CSS
|
|
|
|
*
|
|
|
|
* @param bool $reloadCss
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setReloadCss($reloadCss)
|
|
|
|
{
|
|
|
|
$this->reloadCss = $reloadCss;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2015-07-29 14:39:45 +02:00
|
|
|
/**
|
|
|
|
* Get whether to send the rerender layout header on XHR
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function getRerenderLayout()
|
|
|
|
{
|
|
|
|
return $this->rerenderLayout;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get whether to send the rerender layout header on XHR
|
|
|
|
*
|
|
|
|
* @param bool $rerenderLayout
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setRerenderLayout($rerenderLayout = true)
|
|
|
|
{
|
|
|
|
$this->rerenderLayout = (bool) $rerenderLayout;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
2016-10-14 16:12:47 +02:00
|
|
|
/**
|
|
|
|
* Set the content type of this response
|
|
|
|
*
|
|
|
|
* @param string $contentType
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setContentType($contentType)
|
|
|
|
{
|
|
|
|
$this->contentType = $contentType;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the content type of this response
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getContentType()
|
|
|
|
{
|
|
|
|
return $this->contentType;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-09-07 13:24:21 +02:00
|
|
|
/**
|
|
|
|
* Entry point for HTTP responses in JSON format
|
|
|
|
*
|
|
|
|
* @return JsonResponse
|
|
|
|
*/
|
2016-09-27 13:26:20 +02:00
|
|
|
public function json()
|
2015-09-07 13:24:21 +02:00
|
|
|
{
|
2016-09-27 13:26:20 +02:00
|
|
|
$response = new JsonResponse();
|
2016-10-11 10:45:15 +02:00
|
|
|
$response->copyMetaDataFrom($this);
|
2016-09-27 13:26:20 +02:00
|
|
|
return $response;
|
2015-09-07 13:24:21 +02:00
|
|
|
}
|
|
|
|
|
2015-07-29 14:39:45 +02:00
|
|
|
/**
|
|
|
|
* Prepare the request before sending
|
|
|
|
*/
|
|
|
|
protected function prepare()
|
|
|
|
{
|
2015-07-29 15:08:36 +02:00
|
|
|
$redirectUrl = $this->getRedirectUrl();
|
|
|
|
if ($this->getRequest()->isXmlHttpRequest()) {
|
|
|
|
if ($redirectUrl !== null) {
|
|
|
|
$this->setHeader('X-Icinga-Redirect', rawurlencode($redirectUrl->getAbsoluteUrl()), true);
|
|
|
|
if ($this->getRerenderLayout()) {
|
|
|
|
$this->setHeader('X-Icinga-Rerender-Layout', 'yes', true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($this->getRerenderLayout()) {
|
|
|
|
$this->setHeader('X-Icinga-Container', 'layout', true);
|
|
|
|
}
|
2015-11-27 15:44:40 +01:00
|
|
|
if ($this->isReloadCss()) {
|
|
|
|
$this->setHeader('X-Icinga-Reload-Css', 'now', true);
|
|
|
|
}
|
2016-01-27 09:14:11 +01:00
|
|
|
if (($autoRefreshInterval = $this->getAutoRefreshInterval()) !== null) {
|
|
|
|
$this->setHeader('X-Icinga-Refresh', $autoRefreshInterval, true);
|
|
|
|
}
|
2015-07-29 15:08:36 +02:00
|
|
|
} else {
|
|
|
|
if ($redirectUrl !== null) {
|
|
|
|
$this->setRedirect($redirectUrl->getAbsoluteUrl());
|
|
|
|
}
|
2015-07-29 14:39:45 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-29 14:22:45 +02:00
|
|
|
/**
|
|
|
|
* Redirect to the given URL and exit immediately
|
|
|
|
*
|
|
|
|
* @param string|Url $url
|
|
|
|
*/
|
2014-07-04 12:35:33 +02:00
|
|
|
public function redirectAndExit($url)
|
|
|
|
{
|
2015-07-29 15:08:36 +02:00
|
|
|
$this->setRedirectUrl($url);
|
2014-09-17 10:42:56 +02:00
|
|
|
|
|
|
|
$session = Session::getSession();
|
|
|
|
if ($session->hasChanged()) {
|
|
|
|
$session->write();
|
|
|
|
}
|
|
|
|
|
2014-07-04 12:35:33 +02:00
|
|
|
$this->sendHeaders();
|
|
|
|
exit;
|
|
|
|
}
|
2015-07-29 14:39:45 +02:00
|
|
|
|
2015-11-27 15:51:38 +01:00
|
|
|
/**
|
|
|
|
* Send the cookies to the client
|
|
|
|
*/
|
|
|
|
public function sendCookies()
|
|
|
|
{
|
|
|
|
foreach ($this->getCookies() as $cookie) {
|
|
|
|
/** @var Cookie $cookie */
|
|
|
|
setcookie(
|
|
|
|
$cookie->getName(),
|
|
|
|
$cookie->getValue(),
|
|
|
|
$cookie->getExpire(),
|
|
|
|
$cookie->getPath(),
|
|
|
|
$cookie->getDomain(),
|
|
|
|
$cookie->isSecure(),
|
|
|
|
$cookie->isHttpOnly()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-29 14:39:45 +02:00
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
public function sendHeaders()
|
|
|
|
{
|
|
|
|
$this->prepare();
|
2015-12-10 13:20:27 +01:00
|
|
|
if (! $this->getRequest()->isApiRequest()) {
|
|
|
|
$this->sendCookies();
|
|
|
|
}
|
2015-07-29 14:39:45 +02:00
|
|
|
return parent::sendHeaders();
|
|
|
|
}
|
2016-09-27 13:26:20 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Copies non-body-related response data from $response
|
|
|
|
*
|
|
|
|
* @param Response $response
|
|
|
|
*
|
|
|
|
* @return $this
|
|
|
|
*/
|
2016-10-11 10:45:15 +02:00
|
|
|
protected function copyMetaDataFrom(self $response)
|
2016-09-27 13:26:20 +02:00
|
|
|
{
|
|
|
|
$this->_headers = $response->_headers;
|
|
|
|
$this->_headersRaw = $response->_headersRaw;
|
|
|
|
$this->_httpResponseCode = $response->_httpResponseCode;
|
|
|
|
$this->headersSentThrowsException = $response->headersSentThrowsException;
|
|
|
|
return $this;
|
|
|
|
}
|
2014-06-22 13:49:21 +02:00
|
|
|
}
|