contributte / psr7-http-message

:dizzy: PSR #7 [HTTP Message Interface] to Nette Framework (@nette)
https://contributte.org/packages/contributte/psr7-http-message.html
MIT License
21 stars 5 forks source link

Multiple files in POST #13

Closed sladdky closed 6 years ago

sladdky commented 6 years ago

If you try to upload two files in POST and one is empty (in case of both being empty, the issue occurs as well, but I'm not sure now),

Contributte\Psr7\Psr7ServerRequest::normalizeNetteFiles

will throw exception

InvalidArgumentException('Invalid value in files specification').

If you try to upload multiple files in POST as array (type='file[1]', type='file[2]'), it throws exception again because parameter array $files contains inner arrays.

intended or am I doing anything wrong?

for now I modified method of Contributte\Psr7\Psr7ServerRequest to accept recursive arrays and ignore empty files:

public static function normalizeNetteFiles(array $files)
    {
        $normalized = [];

        foreach ($files as $file) {
            if ($file instanceof FileUpload) {
                $normalized[] = new Psr7UploadedFile(
                    $file->getTemporaryFile(),
                    intval($file->getSize()),
                    $file->getError(),
                    $file->getName(),
                    $file->getContentType()
                );
            } else if (is_array($file)) {
                $normalized = array_merge($normalized, self::normalizeNetteFiles($file));
            } else if ($file === null) {
                continue;
            } else {
                throw new InvalidArgumentException('Invalid value in files specification');
            }
        }

        return $normalized;
    }
f3l1x commented 6 years ago

Hi, thanks for an issue. I need to check it manually. Could you please describe when file is empty?

sladdky commented 6 years ago

This package is being used in apitte. Here's my code of a controller and a form.

/**
 * @Controller
 * @ControllerPath("/test")
 */
final class TestController extends BaseController
{
    /**
     * @Path("/")
     * @Method("POST")
     */
    public function index(ApiRequest $request, ApiResponse $response)
    {
        $files = [];

        foreach ($request->getUploadedFiles() as $file) {
            $files[] = $file;
        }

        return $response->withStatus(420, strval(count($request->getUploadedFiles())));
    }
}
<form action="http://localhost/test" method="POST" enctype="multipart/form-data">
    <input type="file" name="file1">
    <input type="submit">
</form>

if sent without image, exception is thrown that cannot be caught in the controller.

By empty file I meant empty field, thus no file being send.

f3l1x commented 6 years ago

You be fixed. Could you please test it @Odoaker-Alaric ?

sladdky commented 6 years ago

I'll have to try it somewhere separately, the project I am working on uses apitte/core, apitte/debug, apitte/middlewares and all require lower versions of this library and I didn't manage to forceupdate psr7-http-message to version 0.5, it always kicks it back to 0.3. If it's the same code I suggested, it should be fine tho. Works for me in my personal project.

2018-06-28 7:39 GMT+02:00 Milan Felix Šulc notifications@github.com:

You be fixed. Could you please test it @Odoaker-Alaric https://github.com/Odoaker-Alaric ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/contributte/psr7-http-message/issues/13#issuecomment-400916646, or mute the thread https://github.com/notifications/unsubscribe-auth/AKYmGCjQN53tvit0jFNjlNKA1OfgGJyPks5uBGv2gaJpZM4U084n .

f3l1x commented 6 years ago

Yep, it will be in apitte v0.4. We will release v0.3 with some tiny improvements and then v0.4 will be with PHP 7.1

You can trick it with contributte/psr-7-http-message: "dev-master as 0.3.

It should use dev-master branch and for the rest of the packages it looks like same old v0.3.

sladdky commented 6 years ago

Cool trick, so far so good. Works as intended.