-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
PUT request not responding to multipart/form-data #9226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
EDIT: This is strange. The below problem resolved itself literally overnight, with no change. Now I get the following result when I POST using Content-Type: multipart/form-data:
If anyone knows what may have caused this, please let me know. I used two different clients to test. OLD POST: I am experiencing a similar, if not the same issue. Recently I started getting validation errors when POSTing to my REST interface with Content-Type: multipart/form-data. Content-Type: application/x-www-form-urlencoded is working. Here is my testing function:
When I POST using Content-Type: application/x-www-form-urlencoded:
When I POST using Content-Type: multipart/form-data:
I'm using Symfony 2.3.7 and FOSRestBundle 1.0.0. |
Anything new here? This one is a little bit important I think. |
I found the following, which leads me to think this is not a Symfony issue.:
My stackoverflow post doesn't offer much more info, but here it is: http://stackoverflow.com/questions/20229915/posting-with-content-type-multipart-form-data-results-in-empty-request-body I am not a dev on this project but -- out of curiosity -- what are you seeing, specifically. |
P.S. PUT and POST requests treat multipart/form-data in different ways: https://bugs.php.net/bug.php?id=55815 |
The problem is that; one of the users of symfony, (which is Laravel 4.*) uses resource controllers; which uses put requests to handle update requests. When the developer is updating an existing post for example, with images (multipart/form-data) and some input information, "Input::get(), Input::all()" returns an empty array or whatever. As far as I see; php.net won't use php://input with put requests because of the requirement specifications it relies on. And they are doing what they SHOULD do. That makes us look for a solution and redirects us to here because our update functions are malfunctioning. I no longer understand which package has the problem. Or if that is not a problem; what is the right way of doing that properly. Should we really use [POST]http://example.com/posts/1/update instead of using [PUT]http://example.com/posts/1 ? |
Yes, the issue is php does not respond in the same way it does for posts. It should since the HTTP spec points out that PUT is not limited to a specific Content-Type. So this may in fact be a PHP bug (which has now been open since 2011). Here's a SO response with some links detailing the HTTP spec: http://stackoverflow.com/a/6115547/862636 |
…sts. 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, 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 fixes symfony#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). Fix symfony#9226.
…sts. 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, 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 fixes symfony#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). Fix symfony#9226.
…sts. 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 fixes symfony#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). Fix symfony#9226.
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 fixes symfony#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). Fix symfony#9226.
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 fixes symfony#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). Fix symfony#9226.
I have submitted a fix for this. Please take a look at pull #10381 and let me know what you think. Sorry for the reference spam! |
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 fixes symfony#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). Fix symfony#9226. Conflicts: src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
This is currently being shot down by all commenters. If you guys want/need this, you need to weigh in. |
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 fixes symfony#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). Fix symfony#9226. Conflicts: src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
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 fixes symfony#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). Fix symfony#9226. Conflicts: src/Symfony/Component/HttpFoundation/Tests/RequestTest.php
Closing as the corresponding PR was closed a while ago. |
symfony/symfony#9226 (reverted from commit 806f37a)
@fabpot |
@shyandsy can you confirm to me this bug still exist on Symfony 4 ? |
We still can't read PUT using |
@fabpot I can confirm that this PR does not fix the PUT bug :/. |
@Simperfit The PR was closed because it was rejected. It was never merged. |
Yes it is. |
For me it is not an option since I need to post files combined with other data. The only workaround is using |
Hello guys. I really think this will never be done directly in Symfony considering it's based on a PHP behavior that differs in case of PUT multipart/form-data. Supporting this would add a huge set of classes (I think of streaming file transfert and complete form data decoding support, which is are both not trivial) to make it work just like POST does. For a very edgy case. Please consider implementing your own solution. This ticket should be close IMO as it is out of the scope of Symfony. |
@Nek- I agree that this should be fixed in PHP and not Symfony. But implementing support for form data decoding is not a huge amount of work. I already implemented it in #10381, but it was rejected by @fabpot because he (correctly) believes it should be fixed in PHP instead of having Symfony take on the responsibility of manually decoding form data. |
Here is the issue in PHP's bug tracker. It's 8 years old now. If you want it you should vote and weigh in here: https://bugs.php.net/bug.php?id=55815 |
Closing as there is nothing to keep track of in the Symfony repo. See php bug above. |
I've been trying to figure out how to work with this issue without having to break RESTful convention and boy howdie, what a rabbit hole, let me tell you. I'm adding this anywhere I can find in the hope that it will help somebody out in the future. I've just lost a day of development firstly figuring out that this was an issue, then figuring out where the issue lay. As mentioned, this isn't a symfony (or laravel, or any other framework) issue, it's a limitation of PHP. After trawling through a good few RFCs for php core, the core development team seem somewhat resistant to implementing anything to do with modernising the handling of HTTP requests. The issue was first reported in 2011, it doesn't look any closer to having a native solution. That said, I managed to find this PECL extension. I'm not really very familiar with pecl, and couldn't seem to get it working using pear. but I'm using CentOS and Remi PHP which has a yum package. I ran I believe there are other packages in various flavours of linux and I'm sure anybody with more knowledge of pear/pecl/general php extensions could get it running on windows or mac with no issue. |
Also lost a day of development like @DazDotOne |
@rrenteria-dev What OS are you using? |
@rrenteria-dev you can use But I also time to time lose a lot of time on this... I'm sure the PHP team would accept a fix 😬 . |
You can use this package: And this is a Laravel Service Provider for above package: |
As this issue begin to grind my gears, I would like to propose a RFC. |
Please open a new issue if you want to discuss any idea, or send a PR if you have code of course. |
@nicolas-grekas So it seems that currently we have only one way to change PUT request to the POST if we need, f.e., upload files, right? |
Yes. |
I'm locking this issue to prevent further support questions. Please read the PHP bug to learn why things are this way, use GitHub discussions if you need support or open a new issue if you have new ideas on how to tackle the problem. |
In the recent build of Laravel it seems to not be responding to PUT requests that are encoded with multipart/form-data. It only works with application/x-www-form-urlencoded. I believe the http spec states that it should work no matter what you use.
For example when sending a request using mulitpart/form-data I observe the following:
I tried to track it back through the code and the issue definitely seems to be the Symfony Request package and not the Laravel framework itself. The data never gets passed to the Input object in Laravel.
The text was updated successfully, but these errors were encountered: