Skip to content

Commit ba86d7b

Browse files
committed
v3
1 parent e7b261b commit ba86d7b

File tree

8 files changed

+149
-86
lines changed

8 files changed

+149
-86
lines changed

resources/definitions/middlewares/error_handling_middleware.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use Sunrise\Coder\CodecManagerInterface;
1111
use Sunrise\Coder\Dictionary\MediaType;
1212
use Sunrise\Coder\MediaTypeInterface;
13-
use Sunrise\Http\Router\Dictionary\LanguageCode;
13+
use Sunrise\Http\Router\Dictionary\Language;
1414
use Sunrise\Http\Router\Middleware\ErrorHandlingMiddleware;
1515
use Sunrise\Http\Router\OpenApi\Type;
1616
use Sunrise\Http\Router\View\ErrorView;
@@ -29,7 +29,7 @@
2929
'router.error_handling_middleware.produced_media_types' => [],
3030
'router.error_handling_middleware.default_media_type' => MediaType::JSON,
3131
'router.error_handling_middleware.produced_languages' => [],
32-
'router.error_handling_middleware.default_language' => LanguageCode::English,
32+
'router.error_handling_middleware.default_language' => Language::English,
3333
'router.error_handling_middleware.fatal_error_status_code' => null,
3434
'router.error_handling_middleware.fatal_error_message' => null,
3535

resources/definitions/middlewares/payload_decoding_middleware.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,12 @@
1111

1212
return [
1313
'router.payload_decoding_middleware.codec_context' => [],
14-
'router.payload_decoding_middleware.error_status_code' => null,
15-
'router.payload_decoding_middleware.error_message' => null,
1614

1715
'router.route_middlewares' => add([
1816
create(PayloadDecodingMiddleware::class)
1917
->constructor(
2018
codecManager: get(CodecManagerInterface::class),
2119
codecContext: get('router.payload_decoding_middleware.codec_context'),
22-
errorStatusCode: get('router.payload_decoding_middleware.error_status_code'),
23-
errorMessage: get('router.payload_decoding_middleware.error_message'),
2420
)
2521
]),
2622
];

src/Dictionary/ErrorMessage.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ final class ErrorMessage
2222
public const MALFORMED_URI = 'The request URI is malformed and cannot be accepted by the server.';
2323
public const RESOURCE_NOT_FOUND = 'The requested resource was not found for this URI.';
2424
public const METHOD_NOT_ALLOWED = 'The requested method is not allowed for this resource.';
25+
public const MISSING_MEDIA_TYPE = 'The request media type is missing.';
26+
public const UNSUPPORTED_MEDIA_TYPE = 'The request media type is not supported by this resource.';
2527
public const INVALID_VARIABLE = 'The value of the variable {{{ variable_name }}} in the request URI "{{ route_uri }}" is invalid.';
26-
public const INVALID_QUERY = 'The request parameters are invalid.';
28+
public const INVALID_QUERY = 'The request query is invalid.';
2729
public const MISSING_HEADER = 'The request header "{{ header_name }}" is missing.';
2830
public const INVALID_HEADER = 'The request header "{{ header_name }}" is invalid.';
2931
public const MISSING_COOKIE = 'The cookie "{{ cookie_name }}" is missing.';

src/Dictionary/LanguageCode.php renamed to src/Dictionary/Language.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
/**
1919
* @since 3.0.0
2020
*/
21-
enum LanguageCode: string implements LanguageInterface
21+
enum Language: string implements LanguageInterface
2222
{
2323
case English = 'en';
2424

src/Exception/HttpExceptionFactory.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,30 @@ public static function methodNotAllowed(
5858
);
5959
}
6060

