Make WordPress Core

Changeset 12263


Ignore:
Timestamp:
11/23/2009 04:53:36 PM (15 years ago)
Author:
ryan
Message:

Reduce memory usage for XML-RPC requests. Props Demitrious Kelly. fixes #10698

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class-IXR.php

    r10571 r12263  
    154154    // The XML parser
    155155    var $_parser;
    156     function IXR_Message ($message) {
    157         $this->message = $message;
     156    function IXR_Message (&$message) {
     157        $this->message = &$message;
    158158    }
    159159    function parse() {
    160         // first remove the XML declaration
    161         $this->message = preg_replace('/<\?xml.*?\?'.'>/', '', $this->message);
     160        // first remove the XML declaration
     161        // this method avoids the RAM usage of preg_replace on very large messages
     162        $header = preg_replace( '/<\?xml.*?\?'.'>/', '', substr( $this->message, 0, 100 ), 1 );
     163        $this->message = substr_replace($this->message, $header, 0, 100);
    162164        if (trim($this->message) == '') {
    163165            return false;
    164         }
     166        }
    165167        $this->_parser = xml_parser_create();
    166168        // Set XML parser to take the case of tags in to account
     
    169171        xml_set_object($this->_parser, $this);
    170172        xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
    171         xml_set_character_data_handler($this->_parser, 'cdata');
    172         if (!xml_parse($this->_parser, $this->message)) {
    173             /* die(sprintf('XML error: %s at line %d',
    174                 xml_error_string(xml_get_error_code($this->_parser)),
    175                 xml_get_current_line_number($this->_parser))); */
    176             return false;
    177         }
    178         xml_parser_free($this->_parser);
     173        xml_set_character_data_handler($this->_parser, 'cdata');
     174        $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
     175        do {
     176            if ( strlen($this->message) <= $chunk_size )
     177                $final=true;
     178            $part = substr( $this->message, 0, $chunk_size );
     179            $this->message = substr( $this->message, $chunk_size );
     180            if ( !xml_parse( $this->_parser, $part, $final ) )
     181                return false;
     182            if ( $final )
     183                break;
     184        } while ( true );
     185        xml_parser_free($this->_parser);
    179186        // Grab the error messages, if any
    180187        if ($this->messageType == 'fault') {
    181188            $this->faultCode = $this->params[0]['faultCode'];
    182189            $this->faultString = $this->params[0]['faultString'];
    183         }
     190        }
    184191        return true;
    185192    }
     
    305312               die('XML-RPC server accepts POST requests only.');
    306313            }
    307             $data = $HTTP_RAW_POST_DATA;
     314            $data = &$HTTP_RAW_POST_DATA;
    308315        }
    309316        $this->message = new IXR_Message($data);
Note: See TracChangeset for help on using the changeset viewer.