Skip to content

Commit

Permalink
(thephpleague#134) Add support for comma-separated list of encoding c…
Browse files Browse the repository at this point in the history
…ontent types
  • Loading branch information
Jim Cottrell committed Jul 12, 2021
1 parent 4a16cd2 commit b18f235
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 23 deletions.
49 changes: 27 additions & 22 deletions src/PSR7/Validators/BodyValidator/MultipartValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
use Riverline\MultiPartParser\StreamedPart;
use RuntimeException;

use function array_map;
use function array_replace;
use function explode;
use function in_array;
use function is_array;
use function json_decode;
Expand Down Expand Up @@ -117,29 +119,29 @@ private function validatePlainBodyMultipart(

foreach ($parts as $part) {
// 2.1 parts encoding
$partContentType = $part->getHeader(self::HEADER_CONTENT_TYPE);
$encodingContentType = $this->detectEncondingContentType($encoding, $part, $schema->properties[$partName]);
if (strpos($encodingContentType, '*') === false) {
// strict comparison (ie "image/jpeg")
if ($encodingContentType !== $partContentType) {
throw InvalidBody::becauseBodyDoesNotMatchSchemaMultipart(
$partName,
$partContentType,
$addr
);
}
} else {
// loose comparison (ie "image/*")
$encodingContentType = str_replace('*', '.*', $encodingContentType);
if (! preg_match('#' . $encodingContentType . '#', $partContentType)) {
throw InvalidBody::becauseBodyDoesNotMatchSchemaMultipart(
$partName,
$partContentType,
$addr
);
$partContentType = $part->getHeader(self::HEADER_CONTENT_TYPE);
$validContentTypes = $this->detectEncodingContentTypes($encoding, $part, $schema->properties[$partName]);
$match = false;

foreach ($validContentTypes as $encodingContentType) {
if (strpos($encodingContentType, '*') === false) {
// strict comparison (ie "image/jpeg")
$match = $match || $encodingContentType === $partContentType;
} else {
// loose comparison (ie "image/*")
$encodingContentType = str_replace('*', '.*', $encodingContentType);
$match = $match || preg_match('#' . $encodingContentType . '#', $partContentType);
}
}

if (! $match) {
throw InvalidBody::becauseBodyDoesNotMatchSchemaMultipart(
$partName,
$partContentType,
$addr
);
}

// 2.2. parts headers
$validator = new SchemaValidator($this->detectValidationStrategy($message));
foreach ($encoding->headers as $headerName => $headerSpec) {
Expand Down Expand Up @@ -195,7 +197,10 @@ private function parseMultipartData(OperationAddress $addr, StreamedPart $docume
return $multipartData;
}

private function detectEncondingContentType(Encoding $encoding, StreamedPart $part, Schema $partSchema): string
/**
* @return string[]
*/
private function detectEncodingContentTypes(Encoding $encoding, StreamedPart $part, Schema $partSchema): array
{
$contentType = $encoding->contentType;

Expand All @@ -219,7 +224,7 @@ private function detectEncondingContentType(Encoding $encoding, StreamedPart $pa
}
}

return $contentType;
return array_map('trim', explode(',', $contentType));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/stubs/multipart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ paths:
format: binary
encoding:
image:
contentType: image/*
contentType: specific/type, image/*
responses:
204:
description: good post
Expand Down

0 comments on commit b18f235

Please sign in to comment.