Home » Php » php – Get raw post data

php – Get raw post data

Posted by: admin April 23, 2020 Leave a comment

Questions:

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?

How to&Answers:

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.

Answer:

You can set enable_post_data_reading = Off and PHP won’t intercept multipart/form-data data.

Requires: PHP 5.4

Answer:

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.