public function dirFixups(\HTRouter\Request $request) { $filename = $request->getFilename(); if (empty($filename) || is_dir($request->getDocumentRoot() . $filename)) { return $this->_fixup_dir($request); } elseif (!empty($filename) && !file_exists($request->getDocumentRoot() . $filename) && @filetype($request->getDocumentRoot() . $filename) == "unknown") { // @TODO: This must be different FILE_NOT_EXIST return $this->_fixup_dflt($request); } return \HTRouter::STATUS_DECLINED; }
/** * Outputs an error message generated from the current request. * * @param HTRouter\Request $request */ protected function _print_error(\HTRouter\Request $request) { echo <<<EOH <html> <head> <title>HTRouter error code: {$request->getStatus()} - {$request->getStatusLine()} </title> </head> <body> <h1>{$request->getStatus()} - {$request->getStatusLine()}</h1> <table> <tr><td>Uri</td><td>:</td><td>{$request->getUri()}<td></tr> <tr><td>DocRoot</td><td>:</td><td>{$request->getDocumentRoot()}<td></tr> <tr><td>Filename</td><td>:</td><td>{$request->getFilename()}<td></tr> </table> </body> </html> EOH; }
function fixUp(\HTRouter\Request $request) { if ($this->getConfig()->get("RewriteEngine") == false) { return \HTRouter::STATUS_DECLINED; } // Temp save $oldFilename = $request->getFilename(); if (!$request->getFilename()) { $request->setFilename($request->getUri()); } $ruleStatus = $this->_applyRewrites(); if ($ruleStatus) { if ($ruleStatus == self::ACTION_STATUS) { $n = $request->getStatus(); $request->setStatus(\HTROUTER::STATUS_HTTP_OK); return $n; } if (($skip = $this->_is_absolute_url($request->getFilename())) > 0) { if ($ruleStatus == self::ACTION_NOESCAPE) { $request->setFilename(urlencode($request->getFilename(), $skip)); } // Add query string if needed if ($request->getArgs()) { if ($ruleStatus == self::ACTION_NOESCAPE) { $request->setFilename($request->getFilename() . "?" . $request->getQueryString()); } else { $request->setFilename($request->getFilename() . "?" . urlencode($request->getQueryString())); } } // Is this a redirect? if ($request->getStatus() >= 300 && $request->getStatus() < 400) { $n = $request->getStatus(); $request->setStatus(\HTRouter::STATUS_HTTP_OK); } else { // No redirect, but we need to redir anyway.. $n = \HTRouter::STATUS_HTTP_MOVED_TEMPORARILY; } // The filename is the URI to redirect.. strange, I know... $request->appendOutHeaders("Location", $request->getFilename()); return $n; } elseif (substr($request->getFilename(), 0, 12) == "passthrough:") { // Starts with passthrough? Let's pass $request->setUri(substr($request->getFilename(), 13)); return \HTRouter::STATUS_DECLINED; } else { // Local path if ($oldFilename == $request->getFilename()) { // Rewrite to the same name. Prevent deadlocks return \HTRouter::STATUS_HTTP_OK; } } } else { $request->getFilename($oldFilename); return \HTRouter::STATUS_DECLINED; } return \HTRouter::STATUS_DECLINED; }
/** * These functions should return true|false or something to make sure we can continue with our stuff? * * @param \HTRouter\Request $request * @return bool * @throws \LogicException */ public function checkAccess(\HTRouter\Request $request) { // The way we parse things depends on the "order" switch ($this->getConfig()->get("AccessOrder")) { case self::ALLOW_THEN_DENY: $result = false; if ($this->_findAllowDeny($this->getConfig()->get("AccessAllow"))) { $result = \HTRouter::STATUS_OK; } if ($this->_findAllowDeny($this->getConfig()->get("AccessDeny"))) { $result = \HTRouter::STATUS_HTTP_FORBIDDEN; } break; case self::DENY_THEN_ALLOW: $result = \HTRouter::STATUS_OK; if ($this->_findAllowDeny($this->getConfig()->get("AccessDeny"))) { $result = \HTRouter::STATUS_HTTP_FORBIDDEN; } if ($this->_findAllowDeny($this->getConfig()->get("AccessAllow"))) { $result = \HTRouter::STATUS_OK; } break; case self::MUTUAL_FAILURE: if ($this->_findAllowDeny($this->getConfig()->get("AccessAllow")) and !$this->_findAllowDeny($this->getConfig()->get("AccessDeny"))) { $result = \HTRouter::STATUS_OK; } else { $result = \HTRouter::STATUS_HTTP_FORBIDDEN; } break; default: throw new \LogicException("Unknown order"); break; } // Not ok. Now we need to check if "satisfy any" already got a satisfaction if ($result == \HTRouter::STATUS_HTTP_FORBIDDEN && ($this->getConfig()->get("Satisfy") == "any" || count($this->getConfig()->get("Requires", array()) == 0))) { // Check if there is at least one require line in the htaccess. If found, it means that // we still have to possibility that we can be authorized $this->getLogger()->log(\HTRouter\Logger::ERRORLEVEL_ERROR, "Access denied for " . $request->getFilename() . " / " . $request->getUri()); } // Return what we need to return return $result; }
/** * @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; }
/** * ap_directory_walk is really difficult since it needs to be highly optimized. Since we don't need that * optimization and we don't need much of the functionality, I've used some artistic freedom in creating * this method. * * @param \HTRouter\Request $request * @return int */ protected function _directoryWalk(\HTRouter\Request $request) { // No filename found to start from? $fn = $request->getFilename(); if (empty($fn)) { $utils = new \HTrouter\Utils(); $path = $utils->findUriOnDisk($request, $request->getUri()); $request->setFilename($path); return \HTRouter::STATUS_OK; } // get htaccess name from config or constant $config = $this->getRouterConfig("global"); if (isset($config['htaccessfilename'])) { $htaccessFilename = $config['htaccessfilename']; } else { $htaccessFilename = \HTRouter::HTACCESS_FILE; } /* Create an array with the following paths: * * / * /wwwroot * /wwwroot/router * /wwwroot/router/public * * So we can do a simple iteration without worrying about stuff. Easier to reverse the process if needed. */ if ($fn[strlen($fn) - 1] == '/') { // THis is a "directory" (ie: /dir/, so filename is the dirname) $dirname = $fn; } else { // This might be a directory, we should check to see if the file is a directory, if so, it's a dir if (is_dir($request->getDocumentRoot() . $fn)) { $dirname = $fn; } else { // A file, so get the dirname $dirname = dirname($fn); } } $path = explode("/", $dirname); if (empty($path[count($path) - 1])) { array_pop($path); } $dirs = array(); while (count($path) > 0) { $dirs[] = $request->getDocumentRoot() . join("/", $path); array_pop($path); } $dirs = array_unique($dirs); // Just in case... // Iterate directories and find htaccess files foreach ($dirs as $dir) { $htaccessPath = $dir . "/" . $htaccessFilename; if (is_readable($htaccessPath)) { // Read HTACCESS and merge information $newConfig = $this->_readHTAccess($request, $htaccessPath); // Merge together with current request foreach ($this->getRouter()->getModules() as $module) { /** * @var $module \HTRouter\Module */ $module->mergeConfigs($this->getConfig(), $newConfig); } } } return \HTRouter::STATUS_OK; }