ctf-resources/htb/hacktheboo2024/web/web_void_whispers/challenge/Router.php

125 lines
3 KiB
PHP

<?php
class Router
{
public $routes = [];
public function new($method, $route, $controller)
{
$r = [
'method' => $method,
'route' => $route,
];
if (is_callable($controller))
{
$r['controller'] = $controller;
$this->routes[] = $r;
}
else if (strpos($controller, '@'))
{
$split = explode('@', $controller);
$class = $split[0];
$function = $split[1];
$r['controller'] = [
'class' => $class,
'function' => $function
];
$this->routes[] = $r;
}
else
{
throw new Exception('Invalid controller');
}
}
public function match()
{
foreach($this->routes as $route)
{
if ($this->_match_route($route['route']))
{
if ($route['method'] != $_SERVER['REQUEST_METHOD'])
{
$this->abort(405);
}
$params = $this->getRouteParameters($route['route']);
if (is_array($route['controller']))
{
$controller = $route['controller'];
$class = $controller['class'];
$function = $controller['function'];
return (new $class)->$function($this,$params);
}
return $route['controller']($this,$params);
}
}
$this->abort(404);
}
public function _match_route($route)
{
$uri = explode('/', strtok($_SERVER['REQUEST_URI'], '?'));
$route = explode('/', $route);
if (count($uri) != count($route)) return false;
foreach ($route as $key => $value)
{
if ($uri[$key] != $value && $value != '{param}') return false;
}
return true;
}
public function getRouteParameters($route)
{
$params = [];
$uri = explode('/', strtok($_SERVER['REQUEST_URI'], '?'));
$route = explode('/', $route);
foreach ($route as $key => $value)
{
if ($uri[$key] == $value) continue;
if ($value == '{param}')
{
if ($uri[$key] == '')
{
$this->abort(404);
}
$params[] = $uri[$key];
}
}
return $params;
}
public function abort($code)
{
http_response_code($code);
exit;
}
public function view($view, $data = [])
{
extract($data);
include __DIR__."/views/{$view}.php";
exit;
}
public function jsonify($body, $code = null)
{
if ($code) {
http_response_code($code);
}
header('Content-Type: application/json; charset=utf-8');
echo json_encode($body);
exit;
}
}