Skip to content

Instantly share code, notes, and snippets.

@koke
Created June 6, 2013 11:26
Show Gist options
  • Save koke/5720860 to your computer and use it in GitHub Desktop.
Save koke/5720860 to your computer and use it in GitHub Desktop.
diff --git a/wp-includes/class-IXR.php b/wp-includes/class-IXR.php
index f8fbc00..4c7f58a 100644
--- a/wp-includes/class-IXR.php
+++ b/wp-includes/class-IXR.php
@@ -193,21 +193,41 @@ class IXR_Message
var $_currentTagContents;
// The XML parser
var $_parser;
+ // Input management
+ var $_inputHandler; // If using php://input
+ var $_bytesRead;
function IXR_Message($message)
{
$this->message =& $message;
+ $this->_bytesRead = 0;
+ if ( ! $this->message ) {
+ $this->_inputHandler = fopen( 'php://input', 'r' );
+ }
}
- function parse()
+ function read_chunk( $chunk_size = 0 )
{
- // first remove the XML declaration
- // merged from WP #10698 - this method avoids the RAM usage of preg_replace on very large messages
- $header = preg_replace( '/<\?xml.*?\?'.'>/', '', substr($this->message, 0, 100), 1);
- $this->message = substr_replace($this->message, $header, 0, 100);
- if (trim($this->message) == '') {
- return false;
+ $chunk = "";
+ if ( $this->message ) {
+ $chunk = substr( $this->message, $this->_bytesRead, $chunk_size );
+ } else {
+ $chunk = fread( $this->_inputHandler, $chunk_size );
}
+ $this->_bytesRead += strlen( $chunk );
+ return $chunk;
+ }
+
+ function eof() {
+ if ( $this->message ) {
+ return $this->_bytesRead >= strlen( $this->message );
+ } else {
+ return feof( $this->_inputHandler );
+ }
+ }
+
+ function parse()
+ {
$this->_parser = xml_parser_create();
// Set XML parser to take the case of tags in to account
xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
@@ -217,18 +237,25 @@ class IXR_Message
xml_set_character_data_handler($this->_parser, 'cdata');
$chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
$final = false;
+
+ // first remove the XML declaration
+ // merged from WP #10698 - this method avoids the RAM usage of preg_replace on very large messages
+ $chunk = preg_replace( '/<\?xml.*?\?'.'>/', '', $this->read_chunk( 100 ), 1 );
+ if ( trim( $chunk ) == '' ) {
+ return false;
+ }
+
+ $i = 0;
do {
- if (strlen($this->message) <= $chunk_size) {
- $final = true;
- }
- $part = substr($this->message, 0, $chunk_size);
- $this->message = substr($this->message, $chunk_size);
- if (!xml_parse($this->_parser, $part, $final)) {
+ $final = $this->eof();
+
+ if (!xml_parse($this->_parser, $chunk, $final)) {
return false;
}
if ($final) {
break;
}
+ $chunk = $this->read_chunk( $chunk_size );
} while (true);
xml_parser_free($this->_parser);
@@ -372,14 +399,6 @@ class IXR_Server
header('Content-Type: text/plain'); // merged from WP #9093
die('XML-RPC server accepts POST requests only.');
}
-
- global $HTTP_RAW_POST_DATA;
- if (empty($HTTP_RAW_POST_DATA)) {
- // workaround for a bug in PHP 5.2.2 - http://bugs.php.net/bug.php?id=41293
- $data = file_get_contents('php://input');
- } else {
- $data =& $HTTP_RAW_POST_DATA;
- }
}
$this->message = new IXR_Message($data);
if (!$this->message->parse()) {
diff --git a/xmlrpc.php b/xmlrpc.php
index 59674df..a6e6dcb 100644
--- a/xmlrpc.php
+++ b/xmlrpc.php
@@ -15,16 +15,6 @@ define('XMLRPC_REQUEST', true);
// Some browser-embedded clients send cookies. We don't want them.
$_COOKIE = array();
-// A bug in PHP < 5.2.2 makes $HTTP_RAW_POST_DATA not set by default,
-// but we can do it ourself.
-if ( !isset( $HTTP_RAW_POST_DATA ) ) {
- $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' );
-}
-
-// fix for mozBlog and other cases where '<?xml' isn't on the very first line
-if ( isset($HTTP_RAW_POST_DATA) )
- $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
-
/** Include the bootstrap for setting up WordPress environment */
include('./wp-load.php');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment