X-Git-Url: https://scripts.mit.edu/gitweb/autoinstalls/wordpress.git/blobdiff_plain/ff81ee6e8304a1982a3ec4f5b134764a29d502cf..refs/tags/wordpress-2.9:/wp-includes/class-IXR.php diff --git a/wp-includes/class-IXR.php b/wp-includes/class-IXR.php index 7851b68a..f8d61fe8 100644 --- a/wp-includes/class-IXR.php +++ b/wp-includes/class-IXR.php @@ -1,15 +1,28 @@ data = $data; if (!$type) { @@ -28,6 +41,7 @@ class IXR_Value { } } } + function calculateType() { if ($this->data === true || $this->data === false) { return 'boolean'; @@ -47,7 +61,7 @@ class IXR_Value { } // If it is a normal PHP object convert it in to a struct if (is_object($this->data)) { - + $this->data = get_object_vars($this->data); return 'struct'; } @@ -61,6 +75,7 @@ class IXR_Value { return 'array'; } } + function getXml() { /* Return XML for this value */ switch ($this->type) { @@ -101,6 +116,7 @@ class IXR_Value { } return false; } + function isStruct($array) { /* Nasty function to check if an array is a struct or not */ $expected = 0; @@ -114,7 +130,12 @@ class IXR_Value { } } - +/** + * IXR_Message + * + * @package IXR + * @since 1.5 + */ class IXR_Message { var $message; var $messageType; // methodCall / methodResponse / fault @@ -132,38 +153,45 @@ class IXR_Message { var $_currentTagContents; // The XML parser var $_parser; - function IXR_Message ($message) { - $this->message = $message; + function IXR_Message (&$message) { + $this->message = &$message; } function parse() { - // first remove the XML declaration - $this->message = preg_replace('/<\?xml(.*)?\?'.'>/', '', $this->message); + // first remove the XML declaration + // 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; - } + } $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); // Set XML parser callback functions xml_set_object($this->_parser, $this); xml_set_element_handler($this->_parser, 'tag_open', 'tag_close'); - xml_set_character_data_handler($this->_parser, 'cdata'); - if (!xml_parse($this->_parser, $this->message)) { - /* die(sprintf('XML error: %s at line %d', - xml_error_string(xml_get_error_code($this->_parser)), - xml_get_current_line_number($this->_parser))); */ - return false; - } - xml_parser_free($this->_parser); + xml_set_character_data_handler($this->_parser, 'cdata'); + $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages + 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 ) ) + return false; + if ( $final ) + break; + } while ( true ); + xml_parser_free($this->_parser); // Grab the error messages, if any if ($this->messageType == 'fault') { $this->faultCode = $this->params[0]['faultCode']; $this->faultString = $this->params[0]['faultString']; - } + } return true; } function tag_open($parser, $tag, $attr) { - $this->_currentTagContents = ''; + $this->_currentTagContents = ''; $this->currentTag = $tag; switch($tag) { case 'methodCall': @@ -253,11 +281,16 @@ class IXR_Message { $this->params[] = $value; } } - $this->_currentTagContents = ''; - } + $this->_currentTagContents = ''; + } } - +/** + * IXR_Server + * + * @package IXR + * @since 1.5 + */ class IXR_Server { var $data; var $callbacks = array(); @@ -275,9 +308,10 @@ class IXR_Server { if (!$data) { global $HTTP_RAW_POST_DATA; if (!$HTTP_RAW_POST_DATA) { + header( 'Content-Type: text/plain' ); die('XML-RPC server accepts POST requests only.'); } - $data = $HTTP_RAW_POST_DATA; + $data = &$HTTP_RAW_POST_DATA; } $this->message = new IXR_Message($data); if (!$this->message->parse()) { @@ -312,7 +346,8 @@ EOD; } function call($methodname, $args) { if (!$this->hasMethod($methodname)) { - return new IXR_Error(-32601, 'server error. requested method '.$methodname.' does not exist.'); + return new IXR_Error(-32601, 'server error. requested method '. + $methodname.' does not exist.'); } $method = $this->callbacks[$methodname]; // Perform the callback and send the response @@ -325,18 +360,21 @@ EOD; // It's a class method - check it exists $method = substr($method, 5); if (!method_exists($this, $method)) { - return new IXR_Error(-32601, 'server error. requested class method "'.$method.'" does not exist.'); + return new IXR_Error(-32601, 'server error. requested class method "'. + $method.'" does not exist.'); } // Call the method $result = $this->$method($args); } else { // It's a function - does it exist? if (is_array($method)) { - if (!method_exists($method[0], $method[1])) { - return new IXR_Error(-32601, 'server error. requested object method "'.$method[1].'" does not exist.'); - } + if (!method_exists($method[0], $method[1])) { + return new IXR_Error(-32601, 'server error. requested object method "'. + $method[1].'" does not exist.'); + } } else if (!function_exists($method)) { - return new IXR_Error(-32601, 'server error. requested function "'.$method.'" does not exist.'); + return new IXR_Error(-32601, 'server error. requested function "'. + $method.'" does not exist.'); } // Call the function $result = call_user_func($method, $args); @@ -379,7 +417,7 @@ EOD; 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208', 'specVersion' => 1 ), - ); + ); } function getCapabilities($args) { return $this->capabilities; @@ -418,6 +456,12 @@ EOD; } } +/** + * IXR_Request + * + * @package IXR + * @since 1.5 + */ class IXR_Request { var $method; var $args; @@ -448,16 +492,22 @@ EOD; } } - +/** + * IXR_Client + * + * @package IXR + * @since 1.5 + */ class IXR_Client { var $server; var $port; var $path; var $useragent; + var $headers; var $response; var $message = false; var $debug = false; - var $timeout; + var $timeout; // Storage place for an error message var $error = false; function IXR_Client($server, $path = false, $port = 80, $timeout = false) { @@ -476,8 +526,8 @@ class IXR_Client { $this->path = $path; $this->port = $port; } - $this->useragent = 'Incutio XML-RPC'; - $this->timeout = $timeout; + $this->useragent = 'The Incutio XML-RPC PHP Library'; + $this->timeout = $timeout; } function query() { $args = func_get_args(); @@ -487,14 +537,21 @@ class IXR_Client { $xml = $request->getXml(); $r = "\r\n"; $request = "POST {$this->path} HTTP/1.0$r"; - $request .= "Host: {$this->server}$r"; - $request .= "Content-Type: text/xml$r"; - $request .= "User-Agent: {$this->useragent}$r"; - $request .= "Content-length: {$length}$r$r"; + + $this->headers['Host'] = $this->server; + $this->headers['Content-Type'] = 'text/xml'; + $this->headers['User-Agent'] = $this->useragent; + $this->headers['Content-Length']= $length; + + foreach( $this->headers as $header => $value ) { + $request .= "{$header}: {$value}{$r}"; + } + $request .= $r; + $request .= $xml; // Now send the request if ($this->debug) { - echo '
'.htmlspecialchars($request)."\n
\n\n"; + echo '
'.htmlspecialchars($request)."\n
\n\n"; } if ($this->timeout) { $fp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout); @@ -507,6 +564,7 @@ class IXR_Client { } fputs($fp, $request); $contents = ''; + $debug_contents = ''; $gotFirstLine = false; $gettingHeaders = true; while (!feof($fp)) { @@ -514,7 +572,7 @@ class IXR_Client { if (!$gotFirstLine) { // Check line for '200' if (strstr($line, '200') === false) { - $this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200'); + $this->error = new IXR_Error(-32301, 'transport error - HTTP status code was not 200'); return false; } $gotFirstLine = true; @@ -523,11 +581,14 @@ class IXR_Client { $gettingHeaders = false; } if (!$gettingHeaders) { - $contents .= trim($line)."\n"; + $contents .= trim($line); + } + if ($this->debug) { + $debug_contents .= $line; } } if ($this->debug) { - echo '
'.htmlspecialchars($contents)."\n
\n\n"; + echo '
'.htmlspecialchars($debug_contents)."\n
\n\n"; } // Now parse what we've got back $this->message = new IXR_Message($contents); @@ -559,13 +620,19 @@ class IXR_Client { } } - +/** + * IXR_Error + * + * @package IXR + * @since 1.5 + */ class IXR_Error { var $code; var $message; function IXR_Error($code, $message) { $this->code = $code; - $this->message = $message; + // WP adds htmlspecialchars(). See #5666 + $this->message = htmlspecialchars($message); } function getXml() { $xml = << - + EOD; return $xml; } } - +/** + * IXR_Date + * + * @package IXR + * @since 1.5 + */ class IXR_Date { var $year; var $month; @@ -599,6 +671,7 @@ class IXR_Date { var $hour; var $minute; var $second; + var $timezone; function IXR_Date($time) { // $time can be a PHP timestamp or an ISO one if (is_numeric($time)) { @@ -614,6 +687,8 @@ class IXR_Date { $this->hour = date('H', $timestamp); $this->minute = date('i', $timestamp); $this->second = date('s', $timestamp); + // WP adds timezone. See #2036 + $this->timezone = ''; } function parseIso($iso) { $this->year = substr($iso, 0, 4); @@ -622,9 +697,11 @@ class IXR_Date { $this->hour = substr($iso, 9, 2); $this->minute = substr($iso, 12, 2); $this->second = substr($iso, 15, 2); + // WP adds timezone. See #2036 $this->timezone = substr($iso, 17); } function getIso() { + // WP adds timezone. See #2036 return $this->year.$this->month.$this->day.'T'.$this->hour.':'.$this->minute.':'.$this->second.$this->timezone; } function getXml() { @@ -635,7 +712,12 @@ class IXR_Date { } } - +/** + * IXR_Base64 + * + * @package IXR + * @since 1.5 + */ class IXR_Base64 { var $data; function IXR_Base64($data) { @@ -646,7 +728,12 @@ class IXR_Base64 { } } - +/** + * IXR_IntrospectionServer + * + * @package IXR + * @since 1.5 + */ class IXR_IntrospectionServer extends IXR_Server { var $signatures; var $help; @@ -658,27 +745,27 @@ class IXR_IntrospectionServer extends IXR_Server { 'specVersion' => 1 ); $this->addCallback( - 'system.methodSignature', - 'this:methodSignature', - array('array', 'string'), + 'system.methodSignature', + 'this:methodSignature', + array('array', 'string'), 'Returns an array describing the return type and required parameters of a method' ); $this->addCallback( - 'system.getCapabilities', - 'this:getCapabilities', - array('struct'), + 'system.getCapabilities', + 'this:getCapabilities', + array('struct'), 'Returns a struct describing the XML-RPC specifications supported by this server' ); $this->addCallback( - 'system.listMethods', - 'this:listMethods', - array('array'), + 'system.listMethods', + 'this:listMethods', + array('array'), 'Returns an array of available methods on this server' ); $this->addCallback( - 'system.methodHelp', - 'this:methodHelp', - array('string', 'string'), + 'system.methodHelp', + 'this:methodHelp', + array('string', 'string'), 'Returns a documentation string for the specified method' ); } @@ -790,7 +877,12 @@ class IXR_IntrospectionServer extends IXR_Server { } } - +/** + * IXR_ClientMulticall + * + * @package IXR + * @since 1.5 + */ class IXR_ClientMulticall extends IXR_Client { var $calls = array(); function IXR_ClientMulticall($server, $path = false, $port = 80) { @@ -812,4 +904,4 @@ class IXR_ClientMulticall extends IXR_Client { } } -?> \ No newline at end of file +?>