Reduce memory usage for XML-RPC requests. Props Demitrious Kelly. fixes #10698
git-svn-id: http://svn.automattic.com/wordpress/trunk@12263 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
bc718b550a
commit
38bcfbb49b
|
@ -153,34 +153,41 @@ class IXR_Message {
|
||||||
var $_currentTagContents;
|
var $_currentTagContents;
|
||||||
// The XML parser
|
// The XML parser
|
||||||
var $_parser;
|
var $_parser;
|
||||||
function IXR_Message ($message) {
|
function IXR_Message (&$message) {
|
||||||
$this->message = $message;
|
$this->message = &$message;
|
||||||
}
|
}
|
||||||
function parse() {
|
function parse() {
|
||||||
// first remove the XML declaration
|
// first remove the XML declaration
|
||||||
$this->message = preg_replace('/<\?xml.*?\?'.'>/', '', $this->message);
|
// 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) == '') {
|
if (trim($this->message) == '') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
$this->_parser = xml_parser_create();
|
$this->_parser = xml_parser_create();
|
||||||
// Set XML parser to take the case of tags in to account
|
// Set XML parser to take the case of tags in to account
|
||||||
xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
|
xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
|
||||||
// Set XML parser callback functions
|
// Set XML parser callback functions
|
||||||
xml_set_object($this->_parser, $this);
|
xml_set_object($this->_parser, $this);
|
||||||
xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
|
xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
|
||||||
xml_set_character_data_handler($this->_parser, 'cdata');
|
xml_set_character_data_handler($this->_parser, 'cdata');
|
||||||
if (!xml_parse($this->_parser, $this->message)) {
|
$chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
|
||||||
/* die(sprintf('XML error: %s at line %d',
|
do {
|
||||||
xml_error_string(xml_get_error_code($this->_parser)),
|
if ( strlen($this->message) <= $chunk_size )
|
||||||
xml_get_current_line_number($this->_parser))); */
|
$final=true;
|
||||||
return false;
|
$part = substr( $this->message, 0, $chunk_size );
|
||||||
}
|
$this->message = substr( $this->message, $chunk_size );
|
||||||
xml_parser_free($this->_parser);
|
if ( !xml_parse( $this->_parser, $part, $final ) )
|
||||||
|
return false;
|
||||||
|
if ( $final )
|
||||||
|
break;
|
||||||
|
} while ( true );
|
||||||
|
xml_parser_free($this->_parser);
|
||||||
// Grab the error messages, if any
|
// Grab the error messages, if any
|
||||||
if ($this->messageType == 'fault') {
|
if ($this->messageType == 'fault') {
|
||||||
$this->faultCode = $this->params[0]['faultCode'];
|
$this->faultCode = $this->params[0]['faultCode'];
|
||||||
$this->faultString = $this->params[0]['faultString'];
|
$this->faultString = $this->params[0]['faultString'];
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
function tag_open($parser, $tag, $attr) {
|
function tag_open($parser, $tag, $attr) {
|
||||||
|
@ -304,7 +311,7 @@ class IXR_Server {
|
||||||
header( 'Content-Type: text/plain' );
|
header( 'Content-Type: text/plain' );
|
||||||
die('XML-RPC server accepts POST requests only.');
|
die('XML-RPC server accepts POST requests only.');
|
||||||
}
|
}
|
||||||
$data = $HTTP_RAW_POST_DATA;
|
$data = &$HTTP_RAW_POST_DATA;
|
||||||
}
|
}
|
||||||
$this->message = new IXR_Message($data);
|
$this->message = new IXR_Message($data);
|
||||||
if (!$this->message->parse()) {
|
if (!$this->message->parse()) {
|
||||||
|
|
Loading…
Reference in New Issue