/** * @static * @return \HTRouter */ public static function getInstance() { if (!self::$_instance) { $class = __CLASS__; self::$_instance = new $class(); } return self::$_instance; }
function setUp() { $router = \HTRouter::getInstance(); $this->_request = new \HTRouter\Request(); $this->_request->setFilename("foo"); $this->_request->setDocumentRoot("/www"); $this->_request->setHostname("php.unittest.org"); }
<?php include_once "autoload.php"; $router = HTRouter::getInstance(); $router->route();
function apache_get_version() { $router = \HTRouter::getInstance(); return $router->getServerSoftware(); }
/** * @static * @param $string * @param \HTRouter\Request $request * @param array $ruleMatches * @param array $condMatches * @return mixed * @throws \RuntimeException */ public static function expandSubstitutions($string, \HTRouter\Request $request, $ruleMatches = array(), $condMatches = array()) { // Do backref matching on rewriterule ($1-$9) preg_match_all('|\\$([1-9])|', $string, $matches); foreach ($matches[1] as $index) { if (!isset($ruleMatches[$index - 1])) { throw new \RuntimeException("Want to match index {$index}, but nothing found in rule to match"); } $string = str_replace("\${$index}", $ruleMatches[$index - 1], $string); } // Do backref matching on the last rewritecond (%1-%9) preg_match_all('|\\%([1-9])|', $string, $matches); foreach ($matches[1] as $index) { if (!isset($condMatches[$index - 1])) { throw new \RuntimeException("Want to match index {$index}, but nothing found in condition to match"); } $string = str_replace("%{$index}", $condMatches[$index - 1], $string); } // Do variable substitution $string = str_replace("%{HTTP_USER_AGENT}", $request->getServerVar("HTTP_USER_AGENT"), $string); $string = str_replace("%{HTTP_REFERER}", $request->getServerVar("HTTP_REFERER"), $string); $string = str_replace("%{HTTP_COOKIE}", $request->getServerVar("HTTP_COOKIE"), $string); $string = str_replace("%{HTTP_FORWARDED}", $request->getServerVar("HTTP_FORWARDED"), $string); $string = str_replace("%{HTTP_HOST}", $request->getServerVar("HTTP_HOST"), $string); $string = str_replace("%{HTTP_PROXY_CONNECTION}", $request->getServerVar("HTTP_PROXY_CONNECTION"), $string); $string = str_replace("%{HTTP_ACCEPT}", $request->getServerVar("HTTP_ACCEPT"), $string); $string = str_replace("%{REMOTE_ADDR}", $request->getServerVar("REMOTE_ADDR"), $string); $string = str_replace("%{REMOTE_HOST}", $request->getServerVar("REMOTE_HOST"), $string); $string = str_replace("%{REMOTE_PORT}", $request->getServerVar("REMOTE_PORT"), $string); $string = str_replace("%{REMOTE_USER}", $request->getAuthUser(), $string); $string = str_replace("%{REMOTE_IDENT}", "", $string); // We don't support identing! $string = str_replace("%{REQUEST_METHOD}", $request->getMethod(), $string); $string = str_replace("%{SCRIPT_FILENAME}", $request->getFilename(), $string); $string = str_replace("%{PATH_INFO}", $request->getPathInfo(), $string); $string = str_replace("%{QUERY_STRING}", $request->getQueryString(), $string); if ($request->getAuthType()) { $string = str_replace("%{AUTH_TYPE}", $request->getAuthType()->getName(), $string); // Returns either Basic or Digest } else { $string = str_replace("%{AUTH_TYPE}", "", $string); } $string = str_replace("%{DOCUMENT_ROOT}", $request->getDocumentRoot(), $string); $string = str_replace("%{SERVER_ADMIN}", $request->getServerVar("SERVER_ADMIN"), $string); $string = str_replace("%{SERVER_NAME}", $request->getServerVar("SERVER_NAME"), $string); $string = str_replace("%{SERVER_ADDR}", $request->getServerVar("SERVER_ADDR"), $string); $string = str_replace("%{SERVER_PORT}", $request->getServerVar("SERVER_PORT"), $string); $string = str_replace("%{SERVER_PROTOCOL}", $request->getServerVar("SERVER_PROTOCOL"), $string); $router = \HTRouter::getInstance(); $string = str_replace("%{SERVER_SOFTWARE}", $router->getServerSoftware(), $string); // Non-deterministic, but it won't change over the course of a request, even if the seconds have changed! $string = str_replace("%{TIME_YEAR}", date("Y"), $string); // 2011 $string = str_replace("%{TIME_MON}", date("m"), $string); // 01-12 $string = str_replace("%{TIME_DAY}", date("d"), $string); // 01-31 $string = str_replace("%{TIME_HOUR}", date("H"), $string); // 00-23 $string = str_replace("%{TIME_MIN}", date("i"), $string); // 00-59 $string = str_replace("%{TIME_SEC}", date("s"), $string); // 00-59 $string = str_replace("%{TIME_WDAY}", date("w"), $string); // 0-6 (sun-sat) $string = str_replace("%{TIME}", date("YmdHis"), $string); // %04d%02d%02d%02d%02d%02d $string = str_replace("%{API_VERSION}", $router->getServerApi(), $string); //$string = str_replace("%{THE_REQUEST}", $request->getTheRequest(), $string); // "GET /dir HTTP/1.1" $string = str_replace("%{REQUEST_URI}", $request->getUri(), $string); $string = str_replace("%{REQUEST_FILENAME}", $request->getServerVar("SCRIPT_FILENAME"), $string); $string = str_replace("%{IS_SUBREQ}", $request->isSubRequest() ? "true" : "false", $string); $string = str_replace("%{HTTPS}", $request->isHttps() ? "on" : "off", $string); return $string; }
/** * Actual workload of condition matching * @return bool */ protected function _checkMatch($request) { $expanded = Rule::expandSubstitutions($this->_testString, $request); $match = false; // Check expanded string against conditional Pattern switch ($this->_condPatternType) { case self::COND_REGEX: $regex = '|' . $this->_condPattern . '|'; // Don't separate with / since it will be used a path delimiter // Case independent if needed if ($this->hasFlag(Flag::TYPE_NOCASE)) { $regex .= "i"; } // Check regex $match = preg_match($regex, $expanded, $matches) >= 1; // Store matches in case we need to do back references %N inside rules $this->_matches = $matches; break; case self::COND_LEXICAL_PRE: // PRE and POST lexical match does not follow the nocase fields! $sub = substr($expanded, 0, strlen($this->_condPattern)); $match = strcmp($sub, $this->_condPattern) == 0; break; case self::COND_LEXICAL_POST: // PRE and POST lexical match does not follow the nocase fields! $sub = substr($expanded, 0 - strlen($this->_condPattern)); $match = strcmp($sub, $this->_condPattern) == 0; break; case self::COND_LEXICAL_EQ: if ($this->hasFlag(Flag::TYPE_NOCASE)) { $match = strcasecmp($this->_condPattern, $expanded) == 0; } else { $match = strcmp($this->_condPattern, $expanded) == 0; } break; case self::COND_TEST_DIR: $match = is_dir($expanded); break; case self::COND_TEST_FILE: $match = is_file($expanded); break; case self::COND_TEST_SIZE: $match = is_file($expanded) && filesize($expanded) > 0; break; case self::COND_TEST_SYMLINK: $match = is_link($expanded); break; case self::COND_TEST_EXECUTE: $match = is_executable($expanded); break; case self::COND_TEST_FILE_SUBREQ: // @TODO: What to do? break; case self::COND_TEST_URL_SUBREQ: // @TODO: What to do? break; } // If the match must be negated, make it so if ($this->_condPatternNegate) { $match = !$match; } \HTRouter::getInstance()->getLogger()->log(\HTRouter\Logger::ERRORLEVEL_DEBUG, "Conditional match of " . (string) $this . " : " . ($match ? "yes" : "no")); return $match; }
protected function _readHTAccess(\HTRouter\Request $request, $htaccessPath) { // Check if the htaccess exists inside the cache, if so, return that one. if (isset($this->_cachedHTAccess[$htaccessPath])) { return $this->_cachedHTAccess[$htaccessPath]; } // Save current configuration $old_config = $this->getConfig(); $this->_container->setConfig(new \HTRouter\VarContainer()); // Read HTACCESS $f = fopen($htaccessPath, "r"); $this->getConfig()->set("HTAccessFileResource", $f); // temporary saving of the filehandle resource // Parse config $router = \HTRouter::getInstance(); $router->parseConfig($f); // Remove from config and close file $this->getConfig()->clear("HTAccessFileResource"); fclose($f); // Save new config and restore current configuration $new_config = $this->getConfig(); $this->_container->setConfig($old_config); // Store this htaccess configuration inside our cache $this->_cachedHTAccess[$htaccessPath] = $new_config; // Return new configuration return $new_config; }