Skip to content

Commit 0b171c8

Browse files
committed
Allow ini-like filesize for RequestBodyBufferMiddleware and MultipartParser
1 parent bdb7e96 commit 0b171c8

5 files changed

Lines changed: 72 additions & 11 deletions

File tree

src/Io/MultipartParser.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ final class MultipartParser
6868
private $emptyCount = 0;
6969

7070
/**
71-
* @param int|null $uploadMaxFilesize
71+
* @param int|string|null $uploadMaxFilesize
7272
* @param int|null $maxFileUploads
7373
*/
7474
public function __construct($uploadMaxFilesize = null, $maxFileUploads = null)
@@ -83,10 +83,10 @@ public function __construct($uploadMaxFilesize = null, $maxFileUploads = null)
8383
}
8484

8585
if ($uploadMaxFilesize === null) {
86-
$uploadMaxFilesize = IniUtil::iniSizeToBytes(ini_get('upload_max_filesize'));
86+
$uploadMaxFilesize = ini_get('upload_max_filesize');
8787
}
8888

89-
$this->uploadMaxFilesize = (int)$uploadMaxFilesize;
89+
$this->uploadMaxFilesize = IniUtil::iniSizeToBytes($uploadMaxFilesize);
9090
$this->maxFileUploads = $maxFileUploads === null ? (ini_get('file_uploads') === '' ? 0 : (int)ini_get('max_file_uploads')) : (int)$maxFileUploads;
9191
}
9292

src/Middleware/RequestBodyBufferMiddleware.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,19 @@ final class RequestBodyBufferMiddleware
1414
private $sizeLimit;
1515

1616
/**
17-
* @param int|null $sizeLimit Either an int with the max request body size
18-
* or null to use post_max_size from PHP's
19-
* configuration. (Note that the value from
20-
* the CLI configuration will be used.)
17+
* @param int|string|null $sizeLimit Either an int with the max request body size
18+
* in bytes or an ini like size string
19+
* or null to use post_max_size from PHP's
20+
* configuration. (Note that the value from
21+
* the CLI configuration will be used.)
2122
*/
2223
public function __construct($sizeLimit = null)
2324
{
2425
if ($sizeLimit === null) {
25-
$sizeLimit = IniUtil::iniSizeToBytes(ini_get('post_max_size'));
26+
$sizeLimit = ini_get('post_max_size');
2627
}
2728

28-
$this->sizeLimit = $sizeLimit;
29+
$this->sizeLimit = IniUtil::iniSizeToBytes($sizeLimit);
2930
}
3031

3132
public function __invoke(ServerRequestInterface $request, $stack)

src/Middleware/RequestBodyParserMiddleware.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ final class RequestBodyParserMiddleware
1010
private $multipart;
1111

1212
/**
13-
* @param int|null $uploadMaxFilesize
13+
* @param int|string|null $uploadMaxFilesize
1414
* @param int|null $maxFileUploads
1515
*/
1616
public function __construct($uploadMaxFilesize = null, $maxFileUploads = null)

tests/Io/MultipartParserTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,39 @@ public function testUploadTooLargeFile()
721721
$this->assertSame(UPLOAD_ERR_INI_SIZE, $file->getError());
722722
}
723723

724+
public function testUploadTooLargeFileWithIniLikeSize()
725+
{
726+
$boundary = "---------------------------12758086162038677464950549563";
727+
728+
$data = "--$boundary\r\n";
729+
$data .= "Content-Disposition: form-data; name=\"file\"; filename=\"hello\"\r\n";
730+
$data .= "Content-type: text/plain\r\n";
731+
$data .= "\r\n";
732+
$data .= str_repeat('world', 1024) . "\r\n";
733+
$data .= "--$boundary--\r\n";
734+
735+
$request = new ServerRequest('POST', 'http://example.com/', array(
736+
'Content-Type' => 'multipart/form-data; boundary=' . $boundary,
737+
), $data, 1.1);
738+
739+
$parser = new MultipartParser('1K');
740+
$parsedRequest = $parser->parse($request);
741+
742+
$files = $parsedRequest->getUploadedFiles();
743+
744+
$this->assertCount(1, $files);
745+
$this->assertTrue(isset($files['file']));
746+
$this->assertInstanceOf('Psr\Http\Message\UploadedFileInterface', $files['file']);
747+
748+
/* @var $file \Psr\Http\Message\UploadedFileInterface */
749+
$file = $files['file'];
750+
751+
$this->assertSame('hello', $file->getClientFilename());
752+
$this->assertSame('text/plain', $file->getClientMediaType());
753+
$this->assertSame(5120, $file->getSize());
754+
$this->assertSame(UPLOAD_ERR_INI_SIZE, $file->getError());
755+
}
756+
724757
public function testUploadNoFile()
725758
{
726759
$boundary = "---------------------------12758086162038677464950549563";

tests/Middleware/RequestBodyBufferMiddlewareTest.php

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function testAlreadyBufferedResolvesImmediately()
4646
{
4747
$size = 1024;
4848
$body = str_repeat('x', $size);
49-
$stream = new BufferStream($size);
49+
$stream = new BufferStream(1024);
5050
$stream->write($body);
5151
$serverRequest = new ServerRequest(
5252
'GET',
@@ -93,6 +93,33 @@ function (ServerRequestInterface $request) {
9393
$this->assertSame('', $response->getBody()->getContents());
9494
}
9595

96+
public function testKnownExcessiveSizedWithIniLikeSize()
97+
{
98+
$loop = Factory::create();
99+
100+
$stream = new ThroughStream();
101+
$loop->addTimer(0.001, function () use ($stream) {
102+
$stream->end(str_repeat('a', 2048));
103+
});
104+
$serverRequest = new ServerRequest(
105+
'GET',
106+
'https://example.com/',
107+
array(),
108+
new HttpBodyStream($stream, 2048)
109+
);
110+
111+
$buffer = new RequestBodyBufferMiddleware('1K');
112+
$response = Block\await($buffer(
113+
$serverRequest,
114+
function (ServerRequestInterface $request) {
115+
return new Response(200, array(), $request->getBody()->getContents());
116+
}
117+
), $loop);
118+
119+
$this->assertSame(200, $response->getStatusCode());
120+
$this->assertSame('', $response->getBody()->getContents());
121+
}
122+
96123
public function testAlreadyBufferedExceedingSizeResolvesImmediatelyWithEmptyBody()
97124
{
98125
$serverRequest = new ServerRequest(

0 commit comments

Comments
 (0)