+if (!function_exists('http_chunked_decode')) {
+ /**
+ * dechunk an http 'transfer-encoding: chunked' message.
+ *
+ * @param $chunk The encoded message
+ * @return $dechunk The decoded message. If $chunk wasn't encoded properly debug_report_bug() is being called
+ * @author Marques Johansson
+ * @link http://php.net/manual/en/function.http-chunked-decode.php#89786
+ */
+ function http_chunked_decode ($chunk) {
+ // Init some variables
+ $offset = 0;
+ $len = mb_strlen($chunk);
+ $dechunk = '';
+
+ // Walk through all chunks
+ while ($offset < $len) {
+ // Where does the \r\n begin?
+ $lineEndAt = mb_strpos($chunk, getConfig('HTTP_EOL'), $offset);
+
+ /* DEBUG: *
+ print 'lineEndAt[<em>'.__LINE__.'</em>]='.$lineEndAt.'<br />
+offset[<em>'.__LINE__.'</em>]='.$offset.'<br />
+len='.$len.'<br />
+next[offset]=<pre>'.replaceReturnNewLine(htmlentities(mb_substr($chunk, $offset, 10))).'</pre>';
+ /* DEBUG: */
+
+ // Get next hex-coded chunk length
+ $chunkLenHex = mb_substr($chunk, $offset, ($lineEndAt - $offset));
+
+ /* DEBUG: *
+ print 'chunkLenHex[<em>'.__LINE__.'</em>]='.replaceReturnNewLine(htmlentities($chunkLenHex)).'<br />
+';
+ /* DEBUG: */
+
+ // Validation if it is hexadecimal
+ if (!isHexadecimal($chunkLenHex)) {
+ // Please help debugging this
+ //* DEBUG: */ die('ABORT:chunkLenHex=<pre>'.replaceReturnNewLine(htmlentities($chunkLenHex)).'</pre>');
+ debug_report_bug(__FUNCTION__, __LINE__, 'Value ' . $chunkLenHex . ' is not properly chunk encoded.');
+
+ // This won't be reached
+ return $chunk;
+ } // END - if
+
+ // Position of next chunk is right after \r\n
+ $offset = $offset + strlen($chunkLenHex) + strlen(getConfig('HTTP_EOL'));
+ $chunkLen = hexdec(rtrim($chunkLenHex, getConfig('HTTP_EOL')));
+
+ /* DEBUG: *
+ print 'chunkLen='.$chunkLen.'<br />
+offset[<em>'.__LINE__.'</em>]='.$offset.'<br />';
+ /* DEBUG: */
+
+ // Moved out for debugging
+ $next = mb_substr($chunk, $offset, $chunkLen);
+ //* DEBUG: */ print 'next=<pre>'.replaceReturnNewLine(htmlentities($next)).'</pre>';
+
+ // Count occurrences of \r\n
+ $count = mb_substr_count($next, getConfig('HTTP_EOL'));
+
+ // Correct it because we need to subtract occurrences of \r\n
+ $chunkLen = hexdec(rtrim($chunkLenHex, getConfig('HTTP_EOL'))) - ($count * strlen(getConfig('HTTP_EOL')));
+
+ $dechunk .= mb_substr($chunk, $offset, $chunkLen);
+
+ /* DEBUG: *
+ print('offset[<em>'.__LINE__.'</em>]='.$offset.'<br />
+lineEndAt[<em>'.__LINE__.'</em>]='.$lineEndAt.'<br />
+len='.$len.'<br />
+count='.$count.'<br />
+chunkLen='.$chunkLen.'<br />
+chunkLenHex='.$chunkLenHex.'<br />
+dechunk=<pre>'.replaceReturnNewLine(htmlentities($dechunk)).'</pre>
+chunk=<pre>'.replaceReturnNewLine(htmlentities($chunk)).'</pre>');
+ /* DEBUG: */
+
+ // Is $offset + $chunkLen larger than or equal $len?
+ if (($offset + $chunkLen) >= $len) {
+ // Then stop processing here
+ break;
+ } // END - if
+
+ // Calculate next offset of chunk
+ $offset = mb_strpos($chunk, getConfig('HTTP_EOL'), $offset + $chunkLen) + 2;
+
+ /* DEBUG: *
+ print('offset[<em>'.__LINE__.'</em>]='.$offset.'<br />
+next[100]=<pre>'.replaceReturnNewLine(htmlentities(mb_substr($chunk, $offset, 100))).'</pre>
+---:---:---:---:---:---:---:---:---<br />
+');
+ /* DEBUG: */
+ } // END - while
+
+ // Return de-chunked string
+ return $dechunk;
+ }
+} // END - if
+