mirror of
				https://github.com/Icinga/icingaweb2.git
				synced 2025-11-04 05:05:01 +01:00 
			
		
		
		
	The only header that is now set by the ActionController is X-Icinga-Title, all others are delegated to Icinga\Web\Response.
		
			
				
	
	
		
			359 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			359 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */
 | 
						|
 | 
						|
namespace Icinga\Web;
 | 
						|
 | 
						|
use Zend_Controller_Response_Http;
 | 
						|
use Icinga\Application\Icinga;
 | 
						|
use Icinga\Web\Response\JsonResponse;
 | 
						|
 | 
						|
/**
 | 
						|
 * A HTTP response
 | 
						|
 */
 | 
						|
class Response extends Zend_Controller_Response_Http
 | 
						|
{
 | 
						|
    /**
 | 
						|
     * The default content type being used for responses
 | 
						|
     *
 | 
						|
     * @var string
 | 
						|
     */
 | 
						|
    const DEFAULT_CONTENT_TYPE = 'text/html; charset=UTF-8';
 | 
						|
 | 
						|
    /**
 | 
						|
     * Auto-refresh interval
 | 
						|
     *
 | 
						|
     * @var int
 | 
						|
     */
 | 
						|
    protected $autoRefreshInterval;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Set of cookies which are to be sent to the client
 | 
						|
     *
 | 
						|
     * @var CookieSet
 | 
						|
     */
 | 
						|
    protected $cookies;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Redirect URL
 | 
						|
     *
 | 
						|
     * @var Url|null
 | 
						|
     */
 | 
						|
    protected $redirectUrl;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Request
 | 
						|
     *
 | 
						|
     * @var Request
 | 
						|
     */
 | 
						|
    protected $request;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Whether to instruct client side script code to reload CSS
 | 
						|
     *
 | 
						|
     * @var bool
 | 
						|
     */
 | 
						|
    protected $reloadCss;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Whether to send the rerender layout header on XHR
 | 
						|
     *
 | 
						|
     * @var bool
 | 
						|
     */
 | 
						|
    protected $rerenderLayout = false;
 | 
						|
 | 
						|
    /**
 | 
						|
     * 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;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 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;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 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;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Get an array of all header values for the given name
 | 
						|
     *
 | 
						|
     * @param   string  $name       The name of the header
 | 
						|
     * @param   bool    $lastOnly   If this is true, the last value will be returned as a string
 | 
						|
     *
 | 
						|
     * @return  null|array|string
 | 
						|
     */
 | 
						|
    public function getHeader($name, $lastOnly = false)
 | 
						|
    {
 | 
						|
        $result = ($lastOnly ? null : array());
 | 
						|
        $headers = $this->getHeaders();
 | 
						|
        foreach ($headers as $header) {
 | 
						|
            if ($header['name'] === $name) {
 | 
						|
                if ($lastOnly) {
 | 
						|
                    $result = $header['value'];
 | 
						|
                } else {
 | 
						|
                    $result[] = $header['value'];
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $result;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Get the request
 | 
						|
     *
 | 
						|
     * @return Request
 | 
						|
     */
 | 
						|
    public function getRequest()
 | 
						|
    {
 | 
						|
        if ($this->request === null) {
 | 
						|
            $this->request = Icinga::app()->getRequest();
 | 
						|
        }
 | 
						|
        return $this->request;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 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;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 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;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Entry point for HTTP responses in JSON format
 | 
						|
     *
 | 
						|
     * @return JsonResponse
 | 
						|
     */
 | 
						|
    public function json()
 | 
						|
    {
 | 
						|
        $response = new JsonResponse();
 | 
						|
        $response->copyMetaDataFrom($this);
 | 
						|
        return $response;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Prepare the request before sending
 | 
						|
     */
 | 
						|
    protected function prepare()
 | 
						|
    {
 | 
						|
        $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);
 | 
						|
            }
 | 
						|
            if ($this->isReloadCss()) {
 | 
						|
                $this->setHeader('X-Icinga-Reload-Css', 'now', true);
 | 
						|
            }
 | 
						|
            if (($autoRefreshInterval = $this->getAutoRefreshInterval()) !== null) {
 | 
						|
                $this->setHeader('X-Icinga-Refresh', $autoRefreshInterval, true);
 | 
						|
            }
 | 
						|
 | 
						|
            $notifications = Notification::getInstance();
 | 
						|
            if ($notifications->hasMessages()) {
 | 
						|
                $notificationList = array();
 | 
						|
                foreach ($notifications->popMessages() as $m) {
 | 
						|
                    $notificationList[] = rawurlencode($m->type . ' ' . $m->message);
 | 
						|
                }
 | 
						|
                $this->setHeader('X-Icinga-Notification', implode('&', $notificationList), true);
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            if ($redirectUrl !== null) {
 | 
						|
                $this->setRedirect($redirectUrl->getAbsoluteUrl());
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (! $this->getHeader('Content-Type', true)) {
 | 
						|
            $this->setHeader('Content-Type', static::DEFAULT_CONTENT_TYPE);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Redirect to the given URL and exit immediately
 | 
						|
     *
 | 
						|
     * @param string|Url $url
 | 
						|
     */
 | 
						|
    public function redirectAndExit($url)
 | 
						|
    {
 | 
						|
        $this->setRedirectUrl($url);
 | 
						|
 | 
						|
        $session = Session::getSession();
 | 
						|
        if ($session->hasChanged()) {
 | 
						|
            $session->write();
 | 
						|
        }
 | 
						|
 | 
						|
        $this->sendHeaders();
 | 
						|
        exit;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 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()
 | 
						|
            );
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * {@inheritdoc}
 | 
						|
     */
 | 
						|
    public function sendHeaders()
 | 
						|
    {
 | 
						|
        $this->prepare();
 | 
						|
        if (! $this->getRequest()->isApiRequest()) {
 | 
						|
            $this->sendCookies();
 | 
						|
        }
 | 
						|
        return parent::sendHeaders();
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Copies non-body-related response data from $response
 | 
						|
     *
 | 
						|
     * @param   Response    $response
 | 
						|
     *
 | 
						|
     * @return  $this
 | 
						|
     */
 | 
						|
    protected function copyMetaDataFrom(self $response)
 | 
						|
    {
 | 
						|
        $this->_headers = $response->_headers;
 | 
						|
        $this->_headersRaw = $response->_headersRaw;
 | 
						|
        $this->_httpResponseCode = $response->_httpResponseCode;
 | 
						|
        $this->headersSentThrowsException = $response->headersSentThrowsException;
 | 
						|
        return $this;
 | 
						|
    }
 | 
						|
}
 |