#!/usr/bin/env php 2, 'c' => 'text/plain', 'cc' => 'text/plain', 'cpp' => 'text/plain', 'c++' => 'text/plain', 'dtd' => 'text/plain', 'h' => 'text/plain', 'log' => 'text/plain', 'rng' => 'text/plain', 'txt' => 'text/plain', 'xsd' => 'text/plain', 'php' => 1, 'inc' => 1, 'avi' => 'video/avi', 'bmp' => 'image/bmp', 'css' => 'text/css', 'gif' => 'image/gif', 'htm' => 'text/html', 'html' => 'text/html', 'htmls' => 'text/html', 'ico' => 'image/x-ico', 'jpe' => 'image/jpeg', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'js' => 'application/x-javascript', 'midi' => 'audio/midi', 'mid' => 'audio/midi', 'mod' => 'audio/mod', 'mov' => 'movie/quicktime', 'mp3' => 'audio/mp3', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg', 'pdf' => 'application/pdf', 'png' => 'image/png', 'swf' => 'application/shockwave-flash', 'tif' => 'image/tiff', 'tiff' => 'image/tiff', 'wav' => 'audio/wav', 'xbm' => 'image/xbm', 'xml' => 'text/xml', ); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); $basename = basename(__FILE__); if (!strpos($_SERVER['REQUEST_URI'], $basename)) { chdir(Extract_Phar::$temp); include $web; return; } $pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename)); if (!$pt || $pt == '/') { $pt = $web; header('HTTP/1.1 301 Moved Permanently'); header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt); exit; } $a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt); if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) { header('HTTP/1.0 404 Not Found'); echo "\n \n File Not Found<title>\n </head>\n <body>\n <h1>404 - File ", $pt, " Not Found</h1>\n </body>\n</html>"; exit; } $b = pathinfo($a); if (!isset($b['extension'])) { header('Content-Type: text/plain'); header('Content-Length: ' . filesize($a)); readfile($a); exit; } if (isset($mimes[$b['extension']])) { if ($mimes[$b['extension']] === 1) { include $a; exit; } if ($mimes[$b['extension']] === 2) { highlight_file($a); exit; } header('Content-Type: ' .$mimes[$b['extension']]); header('Content-Length: ' . filesize($a)); readfile($a); exit; } } class Extract_Phar { static $temp; static $origdir; const GZ = 0x1000; const BZ2 = 0x2000; const MASK = 0x3000; const START = 'index.php'; const LEN = 6685; static function go($return = false) { $fp = fopen(__FILE__, 'rb'); fseek($fp, self::LEN); $L = unpack('V', $a = (binary)fread($fp, 4)); $m = (binary)''; do { $read = 8192; if ($L[1] - strlen($m) < 8192) { $read = $L[1] - strlen($m); } $last = (binary)fread($fp, $read); $m .= $last; } while (strlen($last) && strlen($m) < $L[1]); if (strlen($m) < $L[1]) { die('ERROR: manifest length read was "' . strlen($m) .'" should be "' . $L[1] . '"'); } $info = self::_unpack($m); $f = $info['c']; if ($f & self::GZ) { if (!function_exists('gzinflate')) { die('Error: zlib extension is not enabled -' . ' gzinflate() function needed for zlib-compressed .phars'); } } if ($f & self::BZ2) { if (!function_exists('bzdecompress')) { die('Error: bzip2 extension is not enabled -' . ' bzdecompress() function needed for bz2-compressed .phars'); } } $temp = self::tmpdir(); if (!$temp || !is_writable($temp)) { $sessionpath = session_save_path(); if (strpos ($sessionpath, ";") !== false) $sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1); if (!file_exists($sessionpath) || !is_dir($sessionpath)) { die('Could not locate temporary directory to extract phar'); } $temp = $sessionpath; } $temp .= '/pharextract/'.basename(__FILE__, '.phar'); self::$temp = $temp; self::$origdir = getcwd(); @mkdir($temp, 0777, true); $temp = realpath($temp); if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) { self::_removeTmpFiles($temp, getcwd()); @mkdir($temp, 0777, true); @file_put_contents($temp . '/' . md5_file(__FILE__), ''); foreach ($info['m'] as $path => $file) { $a = !file_exists(dirname($temp . '/' . $path)); @mkdir(dirname($temp . '/' . $path), 0777, true); clearstatcache(); if ($path[strlen($path) - 1] == '/') { @mkdir($temp . '/' . $path, 0777); } else { file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp)); @chmod($temp . '/' . $path, 0666); } } } chdir($temp); if (!$return) { include self::START; } } static function tmpdir() { if (strpos(PHP_OS, 'WIN') !== false) { if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) { return $var; } if (is_dir('/temp') || mkdir('/temp')) { return realpath('/temp'); } return false; } if ($var = getenv('TMPDIR')) { return $var; } return realpath('/tmp'); } static function _unpack($m) { $info = unpack('V', substr($m, 0, 4)); $l = unpack('V', substr($m, 10, 4)); $m = substr($m, 14 + $l[1]); $s = unpack('V', substr($m, 0, 4)); $o = 0; $start = 4 + $s[1]; $ret['c'] = 0; for ($i = 0; $i < $info[1]; $i++) { $len = unpack('V', substr($m, $start, 4)); $start += 4; $savepath = substr($m, $start, $len[1]); $start += $len[1]; $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24))); $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3] & 0xffffffff); $ret['m'][$savepath][7] = $o; $o += $ret['m'][$savepath][2]; $start += 24 + $ret['m'][$savepath][5]; $ret['c'] |= $ret['m'][$savepath][4] & self::MASK; } return $ret; } static function extractFile($path, $entry, $fp) { $data = ''; $c = $entry[2]; while ($c) { if ($c < 8192) { $data .= @fread($fp, $c); $c = 0; } else { $c -= 8192; $data .= @fread($fp, 8192); } } if ($entry[4] & self::GZ) { $data = gzinflate($data); } elseif ($entry[4] & self::BZ2) { $data = bzdecompress($data); } if (strlen($data) != $entry[0]) { die("Invalid internal .phar file (size error " . strlen($data) . " != " . $stat[7] . ")"); } if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) { die("Invalid internal .phar file (checksum error)"); } return $data; } static function _removeTmpFiles($temp, $origdir) { chdir($temp); foreach (glob('*') as $f) { if (file_exists($f)) { is_dir($f) ? @rmdir($f) : @unlink($f); if (file_exists($f) && is_dir($f)) { self::_removeTmpFiles($f, getcwd()); } } } @rmdir($temp); clearstatcache(); chdir($origdir); } } Extract_Phar::go(); __HALT_COMPILER(); ?> ���������� ���hart.phar���� ���index.phpt��ێTt��B���������Hart.php_(��ێT_(��H$���������ConsoleColorText.php,��ێT,��H-:������<?php define('APPLICATION_VERSION', '1.1.2'); define('APPLICATION_ID', 'HaRT (htaccess redirect test) version ' . APPLICATION_VERSION); date_default_timezone_set('Europe/Kiev'); if (!($zf2Path = getenv('ZF2_PATH'))) { if (!($zf2Path = get_cfg_var('zf2_path'))) { if (!($zf2Path = realpath('/usr/local/share/php-libs/latest/ZF2'))) { die('Zend Framework 2 path is undefined' . PHP_EOL); } } } include $zf2Path . '/library/Zend/Loader/AutoloaderFactory.php'; Zend\Loader\AutoloaderFactory::factory(array( 'Zend\Loader\StandardAutoloader' => array( 'autoregister_zf' => true, ), )); require_once __DIR__ . '/Hart.php'; // MAIN $opts = new Zend\Console\Getopt([ 'user|u-s' => 'Basic Auth user', 'password|p-s' => 'Basic Auth password', 'f' => 'format output using YouTrack markup', 'version|v' => 'version', 'help|h' => 'help', ]); $printHelp = function () use ($opts) { $message = $opts->getUsageMessage(); $message = str_replace('[ options ]', 'FILE [ options ]' . PHP_EOL, $message); echo APPLICATION_ID . PHP_EOL . PHP_EOL . $message . PHP_EOL . 'Example: hart.phar .htaccess -u tester -p test -f' . PHP_EOL . PHP_EOL; }; try { $opts->parse(); } catch (Exception $e) { echo $e->getMessage(), PHP_EOL, PHP_EOL; $printHelp(); exit; } if ($opts->getOption('h')) { die($opts->getUsageMessage()); } if ($opts->getOption('v')) { die('Version: ' . APPLICATION_ID . PHP_EOL); } if (!($opts->getRemainingArgs())) { $printHelp(); exit; } $file = current($opts->getRemainingArgs()); $test = new Hart(); if ($opts->getOption('f')) { $test->setYouTrackFormat(true); } if (($user = $opts->getOption('u')) && ($password = $opts->getOption('p'))) { $test->setCredentials($user, $password); } $test->run($file); echo PHP_EOL; <?php use Zend\Http\Client; use Zend\Http\Request; require_once(__DIR__ . '/ConsoleColorText.php'); class Hart { const TYPE_SRC_URL = 'SRC URL'; const TYPE_DST_URL = 'DST URL'; const TYPE_DST_URL_MATCH = 'DST Url Match'; const STATUS_SUCCESS = 'success'; const STATUS_FAILED = 'failed'; const STATUS_WARNING = 'warning'; /** * @var Zend\Http\Client */ protected $client; protected $clientDefaultOptions = [ 'maxredirects' => 0, 'timeout' => 10 ]; protected $validLocationUrlCodes = [301, 302, 200]; protected $warningLocationUrlCodes = [301]; protected $index; protected $line; protected $columns = [ 'line' => [ 'title' => 'Line', 'width' => 6, 'align' => 'center' ], 'testType' => [ 'title' => 'Test Type', 'width' => 15, ], 'url' => [ 'title' => 'URLs', 'width' => 122, ], 'message' => [ 'title' => 'Message', 'width' => 42, ], 'status' => [ 'title' => 'Status', 'width' => 9, ], ]; /** * @var ConsoleColorText */ protected $text; protected $_user; protected $_password; protected $youTrackFormat = false; function __construct($options = array()) { $this->client = new Client(null, array_merge($this->clientDefaultOptions, $options)); $this->client->getRequest()->setMethod(Request::METHOD_HEAD); $this->text = new ConsoleColorText(); } /** * @param boolean $youTrackFormat * @return $this */ public function setYouTrackFormat($youTrackFormat) { $this->youTrackFormat = (bool) $youTrackFormat; return $this; } /** * @return boolean */ public function getYouTrackFormat() { return $this->youTrackFormat; } public function head($url) { $this->_initCredentials(); return $this->client->setUri($url)->send(); } public function validateRedirect($sourceUrl, $destinationUrl, array $flags = array()) { if (empty($flags['R'])) { $this->logError(self::TYPE_DST_URL, $destinationUrl, 'R flag is undefined'); return false; } $response = $this->head($sourceUrl); // Validate Source URL Redirect Code if ($flags['R'] != ($code = $response->getStatusCode())) { $this->logError( self::TYPE_SRC_URL, $this->_formatUrl($sourceUrl), 'HTTP ' . $code . ' (' . $flags['R'] . ' expected)' ); return false; } $this->logSuccess(self::TYPE_SRC_URL, $this->_formatUrl($sourceUrl), 'HTTP ' . $code); if ($this->areUrlEqual($sourceUrl, $destinationUrl)) { $this->logError(self::TYPE_DST_URL, $destinationUrl, 'infinite loop'); return false; } /** @var $location Zend\Http\Header\Location */ if (!($location = $response->getHeaders()->get('Location')) || !($locationUrl = $location->getFieldValue())) { $this->logError(self::TYPE_SRC_URL, $this->_formatUrl($sourceUrl), '"Location" header is undefined'); return false; } // Validate Location $locationResponse = $this->head($locationUrl); if (!($isValidLocationCode = in_array($locationResponse->getStatusCode(), $this->validLocationUrlCodes))) { $this->logError( self::TYPE_DST_URL, ' --> ' . $this->_formatUrl($locationUrl), 'unexpected HTTP code ' . $locationResponse->getStatusCode() ); } else { $message = 'HTTP ' . $locationResponse->getStatusCode(); if (in_array($locationResponse->getStatusCode(), $this->warningLocationUrlCodes)) { $this->logWarning(self::TYPE_DST_URL, ' --> ' . $this->_formatUrl($locationUrl), $message); } else { $this->logSuccess(self::TYPE_DST_URL, ' --> ' . $this->_formatUrl($locationUrl), $message); } } if (!$this->areUrlEqual($locationUrl, $destinationUrl)) { $this->logError(self::TYPE_DST_URL_MATCH, ' --> ' . $this->_formatUrl($destinationUrl)); } else { $this->logSuccess(self::TYPE_DST_URL_MATCH, ' --> ' . $this->_formatUrl($destinationUrl)); } return true; } protected function logWarning($testType, $url, $message = null) { return $this->log($testType, $url, $this->_formatWarning($message), $this->_formatWarning(self::STATUS_WARNING)); } protected function logError($testType, $url, $message = null) { return $this->log($testType, $url, $this->_formatError($message), $this->_formatError(self::STATUS_FAILED)); } protected function logSuccess($testType, $url, $message = null) { return $this->log($testType, $url, $this->_formatSuccess($message), $this->_formatSuccess(self::STATUS_SUCCESS)); } protected function _formatError($text) { if ($this->getYouTrackFormat()) { return '{color:red}' . $text . '{color}'; } return $this->text->paint($text, 'red'); } protected function _formatWarning($text) { if ($this->getYouTrackFormat()) { return '{color:orange}' . $text . '{color}'; } return $this->text->paint($text, 'orange'); } protected function _formatSuccess($text) { if ($this->getYouTrackFormat()) { return '{color:green}' . $text . '{color}'; } return $this->text->paint($text, 'green'); } protected function areUrlEqual($locationUrl, $destinationUrl) { if ('?' == substr($destinationUrl, -1)) { $destinationUrl = substr($destinationUrl, 0, -1); } return rawurldecode($locationUrl) == rawurldecode($destinationUrl); } public function log($testType, $url, $message, $status) { $separator = '|'; $line = $this->line + 1; $values = compact('line', 'testType', 'url', 'message', 'status'); $result = ''; foreach ($this->columns as $name => $column) { $align = array_key_exists('align', $column) ? $column['align'] : null; $value = $values[$name]; $result .= $separator . $this->sprint($value, $column['width'], $align); } echo $result . $separator. PHP_EOL; return $this; } protected function _formatUrl($url) { if (!$this->getYouTrackFormat()) { return $url; } if (strlen($url) > 80) { $text = substr($url, 0, 10) . '...' . substr($url, -68); return '[' . $url . ' ' . $text . ']'; } return $url; } protected function renderHeaders() { $separator = $this->getYouTrackFormat() ? '||' : '|'; $header = ''; foreach ($this->columns as $column) { $align = array_key_exists('align', $column) ? $column['align'] : null; $header .= $separator . $this->sprint($column['title'], $column['width'], $align); } $header .= $separator . PHP_EOL; return $header; } protected function sprint($text, $width, $align = null) { if (false !== (strpos($text, ConsoleColorText::START))) { $plainText = preg_replace("/\033\\[[\\d;]+m/", '', $text); $length = strlen($plainText); } else { $length = strlen($text); } switch ($align) { case 'center': $paddingLeft = floor(max($width - $length, 0) / 2); $paddingRight = ceil(max($width - $length, 0) / 2); break; case 'right': $paddingRight = ($width - $length > 1) ? 1 : 0; $paddingLeft = floor(max($width - $length - $paddingRight, 0)); break; case null: // break was intentionally omitted case 'left': // break was intentionally omitted default: $paddingLeft = ($width - $length > 1) ? 1 : 0; $paddingRight = max($width - $length - $paddingLeft, 0); } return str_repeat(' ', $paddingLeft) . $text . str_repeat(' ', $paddingRight); } public function run($file) { $srcUrls = []; $lines = file($file); $prevLine = null; echo $this->renderHeaders(); $this->index = 0; foreach ($lines as $this->line => $line) { $line = trim($line); if (empty($line)) { $srcUrls = []; continue; } if ($line[0] == '#' && ($url = trim(ltrim($line, '# '), "\n")) && 0 === strpos($url, 'http')) { $srcUrls[] = str_replace(' ','%20', $url); } if (empty($srcUrls) || 0 !== strncmp($line, 'RewriteRule', 11)) { continue; } $matches = array(); if (!preg_match('/^RewriteRule\s+\^([^\$]+)\$\s+([^\s]+)(?:\s+\[([^\s]+)\])/', $line, $matches)) { continue; } list(,, $substitution, $flags) = $matches; $this->index++; foreach ($srcUrls as $sourceUrl) { $this->validateRedirect($sourceUrl, $substitution, $this->_parseFlags($flags)); } $srcUrls = []; } } protected function _parseFlags($value) { $fields = array(); $parts = explode(',', $value); foreach ($parts as $part) { $list = explode('=', $part); $fields[$list[0]] = isset($list[1]) ? $list[1] : null; } return $fields; } protected function _initCredentials() { if (!empty($this->_user) && !empty($this->_password)) { $this->client->setAuth($this->_user, $this->_password); } return $this; } public function setCredentials($user, $password) { $this->_user = $user; $this->_password = $password; return $this; } } <?php class ConsoleColorText { const COLOR_BLACK = 'black'; const COLOR_GRAY = 'gray'; const COLOR_GREEN = 'green'; const COLOR_ORANGE = 'orange'; const COLOR_RED = 'red'; const START = "\033["; const END = "\033[0m"; private $colors = [ self::COLOR_BLACK => 0, self::COLOR_GREEN => 10, self::COLOR_ORANGE => 208, self::COLOR_RED => 196, ]; public function paint($string, $textColor = null, $backgroundColor = null, $attribute = 0) { if (false === ($color = $this->parseColor($textColor))) { trigger_error('Invalid Color "' . $textColor . '"', E_USER_WARNING); return $string; } $result = self::START . ((int) $attribute) . ';38;5;' . $color . 'm'; if (null !== $backgroundColor) { if (false === ($color = $this->parseColor($backgroundColor))) { trigger_error('Invalid Background Color "' . $backgroundColor . '"', E_USER_WARNING); return $result . $string . self::END; } else { $result .= self::START . '48;5;' . $color . 'm'; } } $result .= $string . self::END; return $result; } protected function parseColor($color) { if (null === $color) { return false; } if (is_numeric($color)) { return (int) $color; } if (array_key_exists($color, $this->colors)) { return $this->colors[$color]; } return false; } } }v0&4t� @3���GBMB