How can I send raw POST data with cURL? (PHP)

23,460

Solution 1

For some odd reason the aforementioned header thing seems to fix it. Previously it wasn't working, and I'm unsure why it works now.

Anyway, for those who don't know, this is the code:

curl_setopt($handle, CURLOPT_HTTPHEADER, array('Content-Type: text/plain'));

Solution 2

You get an error in the response part of your sender/receiver cycle.

While this might very well be a problem of the sender (which does not send a proper request), it may also be caused by a misconfiguration in the receiving PHP script. To wit, even if the request is correct, the receiver might nonetheless not have HTTP_RAW_POST_DATA available.

See: http://www.php.net/manual/en/ini.core.php#ini.always-populate-raw-post-data

Always populate the $HTTP_RAW_POST_DATA containing the raw POST data. Otherwise, the variable is populated only with unrecognized MIME type of the data. However, the preferred method for accessing the raw POST data is php://input. $HTTP_RAW_POST_DATA is not available with enctype="multipart/form-data".

So the first thing to check is whether $HTTP_RAW_POST_DATA is indeed populated, which from the page above requires either:

  1. the .ini variable always_populate_raw_post_data is True,
  2. or the POST is sent with a Content-Type that the POST handler does not recognize (maybe one could use "text/raw")

At this point, the correct way of sending data would be

curl_setopt($handle, CURLOPT_POSTFIELDS, urlencode('Raw POST data'));

However, note that the recommended way of receiving those data would be not to rely on $HTTP_RAW_POST_DATA at all, but to read the contents of the virtual file php://input.

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. Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by default, it is a potentially less memory intensive alternative to activating always_populate_raw_post_data.

Share:
23,460
user1488335
Author by

user1488335

Updated on October 22, 2021

Comments

  • user1488335
    user1488335 over 2 years

    I'm attempting to send raw POST data to a page using $HTTP_RAW_POST_DATA, but my attempts failed and an undefined index notice was given.

    I have attempted the following:

    curl_setopt($handle, CURLOPT_POSTFIELDS, 'Raw POST data');   // Doesn't seem to work at all.
    curl_setopt($handle, CURLOPT_POSTFIELDS, array('Raw POST data'));   // 0 => Raw POST data
    

    I did some research and some people had suggested sending a header (Content-Type: text/plain) in the request, which didn't seem to affect anything.

    Is there a solution for this issue?

  • user1488335
    user1488335 over 11 years
    I'm quite certain the receiver is fine as sending the POST data manually works fine (using the Live HTTP Headers add-on for Firefox). I'm aware of php://input and how it's better, however, in this case I require a solution for $HTTP_RAW_POST_DATA. Thank you for the reply!
  • LSerni
    LSerni over 11 years
    Well, in that case you can set the always-populate-raw-post-data setting in the PHP.INI; or you can send an "unrecognized" (whatever that means) "MIME type" to force population of $HTTP_RAW_POST_DATA. Updating answer...
  • Shadocko
    Shadocko almost 9 years
    This answer seems unrelated to the original question, which was really about performing an HTTP request using libcurl from PHP and not about accessing POST data sent to a PHP script running in a web server.
  • LSerni
    LSerni almost 9 years
    @Shadocko - the original question did describe an undefined index error while accessing POST data from the PHP script running in a web server. I'll readily admit that in this specific case the error was in the sending script, but the solution I gave is related to a situation I observed first hand, and know to occur. While it is not an answer for this specific case, it may well be for someone else looking for the same thing.
  • Shadocko
    Shadocko almost 9 years
    @lserni OK, sorry for the downvote, didn't realise that the PHP script indeed received data in $HTTP_RAW_POST_DATA before bundling it in another HTTP request, so your answer can be useful. My vote is locked in but I will cancel it if you edit your answer.
  • LSerni
    LSerni almost 9 years
    That's okay, no problem. Actually, I have been unclear; on re-reading, your misunderstanding was in large part my own fault, and editing the answer is beneficial. Thanks for calling my attention to that; let me know if the answer is clearer now.
  • Shadocko
    Shadocko almost 9 years
    @lserni - your answer is actually so much clearer now that I upvoted it, even if it's not the one I was looking for when I stumbled here.
  • LSerni
    LSerni almost 9 years
    Wow, thanks! But what was it that you were looking for? I'd like to help :-)
  • Shadocko
    Shadocko almost 9 years
    @lserni - My problem was posting huge files as raw POST body. I eventually solved it: stackoverflow.com/questions/15508850/…
  • Matthew Lock
    Matthew Lock about 2 years
    I actually required a different Content-Type but this got me on the right track