[!!!][TASK] Remove request type specific code in Bootstrap
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Http / AbstractApplication.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Core\Http;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
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.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
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;
23
24 /**
25 * @internal
26 */
27 abstract class AbstractApplication implements ApplicationInterface
28 {
29 /**
30 * @var string
31 */
32 protected $requestHandler = '';
33
34 /**
35 * @var string
36 */
37 protected $middlewareStack = '';
38
39 /**
40 * @param RequestHandlerInterface $requestHandler
41 * @return MiddlewareDispatcher
42 */
43 protected function createMiddlewareDispatcher(RequestHandlerInterface $requestHandler): MiddlewareDispatcher
44 {
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')
49 );
50 $middlewares = $resolver->resolve($this->middlewareStack);
51
52 return new MiddlewareDispatcher($requestHandler, $middlewares);
53 }
54
55 /**
56 * Outputs content
57 *
58 * @param ResponseInterface $response
59 */
60 protected function sendResponse(ResponseInterface $response)
61 {
62 if ($response instanceof \TYPO3\CMS\Core\Http\NullResponse) {
63 return;
64 }
65
66 if (!headers_sent()) {
67 // If the response code was not changed by legacy code (still is 200)
68 // then allow the PSR-7 response object to explicitly set it.
69 // Otherwise let legacy code take precedence.
70 // This code path can be deprecated once we expose the response object to third party code
71 if (http_response_code() === 200) {
72 header('HTTP/' . $response->getProtocolVersion() . ' ' . $response->getStatusCode() . ' ' . $response->getReasonPhrase());
73 }
74
75 foreach ($response->getHeaders() as $name => $values) {
76 header($name . ': ' . implode(', ', $values));
77 }
78 }
79 echo $response->getBody()->__toString();
80 }
81
82 /**
83 * @param ServerRequestInterface $request
84 * @return ResponseInterface
85 */
86 protected function handle(ServerRequestInterface $request): ResponseInterface
87 {
88 $requestHandler = GeneralUtility::makeInstance($this->requestHandler);
89 $dispatcher = $this->createMiddlewareDispatcher($requestHandler);
90
91 return $dispatcher->handle($request);
92 }
93
94 /**
95 * Set up the application and shut it down afterwards
96 *
97 * @param callable $execute
98 */
99 public function run(callable $execute = null)
100 {
101 $response = $this->handle(\TYPO3\CMS\Core\Http\ServerRequestFactory::fromGlobals());
102
103 if ($execute !== null) {
104 call_user_func($execute);
105 }
106
107 $this->sendResponse($response);
108 }
109 }