X-Git-Url: https://git.mxchange.org/?p=mailer.git;a=blobdiff_plain;f=inc%2Ffunctions.php;h=79e5d8d5a7541f79bae4a3cc289f8032a9a5e27d;hp=4b25ba977704ed82f709b48713f0e574d5c634f6;hb=1c28686d33a76fa9e3e5bd90f737b20bfe211575;hpb=c4823d28fd0bd22250b16d73f2034f36fc54abda diff --git a/inc/functions.php b/inc/functions.php index 4b25ba9777..79e5d8d5a7 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -118,12 +118,12 @@ function sendEmail ($toEmail, $subject, $message, $isHtml = 'N', $mailHeader = ' $toEmail = getUserData('email'); } else { // Set webmaster - $toEmail = getConfig('WEBMASTER'); + $toEmail = getWebmaster(); } } } elseif ($toEmail == '0') { // Is the webmaster! - $toEmail = getConfig('WEBMASTER'); + $toEmail = getWebmaster(); } //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, "TO={$toEmail}
"); @@ -170,7 +170,7 @@ Message : ' . htmlentities(utf8_decode($message)) . ' return sendRawEmail($toEmail, $subject, $message, $mailHeader); } elseif ($isHtml != 'Y') { // Problem detected while sending a mail, forward it to admin - return sendRawEmail(getConfig('WEBMASTER'), '[PROBLEM:]' . $subject, $message, $mailHeader); + return sendRawEmail(getWebmaster(), '[PROBLEM:]' . $subject, $message, $mailHeader); } // Why did we end up here? This should not happen @@ -219,7 +219,7 @@ function sendRawEmail ($toEmail, $subject, $message, $headers) { $mail->Username = getConfig('SMTP_USER'); $mail->Password = getConfig('SMTP_PASSWORD'); if (empty($headers)) { - $mail->From = getConfig('WEBMASTER'); + $mail->From = getWebmaster(); } else { $mail->From = $headers; } @@ -235,10 +235,10 @@ function sendRawEmail ($toEmail, $subject, $message, $headers) { } $mail->AddAddress($toEmail, ''); - $mail->AddReplyTo(getConfig('WEBMASTER'), getMainTitle()); - $mail->AddCustomHeader('Errors-To:' . getConfig('WEBMASTER')); - $mail->AddCustomHeader('X-Loop:' . getConfig('WEBMASTER')); - $mail->AddCustomHeader('Bounces-To:' . getConfig('WEBMASTER')); + $mail->AddReplyTo(getWebmaster(), getMainTitle()); + $mail->AddCustomHeader('Errors-To:' . getWebmaster()); + $mail->AddCustomHeader('X-Loop:' . getWebmaster()); + $mail->AddCustomHeader('Bounces-To:' . getWebmaster()); $mail->Send(); // Has an error occured? @@ -659,7 +659,7 @@ function generateRandomCode ($length, $code, $userid, $DATA = '') { $server = $_SERVER['PHP_SELF'] . getEncryptSeperator() . detectUserAgent() . getEncryptSeperator() . getenv('SERVER_SOFTWARE') . getEncryptSeperator() . detectRealIpAddress() . getEncryptSeperator() . detectRemoteAddr(); // Build key string - $keys = getConfig('SITE_KEY') . getEncryptSeperator() . getConfig('DATE_KEY'); + $keys = getSiteKey() . getEncryptSeperator() . getDateKey(); if (isConfigEntrySet('secret_key')) { $keys .= getEncryptSeperator().getSecretKey(); } // END - if @@ -690,22 +690,26 @@ function generateRandomCode ($length, $code, $userid, $DATA = '') { if (isConfigEntrySet('master_salt')) { // Generate hash with master salt from modula of number with the prime number and other data - $saltedHash = generateHash(($a % getPrime()) . getEncryptSeperator() . $server . getEncryptSeperator() . $keys . getEncryptSeperator() . $data . getEncryptSeperator() . getConfig('DATE_KEY') . getEncryptSeperator() . $a, getMasterSalt()); + $saltedHash = generateHash(($a % getPrime()) . getEncryptSeperator() . $server . getEncryptSeperator() . $keys . getEncryptSeperator() . $data . getEncryptSeperator() . getDateKey() . getEncryptSeperator() . $a, getMasterSalt()); // Create number from hash - $rcode = hexdec(substr($saltedHash, strlen(getMasterSalt()), 9)) / abs(getConfig('rand_no') - $a + sqrt(getConfig('_ADD'))) / pi(); + $rcode = hexdec(substr($saltedHash, strlen(getMasterSalt()), 9)) / abs(getRandNo() - $a + sqrt(getConfig('_ADD'))) / pi(); } else { // Generate hash with "hash of site key" from modula of number with the prime number and other data - $saltedHash = generateHash(($a % getPrime()) . getEncryptSeperator() . $server . getEncryptSeperator() . $keys . getEncryptSeperator() . $data . getEncryptSeperator() . getConfig('DATE_KEY') . getEncryptSeperator() . $a, substr(sha1(getConfig('SITE_KEY')), 0, getSaltLength())); + $saltedHash = generateHash(($a % getPrime()) . getEncryptSeperator() . $server . getEncryptSeperator() . $keys . getEncryptSeperator() . $data . getEncryptSeperator() . getDateKey() . getEncryptSeperator() . $a, substr(sha1(getSiteKey()), 0, getSaltLength())); // Create number from hash - $rcode = hexdec(substr($saltedHash, 8, 9)) / abs(getConfig('rand_no') - $a + sqrt(getConfig('_ADD'))) / pi(); + $rcode = hexdec(substr($saltedHash, 8, 9)) / abs(getRandNo() - $a + sqrt(getConfig('_ADD'))) / pi(); } // At least 10 numbers shall be secure enought! $len = getCodeLength(); - if ($len == '0') $len = $length; - if ($len == '0') $len = 10; + if ($len == '0') { + $len = $length; + } // END - if + if ($len == '0') { + $len = 10; + } // END - if // Cut off requested counts of number $return = substr(str_replace('.', '', $rcode), 0, $len); @@ -815,7 +819,9 @@ function extractHostnameFromUrl (&$script) { // Extract host name $host = str_replace('http://', '', $url); - if (isInString('/', $host)) $host = substr($host, 0, strpos($host, '/')); + if (isInString('/', $host)) { + $host = substr($host, 0, strpos($host, '/')); + } // END - if // Generate relative URL //* DEBUG: */ debugOutput('SCRIPT=' . $script); @@ -828,22 +834,24 @@ function extractHostnameFromUrl (&$script) { } //* DEBUG: */ debugOutput('SCRIPT=' . $script); - if (substr($script, 0, 1) == '/') $script = substr($script, 1); + if (substr($script, 0, 1) == '/') { + $script = substr($script, 1); + } // END - if // Return host name return $host; } // Send a GET request -function sendGetRequest ($script, $data = array()) { - // Extract host name from script +function sendGetRequest ($script, $data = array(), $removeHeader = false) { + // Extract hostname and port from script $host = extractHostnameFromUrl($script); // Add data $body = http_build_query($data, '', '&'); // There should be data, else we don't need to extend $script with $body - if (empty($body)) { + if (!empty($body)) { // Do we have a question-mark in the script? if (strpos($script, '?') === false) { // No, so first char must be question mark @@ -857,7 +865,9 @@ function sendGetRequest ($script, $data = array()) { $script .= $body; // Remove trailed & to make it more conform - if (substr($script, -1, 1) == '&') $script = substr($script, 0, -1); + if (substr($script, -1, 1) == '&') { + $script = substr($script, 0, -1); + } // END - if } // END - if // Generate GET request header @@ -878,19 +888,18 @@ function sendGetRequest ($script, $data = array()) { // Send the raw request $response = sendRawRequest($host, $request); + // Should we remove header lines? + if ($removeHeader === true) { + // Okay, remove them + $response = removeHttpHeaderFromResponse($response); + } // END - if + // Return the result to the caller function return $response; } // Send a POST request -function sendPostRequest ($script, $postData) { - // Is postData an array? - if (!is_array($postData)) { - // Abort here - logDebugMessage(__FUNCTION__, __LINE__, sprintf("postData is not an array. Type: %s", gettype($postData))); - return array('', '', ''); - } // END - if - +function sendPostRequest ($script, array $postData, $removeHeader = false) { // Extract host name from script $host = extractHostnameFromUrl($script); @@ -916,6 +925,12 @@ function sendPostRequest ($script, $postData) { // Send the raw request $response = sendRawRequest($host, $request); + // Should we remove header lines? + if ($removeHeader === true) { + // Okay, remove them + $response = removeHttpHeaderFromResponse($response); + } // END - if + // Return the result to the caller function return $response; } @@ -923,7 +938,11 @@ function sendPostRequest ($script, $postData) { // Sends a raw request to another host function sendRawRequest ($host, $request) { // Init errno and errdesc with 'all fine' values - $errno = '0'; $errdesc = ''; + $errno = '0'; + $errdesc = ''; + + // Default port is 80 + $port = 80; // Initialize array $response = array('', '', ''); @@ -940,6 +959,17 @@ function sendRawRequest ($host, $request) { // Load include loadIncludeOnce('inc/classes/resolver.class.php'); + // Extract port part from host + $portArray = explode(':', $host); + if (count($portArray) == 2) { + // Extract host and port + $host = $portArray[0]; + $port = $portArray[1]; + } elseif (count($portArray) > 2) { + // This should not happen! + debug_report_bug(__FUNCTION__, __LINE__, 'Invalid ' . $host . '. Please report this to the Mailer-Project team.'); + } + // Get resolver instance $resolver = new HostnameResolver(); @@ -947,16 +977,16 @@ function sendRawRequest ($host, $request) { //* DEBUG: */ die('SCRIPT=' . $script); if ($useProxy === true) { // Resolve hostname into IP address - $ip = $resolver->resolveHostname(compileRawCode(getConfig('proxy_host'))); + $ip = $resolver->resolveHostname(compileRawCode(getProxyHost())); // Connect to host through proxy connection - $fp = fsockopen($ip, bigintval(getConfig('proxy_port')), $errno, $errdesc, 30); + $fp = fsockopen($ip, bigintval(getProxyPort()), $errno, $errdesc, 30); } else { // Resolve hostname into IP address $ip = $resolver->resolveHostname($host); // Connect to host directly - $fp = fsockopen($ip, 80, $errno, $errdesc, 30); + $fp = fsockopen($ip, $port, $errno, $errdesc, 30); } // Is there a link? @@ -973,7 +1003,7 @@ function sendRawRequest ($host, $request) { // Do we use proxy? if ($useProxy === true) { // Setup proxy tunnel - $response = setupProxyTunnel($host, $fp); + $response = setupProxyTunnel($host, $port, $fp); // If the response is invalid, abort if ((count($response) == 3) && (empty($response[0])) && (empty($response[1])) && (empty($response[2]))) { @@ -1016,7 +1046,7 @@ function sendRawRequest ($host, $request) { } // END - if // Add it to response - $response[] = trim($line); + $response[] = $line; } // END - while // Close socket @@ -1063,6 +1093,9 @@ function sendRawRequest ($host, $request) { // Not found / access forbidden logDebugMessage(__FUNCTION__, __LINE__, 'Unexpected status code ' . $response[0] . ' detected. "200 OK" was expected.'); $response = array('', '', ''); + } else { + // Check array for chuncked encoding + $response = unchunkHttpResponse($response); } // END - if // Return response @@ -1070,18 +1103,18 @@ function sendRawRequest ($host, $request) { } // Sets up a proxy tunnel for given hostname and through resource -function setupProxyTunnel ($host, $resource) { +function setupProxyTunnel ($host, $port, $resource) { // Initialize array $response = array('', '', ''); // Generate CONNECT request header - $proxyTunnel = 'CONNECT ' . $host . ':80 HTTP/1.0' . getConfig('HTTP_EOL'); + $proxyTunnel = 'CONNECT ' . $host . ':' . $port . ' HTTP/1.0' . getConfig('HTTP_EOL'); $proxyTunnel .= 'Host: ' . $host . getConfig('HTTP_EOL'); // Use login data to proxy? (username at least!) - if (getConfig('proxy_username') != '') { + if (getProxyUsername() != '') { // Add it as well - $encodedAuth = base64_encode(compileRawCode(getConfig('proxy_username')) . ':' . compileRawCode(getConfig('proxy_password'))); + $encodedAuth = base64_encode(compileRawCode(getProxyUsername()) . ':' . compileRawCode(getProxyPassword())); $proxyTunnel .= 'Proxy-Authorization: Basic ' . $encodedAuth . getConfig('HTTP_EOL'); } // END - if @@ -1110,6 +1143,76 @@ function setupProxyTunnel ($host, $resource) { return $respArray; } +// Check array for chuncked encoding +function unchunkHttpResponse (array $response) { + // Default is not chunked + $isChunked = false; + + // Check if we have chunks + foreach ($response as $line) { + // Make lower-case and trim it + $line = trim(strtolower($line)); + + // Entry found? + if ((strpos($line, 'transfer-encoding') !== false) && (strpos($line, 'chunked') !== false)) { + // Found! + $isChunked = true; + break; + } // END - if + } // END - foreach + + // Is it chunked? + if ($isChunked === true) { + // Good, we still have the HTTP headers in there, so we need to get rid + // of them temporarly + //* DEBUG: */ die('
'.htmlentities(print_r(removeHttpHeaderFromResponse($response), true)).'
'); + $tempResponse = http_chunked_decode(implode('', removeHttpHeaderFromResponse($response))); + + // We got a string back from http_chunked_decode(), so we need to convert it back to an array + //* DEBUG: */ die('tempResponse['.strlen($tempResponse).']=
'.replaceReturnNewLine(htmlentities($tempResponse)).'
'); + + // Re-add the headers + $response = merge_array($GLOBALS['http_headers'], stringToArray("\n", $tempResponse)); + } // END - if + + // Return the unchunked array + return $response; +} + +// Removes HTTP header lines from a response array (e.g. output from sendRequest() ) +function removeHttpHeaderFromResponse (array $response) { + // Save headers for later usage + $GLOBALS['http_headers'] = array(); + + // The first array element has to contain HTTP + if ((isset($response[0])) && (substr(strtoupper($response[0]), 0, 5) == 'HTTP/')) { + // Okay, we have headers, now remove them with a second array + $response2 = $response; + foreach ($response as $line) { + // Remove line + array_shift($response2); + + // Add full line to temporary global array + $GLOBALS['http_headers'][] = $line; + + // Trim it for testing + $lineTest = trim($line); + + // Is this line empty? + if (empty($lineTest)) { + // Then stop here + break; + } // END - if + } // END - foreach + + // Write back the array + $response = $response2; + } // END - if + + // Return the modified response array + return $response; +} + // Taken from www.php.net isInStringIgnoreCase() user comments function isEmailValid ($email) { // Check first part of email address @@ -1176,7 +1279,7 @@ function generateHash ($plainText, $salt = '', $hash = true) { $server = $_SERVER['PHP_SELF'] . getEncryptSeperator() . detectUserAgent() . getEncryptSeperator() . getenv('SERVER_SOFTWARE') . getEncryptSeperator() . detectRealIpAddress() . getEncryptSeperator() . detectRemoteAddr(); // Build key string - $keys = getConfig('SITE_KEY') . getEncryptSeperator() . getConfig('DATE_KEY') . getEncryptSeperator() . getSecretKey() . getEncryptSeperator() . getFileHash() . getEncryptSeperator() . getDateFromPatchTime() . getEncryptSeperator() . getMasterSalt(); + $keys = getSiteKey() . getEncryptSeperator() . getDateKey() . getEncryptSeperator() . getSecretKey() . getEncryptSeperator() . getFileHash() . getEncryptSeperator() . getDateFromPatchTime() . getEncryptSeperator() . getMasterSalt(); // Additional data $data = $plainText . getEncryptSeperator() . uniqid(mt_rand(), true) . getEncryptSeperator() . time(); @@ -1185,7 +1288,7 @@ function generateHash ($plainText, $salt = '', $hash = true) { $a = time() + getConfig('_ADD') - 1; // Generate SHA1 sum from modula of number and the prime number - $sha1 = sha1(($a % getPrime()) . $server . getEncryptSeperator() . $keys . getEncryptSeperator() . $data . getEncryptSeperator() . getConfig('DATE_KEY') . getEncryptSeperator() . $a); + $sha1 = sha1(($a % getPrime()) . $server . getEncryptSeperator() . $keys . getEncryptSeperator() . $data . getEncryptSeperator() . getDateKey() . getEncryptSeperator() . $a); //* DEBUG: */ debugOutput('SHA1=' . $sha1.' ('.strlen($sha1).')
'); $sha1 = scrambleString($sha1); //* DEBUG: */ debugOutput('Scrambled=' . $sha1.' ('.strlen($sha1).')
'); @@ -1519,13 +1622,13 @@ function getMessageFromErrorCode ($code) { $content['timestamp'] = generateDateTime($content['timestamp'], 1); // Calculate hours... - $content['hours'] = round(getConfig('url_tlock') / 60 / 60); + $content['hours'] = round(getUrlTlock() / 60 / 60); // Minutes... - $content['minutes'] = round((getConfig('url_tlock') - $content['hours'] * 60 * 60) / 60); + $content['minutes'] = round((getUrlTlock() - $content['hours'] * 60 * 60) / 60); // And seconds - $content['seconds'] = round(getConfig('url_tlock') - $content['hours'] * 60 * 60 - $content['minutes'] * 60); + $content['seconds'] = round(getUrlTlock() - $content['hours'] * 60 * 60 - $content['minutes'] * 60); // Finally contruct the message $message = loadTemplate('tlock_message', true, $content); @@ -1917,11 +2020,11 @@ function addNewBonusMail ($data, $mode = '', $output = true) { // Mail inserted into bonus pool if ($output === true) { - loadTemplate('admin_settings_saved', false, '{--ADMIN_BONUS_SEND--}'); + displayMessage('{--ADMIN_BONUS_SEND--}'); } // END - if } elseif ($output === true) { // More entered than can be reached! - loadTemplate('admin_settings_saved', false, '{--ADMIN_MORE_SELECTED--}'); + displayMessage('{--ADMIN_MORE_SELECTED--}'); } else { // Debug log logDebugMessage(__FUNCTION__, __LINE__, 'cat=' . $data['cat'] . ',receiver=' . $data['receiver'] . ',data=' . base64_encode(serialize($data)) . ' More selected, than available!'); @@ -1931,7 +2034,9 @@ function addNewBonusMail ($data, $mode = '', $output = true) { // Determines referal id and sets it function determineReferalId () { // Skip this in non-html-mode and outside ref.php - if ((!isHtmlOutputMode()) && (basename($_SERVER['PHP_SELF']) != 'ref.php')) return false; + if ((!isHtmlOutputMode()) && (basename($_SERVER['PHP_SELF']) != 'ref.php')) { + return false; + } // END - if // Check if refid is set if ((isset($GLOBALS['refid'])) && ($GLOBALS['refid'] > 0)) { @@ -1999,6 +2104,15 @@ function doReset () { runFilterChain('reset'); } +// Enables the reset mode (hourly, weekly and monthly) and runs it +function doHourly () { + // Enable the hourly reset mode + $GLOBALS['hourly_enabled'] = true; + + // Run filters (one always!) + runFilterChain('hourly'); +} + // Our shutdown-function function shutdown () { // Call the filter chain 'shutdown' @@ -2126,7 +2240,7 @@ function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = false, $ad // And skip further processing continue; - } elseif (substr($baseFile, 0, strlen($prefix)) != $prefix) { + } elseif (!isFilePrefixFound($baseFile, $prefix)) { // Skip this file //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'Invalid prefix in file ' . $baseFile . ', prefix=' . $prefix); continue; @@ -2140,9 +2254,12 @@ function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = false, $ad continue; } + // Get file' extension (last 4 chars) + $fileExtension = substr($baseFile, -4, 4); + // Is the file a PHP script or other? //* DEBUG: */ logDebugMessage(__FUNCTION__, __LINE__, 'baseDir=' . $baseDir . ',prefix=' . $prefix . ',baseFile=' . $baseFile); - if ((substr($baseFile, -4, 4) == '.php') || (($fileIncludeDirs === true) && (isDirectory($FQFN)))) { + if (($fileExtension == '.php') || (($fileIncludeDirs === true) && (isDirectory($FQFN)))) { // Is this a valid include file? if ($extension == '.php') { // Remove both for extension name @@ -2158,9 +2275,9 @@ function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = false, $ad } } else { // We found .php file but should not search for them, why? - debug_report_bug(__FUNCTION__, __LINE__, 'We should find files with extension=' . $extension . ', but we found a PHP script.'); + debug_report_bug(__FUNCTION__, __LINE__, 'We should find files with extension=' . $extension . ', but we found a PHP script. (baseFile=' . $baseFile . ')'); } - } elseif (substr($baseFile, -4, 4) == $extension) { + } elseif ($fileExtension == $extension) { // Other, generic file found $files[] = $fileName; } @@ -2177,6 +2294,12 @@ function getArrayFromDirectory ($baseDir, $prefix, $fileIncludeDirs = false, $ad return $files; } +// Checks wether $prefix is found in $fileName +function isFilePrefixFound ($fileName, $prefix) { + // @TODO Find a way to cache this + return (substr($fileName, 0, strlen($prefix)) == $prefix); +} + // Maps a module name into a database table name function mapModuleToTable ($moduleName) { // Map only these, still lame code... @@ -2298,7 +2421,10 @@ function getModuleFromFileName ($file, $accessLevel) { // Encodes an URL for adding session id, etc. function encodeUrl ($url, $outputMode = '0') { // Do we have already have a PHPSESSID inside or view.php is called? Then abort here - if ((strpos($url, session_name()) !== false) || (isRawOutputMode())) return $url; + if ((strpos($url, session_name()) !== false) || (isRawOutputMode())) { + // Raw output mode detected or session_name() found in URL + return $url; + } // END - if // Do we have a valid session? if (((!isset($GLOBALS['valid_session'])) || ($GLOBALS['valid_session'] === false) || (!isset($_COOKIE[session_name()]))) && (isSpider() === false)) { @@ -2309,7 +2435,7 @@ function encodeUrl ($url, $outputMode = '0') { // No question mark $seperator = '?'; } elseif ((!isHtmlOutputMode()) || ($outputMode != '0')) { - // Non-HTML mode + // Non-HTML mode (or forced non-HTML mode $seperator = '&'; } @@ -2480,7 +2606,7 @@ function generateAdminMailLinks ($mailType, $mailId) { if (SQL_NUMROWS($result) == 1) { // Load the entry $content = SQL_FETCHARRAY($result); - die('
'.print_r($content, true).'
'); + die(__FUNCTION__.':
content=
'.print_r($content, true).'
'); } // END - if // Free result @@ -2491,10 +2617,55 @@ function generateAdminMailLinks ($mailType, $mailId) { return $OUT; } + +/** + * determine if a string can represent a number in hexadecimal + * + * @param $hex A string to check if it is hex-encoded + * @return $foo True if the string is a hex, otherwise false + * @author Marques Johansson + * @link http://php.net/manual/en/function.http-chunked-decode.php#89786 + */ +function isHexadecimal ($hex) { + // Make it lowercase + $hex = strtolower(trim(ltrim($hex, '0'))); + + // Fix empty strings to zero + if (empty($hex)) { + $hex = 0; + } // END - if + + // Simply compare decode->encode result with original + return ($hex == dechex(hexdec($hex))); +} + +// Replace "\r" with "[r]" and "\n" with "[n]" and add a final new-line to make +// them visible to the developer. Use this function to debug e.g. buggy HTTP +// response handler functions. +function replaceReturnNewLine ($str) { + return str_replace("\r", '[r]', str_replace("\n", '[n] +', $str)); +} + +// Converts a given string by splitting it up with given delimiter similar to +// explode(), but appending the delimiter again +function stringToArray ($delimiter, $string) { + // Init array + $strArray = array(); + + // "Walk" through all entries + foreach (explode($delimiter, $string) as $split) { + // Append the delimiter and add it to the array + $strArray[] = $split . $delimiter; + } // END - foreach + + // Return array + return $strArray; +} + //----------------------------------------------------------------------------- // Automatically re-created functions, all taken from user comments on www.php.net //----------------------------------------------------------------------------- -// if (!function_exists('html_entity_decode')) { // Taken from documentation on www.php.net function html_entity_decode ($string) { @@ -2513,7 +2684,9 @@ if (!function_exists('http_build_query')) { $k = urlencode($prefix . $k); } // END - if - if ((!empty($key)) || ($key === 0)) $k = $key . '[' . urlencode($k) . ']'; + if ((!empty($key)) || ($key === 0)) { + $k = $key . '[' . urlencode($k) . ']'; + } // END - if if (is_array($v) || is_object($v)) { array_push($ret, http_build_query($v, '', $sep, $k)); @@ -2522,11 +2695,112 @@ if (!function_exists('http_build_query')) { } } // END - foreach - if (empty($sep)) $sep = ini_get('arg_separator.output'); + if (empty($sep)) { + $sep = ini_get('arg_separator.output'); + } // END - if return implode($sep, $ret); } } // END - if +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['.__LINE__.']='.$lineEndAt.'
+offset['.__LINE__.']='.$offset.'
+len='.$len.'
+next[offset]=
'.replaceReturnNewLine(htmlentities(mb_substr($chunk, $offset, 10))).'
'; + /* DEBUG: */ + + // Get next hex-coded chunk length + $chunkLenHex = mb_substr($chunk, $offset, ($lineEndAt - $offset)); + + /* DEBUG: * + print 'chunkLenHex['.__LINE__.']='.replaceReturnNewLine(htmlentities($chunkLenHex)).'
+'; + /* DEBUG: */ + + // Validation if it is hexadecimal + if (!isHexadecimal($chunkLenHex)) { + // Please help debugging this + //* DEBUG: */ die('ABORT:chunkLenHex=
'.replaceReturnNewLine(htmlentities($chunkLenHex)).'
'); + 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.'
+offset['.__LINE__.']='.$offset.'
'; + /* DEBUG: */ + + // Moved out for debugging + $next = mb_substr($chunk, $offset, $chunkLen); + //* DEBUG: */ print 'next=
'.replaceReturnNewLine(htmlentities($next)).'
'; + + // 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['.__LINE__.']='.$offset.'
+lineEndAt['.__LINE__.']='.$lineEndAt.'
+len='.$len.'
+count='.$count.'
+chunkLen='.$chunkLen.'
+chunkLenHex='.$chunkLenHex.'
+dechunk=
'.replaceReturnNewLine(htmlentities($dechunk)).'
+chunk=
'.replaceReturnNewLine(htmlentities($chunk)).'
'); + /* 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['.__LINE__.']='.$offset.'
+next[100]=
'.replaceReturnNewLine(htmlentities(mb_substr($chunk, $offset, 100))).'
+---:---:---:---:---:---:---:---:---
+'); + /* DEBUG: */ + } // END - while + + // Return de-chunked string + return $dechunk; + } +} // END - if + // [EOF] ?>