Преглед изворни кода

[HttpKernel] Add support for 'upload_max_filesize' ini directive in the Client

Victor Berchet пре 14 година
родитељ
комит
3df5ec3de5

+ 51 - 11
src/Symfony/Component/HttpKernel/Client.php

@@ -106,8 +106,13 @@ EOF;
     /**
      * Filters an array of files.
      *
-     * This method marks all uploaded files as already moved thus avoiding
-     * UploadedFile's call to move_uploaded_file(), which would otherwise fail.
+     * This method created test instances of UploadedFile so that the move()
+     * method can be called on those instances.
+     *
+     * If the size of a file is greater than the allowed size (from php.ini) then
+     * an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE.
+     *
+     * @see Symfony\Component\HttpFoundation\File\UploadedFile
      *
      * @param array $files An array of files
      *
@@ -120,15 +125,25 @@ EOF;
             if (is_array($value)) {
                 $filtered[$key] = $this->filterFiles($value);
             } elseif ($value instanceof UploadedFile) {
-                // Create a test mode UploadedFile
-                $filtered[$key] = new UploadedFile(
-                    $value->getPathname(),
-                    $value->getClientOriginalName(),
-                    $value->getClientMimeType(),
-                    $value->getClientSize(),
-                    $value->getError(),
-                    true
-                );
+                if ($value->isValid() && $value->getSize() > static::getMaxUploadFilesize()) {
+                    $filtered[$key] = new UploadedFile(
+                        '',
+                        $value->getClientOriginalName(),
+                        $value->getClientMimeType(),
+                        0,
+                        UPLOAD_ERR_INI_SIZE,
+                        true
+                    );
+                } else {
+                    $filtered[$key] = new UploadedFile(
+                        $value->getPathname(),
+                        $value->getClientOriginalName(),
+                        $value->getClientMimeType(),
+                        $value->getClientSize(),
+                        $value->getError(),
+                        true
+                    );
+                }
             } else {
                 $filtered[$key] = $value;
             }
@@ -157,4 +172,29 @@ EOF;
 
         return new DomResponse($response->getContent(), $response->getStatusCode(), $headers);
     }
+
+    /**
+     * Returns the maximum size of an uploaded file
+     *
+     * @return type The maximum size of an uploaded file in bytes
+     */
+    static protected function getMaxUploadFilesize()
+    {
+        $max = trim(ini_get('upload_max_filesize'));
+
+        if ('' === $max) {
+            return PHP_INT_MAX;
+        }
+
+        switch (strtolower(substr($max, -1))) {
+            case 'g':
+                $max *= 1024;
+            case 'm':
+                $max *= 1024;
+            case 'k':
+                $max *= 1024;
+        }
+
+        return (integer) $max;
+    }
 }

+ 38 - 0
tests/Symfony/Tests/Component/HttpKernel/ClientTest.php

@@ -105,4 +105,42 @@ class ClientTest extends \PHPUnit_Framework_TestCase
         $this->assertFileExists($target);
         unlink($target);
     }
+
+    public function testUploadedFileWhenSizeExceedsUploadMaxFileSize()
+    {
+        $source = tempnam(sys_get_temp_dir(), 'source');
+
+        file_put_contents($source, 'foo');
+
+        $kernel = new TestHttpKernel();
+
+        $client = $this
+            ->getMockBuilder('Symfony\Component\HttpKernel\Client')
+            ->setConstructorArgs(array($kernel))
+            ->setMethods(array('getMaxUploadFilesize'))
+            ->getMock()
+        ;
+
+        $client
+            ->staticExpects($this->once())
+            ->method('getMaxUploadFilesize')
+            ->will($this->returnValue(1))
+        ;
+
+        $client->request('POST', '/', array(), array(new UploadedFile($source, 'original', 'mime/original', 123, UPLOAD_ERR_OK)));
+
+        $files = $kernel->request->files->all();
+
+        $this->assertEquals(1, count($files));
+
+        $file = $files[0];
+
+        $this->assertFalse($file->isValid());
+        $this->assertEquals(UPLOAD_ERR_INI_SIZE, $file->getError());
+        $this->assertEquals('mime/original', $file->getClientMimeType());
+        $this->assertEquals('original', $file->getClientOriginalName());
+        $this->assertEquals(0, $file->getClientSize());
+
+        unlink($source);
+    }
 }