You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implement multipart/form-data support for PUT, DELETE and PATCH requests.
PHP, and by extension, Symfony does not support multipart/form-data requests when using any request method other than POST. This limits the ability to implement RESTful architectures using Symfony. This is a follow up to Pull Request symfony#849 I made a few years ago, and addresses concerns brought up by Saldaek at the time.
I have implemented this functionality by manually decoding the php://input stream when the request type is PUT, DELETE or PATCH and the Content-Type header is mutlipart/form-data. The implementation is based on an example by [netcoder at stackoverflow](http://stackoverflow.com/a/9469615).
This is necessary due to an underlying limitation of PHP, as discussed here: https://bugs.php.net/bug.php?id=55815.
This fixessymfony#9226.
__Security Concerns__
The main concern I had while implementing this feature, was working with PHP's assumptions as to what constituted an uploaded file. Since the files that this commit creates are not done so through PHP's usual uploaded file mechanisms, none of the uploaded file functions (such as is_uploaded_file, move_uploaded_file) will work with them. As such, I had to implement a mechanism for recording the uploaded files as they were created, so that Symfony's UploadedFile class could be sure that it was not moving non-uploaded files.
To achieve this, I added a static array to the UploadedFile class called $files. Any uploaded files that are created outside of PHP's normal mechanism can be recorded here. UploadedFile can then check this list to ensure that if is_uploaded_file returns false, that the file being moved is in fact an uploaded file. This results in two changes to UploadedFile: Firstly, the is_uploaded_file check had to be expanded to also check if the file was recorded in UploadedFile::$files. Secondly, the move_uploaded_file needed to be changed to rename.
The change of move_uploaded_file to rename might raise a few red flags, but I do not believe this is a problem. Before rename is called, UploadedFile calls isValid, which checks that the file either is_uploaded_file, or is a member of UploadedFile::$files. Therefore the use of move_uploaded_file is an unnecessary double check (even without these changes).
Fixsymfony#9226.
0 commit comments