AppCoreMiddleware.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace App\Middlewares;
  12. use App\Constants\CommonConstant;
  13. use Hyperf\HttpMessage\Stream\SwooleStream;
  14. use Hyperf\HttpServer\CoreMiddleware;
  15. use Hyperf\Utils\Codec\Json;
  16. use Hyperf\Utils\Contracts\Arrayable;
  17. use Hyperf\Utils\Contracts\Jsonable;
  18. use Hyperf\Utils\Str;
  19. use Psr\Http\Message\ResponseInterface;
  20. use Psr\Http\Message\ServerRequestInterface;
  21. use Psr\Http\Server\RequestHandlerInterface;
  22. use App\Contracts\Responsable;
  23. /**
  24. * Core middleware of Hyperf, main responsibility is use to handle route info
  25. * and then delegate to the specified handler (which is Controller) to handle the request,
  26. * generate a response object and delegate to next middleware (Because this middleware is the
  27. * core middleware, then the next middleware also means it's the previous middlewares object) .
  28. */
  29. class AppCoreMiddleware extends CoreMiddleware
  30. {
  31. /**
  32. * Process an incoming server request and return a response, optionally delegating
  33. * response creation to a handler.
  34. */
  35. public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
  36. {
  37. // 覆盖Hyperf服务名字标识.
  38. $res = parent::process($request, $handler);
  39. return $res->withHeader('Server', env('RESPONSE_SERVER_NAME', 'Hyperf'));
  40. }
  41. /**
  42. * Transfer the non-standard response content to a standard response object.
  43. *
  44. * @param null|array|Arrayable|Jsonable|string $response
  45. */
  46. protected function transferToResponse($response, ServerRequestInterface $request): ResponseInterface
  47. {
  48. // 加入Responsable钩子.
  49. if ($response instanceof Responsable) {
  50. $response = $response->toResponse($request);
  51. }
  52. if (is_string($response)) {
  53. return $this->response()->withAddedHeader('content-type', 'text/plain')->withBody(new SwooleStream($response));
  54. }
  55. if (is_array($response) || $response instanceof Arrayable) {
  56. return $this->response()
  57. ->withAddedHeader('content-type', 'application/json')
  58. ->withBody(new SwooleStream(Json::encode($response)));
  59. }
  60. if ($response instanceof Jsonable) {
  61. return $this->response()
  62. ->withAddedHeader('content-type', 'application/json')
  63. ->withBody(new SwooleStream((string) $response));
  64. }
  65. return $response;
  66. // return $this->response()->withAddedHeader('content-type', 'text/plain')->withBody(new SwooleStream((string) $response));
  67. }
  68. /**
  69. * Handle the response when cannot found any routes.
  70. *
  71. * @param ServerRequestInterface $request
  72. * @return array|Arrayable|mixed|ResponseInterface|string
  73. */
  74. protected function handleNotFound(ServerRequestInterface $request)
  75. {
  76. // 重写路由找不到的处理逻辑.
  77. $statusCode = 404;
  78. $clientRequest = request();
  79. $headerContentType = $clientRequest->header('content-type');
  80. if (!empty($headerContentType) && Str::contains($headerContentType, ['/json', '+json'])) {
  81. $res = [
  82. 'code' => $statusCode,
  83. 'message' => '404 not found',
  84. 'data' => [],
  85. 'handshake' => CommonConstant::HANDSHAKE,
  86. ];
  87. return $this->response()->withStatus($statusCode)->withAddedHeader('content-type', 'application/json')
  88. ->withBody(new SwooleStream(Json::encode($res)));
  89. } else {
  90. return $this->response()->withStatus($statusCode)->withBody(new SwooleStream((string)$statusCode));
  91. }
  92. }
  93. /**
  94. * Handle the response when the routes found but doesn't match any available methods.
  95. *
  96. * @return array|Arrayable|mixed|ResponseInterface|string
  97. */
  98. protected function handleMethodNotAllowed(array $methods, ServerRequestInterface $request)
  99. {
  100. // 重写 HTTP 方法不允许的处理逻辑.
  101. $statusCode = 405;
  102. $clientRequest = request();
  103. $headerContentType = $clientRequest->header('content-type');
  104. if (!empty($headerContentType) && Str::contains($headerContentType, ['/json', '+json'])) {
  105. // 重写路由找不到的处理逻辑.
  106. $res = [
  107. 'code' => $statusCode,
  108. 'message' => '405 Method Not Allowed',
  109. 'data' => [],
  110. 'handshake' => CommonConstant::HANDSHAKE,
  111. ];
  112. return $this->response()->withStatus($statusCode)->withAddedHeader('content-type', 'application/json')
  113. ->withBody(new SwooleStream(Json::encode($res)));
  114. } else {
  115. return $this->response()->withStatus($statusCode)->withAddedHeader('Allow', implode(', ', $methods))->withBody(new SwooleStream((string)$statusCode));
  116. }
  117. }
  118. }