61+
public static function missingMediaType(
62+
?string $message = null,
63+
?int $code = null,
64+
?Throwable $previous = null,
65+
): HttpException {
66+
return new HttpException(
67+
$message ?? ErrorMessage::MISSING_MEDIA_TYPE,
68+
$code ?? StatusCodeInterface::STATUS_BAD_REQUEST,
69+
$previous,
70+
);
71+
}
72+
73+
public static function unsupportedMediaType(
74+
?string $message = null,
75+
?int $code = null,
76+
?Throwable $previous = null,
77+
): HttpException {
78+
return new HttpException(
79+
$message ?? ErrorMessage::UNSUPPORTED_MEDIA_TYPE,
80+
$code ?? StatusCodeInterface::STATUS_UNSUPPORTED_MEDIA_TYPE,
81+
$previous,
82+
);
83+
}
84+
6185
public static function invalidVariable(
6286
?string $message = null,
6387
?int $code = null,

src/Middleware/PayloadDecodingMiddleware.php

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,20 @@
1313

1414
namespace Sunrise\Http\Router\Middleware;
1515

16+
use LogicException;
1617
use Psr\Http\Message\ResponseInterface;
1718
use Psr\Http\Message\ServerRequestInterface;
1819
use Psr\Http\Server\MiddlewareInterface;
1920
use Psr\Http\Server\RequestHandlerInterface;
2021
use Sunrise\Coder\CodecManagerInterface;
2122
use Sunrise\Coder\Exception\CodecException;
22-
use Sunrise\Http\Router\Exception\HttpException;
23+
use Sunrise\Http\Router\Dictionary\HeaderName;
2324
use Sunrise\Http\Router\Exception\HttpExceptionFactory;
2425
use Sunrise\Http\Router\ServerRequest;
26+
use Sunrise\Http\Router\StringableMediaType;
27+
28+
use function array_map;
29+
use function sprintf;
2530

2631
/**
2732
* @since 3.0.0
@@ -34,31 +39,42 @@ final class PayloadDecodingMiddleware implements MiddlewareInterface
3439
public function __construct(
3540
private readonly CodecManagerInterface $codecManager,
3641
private readonly array $codecContext = [],
37-
private readonly ?int $errorStatusCode = null,
38-
private readonly ?string $errorMessage = null,
3942
) {
4043
}
4144

4245
/**
4346
* @inheritDoc
44-
*
45-
* @throws HttpException If the request's payload couldn't be decoded.
4647
*/
4748
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
4849
{
4950
$serverRequest = ServerRequest::create($request);
51+
$route = $serverRequest->getRoute();
52+
$serverConsumedMediaTypes = $route->getConsumedMediaTypes();
53+
54+
// The server expects nothing from the client, just keep going...
55+
if ($serverConsumedMediaTypes === []) {
56+
return $handler->handle($request);
57+
}
5058

5159
$clientProducedMediaType = $serverRequest->getClientProducedMediaType();
5260
if ($clientProducedMediaType === null) {
53-
return $handler->handle($request);
61+
throw HttpExceptionFactory::missingMediaType();
5462
}
5563

5664
if (!$serverRequest->serverConsumesMediaType($clientProducedMediaType)) {
57-
return $handler->handle($request);
65+
throw HttpExceptionFactory::unsupportedMediaType()
66+
->addHeaderField(HeaderName::ACCEPT, ...array_map(
67+
StringableMediaType::create(...),
68+
$serverConsumedMediaTypes,
69+
));
5870
}
5971

6072
if (!$this->codecManager->supportsMediaType($clientProducedMediaType)) {
61-
return $handler->handle($request);
73+
throw new LogicException(sprintf(
74+
'The route "%s" expects the media type "%s" that is not supported by the codec manager.',
75+
$route->getName(),
76+
$clientProducedMediaType->getIdentifier(),
77+
));
6278
}
6379

6480
try {
@@ -69,15 +85,9 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
6985
$this->codecContext,
7086
);
7187
} catch (CodecException $e) {
72-
throw HttpExceptionFactory::invalidBody(
73-
$this->errorMessage,
74-
$this->errorStatusCode,
75-
previous: $e,
76-
);
88+
throw HttpExceptionFactory::invalidBody(previous: $e);
7789
}
7890

79-
return $handler->handle(
80-
$request->withParsedBody($parsedBody)
81-
);
91+
return $handler->handle($request->withParsedBody($parsedBody));
8292
}
8393
}

tests/Dictionary/LanguageCodeTest.php renamed to tests/Dictionary/LanguageTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
namespace Sunrise\Http\Router\Tests\Dictionary;
66

77
use PHPUnit\Framework\TestCase;
8-
use Sunrise\Http\Router\Dictionary\LanguageCode;
8+
use Sunrise\Http\Router\Dictionary\Language;
99

10-
final class LanguageCodeTest extends TestCase
10+
final class LanguageTest extends TestCase
1111
{
1212
public function testCode(): void
1313
{
14-
self::assertSame('en', LanguageCode::English->getCode());
14+
self::assertSame('en', Language::English->getCode());
1515
}
1616
}

0 commit comments

Comments
 (0)