PHP 5.2.2 vs. WordPress XMLRPC
NOTE: This article is out of date and likely obsolete.
Experimenting with the new Automattic Stats Plugin that uses the WordPress.com statistics infrastructure to track traffic. So far, so good… except for one problem. Titles and links are missing from all the “most visited” posts. They’re just listed as numeric IDs.
Actually, today’s posts seem OK. The plugin seems to just send the blog ID and post ID. I’ve been trying to figure out how the central server is retrieving the permalink and title. It doesn’t look like Bad Behavior is blocking it. And it doesn’t seem to be using the RSS feed, since posts that are still on the front page (and presumably still in the feed) are also showing up as numbers. *grumble*
…
I just noticed that all of the number-only posts show the same placeholder graph showing “Region A” vs. “Region B” for 2003-2005.
…
Andy Skelton at WordPress points out:
Your XMLRPC server is receiving our POST requests and replying with “XML-RPC server accespt POST requests only.” Any idea why?
That error seems to be generated by WordPress, in class-IXR.php. It indicates that $HTTP_RAW_POST_DATA
does not exist.
I’m having a hard time finding anything definitive about that variable in the PHP documentation. We have register_globals
turned off, but it’s not clear whether this variable is supposed to be global anyway, or whether it’s supposed to appear in one of the global arrays, or what. All I’m finding in the PHP docs are third-party comments.
Anyway, we also have suhosin installed on this server, a patch and an extension for increasing PHP security. It’s possible that might be seeing something odd and blocking the variable. I’ve turned off the extension for now to see if it makes a difference.
…
Well, that didn’t help. Now that I know what to look for, I’m tracking RPC requests in the logs. After disabling the Suhosin extension, nothing changed. It looks like the WP server farm is sending an RPC each time I access a page on the stats, and while I can’t see what my server is replying with, it’s the same 42-byte length.
I searched through the source on the Suhosin extension, and all it does with $HTTP_RAW_POST_DATA
is make sure that the user-agent isn’t trying to set that variable. And it doesn’t appear at all in the corresponding patch.
I tried turning register_globals
on, and I tried setting always_populate_raw_post_data
to On, but nothing changed. I even tried submitting a test form to a phpinfo page, and it just wasn’t setting that variable.
I did find that apparently the “preferred” method of getting raw info is now to use php://input. I added the following line at the beginning of WordPress’ xmlrpc.php, right before if ( isset($HTTP_RAW_POST_DATA) )
:
$HTTP_RAW_POST_DATA = file_get_contents("php://input");
Now it works! It served up a 37 KB XMLRPC response, and the stats filled in all the missing titles and links. It didn’t make any more requests when I clicked around. I re-enabled everything, then went back again, and it made another request, pulling 594 B of data that presumably included info on another post that got accessed.
I’ll keep looking into why that variable isn’t getting set. For the record, the server is currently using PHP 5.2.2 with Suhosin Patch 0.9.6.2 and Suhosin Extension 0.9.19.
At least there’s a workaround for now. Once I have a little more info, I’ll submit a bug report to Trac, since it looks like a compatibility issue with WordPress and hosting config.
…
OK… now I’m really confused, because I did some more tests, and it is setting that variable. (It just doesn’t show up in phpinfo)
It works fine on my test page on the same server with the same config, but not in WordPress’ XMLRPC code. I have to use that workaround.
It doesn’t make any sense.
…
Andy Skelton adds:
The wordpress.com servers originate XMLRPC requests whenever they need to know about your posts. You can force this to happen by changing your permalink structure, which will trigger a flush because it obsoletes of all your post permalinks in our database.
So, it’s a problem with WordPress’ XMLRPC interface, and affects other uses (like connecting with Flock). I’ve got a workaround, though!
Update (May 10): Thanks to the pingback from dot unplanned, it’s confirmed to be a bug in PHP 5.2.2. With any luck, the workaround will cease to be necessary when the next PHP bugfix is released.