Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is $HTTP_RAW_POST_DATA being called?

Tags:

php

I recently upgraded my production server to Ubuntu 14.04 and PHP 5.6, and now I'm getting warnings in my error log:

2014/10/31 10:42:45 [error] 17128#0: *46238 FastCGI sent in stderr: "PHP message: PHP Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in Unknown on line 0" while reading response header from upstream, client: 24.123.216.42, server: example.com, request: "POST /api/notes HTTP/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "example.com", referrer: "https://example.com/admin/"

I read the documentation as well as this somewhat relevant question: Undefined variable: HTTP_RAW_POST_DATA. However, I can't figure out why this notice is being recorded. As far as I can tell, I'm not using $HTTP_RAW_POST_DATA anywhere in my codebase. I've tried:

find . -exec grep "HTTP_RAW_POST_DATA" {} \; -print 2>/dev/null

from the root directory of my project (including all vendor directories), but I'm not finding any matches.

I read more about always_populate_raw_post_data and it appears that $HTTP_RAW_POST_DATA should only be populated if the always_populate_raw_post_data parameter is set to TRUE. I checked my phpinfo() and the parameter is set to 0.

If I'm not explicitly invoking $HTTP_RAW_POST_DATA and always_populate_raw_post_data is set to 0, why am I getting these notices in my error log? What does setting always_populate_raw_post_data to -1 do?

like image 557
Ben Harold Avatar asked Oct 31 '14 16:10

Ben Harold


2 Answers

Here's the relevant C code with my comments:

static zend_bool populate_raw_post_data(TSRMLS_D)
{
    // not a post, empty request - return FALSE
    if (!SG(request_info).request_body) {
        return (zend_bool) 0;
    }

    // if always_populate_raw_post_data=0 then
    // if we don't know how to parse the post (unknown mimetype) return TRUE
    // otherwise (known mimetype) return FALSE
    if (!PG(always_populate_raw_post_data)) {
        return (zend_bool) !SG(request_info).post_entry;
    }

    // if always_populate_raw_post_data > 0 return TRUE
    // if always_populate_raw_post_data < 0 return FALSE
    return (zend_bool) (PG(always_populate_raw_post_data) > 0);
}

That is, setting always_populate_raw_post_data to 0 still enables populating for unknown content types. You have to use a negative value to skip it altogether.

This is now documented in the manual:

The preferred method for accessing raw POST data is php://input, and $HTTP_RAW_POST_DATA is deprecated in PHP 5.6.0 onwards. Setting always_populate_raw_post_data to -1 will opt into the new behaviour that will be implemented in a future version of PHP, in which $HTTP_RAW_POST_DATA is never defined.

like image 136
georg Avatar answered Oct 18 '22 19:10

georg


It's already been filed as a bug report

Also read this.

Basically change the value to -1 and that'll fix your "problem".

Also make sure you use php://input read more below V

I think it would be better to describe what is actually happening: the E_DEPRECATED will be generated when $HTTP_RAW_POST_DATA is populated which controlled by the value of always_populate_raw_post_data (link to http://php.net/manual/en/ini.core.php where we already describe in which case will $HTTP_RAW_POST_DATA be populated) and to remove the deprecated message make sure that you don't use $HTTP_RAW_POST_DATA but php://input then you can disable the population of $HTTP_RAW_POST_DATA via setting always_populate_raw_post_data to -1, which will remove the E_DEPRECATED.

from http://php.net/manual/en/ini.core.php:

If set to TRUE, PHP will always populate the $HTTP_RAW_POST_DATA containing the raw POST data. Otherwise, the variable is populated only when the MIME type of the data is unrecognised.

The preferred method for accessing raw POST data is php://input, and $HTTP_RAW_POST_DATA is deprecated in PHP 5.6.0 onwards. Setting always_populate_raw_post_data to -1 will opt into the new behaviour that will be implemented in a future version of PHP, in which $HTTP_RAW_POST_DATA is never defined.


Changes to PHP-5.6

Re-usable, optioanlly JITty initialized php://input stream Change always_populate_raw_post_data INI setting to accept three values instead of two.

-1: The behavior of master; don't ever populate $GLOBALS[HTTP_RAW_POST_DATA]

0/off/whatever: BC behavior (populate if content-type is not registered or request method is other than POST)

1/on/yes/true: BC behavior (always populate $GLOBALS[HTTP_RAW_POST_DATA])

like image 21
deW1 Avatar answered Oct 18 '22 20:10

deW1