diff --git a/src/Symfony/Components/HttpKernel/HttpKernel.php b/src/Symfony/Components/HttpKernel/HttpKernel.php index f33a83afd5..ebab5ddcb9 100644 --- a/src/Symfony/Components/HttpKernel/HttpKernel.php +++ b/src/Symfony/Components/HttpKernel/HttpKernel.php @@ -38,7 +38,7 @@ class HttpKernel implements HttpKernelInterface } /** - * Gets the Request instance associated with the main request. + * Gets the Request instance associated with the master request. * * @return Request A Request instance */ @@ -48,42 +48,45 @@ class HttpKernel implements HttpKernelInterface } /** - * Handles a request to convert it to a response. + * Handles a Request to convert it to a Response. * * All exceptions are caught, and a core.exception event is notified * for user management. * - * @param Request $request A Request instance - * @param Boolean $main Whether this is the main request or not - * @param Boolean $raw Whether to catch exceptions or not + * @param Request $request A Request instance + * @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST) + * @param Boolean $raw Whether to catch exceptions or not * - * @return Response $response A Response instance + * @return Response A Response instance * - * @throws \Exception When Exception couldn't be caught by event processing + * @throws \Exception When an Exception occurs during processing + * and couldn't be caught by event processing or $raw is true */ - public function handle(Request $request = null, $main = true, $raw = false) + public function handle(Request $request = null, $type = HttpKernelInterface::MASTER_REQUEST, $raw = false) { - $main = (Boolean) $main; + if (HttpKernelInterface::EMBEDDED_REQUEST === $type) { + return $this->handleEmbedded($request, $raw); + } if (null === $request) { $request = new Request(); } - if (true === $main) { + if (HttpKernelInterface::MASTER_REQUEST === $type) { $this->request = $request; } try { - return $this->handleRaw($request, $main); + return $this->handleRaw($request, $type); } catch (\Exception $e) { if (true === $raw) { throw $e; } // exception - $event = $this->dispatcher->notifyUntil(new Event($this, 'core.exception', array('main_request' => $main, 'request' => $request, 'exception' => $e))); + $event = $this->dispatcher->notifyUntil(new Event($this, 'core.exception', array('request_type' => $type, 'request' => $request, 'exception' => $e))); if ($event->isProcessed()) { - return $this->filterResponse($event->getReturnValue(), $request, 'A "core.exception" listener returned a non response object.', $main); + return $this->filterResponse($event->getReturnValue(), $request, 'A "core.exception" listener returned a non response object.', $type); } throw $e; @@ -95,26 +98,24 @@ class HttpKernel implements HttpKernelInterface * * Exceptions are not caught. * - * @param Request $request A Request instance - * @param Boolean $main Whether this is the main request or not + * @param Request $request A Request instance + * @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST) * - * @return Response $response A Response instance + * @return Response A Response instance * * @throws \LogicException If one of the listener does not behave as expected * @throws NotFoundHttpException When controller cannot be found */ - protected function handleRaw(Request $request, $main = true) + protected function handleRaw(Request $request, $type = self::MASTER_REQUEST) { - $main = (Boolean) $main; - // request - $event = $this->dispatcher->notifyUntil(new Event($this, 'core.request', array('main_request' => $main, 'request' => $request))); + $event = $this->dispatcher->notifyUntil(new Event($this, 'core.request', array('request_type' => $type, 'request' => $request))); if ($event->isProcessed()) { - return $this->filterResponse($event->getReturnValue(), $request, 'A "core.request" listener returned a non response object.', $main); + return $this->filterResponse($event->getReturnValue(), $request, 'A "core.request" listener returned a non response object.', $type); } // load controller - $event = $this->dispatcher->notifyUntil(new Event($this, 'core.load_controller', array('main_request' => $main, 'request' => $request))); + $event = $this->dispatcher->notifyUntil(new Event($this, 'core.load_controller', array('request_type' => $type, 'request' => $request))); if (!$event->isProcessed()) { throw new NotFoundHttpException('Unable to find the controller.'); } @@ -127,10 +128,10 @@ class HttpKernel implements HttpKernelInterface } // controller - $event = $this->dispatcher->notifyUntil(new Event($this, 'core.controller', array('main_request' => $main, 'request' => $request, 'controller' => &$controller, 'arguments' => &$arguments))); + $event = $this->dispatcher->notifyUntil(new Event($this, 'core.controller', array('request_type' => $type, 'request' => $request, 'controller' => &$controller, 'arguments' => &$arguments))); if ($event->isProcessed()) { try { - return $this->filterResponse($event->getReturnValue(), $request, 'A "core.controller" listener returned a non response object.', $main); + return $this->filterResponse($event->getReturnValue(), $request, 'A "core.controller" listener returned a non response object.', $type); } catch (\Exception $e) { $retval = $event->getReturnValue(); } @@ -140,28 +141,60 @@ class HttpKernel implements HttpKernelInterface } // view - $event = $this->dispatcher->filter(new Event($this, 'core.view', array('main_request' => $main, 'request' => $request)), $retval); + $event = $this->dispatcher->filter(new Event($this, 'core.view', array('request_type' => $type, 'request' => $request)), $retval); - return $this->filterResponse($event->getReturnValue(), $request, sprintf('The controller must return a response (instead of %s).', is_object($event->getReturnValue()) ? 'an object of class '.get_class($event->getReturnValue()) : str_replace("\n", '', var_export($event->getReturnValue(), true))), $main); + return $this->filterResponse($event->getReturnValue(), $request, sprintf('The controller must return a response (instead of %s).', is_object($event->getReturnValue()) ? 'an object of class '.get_class($event->getReturnValue()) : str_replace("\n", '', var_export($event->getReturnValue(), true))), $type); + } + + /** + * Handles a request that need to be embedded. + * + * @param Request $request A Request instance + * @param Boolean $raw Whether to catch exceptions or not + * + * @return string|false The Response content or false if there is a problem + * + * @throws \RuntimeException When an Exception occurs during processing + * and couldn't be caught by event processing or $raw is true + */ + protected function handleEmbedded(Request $request, $raw = false) + { + try { + $response = $this->handleRaw($request, HttpKernelInterface::EMBEDDED_REQUEST); + + if (200 != $response->getStatusCode()) { + throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $request->getUri(), $response->getStatusCode())); + } + + return $response->getContent(); + } catch (\Exception $e) { + if (true === $raw) + { + throw $e; + } + + return false; + } } /** * Filters a response object. * - * @param Object $response A Response instance - * @param string $message A error message in case the response is not a Response object + * @param Response $response A Response instance + * @param string $message A error message in case the response is not a Response object + * @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST) * - * @param Object $response The filtered Response instance + * @return Response The filtered Response instance * - * @throws \RuntimeException if the response object does not implement the send() method + * @throws \RuntimeException if the passed object is not a Response instance */ - protected function filterResponse($response, $request, $message, $main) + protected function filterResponse($response, $request, $message, $type) { if (!$response instanceof Response) { throw new \RuntimeException($message); } - $event = $this->dispatcher->filter(new Event($this, 'core.response', array('main_request' => $main, 'request' => $request)), $response); + $event = $this->dispatcher->filter(new Event($this, 'core.response', array('request_type' => $type, 'request' => $request)), $response); $response = $event->getReturnValue(); if (!$response instanceof Response) { diff --git a/src/Symfony/Components/HttpKernel/HttpKernelInterface.php b/src/Symfony/Components/HttpKernel/HttpKernelInterface.php index 300ae5d21a..ec95d21826 100644 --- a/src/Symfony/Components/HttpKernel/HttpKernelInterface.php +++ b/src/Symfony/Components/HttpKernel/HttpKernelInterface.php @@ -20,19 +20,23 @@ namespace Symfony\Components\HttpKernel; */ interface HttpKernelInterface { + const MASTER_REQUEST = 1; + const FORWARDED_REQUEST = 2; + const EMBEDDED_REQUEST = 3; + /** * Handles a request to convert it to a response. * * @param Request $request A Request instance - * @param Boolean $main Whether this is the main request or not + * @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST) * @param Boolean $raw Whether to catch exceptions or not * * @return Response $response A Response instance */ - public function handle(Request $request = null, $main = true, $raw = false); + public function handle(Request $request = null, $type = self::MASTER_REQUEST, $raw = false); /** - * Gets the Request instance associated with the main request. + * Gets the Request instance associated with the master request. * * @return Request A Request instance */ diff --git a/src/Symfony/Foundation/Kernel.php b/src/Symfony/Foundation/Kernel.php index 60d3fa3376..dbb88cce93 100644 --- a/src/Symfony/Foundation/Kernel.php +++ b/src/Symfony/Foundation/Kernel.php @@ -151,7 +151,7 @@ abstract class Kernel implements HttpKernelInterface, \Serializable } /** - * Gets the Request instance associated with the main request. + * Gets the Request instance associated with the master request. * * @return Request A Request instance */ @@ -164,12 +164,12 @@ abstract class Kernel implements HttpKernelInterface, \Serializable * Handles a request to convert it to a response by calling the HttpKernel service. * * @param Request $request A Request instance - * @param Boolean $main Whether this is the main request or not + * @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST, HttpKernelInterface::FORWARDED_REQUEST, or HttpKernelInterface::EMBEDDED_REQUEST) * @param Boolean $raw Whether to catch exceptions or not * * @return Response $response A Response instance */ - public function handle(Request $request = null, $main = true, $raw = false) + public function handle(Request $request = null, $type = HttpKernelInterface::MASTER_REQUEST, $raw = false) { if (false === $this->booted) { $this->boot(); @@ -179,13 +179,13 @@ abstract class Kernel implements HttpKernelInterface, \Serializable $request = $this->container->getRequestService(); } - if (true === $main) { + if (HttpKernelInterface::MASTER_REQUEST === $type) { $this->request = $request; } $this->container->setService('request', $request); - $response = $this->container->getHttpKernelService()->handle($request, $main, $raw); + $response = $this->container->getHttpKernelService()->handle($request, $type, $raw); $this->container->setService('request', $this->request); diff --git a/src/Symfony/Framework/ProfilerBundle/DataCollector/DataCollectorManager.php b/src/Symfony/Framework/ProfilerBundle/DataCollector/DataCollectorManager.php index c39c5545c9..4fded9e296 100644 --- a/src/Symfony/Framework/ProfilerBundle/DataCollector/DataCollectorManager.php +++ b/src/Symfony/Framework/ProfilerBundle/DataCollector/DataCollectorManager.php @@ -5,6 +5,7 @@ namespace Symfony\Framework\ProfilerBundle\DataCollector; use Symfony\Components\DependencyInjection\ContainerInterface; use Symfony\Components\EventDispatcher\Event; use Symfony\Components\HttpKernel\Response; +use Symfony\Components\HttpKernel\HttpKernelInterface; use Symfony\Framework\ProfilerBundle\ProfilerStorage; use Symfony\Foundation\LoggerInterface; @@ -49,7 +50,7 @@ class DataCollectorManager public function handle(Event $event, Response $response) { - if (!$event->getParameter('main_request')) { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getParameter('request_type')) { return $response; } diff --git a/src/Symfony/Framework/ProfilerBundle/Listener/WebDebugToolbar.php b/src/Symfony/Framework/ProfilerBundle/Listener/WebDebugToolbar.php index 276e7ed3d6..88801580b2 100644 --- a/src/Symfony/Framework/ProfilerBundle/Listener/WebDebugToolbar.php +++ b/src/Symfony/Framework/ProfilerBundle/Listener/WebDebugToolbar.php @@ -5,6 +5,7 @@ namespace Symfony\Framework\ProfilerBundle\Listener; use Symfony\Components\DependencyInjection\ContainerInterface; use Symfony\Components\EventDispatcher\Event; use Symfony\Components\HttpKernel\Response; +use Symfony\Components\HttpKernel\HttpKernelInterface; use Symfony\Framework\ProfilerBundle\DataCollector\DataCollectorManager; /* @@ -41,7 +42,7 @@ class WebDebugToolbar public function handle(Event $event, Response $response) { - if (!$event->getParameter('main_request')) { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getParameter('request_type')) { return $response; } diff --git a/src/Symfony/Framework/WebBundle/Controller.php b/src/Symfony/Framework/WebBundle/Controller.php index d972224d69..0a4de2ae1f 100644 --- a/src/Symfony/Framework/WebBundle/Controller.php +++ b/src/Symfony/Framework/WebBundle/Controller.php @@ -5,6 +5,7 @@ namespace Symfony\Framework\WebBundle; use Symfony\Components\DependencyInjection\ContainerInterface; use Symfony\Components\HttpKernel\Request; use Symfony\Components\HttpKernel\Response; +use Symfony\Components\HttpKernel\HttpKernelInterface; /* * This file is part of the Symfony framework. @@ -96,7 +97,7 @@ class Controller $path['_controller'] = $controller; $subRequest = $this->getRequest()->duplicate($query, null, $path); - return $this->container->getKernelService()->handle($subRequest, false, true); + return $this->container->getKernelService()->handle($subRequest, HttpKernelInterface::FORWARDED_REQUEST, true); } /** diff --git a/src/Symfony/Framework/WebBundle/Helper/ActionsHelper.php b/src/Symfony/Framework/WebBundle/Helper/ActionsHelper.php index b4c8e6310a..120515da60 100644 --- a/src/Symfony/Framework/WebBundle/Helper/ActionsHelper.php +++ b/src/Symfony/Framework/WebBundle/Helper/ActionsHelper.php @@ -62,7 +62,7 @@ class ActionsHelper extends Helper $path['_controller'] = $controller; $subRequest = $this->container->getRequestService()->duplicate($query, null, Escaper::unescape($path)); - return $this->container->getKernelService()->handle($subRequest, false, true); + return $this->container->getKernelService()->handle($subRequest, HttpKernelInterface::EMBEDDED_REQUEST, true); } /** diff --git a/src/Symfony/Framework/WebBundle/Listener/ExceptionHandler.php b/src/Symfony/Framework/WebBundle/Listener/ExceptionHandler.php index f9b65a01cb..793c38141c 100644 --- a/src/Symfony/Framework/WebBundle/Listener/ExceptionHandler.php +++ b/src/Symfony/Framework/WebBundle/Listener/ExceptionHandler.php @@ -5,6 +5,7 @@ namespace Symfony\Framework\WebBundle\Listener; use Symfony\Components\DependencyInjection\ContainerInterface; use Symfony\Components\EventDispatcher\Event; use Symfony\Foundation\LoggerInterface; +use Symfony\Components\HttpKernel\HttpKernelInterface; /* * This file is part of the Symfony framework. @@ -43,7 +44,7 @@ class ExceptionHandler public function handle(Event $event) { - if (!$event->getParameter('main_request')) { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getParameter('request_type')) { return false; } @@ -63,7 +64,7 @@ class ExceptionHandler $request = $event->getParameter('request')->duplicate(null, null, $parameters); try { - $response = $event->getSubject()->handle($request, false, true); + $response = $event->getSubject()->handle($request, HttpKernelInterface::FORWARDED_REQUEST, true); error_log(sprintf('%s: %s', get_class($exception), $exception->getMessage())); } catch (\Exception $e) { diff --git a/src/Symfony/Framework/WebBundle/Listener/RequestParser.php b/src/Symfony/Framework/WebBundle/Listener/RequestParser.php index c99c731fcc..9f5d57644e 100644 --- a/src/Symfony/Framework/WebBundle/Listener/RequestParser.php +++ b/src/Symfony/Framework/WebBundle/Listener/RequestParser.php @@ -6,6 +6,7 @@ use Symfony\Foundation\LoggerInterface; use Symfony\Components\DependencyInjection\ContainerInterface; use Symfony\Components\EventDispatcher\Event; use Symfony\Components\Routing\RouterInterface; +use Symfony\Components\HttpKernel\HttpKernelInterface; /* * This file is part of the Symfony framework. @@ -45,20 +46,18 @@ class RequestParser { $request = $event->getParameter('request'); - if (!$event->getParameter('main_request')) { - return; + if (HttpKernelInterface::MASTER_REQUEST === $event->getParameter('request_type')) { + // set the context even if the parsing does not need to be done + // to have correct link generation + $this->router->setContext(array( + 'base_url' => $request->getBaseUrl(), + 'method' => $request->getMethod(), + 'host' => $request->getHost(), + 'is_secure' => $request->isSecure(), + )); + $this->container->setParameter('request.base_path', $request->getBasePath()); } - // set the context even if the parsing does not need to be done - // to have correct link generation - $this->router->setContext(array( - 'base_url' => $request->getBaseUrl(), - 'method' => $request->getMethod(), - 'host' => $request->getHost(), - 'is_secure' => $request->isSecure(), - )); - $this->container->setParameter('request.base_path', $request->getBasePath()); - if ($request->path->has('_controller')) { return; } diff --git a/src/Symfony/Framework/WebBundle/Listener/ResponseFilter.php b/src/Symfony/Framework/WebBundle/Listener/ResponseFilter.php index 7d9684659a..f4b327d2d2 100644 --- a/src/Symfony/Framework/WebBundle/Listener/ResponseFilter.php +++ b/src/Symfony/Framework/WebBundle/Listener/ResponseFilter.php @@ -6,6 +6,7 @@ use Symfony\Components\EventDispatcher\EventDispatcher; use Symfony\Components\EventDispatcher\Event; use Symfony\Components\HttpKernel\Request; use Symfony\Components\HttpKernel\Response; +use Symfony\Components\HttpKernel\HttpKernelInterface; /* * This file is part of the Symfony framework. @@ -39,7 +40,7 @@ class ResponseFilter public function filter(Event $event, Response $response) { - if (!$event->getParameter('main_request') || $response->headers->has('Content-Type')) { + if (HttpKernelInterface::MASTER_REQUEST !== $event->getParameter('request_type') || $response->headers->has('Content-Type')) { return $response; }