Skip to content

Commit 73569a9

Browse files
committed
Add parameter to control maximum file upload size
1 parent e24e59d commit 73569a9

5 files changed

Lines changed: 58 additions & 8 deletions

File tree

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,18 @@ $server = new StreamingServer(new MiddlewareRunner([
784784

785785
See also [example #12](examples) for more details.
786786

787+
By default, this middleware respects the
788+
[`upload_max_filesize`](http://php.net/manual/en/ini.core.php#ini.upload-max-filesize)
789+
(default `2M`) ini setting.
790+
Files that exceed this limit will be rejected with an `UPLOAD_ERR_INI_SIZE` error.
791+
You can control the maximum filesize for each individual file upload by
792+
explicitly passing the maximum filesize in bytes as the first parameter to the
793+
constructor like this:
794+
795+
```php
796+
new RequestBodyParserMiddleware(8 * 1024 * 1024); // 8 MiB limit per file
797+
```
798+
787799
> Note that this middleware handler simply parses everything that is already
788800
buffered in the request body.
789801
It is imperative that the request body is buffered by a prior middleware
@@ -798,10 +810,9 @@ See also [example #12](examples) for more details.
798810
more details.
799811

800812
> PHP's `MAX_FILE_SIZE` hidden field is respected by this middleware.
813+
Files that exceed this limit will be rejected with an `UPLOAD_ERR_FORM_SIZE` error.
801814

802815
> This middleware respects the
803-
[`upload_max_filesize`](http://php.net/manual/en/ini.core.php#ini.upload-max-filesize)
804-
(default `2M`),
805816
[`max_input_vars`](http://php.net/manual/en/info.configuration.php#ini.max-input-vars)
806817
(default `1000`) and
807818
[`max_input_nesting_level`](http://php.net/manual/en/info.configuration.php#ini.max-input-nesting-level)

examples/12-upload.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@
121121

122122
// buffer and parse HTTP request body before running our request handler
123123
$server = new StreamingServer(new MiddlewareRunner(array(
124-
new RequestBodyBufferMiddleware(100000), // 100 KB max, ignore body otherwise
125-
new RequestBodyParserMiddleware(),
124+
new RequestBodyBufferMiddleware(8 * 1024 * 1024), // 8 MiB max, ignore body otherwise
125+
new RequestBodyParserMiddleware(100 * 1024), // 100 KiB max, reject upload otherwise
126126
$handler
127127
)));
128128

src/Io/MultipartParser.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ final class MultipartParser
5656

5757
private $postCount = 0;
5858

59-
public function __construct()
59+
/**
60+
* @param int|null $uploadMaxFilesize
61+
*/
62+
public function __construct($uploadMaxFilesize = null)
6063
{
6164
$var = ini_get('max_input_vars');
6265
if ($var !== false) {
@@ -67,7 +70,7 @@ public function __construct()
6770
$this->maxInputNestingLevel = (int)$var;
6871
}
6972

70-
$this->uploadMaxFilesize = $this->iniUploadMaxFilesize();
73+
$this->uploadMaxFilesize = $uploadMaxFilesize === null ? $this->iniUploadMaxFilesize() : (int)$uploadMaxFilesize;
7174
}
7275

7376
public function parse(ServerRequestInterface $request)

src/Middleware/RequestBodyParserMiddleware.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@ final class RequestBodyParserMiddleware
99
{
1010
private $multipart;
1111

12-
public function __construct()
12+
/**
13+
* @param int|null $uploadMaxFilesize
14+
*/
15+
public function __construct($uploadMaxFilesize = null)
1316
{
14-
$this->multipart = new MultipartParser();
17+
$this->multipart = new MultipartParser($uploadMaxFilesize);
1518
}
1619

1720
public function __invoke(ServerRequestInterface $request, $next)

tests/Io/MultipartParserTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,39 @@ public function testUploadEmptyFile()
688688
$this->assertSame('', (string)$file->getStream());
689689
}
690690

691+
public function testUploadTooLargeFile()
692+
{
693+
$boundary = "---------------------------12758086162038677464950549563";
694+
695+
$data = "--$boundary\r\n";
696+
$data .= "Content-Disposition: form-data; name=\"file\"; filename=\"hello\"\r\n";
697+
$data .= "Content-type: text/plain\r\n";
698+
$data .= "\r\n";
699+
$data .= "world\r\n";
700+
$data .= "--$boundary--\r\n";
701+
702+
$request = new ServerRequest('POST', 'http://example.com/', array(
703+
'Content-Type' => 'multipart/form-data; boundary=' . $boundary,
704+
), $data, 1.1);
705+
706+
$parser = new MultipartParser(4);
707+
$parsedRequest = $parser->parse($request);
708+
709+
$files = $parsedRequest->getUploadedFiles();
710+
711+
$this->assertCount(1, $files);
712+
$this->assertTrue(isset($files['file']));
713+
$this->assertInstanceOf('Psr\Http\Message\UploadedFileInterface', $files['file']);
714+
715+
/* @var $file \Psr\Http\Message\UploadedFileInterface */
716+
$file = $files['file'];
717+
718+
$this->assertSame('hello', $file->getClientFilename());
719+
$this->assertSame('text/plain', $file->getClientMediaType());
720+
$this->assertSame(5, $file->getSize());
721+
$this->assertSame(UPLOAD_ERR_INI_SIZE, $file->getError());
722+
}
723+
691724
public function testUploadNoFile()
692725
{
693726
$boundary = "---------------------------12758086162038677464950549563";

0 commit comments

Comments
 (0)