Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read raw request body for multipart/form-data with php in PUT, PATCH, DELETE ... request

I am writing a restful api library from scratch and now I'm stuck with a common problem: Read raw data from multipart/form-data from a request.

For POST requests, I am aware that I should use $_FILE / $_POST variables. But what if there is a PUT, PATCH, or whatever request type, other than POST?

  • Is this scenario possible?
  • If so, how can I read the raw body contents, since, according to the documentation it is not avaliable in php://input?

Note: I searched about the input format and how to read it already, I just want to access the RAW data.

like image 795
CarlosCarucce Avatar asked Jun 28 '16 17:06

CarlosCarucce


People also ask

How to read raw data from a POST request in PHP?

php://input is a read-only stream that allows you to read raw data from the request body. In the case of POST requests, it is preferable to use php://input instead of $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives.

What is $http_Raw_post_data in PHP?

$HTTP_RAW_POST_DATA is a global variable that contains the raw POST data. It is only available if the always_populate_raw_post_data directive in php.ini is enabled.

What is a multipart request in schema?

You describe individual parts of the request as properties of the schema object. As you can see, a multipart request can include various data: strings, objects in JSON format, and binary data. You can also specify one or several files for uploading.

What type of data is sent in a POST request?

Usually data sent in a POST request is structured key/value pairs with a MIME type of application/x-www-form-urlencoded. However many applications such as web services require raw data, often in XML or JSON format, to be sent instead.


1 Answers

But what if there is a PUT, PATCH, or whatever request type, other than POST?

Well, since you are the one designing the API, then you are the one who decides whether it accepts only POST, PUT, POST + PUT or any other combination of request headers.

The API should not be designed to "accept-and-try-to-handle" everything a third-party app is submitting to your API. It's the app's job (I mean, the app that connects to API) to prepare a request in such a way, that the API accepts it.

Keep in mind, that enabling multiple request methods (especially those which have to be treated differently) comes with multiple ways to treat a request (e.g. security, types etc). It basically means that either you have to smartly design a request-handling process, or you'll encounter problems with API methods called with different request-types differently, which will be troublesome.

If you need to get raw contents of the request - @Adil Abbasi seems to be on the right track (as far as parsing php://input is concerned). But note that php://input is not available with enctype="multipart/form-data" as described in the docs.

<?php
$input = file_get_contents('php://input');
// assuming it's JSON you allow - convert json to array of params
$requestParams = json_decode($input, true);
if ($requestParams === FALSE) {
   // not proper JSON received - set response headers properly
   header("HTTP/1.1 400 Bad Request"); 
   // respond with error
   die("Bad Request");
}

// proceed with API call - JSON parsed correctly

If you need to use enctype="multipart/form-data" - read about STDIN in I/O Streams docs, and try it like this:

<?php
$bytesToRead = 4096000;
$input = fread(STDIN, $bytesToRead ); // reads 4096K bytes from STDIN
if ($input === FALSE) {
   // handle "failed to read STDIN"
}
// assuming it's json you accept:
$requestParams = json_decode($input , true);
if ($requestParams === FALSE) {
   // not proper JSON received - set response headers properly
   header("HTTP/1.1 400 Bad Request"); 
   // respond with error
   die("Bad Request");
}
like image 161
Kleskowy Avatar answered Sep 20 '22 02:09

Kleskowy