Server.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.3.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Http;
  16. use Cake\Core\HttpApplicationInterface;
  17. use Cake\Core\PluginApplicationInterface;
  18. use Cake\Event\EventDispatcherTrait;
  19. use Psr\Http\Message\ResponseInterface;
  20. use Psr\Http\Message\ServerRequestInterface;
  21. use RuntimeException;
  22. use Zend\Diactoros\Response\EmitterInterface;
  23. /**
  24. * Runs an application invoking all the PSR7 middleware and the registered application.
  25. */
  26. class Server
  27. {
  28. use EventDispatcherTrait;
  29. /**
  30. * @var \Cake\Core\HttpApplicationInterface
  31. */
  32. protected $app;
  33. /**
  34. * @var \Cake\Http\Runner
  35. */
  36. protected $runner;
  37. /**
  38. * Constructor
  39. *
  40. * @param \Cake\Core\HttpApplicationInterface $app The application to use.
  41. */
  42. public function __construct(HttpApplicationInterface $app)
  43. {
  44. $this->setApp($app);
  45. $this->setRunner(new Runner());
  46. }
  47. /**
  48. * Run the request/response through the Application and its middleware.
  49. *
  50. * This will invoke the following methods:
  51. *
  52. * - App->bootstrap() - Perform any bootstrapping logic for your application here.
  53. * - App->middleware() - Attach any application middleware here.
  54. * - Trigger the 'Server.buildMiddleware' event. You can use this to modify the
  55. * from event listeners.
  56. * - Run the middleware queue including the application.
  57. *
  58. * @param \Psr\Http\Message\ServerRequestInterface|null $request The request to use or null.
  59. * @param \Psr\Http\Message\ResponseInterface|null $response The response to use or null.
  60. * @return \Psr\Http\Message\ResponseInterface
  61. * @throws \RuntimeException When the application does not make a response.
  62. */
  63. public function run(ServerRequestInterface $request = null, ResponseInterface $response = null)
  64. {
  65. $this->app->bootstrap();
  66. $hasPlugins = $this->app instanceof PluginApplicationInterface;
  67. if ($hasPlugins) {
  68. $this->app->pluginBootstrap();
  69. }
  70. $response = $response ?: new Response();
  71. $request = $request ?: ServerRequestFactory::fromGlobals();
  72. $middleware = $this->app->middleware(new MiddlewareQueue());
  73. if ($hasPlugins) {
  74. $middleware = $this->app->pluginMiddleware($middleware);
  75. }
  76. if (!($middleware instanceof MiddlewareQueue)) {
  77. throw new RuntimeException('The application `middleware` method did not return a middleware queue.');
  78. }
  79. $this->dispatchEvent('Server.buildMiddleware', ['middleware' => $middleware]);
  80. $middleware->add($this->app);
  81. $response = $this->runner->run($middleware, $request, $response);
  82. if (!($response instanceof ResponseInterface)) {
  83. throw new RuntimeException(sprintf(
  84. 'Application did not create a response. Got "%s" instead.',
  85. is_object($response) ? get_class($response) : $response
  86. ));
  87. }
  88. return $response;
  89. }
  90. /**
  91. * Emit the response using the PHP SAPI.
  92. *
  93. * @param \Psr\Http\Message\ResponseInterface $response The response to emit
  94. * @param \Zend\Diactoros\Response\EmitterInterface|null $emitter The emitter to use.
  95. * When null, a SAPI Stream Emitter will be used.
  96. * @return void
  97. */
  98. public function emit(ResponseInterface $response, EmitterInterface $emitter = null)
  99. {
  100. if (!$emitter) {
  101. $emitter = new ResponseEmitter();
  102. }
  103. $emitter->emit($response);
  104. }
  105. /**
  106. * Set the application.
  107. *
  108. * @param \Cake\Core\HttpApplicationInterface $app The application to set.
  109. * @return $this
  110. */
  111. public function setApp(HttpApplicationInterface $app)
  112. {
  113. $this->app = $app;
  114. return $this;
  115. }
  116. /**
  117. * Get the current application.
  118. *
  119. * @return \Cake\Core\HttpApplicationInterface The application that will be run.
  120. */
  121. public function getApp()
  122. {
  123. return $this->app;
  124. }
  125. /**
  126. * Set the runner
  127. *
  128. * @param \Cake\Http\Runner $runner The runner to use.
  129. * @return $this
  130. */
  131. public function setRunner(Runner $runner)
  132. {
  133. $this->runner = $runner;
  134. return $this;
  135. }
  136. }