Branch 'kolab-syncroton-2.2' - lib/ext
Aleksander Machniak
machniak at kolabsys.com
Tue Oct 8 11:45:00 CEST 2013
lib/ext/Syncroton/Server.php | 40 +++++++++++++++++++++++++++++------
lib/ext/Syncroton/Wbxml/Abstract.php | 3 +-
lib/ext/Syncroton/Wbxml/Decoder.php | 21 ++++++++++--------
lib/ext/Syncroton/Wbxml/Encoder.php | 24 +++++++++++++++------
4 files changed, 66 insertions(+), 22 deletions(-)
New commits:
commit 3ca69420f45b564e68655e2178714d862239c124
Author: Aleksander Machniak <alec at alec.pl>
Date: Tue Oct 8 11:44:33 2013 +0200
Fix encoder memory issue (Bug #2032)
diff --git a/lib/ext/Syncroton/Server.php b/lib/ext/Syncroton/Server.php
index 7b681a0..114db4d 100644
--- a/lib/ext/Syncroton/Server.php
+++ b/lib/ext/Syncroton/Server.php
@@ -172,9 +172,7 @@ class Syncroton_Server
if ($response instanceof DOMDocument) {
if ($this->_logger instanceof Zend_Log) {
- $response->formatOutput = true;
- $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " xml response:\n" . $response->saveXML());
- $response->formatOutput = false;
+ $this->_logDomDocument(Zend_Log::DEBUG, $response, __METHOD__, __LINE__);
}
if (isset($command) && $command instanceof Syncroton_Command_ICommand) {
@@ -190,7 +188,7 @@ class Syncroton_Server
} catch (Syncroton_Wbxml_Exception $swe) {
if ($this->_logger instanceof Zend_Log) {
$this->_logger->err(__METHOD__ . '::' . __LINE__ . " Could not encode output: " . $swe);
- $this->_logger->err(__METHOD__ . '::' . __LINE__ . " xml response:\n" . $response->saveXML());
+ $this->_logDomDocument(Zend_Log::ERR, $response, __METHOD__, __LINE__);
}
header("HTTP/1.1 500 Internal server error");
@@ -227,7 +225,7 @@ class Syncroton_Server
echo $header;
}
-
+
// output body
rewind($outputStream);
fpassthru($outputStream);
@@ -240,7 +238,37 @@ class Syncroton_Server
}
}
}
- }
+ }
+
+ /**
+ * write (possible big) DOMDocument in smaller chunks to log file
+ *
+ * @param unknown $priority
+ * @param DOMDocument $dom
+ * @param string $method
+ * @param string $method
+ */
+ protected function _logDomDocument($priority, DOMDocument $dom, $method, $method)
+ {
+ $loops = 0;
+
+ $tempStream = fopen('php://temp/maxmemory:5242880', 'r+');
+
+ $dom->formatOutput = true;
+ fwrite($tempStream, $dom->saveXML());
+ $dom->formatOutput = false;
+
+ rewind($tempStream);
+
+ // log data in 1MByte chunks
+ while (!feof($tempStream)) {
+ $this->_logger->log($method . '::' . $method . " xml response($loops):\n" . fread($tempStream, 1048576), $priority);
+
+ $loops++;
+ }
+
+ fclose($tempStream);
+ }
/**
* return request params
diff --git a/lib/ext/Syncroton/Wbxml/Abstract.php b/lib/ext/Syncroton/Wbxml/Abstract.php
index bec61f1..1ffa640 100644
--- a/lib/ext/Syncroton/Wbxml/Abstract.php
+++ b/lib/ext/Syncroton/Wbxml/Abstract.php
@@ -166,7 +166,8 @@ abstract class Syncroton_Wbxml_Abstract
$string .= $chunk;
$_length -= $len;
}
- else if (feof($this->_stream)) {
+
+ if (feof($this->_stream)) {
break;
}
}
diff --git a/lib/ext/Syncroton/Wbxml/Decoder.php b/lib/ext/Syncroton/Wbxml/Decoder.php
index 130d84f..8b845e4 100644
--- a/lib/ext/Syncroton/Wbxml/Decoder.php
+++ b/lib/ext/Syncroton/Wbxml/Decoder.php
@@ -129,8 +129,6 @@ class Syncroton_Wbxml_Decoder extends Syncroton_Wbxml_Abstract
case Syncroton_Wbxml_Abstract::OPAQUE:
$length = $this->_getMultibyteUInt();
if($length > 0) {
- // @TODO: handle big data with streams
- // E.g. in SendMail command "opaqued" <Mime> contains full email body
$opaque = $this->_getOpaque($length);
try {
// let see if we can decode it. maybe the opaque data is wbxml encoded content
@@ -173,28 +171,33 @@ class Syncroton_Wbxml_Decoder extends Syncroton_Wbxml_Abstract
// get rid of bit 7+8
$tagHexCode = $byte & 0x3F;
- $tag = $this->_codePage->getTag($tagHexCode);
- $nameSpace = $this->_codePage->getNameSpace();
+ try {
+ $tag = $this->_codePage->getTag($tagHexCode);
+ } catch (Syncroton_Wbxml_Exception $swe) {
+ // tag can not be converted to ASCII name
+ $tag = sprintf('unknown tag 0x%x', $tagHexCode);
+ }
+ $nameSpace = $this->_codePage->getNameSpace();
$codePageName = $this->_codePage->getCodePageName();
#echo "Tag: $nameSpace:$tag\n";
- if($node === NULL) {
+ if ($node === NULL) {
// create the domdocument
- $node = $this->_createDomDocument($nameSpace, $tag);
+ $node = $this->_createDomDocument($nameSpace, $tag);
$newNode = $node->documentElement;
} else {
- if(!$this->_dom->isDefaultNamespace($nameSpace)) {
+ if (!$this->_dom->isDefaultNamespace($nameSpace)) {
$this->_dom->documentElement->setAttribute('xmlns:' . $codePageName, $nameSpace);
}
$newNode = $node->appendChild($this->_dom->createElementNS('uri:' . $codePageName, $tag));
}
- if($tagHasAttributes) {
+ if ($tagHasAttributes) {
$attributes = $this->_getAttributes();
}
- if($tagHasContent == true) {
+ if ($tagHasContent == true) {
$node = $newNode;
$openTags++;
}
diff --git a/lib/ext/Syncroton/Wbxml/Encoder.php b/lib/ext/Syncroton/Wbxml/Encoder.php
index 746ea67..f17db83 100644
--- a/lib/ext/Syncroton/Wbxml/Encoder.php
+++ b/lib/ext/Syncroton/Wbxml/Encoder.php
@@ -151,6 +151,10 @@ class Syncroton_Wbxml_Encoder extends Syncroton_Wbxml_Abstract
{
$_dom->formatOutput = false;
+ $tempStream = fopen('php://temp/maxmemory:5242880', 'r+');
+ fwrite($tempStream, $_dom->saveXML());
+ rewind($tempStream);
+
$this->_initialize($_dom);
$parser = xml_parser_create_ns($this->_charSet, ';');
@@ -159,14 +163,22 @@ class Syncroton_Wbxml_Encoder extends Syncroton_Wbxml_Abstract
xml_set_character_data_handler($parser, '_handleCharacters');
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
- if (!xml_parse($parser, $_dom->saveXML())) {
- #file_put_contents(tempnam(sys_get_temp_dir(), "xmlerrors"), $_dom->saveXML());
- throw new Syncroton_Wbxml_Exception(sprintf('XML error: %s at line %d',
- xml_error_string(xml_get_error_code($parser)),
- xml_get_current_line_number($parser)
- ));
+ while (!feof($tempStream)) {
+ if (!xml_parse($parser, fread($tempStream, 1048576), feof($tempStream))) {
+ // uncomment to write xml document to file
+ #rewind($tempStream);
+ #$xmlStream = fopen(tempnam(sys_get_temp_dir(), "xmlerrors"), 'r+');
+ #stream_copy_to_stream($tempStream, $xmlStream);
+ #fclose($xmlStream);
+
+ throw new Syncroton_Wbxml_Exception(sprintf('XML error: %s at line %d',
+ xml_error_string(xml_get_error_code($parser)),
+ xml_get_current_line_number($parser)
+ ));
+ }
}
+ fclose($tempStream);
xml_parser_free($parser);
}
More information about the commits
mailing list