Get raw post data
According to php manual nor php://input neither $HTTP_RAW_POST_DATA
work with multipart/form-data
POST-requests.
"php://input allows you to read raw POST data. It is a less memory intensive alternative to $HTTP_RAW_POST_DATA
and does not need any special php.ini directives. php://input is not available with enctype="multipart/form-data"
."
How can I get raw data for multipart/form-data
forms?
Direct answer: you can not do that. PHP insists on parsing it itself, whenever it sees the multipart/form-data Content-Type. The raw data will not be available to you. Sadly. But you can hack around it.
I hit a similar problem, a partner was sending incorrectly formatted data as multipart/form-data, PHP could not parse it and was not giving it out so I could parse it myself.
The solution? I added this to my apache conf:
<Location "/backend/XXX.php">
SetEnvIf Content-Type ^(multipart/form-data)(.*) NEW_CONTENT_TYPE=multipart/form-data-alternate$2 OLD_CONTENT_TYPE=$1$2
RequestHeader set Content-Type %{NEW_CONTENT_TYPE}e env=NEW_CONTENT_TYPE
</Location>
This will change the Content-Type of incoming request to XXX.php from multipart/form-data to multipart/form-data-alternate, which is enough to block PHP from trying to parse it
After this you can finally read the whole raw data from php://input and parse it yourself.
It is ugly, but I have not found a better or in fact any other solution - short of asking the partner to fix their side.
NB! When you do what I described here, $_FILES will be empty.
You can set enable_post_data_reading = Off
and PHP won't intercept multipart/form-data
data.
Requires: PHP 5.4
I didn't implement this fully, but it looks like it should work. In Apache conf
:
SetEnvIf Content-Type ^(multipart/form-data)(.*) MULTIPART_CTYPE=$1$2
RequestHeader set Content-Type application/x-httpd-php env=MULTIPART_CTYPE
RequestHeader set X-Real-Content-Type %{MULTIPART_CTYPE}e env=MULTIPART_CTYPE
Setting the Content-Type
to application/x-httpd-php
appears to solve the original problem of PHP parsing the body, and the problem Norbert Farkas reported: "Apache sends back PHP source code". The body is then available on php://input
, and the real content type in the X-Real-Content-Type
header. (That header may not be necessary for you -- the MULTIPART_CTYPE
variable didn't seem to be showing up in my $_ENV
, but the new header did.) All other requests should be handled as usual.
Thanks to Anti Veeranna for most of it! :)
EDIT: P.S. Obviously it's Apache-specific, but in some of the other configurations of PHP there may very well be easier ways.