Commit 40f4b10c authored by Etienne CHAMPETIER's avatar Etienne CHAMPETIER

ZP-797 WBXMLDecoder remove inlog / reread php://input.

Released under the Affero GNU General Public License (AGPL) version 3.

With POST request, we can read multiple times php://input,
this permit us to drop "inlog", which is an "always on" debug code
(introduced in ZP-608 / bbfe372c)
see Notes in http://php.net/manual/en/wrappers.php.php#wrappers.php.input
see also http://stackoverflow.com/a/3402343

we keep readRemainingData() as it's used in printwbxml.php

here is my test:

<?php

// tested working version:

// 5.6.15/fpm-fcgi (fedora22/php-fpm)
// 5.6.5/fpm-fcgi (centos6 php56 scl/php-fpm)
// 5.5.21/fpm-fcgi (centos6 php55 scl/php-fpm)
// 5.3.29/fpm-fcgi (centos6 php53 ius/php-fpm)

// 5.4.45-0+deb7u2/apache2handler
// 5.3.28/apache2handler (rhel6 php53 ius/apache)

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        echo 'not a post request!';
        echo '<br>'.PHP_EOL;
        echo 'curl --data "test POST" http://<server>/test-multi-read-input.php';
        echo PHP_EOL;
        exit();
}

function readinput($close = true) {
        $input = fopen('php://input', 'r');
        $content = stream_get_contents($input);
        if ($close)
                fclose($input);
        return $content;
}

echo "Reading multiple time php://input ";
if (readinput() === readinput() && readinput(false) === readinput(false)) {
        echo "WORKS \o/";
} else {
        echo "DOESN'T WORK :(";
}
echo PHP_EOL;
echo 'Version: '.PHP_VERSION.'/'.PHP_SAPI;
echo PHP_EOL;
echo PHP_EOL;

echo "Input was: ".readinput();
echo PHP_EOL;
parent c42848ed
...@@ -630,4 +630,19 @@ class Request { ...@@ -630,4 +630,19 @@ class Request {
return ($re) ? preg_replace($re, $replacevalue, $input) : ''; return ($re) ? preg_replace($re, $replacevalue, $input) : '';
} }
/**
* Returns base64 encoded "php://input"
* With POST request (our case), you can open and read
* multiple times "php://input"
*
* @access public
* @return string - base64 encoded wbxml
*/
public static function GetInputAsBase64() {
$input = fopen('php://input', 'r');
$wbxml = base64_encode(stream_get_contents($input));
fclose($input);
return $wbxml;
}
} }
...@@ -129,17 +129,12 @@ abstract class RequestProcessor { ...@@ -129,17 +129,12 @@ abstract class RequestProcessor {
// if there is an error decoding wbxml, consume remaining data and include it in the WBXMLException // if there is an error decoding wbxml, consume remaining data and include it in the WBXMLException
if (!$handler->Handle(Request::GetCommandCode())) { if (!$handler->Handle(Request::GetCommandCode())) {
$wbxmlLog = "no decoder"; throw new WBXMLException("Debug data: " . Request::GetInputAsBase64());
if (self::$decoder) {
self::$decoder->readRemainingData();
$wbxmlLog = self::$decoder->getWBXMLLog();
}
throw new WBXMLException("Debug data: " . $wbxmlLog);
} }
// also log WBXML in happy case // also log WBXML in happy case
if (self::$decoder && @constant('WBXML_DEBUG') === true) { if (@constant('WBXML_DEBUG') === true) {
ZLog::Write(LOGLEVEL_WBXML, "WBXML-IN : ". self::$decoder->getWBXMLLog(), false); ZLog::Write(LOGLEVEL_WBXML, "WBXML-IN : ". Request::GetInputAsBase64(), false);
} }
} }
......
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
class WBXMLDecoder extends WBXMLDefs { class WBXMLDecoder extends WBXMLDefs {
private $in; private $in;
private $inLog;
private $version; private $version;
private $publicid; private $publicid;
...@@ -115,7 +114,6 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -115,7 +114,6 @@ class WBXMLDecoder extends WBXMLDefs {
if (!defined('WBXML_DEBUG')) define('WBXML_DEBUG', false); if (!defined('WBXML_DEBUG')) define('WBXML_DEBUG', false);
$this->in = $input; $this->in = $input;
$this->inLog = StringStreamWrapper::Open("");
$this->readVersion(); $this->readVersion();
if (isset($this->version) && $this->version != self::VERSION) { if (isset($this->version) && $this->version != self::VERSION) {
...@@ -293,20 +291,6 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -293,20 +291,6 @@ class WBXMLDecoder extends WBXMLDefs {
while($this->getElement()); while($this->getElement());
} }
/**
* Returns the WBXML data read from the stream
*
* @access public
* @return string - base64 encoded wbxml
*/
public function getWBXMLLog() {
$out = "";
if ($this->inLog) {
$out = base64_encode(stream_get_contents($this->inLog, -1,0));
}
return $out;
}
/**---------------------------------------------------------------------------------------------------------- /**----------------------------------------------------------------------------------------------------------
* Private WBXMLDecoder stuff * Private WBXMLDecoder stuff
*/ */
...@@ -635,10 +619,8 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -635,10 +619,8 @@ class WBXMLDecoder extends WBXMLDefs {
// Stream ends prematurely on instable connections and big mails // Stream ends prematurely on instable connections and big mails
if ($data === false || feof($this->in)) if ($data === false || feof($this->in))
throw new HTTPReturnCodeException(sprintf("WBXMLDecoder->getOpaque() connection unavailable while trying to read %d bytes from stream. Aborting after %d bytes read.", $len, strlen($d)), HTTP_CODE_500, null, LOGLEVEL_WARN); throw new HTTPReturnCodeException(sprintf("WBXMLDecoder->getOpaque() connection unavailable while trying to read %d bytes from stream. Aborting after %d bytes read.", $len, strlen($d)), HTTP_CODE_500, null, LOGLEVEL_WARN);
else { else
$d .= $data; $d .= $data;
fwrite($this->inLog, $data);
}
} }
if (strlen($d) >= $len) break; if (strlen($d) >= $len) break;
} }
...@@ -653,10 +635,8 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -653,10 +635,8 @@ class WBXMLDecoder extends WBXMLDefs {
*/ */
private function getByte() { private function getByte() {
$ch = fread($this->in, 1); $ch = fread($this->in, 1);
if(strlen($ch) > 0) { if(strlen($ch) > 0)
fwrite($this->inLog, $ch);
return ord($ch); return ord($ch);
}
else else
return; return;
} }
...@@ -694,10 +674,8 @@ class WBXMLDecoder extends WBXMLDefs { ...@@ -694,10 +674,8 @@ class WBXMLDecoder extends WBXMLDefs {
$stringtable = ""; $stringtable = "";
$length = $this->getMBUInt(); $length = $this->getMBUInt();
if($length > 0) { if($length > 0)
$stringtable = fread($this->in, $length); $stringtable = fread($this->in, $length);
fwrite($this->inLog, $stringtable);
}
return $stringtable; return $stringtable;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment