From 6dcfb8dda323b4ac67bd9995d480297c93dfb185 Mon Sep 17 00:00:00 2001 From: Jim Cottrell Date: Wed, 15 Feb 2023 18:45:36 -0700 Subject: [PATCH 1/2] Allow specifying encoding for optional parts of multipart data without validation errors --- .../BodyValidator/MultipartValidator.php | 6 ------ .../BodyValidator/MultipartValidatorTest.php | 17 +++++++++++++++++ tests/stubs/multipart.yaml | 6 ++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/PSR7/Validators/BodyValidator/MultipartValidator.php b/src/PSR7/Validators/BodyValidator/MultipartValidator.php index b7f13b71..9cffcc1c 100644 --- a/src/PSR7/Validators/BodyValidator/MultipartValidator.php +++ b/src/PSR7/Validators/BodyValidator/MultipartValidator.php @@ -108,12 +108,6 @@ private function validatePlainBodyMultipart( foreach ($encodings as $partName => $encoding) { $parts = $document->getPartsByName($partName); // multiple parts share a name? - if (! $parts) { - throw new RuntimeException(sprintf( - 'Specified body part %s is not found', - $partName - )); - } foreach ($parts as $part) { // 2.1 parts encoding diff --git a/tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php b/tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php index ee85c0c0..2cdb270f 100644 --- a/tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php +++ b/tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php @@ -211,6 +211,23 @@ public function dataProviderMultipartRed(): array [file content goes there] ------WebKitFormBoundaryWfPNVh4wuWBlyEyQ-- HTTP +, + InvalidBody::class, + ], + // missing required part + [ + << Date: Tue, 21 Feb 2023 13:26:30 -0700 Subject: [PATCH 2/2] Also remove check from multi-part server request validation --- .../BodyValidator/MultipartValidator.php | 4 +- .../BodyValidator/MultipartValidatorTest.php | 60 ++++++++++++++----- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/PSR7/Validators/BodyValidator/MultipartValidator.php b/src/PSR7/Validators/BodyValidator/MultipartValidator.php index 9cffcc1c..b8aff48f 100644 --- a/src/PSR7/Validators/BodyValidator/MultipartValidator.php +++ b/src/PSR7/Validators/BodyValidator/MultipartValidator.php @@ -26,7 +26,6 @@ use Psr\Http\Message\UploadedFileInterface; use Riverline\MultiPartParser\Converters\PSR7; use Riverline\MultiPartParser\StreamedPart; -use RuntimeException; use function array_replace; use function in_array; @@ -35,7 +34,6 @@ use function json_last_error; use function json_last_error_msg; use function preg_match; -use function sprintf; use function str_replace; use function strpos; @@ -247,7 +245,7 @@ private function validateServerRequestMultipart( foreach ($encodings as $partName => $encoding) { if (! isset($body[$partName])) { - throw new RuntimeException(sprintf('Specified body part %s is not found', $partName)); + continue; } $part = $body[$partName]; diff --git a/tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php b/tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php index 2cdb270f..b2c38bcb 100644 --- a/tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php +++ b/tests/PSR7/Validators/BodyValidator/MultipartValidatorTest.php @@ -11,6 +11,7 @@ use League\OpenAPIValidation\PSR7\Exception\Validation\InvalidHeaders; use League\OpenAPIValidation\PSR7\ValidatorBuilder; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\UploadedFileInterface; use function filesize; use function GuzzleHttp\Psr7\parse_request; @@ -339,25 +340,56 @@ public function testValidateMultipartRed(string $message, string $expectedExcept $validator->validate($serverRequest); } - public function testValidateMultipartServerRequestGreen(): void + /** + * @return mixed[][] + */ + public function dataProviderMultipartServerRequestGreen(): array { - $specFile = __DIR__ . '/../../../stubs/multipart.yaml'; - $imagePath = __DIR__ . '/../../../stubs/image.jpg'; $imageSize = filesize($imagePath); - $serverRequest = (new ServerRequest('post', new Uri('/multipart'))) - ->withHeader('Content-Type', 'multipart/form-data') - ->withParsedBody([ - 'id' => 'bc8e1430-a963-11e9-a2a3-2a2ae2dbcce4', - 'address' => [ - 'street' => 'Some street', - 'city' => 'some city', + return [ + // Normal multipart message + [ + 'post', + '/multipart', + [ + 'id' => 'bc8e1430-a963-11e9-a2a3-2a2ae2dbcce4', + 'address' => [ + 'street' => 'Some street', + 'city' => 'some city', + ], + ], + [ + 'profileImage' => new UploadedFile($imagePath, $imageSize, 0), + ], + ], + // Missing optional field with defined encoding + [ + 'post', + '/multipart/encoding', + [], + [ + 'image' => new UploadedFile($imagePath, $imageSize, 0), ], - ]) - ->withUploadedFiles([ - 'profileImage' => new UploadedFile($imagePath, $imageSize, 0), - ]); + ], + ]; + } + + /** + * @param string[] $body + * @param array $files + * + * @dataProvider dataProviderMultipartServerRequestGreen + */ + public function testValidateMultipartServerRequestGreen(string $method, string $uri, array $body = [], array $files = []): void + { + $specFile = __DIR__ . '/../../../stubs/multipart.yaml'; + + $serverRequest = (new ServerRequest($method, new Uri($uri))) + ->withHeader('Content-Type', 'multipart/form-data') + ->withParsedBody($body) + ->withUploadedFiles($files); $validator = (new ValidatorBuilder())->fromYamlFile($specFile)->getServerRequestValidator(); $validator->validate($serverRequest);