Json Flapping

This commit is contained in:
Greyscale 2024-04-14 21:13:06 +02:00
parent cc7e3dcc41
commit eb236a7836
8 changed files with 44 additions and 109 deletions

View file

@ -552,7 +552,7 @@ class App
return $this->logger;
}
public function loadAllRoutes(ServerRequestInterface $request): self
public function loadAllRoutes(?ServerRequestInterface $request = null): self
{
$this->debugBar['time']->startMeasure('interrogateControllers', 'Time to interrogate controllers for routes');
$this->interrogateControllers();

View file

@ -25,7 +25,7 @@ abstract class AbstractController
{
$response->getBody()->write($root->asXML());
return $response->withHeader('Content-type', 'text/xml');
return $response->withHeader('Content-Type', 'text/xml');
}
public function jsonResponse($json, Request $request, Response $response): Response
@ -33,7 +33,7 @@ abstract class AbstractController
$content = json_encode($json, JSON_PRETTY_PRINT);
$response->getBody()->write($content);
return $response->withHeader('Content-type', 'application/json');
return $response->withHeader('Content-Type', 'application/json');
}
public function redirect(Response $response, string $url = '/', int $code = 302): Response

View file

@ -1,90 +0,0 @@
<?php
declare(strict_types=1);
namespace Benzine\Guzzle;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\StreamInterface;
class JsonResponse implements ResponseInterface
{
public function __construct(
protected ResponseInterface $response
) {}
public function json()
{
return json_decode($this->response->getBody()->getContents(), false);
}
public function getProtocolVersion()
{
return $this->response->getProtocolVersion();
}
public function withProtocolVersion($version)
{
return $this->response->withProtocolVersion($version);
}
public function getHeaders()
{
return $this->response->getHeaders();
}
public function hasHeader($name)
{
return $this->response->hasHeader($name);
}
public function getHeader($name)
{
return $this->response->getHeader($name);
}
public function getHeaderLine($name)
{
return $this->response->getHeaderLine($name);
}
public function withHeader($name, $value)
{
return $this->response->withHeader($name, $value);
}
public function withAddedHeader($name, $value)
{
return $this->response->withAddedHeader($name, $value);
}
public function withoutHeader($name)
{
return $this->response->withoutHeader($name);
}
public function getBody()
{
return $this->response->getBody();
}
public function withBody(StreamInterface $body)
{
return $this->response->withBody($body);
}
public function getStatusCode()
{
return $this->response->getStatusCode();
}
public function withStatus($code, $reasonPhrase = '')
{
return $this->response->withStatus($code, $reasonPhrase);
}
public function getReasonPhrase()
{
return $this->response->getReasonPhrase();
}
}

View file

@ -14,6 +14,10 @@ class JsonResponseExecTimeMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// If path ends in .schema, don't add exec time
if (str_ends_with($request->getUri()->getPath(), '.schema')) {
return $handler->handle($request);
}
$response = $handler->handle($request);
$response->getBody()->rewind();
$responseJson = json_decode($response->getBody()->getContents(), true);
@ -30,7 +34,7 @@ class JsonResponseExecTimeMiddleware implements MiddlewareInterface
$replacementResponse = new Response();
$replacementResponse->getBody()->write(json_encode($responseJson, JSON_PRETTY_PRINT));
$replacementResponse = $replacementResponse->withHeader('Content-type', 'application/json');
$replacementResponse = $replacementResponse->withHeader('Content-Type', 'application/json');
$replacementResponse = $replacementResponse->withStatus($response->getStatusCode());

View file

@ -9,16 +9,16 @@ use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Slim\Psr7\Response;
use Benzine\PSR\JsonResponse;
class JsonResponseUnpackerMiddleware implements MiddlewareInterface
{
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);
if(!($response->hasHeader("Content-Type") && $response->getHeader("Content-Type")[0] === "application/json") ) {
return $response;
if($response->hasHeader("Content-Type") && $response->getHeader("Content-Type")[0] === "application/json" && $response instanceof Response) {
$response = new JsonResponse($response);
}
return new JsonResponse($response);
return $response;
}
}

View file

@ -64,7 +64,7 @@ class JsonValidationMiddleware implements MiddlewareInterface
$response->getBody()->write($content);
$response = $response->withHeader('Content-type', 'application/json');
$response = $response->withHeader('Content-Type', 'application/json');
return $response->withStatus(400);
}

View file

@ -2,7 +2,7 @@
declare(strict_types=1);
namespace Benzine\Middleware;
namespace Benzine\PSR;
use Ergebnis\Json\Json;
use Psr\Http\Message\ResponseInterface;
@ -14,10 +14,8 @@ use Slim\Psr7\Response;
class JsonResponse implements ResponseInterface
{
protected Response $response;
public function __construct(Response $response)
public function __construct(protected Response $response)
{
$this->response = $response;
}
public function getJson() : Json
{
@ -103,5 +101,4 @@ class JsonResponse implements ResponseInterface
{
return $this->response->getReasonPhrase();
}
}

View file

@ -7,6 +7,8 @@ namespace Benzine\Tests\Traits;
use Benzine\App as BenzineApp;
use Benzine\Middleware\JsonResponse;
use DI\Container;
use Ergebnis\Json\Json;
use Middlewares\Utils\Factory;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@ -14,8 +16,12 @@ use Psr\Http\Message\UriInterface;
use Slim\App as SlimApp;
use Slim\Factory\ServerRequestCreatorFactory;
use Slim\Psr7\Factory\ServerRequestFactory;
use Slim\Psr7\Headers;
use Slim\Psr7\Request;
use Slim\Psr7\Response;
use Benzine\Middleware\JsonResponseUnpackerMiddleware;
use Slim\Psr7\Stream;
use Slim\Psr7\Uri;
/**
* Container Trait.
@ -145,11 +151,29 @@ trait AppTestTrait
$this->assertSame($expected, (array) json_decode($actual, true));
}
protected function send(Request $request) : JsonResponse|Response|ResponseInterface {
return $this
->app
->loadAllRoutes($request)
static protected function getHttpHandler() : SlimApp {
return self::$app
->loadAllRoutes()
->getApp()
->handle($request);
->addMiddleware(new JsonResponseUnpackerMiddleware());
}
static protected function send(string $method, string $uri, ?array $data = []) : ResponseInterface {
$request = new Request(
method: $method,
uri: new \GuzzleHttp\Psr7\Uri($uri),
headers: new Headers(),
cookies: [],
serverParams: [],
body: new Stream(fopen('php://temp', 'r+')),
uploadedFiles: []
);
$request = $request->withParsedBody(Json::fromString(json_encode($data))->decoded());
$request = $request->withHeader('Content-Type', 'application/json');
return self::handle($request);
}
static function handle(Request $request) : JsonResponse|Response|ResponseInterface {
return self::getHttpHandler()->handle($request);
}
}