2 declare(strict_types
= 1);
3 namespace TYPO3\CMS\Core\Http
;
6 * This file is part of the TYPO3 CMS project.
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
15 * The TYPO3 project - inspiring people to share!
18 use Psr\Http\Message\ResponseInterface
;
19 use Psr\Http\Message\ServerRequestInterface
;
20 use Psr\Http\Server\RequestHandlerInterface
;
21 use TYPO3\CMS\Core\Core\ApplicationInterface
;
22 use TYPO3\CMS\Core\Utility\GeneralUtility
;
27 abstract class AbstractApplication
implements ApplicationInterface
32 protected $requestHandler = '';
37 protected $middlewareStack = '';
40 * @param RequestHandlerInterface $requestHandler
41 * @return MiddlewareDispatcher
43 protected function createMiddlewareDispatcher(RequestHandlerInterface
$requestHandler): MiddlewareDispatcher
45 $resolver = new MiddlewareStackResolver(
46 GeneralUtility
::makeInstance(\TYPO3\CMS\Core\Package\PackageManager
::class),
47 GeneralUtility
::makeInstance(\TYPO3\CMS\Core\Service\DependencyOrderingService
::class),
48 GeneralUtility
::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager
::class)->getCache('cache_core')
50 $middlewares = $resolver->resolve($this->middlewareStack
);
52 return new MiddlewareDispatcher($requestHandler, $middlewares);
58 * @param ResponseInterface $response
60 protected function sendResponse(ResponseInterface
$response)
62 if ($response instanceof NullResponse
) {
66 // @todo This requires some merge strategy or header callback handling
67 if (!headers_sent()) {
68 // If the response code was not changed by legacy code (still is 200)
69 // then allow the PSR-7 response object to explicitly set it.
70 // Otherwise let legacy code take precedence.
71 // This code path can be deprecated once we expose the response object to third party code
72 if (http_response_code() === 200) {
73 header('HTTP/' . $response->getProtocolVersion() . ' ' . $response->getStatusCode() . ' ' . $response->getReasonPhrase());
76 foreach ($response->getHeaders() as $name => $values) {
77 header($name . ': ' . implode(', ', $values));
80 $body = $response->getBody();
81 if ($body instanceof SelfEmittableStreamInterface
) {
82 // Optimization for streams that use php functions like readfile() as fastpath for serving files.
85 echo $body->__toString();
90 * @param ServerRequestInterface $request
91 * @return ResponseInterface
93 protected function handle(ServerRequestInterface
$request): ResponseInterface
95 $requestHandler = GeneralUtility
::makeInstance($this->requestHandler
);
96 $dispatcher = $this->createMiddlewareDispatcher($requestHandler);
98 return $dispatcher->handle($request);
102 * Set up the application and shut it down afterwards
104 * @param callable $execute
106 final public function run(callable
$execute = null)
109 $response = $this->handle(
110 \TYPO3\CMS\Core\Http\ServerRequestFactory
::fromGlobals()
112 if ($execute !== null) {
113 call_user_func($execute);
115 } catch (ImmediateResponseException
$exception) {
116 $response = $exception->getResponse();
119 $this->sendResponse($response);