web/wp-includes/class-IXR.php
branchwordpress
changeset 132 4d4862461b8d
parent 109 03b0d1493584
equal deleted inserted replaced
131:a4642baaf829 132:4d4862461b8d
   151     var $_value;
   151     var $_value;
   152     var $_currentTag;
   152     var $_currentTag;
   153     var $_currentTagContents;
   153     var $_currentTagContents;
   154     // The XML parser
   154     // The XML parser
   155     var $_parser;
   155     var $_parser;
   156     function IXR_Message ($message) {
   156     function IXR_Message (&$message) {
   157         $this->message = $message;
   157         $this->message = &$message;
   158     }
   158     }
   159     function parse() {
   159     function parse() {
   160         // first remove the XML declaration
   160 		// first remove the XML declaration
   161         $this->message = preg_replace('/<\?xml.*?\?'.'>/', '', $this->message);
   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);
   162         if (trim($this->message) == '') {
   164         if (trim($this->message) == '') {
   163             return false;
   165             return false;
   164         }
   166 		}
   165         $this->_parser = xml_parser_create();
   167         $this->_parser = xml_parser_create();
   166         // Set XML parser to take the case of tags in to account
   168         // Set XML parser to take the case of tags in to account
   167         xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
   169         xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
   168         // Set XML parser callback functions
   170         // Set XML parser callback functions
   169         xml_set_object($this->_parser, $this);
   171         xml_set_object($this->_parser, $this);
   170         xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
   172         xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
   171         xml_set_character_data_handler($this->_parser, 'cdata');
   173 		xml_set_character_data_handler($this->_parser, 'cdata');
   172         if (!xml_parse($this->_parser, $this->message)) {
   174 		$chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
   173             /* die(sprintf('XML error: %s at line %d',
   175 		do {
   174                 xml_error_string(xml_get_error_code($this->_parser)),
   176 			if ( strlen($this->message) <= $chunk_size )
   175                 xml_get_current_line_number($this->_parser))); */
   177 				$final=true;
   176             return false;
   178 			$part = substr( $this->message, 0, $chunk_size );
   177         }
   179 			$this->message = substr( $this->message, $chunk_size );
   178         xml_parser_free($this->_parser);
   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);
   179         // Grab the error messages, if any
   186         // Grab the error messages, if any
   180         if ($this->messageType == 'fault') {
   187         if ($this->messageType == 'fault') {
   181             $this->faultCode = $this->params[0]['faultCode'];
   188             $this->faultCode = $this->params[0]['faultCode'];
   182             $this->faultString = $this->params[0]['faultString'];
   189             $this->faultString = $this->params[0]['faultString'];
   183         }
   190 		}
   184         return true;
   191         return true;
   185     }
   192     }
   186     function tag_open($parser, $tag, $attr) {
   193     function tag_open($parser, $tag, $attr) {
   187         $this->_currentTagContents = '';
   194         $this->_currentTagContents = '';
   188         $this->currentTag = $tag;
   195         $this->currentTag = $tag;
   302             global $HTTP_RAW_POST_DATA;
   309             global $HTTP_RAW_POST_DATA;
   303             if (!$HTTP_RAW_POST_DATA) {
   310             if (!$HTTP_RAW_POST_DATA) {
   304                header( 'Content-Type: text/plain' );
   311                header( 'Content-Type: text/plain' );
   305                die('XML-RPC server accepts POST requests only.');
   312                die('XML-RPC server accepts POST requests only.');
   306             }
   313             }
   307             $data = $HTTP_RAW_POST_DATA;
   314             $data = &$HTTP_RAW_POST_DATA;
   308         }
   315         }
   309         $this->message = new IXR_Message($data);
   316         $this->message = new IXR_Message($data);
   310         if (!$this->message->parse()) {
   317         if (!$this->message->parse()) {
   311             $this->error(-32700, 'parse error. not well formed');
   318             $this->error(-32700, 'parse error. not well formed');
   312         }
   319         }