|
|
|
@ -167,7 +167,7 @@ if (!defined('NEXT_SIZE')) define('NEXT_SIZE', 1024);
@@ -167,7 +167,7 @@ if (!defined('NEXT_SIZE')) define('NEXT_SIZE', 1024);
|
|
|
|
|
|
|
|
|
|
if (!defined('NEXT_FAIL')) define('NEXT_FAIL', 'fail'); |
|
|
|
|
|
|
|
|
|
if (!defined('NEXT_DUMP')) define('NEXT_DUMP', '[{time}] [{code}] {host}:{port} {path} {goal}'); |
|
|
|
|
if (!defined('NEXT_DUMP')) define('NEXT_DUMP', '[{time}] [{code}] {host}:{port} {path} {real}'); |
|
|
|
|
|
|
|
|
|
// Init server |
|
|
|
|
$server = new \Yggverse\Nex\Server( |
|
|
|
@ -182,15 +182,11 @@ $server->start(
@@ -182,15 +182,11 @@ $server->start(
|
|
|
|
|
string $connect |
|
|
|
|
): ?string |
|
|
|
|
{ |
|
|
|
|
// Filter goal request |
|
|
|
|
$goal = preg_replace( |
|
|
|
|
[ |
|
|
|
|
'/\\\/', // unify separators |
|
|
|
|
'/(^|\/)[\.]+/', // hidden items started with dot |
|
|
|
|
'/[\.]+\//', // relative directory paths |
|
|
|
|
'/[\/]+\//', // remove extra slashes |
|
|
|
|
], |
|
|
|
|
DIRECTORY_SEPARATOR, |
|
|
|
|
// Define response |
|
|
|
|
$response = null; |
|
|
|
|
|
|
|
|
|
// Build realpath |
|
|
|
|
$realpath = realpath( |
|
|
|
|
NEXT_PATH . filter_var( |
|
|
|
|
urldecode( |
|
|
|
|
$request |
|
|
|
@ -199,49 +195,60 @@ $server->start(
@@ -199,49 +195,60 @@ $server->start(
|
|
|
|
|
) |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
// Define response |
|
|
|
|
$response = null; |
|
|
|
|
// Make sure directory path ending with slash |
|
|
|
|
if (is_dir($realpath)) |
|
|
|
|
{ |
|
|
|
|
$realpath = rtrim( |
|
|
|
|
$realpath, |
|
|
|
|
DIRECTORY_SEPARATOR |
|
|
|
|
) . DIRECTORY_SEPARATOR; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Directory request |
|
|
|
|
if (is_dir($goal)) |
|
|
|
|
// Validate realpath exists, started with path defined and destination resource is not hidden |
|
|
|
|
if ($realpath && str_starts_with($realpath, NEXT_PATH) && !str_starts_with(basename($realpath), '.')) |
|
|
|
|
{ |
|
|
|
|
// Try directory |
|
|
|
|
if (is_dir($realpath)) |
|
|
|
|
{ |
|
|
|
|
// Try index file first on enabled |
|
|
|
|
if (NEXT_FILE && is_readable($goal . NEXT_FILE)) |
|
|
|
|
if (NEXT_FILE && file_exists($realpath . NEXT_FILE) && is_readable($realpath . NEXT_FILE)) |
|
|
|
|
{ |
|
|
|
|
$response = file_get_contents( |
|
|
|
|
$goal . NEXT_FILE |
|
|
|
|
$realpath . NEXT_FILE |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Try directory listing on enabled |
|
|
|
|
else if (NEXT_LIST && is_readable($goal)) |
|
|
|
|
// Try build directory listing on enabled |
|
|
|
|
else if (NEXT_LIST) |
|
|
|
|
{ |
|
|
|
|
$links = []; |
|
|
|
|
|
|
|
|
|
foreach ((array) scandir($goal) as $link) |
|
|
|
|
foreach ((array) scandir($realpath) as $link) |
|
|
|
|
{ |
|
|
|
|
// Skip system entities |
|
|
|
|
// Process system entities |
|
|
|
|
if (str_starts_with($link, '.')) |
|
|
|
|
{ |
|
|
|
|
// Keep parent navigation entities only |
|
|
|
|
if ($link == '..' && $parent = realpath($goal . $link)) |
|
|
|
|
{ |
|
|
|
|
if (str_starts_with($parent . DIRECTORY_SEPARATOR, NEXT_PATH)) |
|
|
|
|
// Parent navigation |
|
|
|
|
if ($link == '..' && $parent = realpath($realpath . $link)) |
|
|
|
|
{ |
|
|
|
|
if (is_readable($parent)) |
|
|
|
|
$parent = rtrim( |
|
|
|
|
$parent, |
|
|
|
|
DIRECTORY_SEPARATOR |
|
|
|
|
) . DIRECTORY_SEPARATOR; |
|
|
|
|
|
|
|
|
|
if (str_starts_with($parent, NEXT_PATH)) |
|
|
|
|
{ |
|
|
|
|
$links[] = '=> ../'; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
continue; |
|
|
|
|
continue; // skip everything else |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Directory |
|
|
|
|
if (is_dir($goal . $link)) |
|
|
|
|
if (is_dir($realpath . $link)) |
|
|
|
|
{ |
|
|
|
|
if (is_readable($goal . $link)) |
|
|
|
|
if (is_readable($realpath . $link)) |
|
|
|
|
{ |
|
|
|
|
$links[] = sprintf( |
|
|
|
|
'=> %s/', |
|
|
|
@ -255,7 +262,7 @@ $server->start(
@@ -255,7 +262,7 @@ $server->start(
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// File |
|
|
|
|
if (is_readable($goal . $link)) |
|
|
|
|
if (is_readable($realpath . $link)) |
|
|
|
|
{ |
|
|
|
|
$links[] = sprintf( |
|
|
|
|
'=> %s', |
|
|
|
@ -274,12 +281,13 @@ $server->start(
@@ -274,12 +281,13 @@ $server->start(
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Try file |
|
|
|
|
else if (is_readable($goal)) |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
$response = file_get_contents( |
|
|
|
|
$goal |
|
|
|
|
$realpath |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Dump request on enabled |
|
|
|
|
if (NEXT_DUMP) |
|
|
|
@ -292,7 +300,7 @@ $server->start(
@@ -292,7 +300,7 @@ $server->start(
|
|
|
|
|
'{host}', |
|
|
|
|
'{port}', |
|
|
|
|
'{path}', |
|
|
|
|
'{goal}', |
|
|
|
|
'{real}', |
|
|
|
|
], |
|
|
|
|
[ |
|
|
|
|
(string) date('c'), |
|
|
|
@ -300,7 +308,7 @@ $server->start(
@@ -300,7 +308,7 @@ $server->start(
|
|
|
|
|
(string) parse_url($connect, PHP_URL_HOST), |
|
|
|
|
(string) parse_url($connect, PHP_URL_PORT), |
|
|
|
|
(string) str_replace('%', '%%', empty($request) ? '/' : trim($request)), |
|
|
|
|
(string) str_replace('%', '%%', $goal) |
|
|
|
|
(string) str_replace('%', '%%', $realpath) |
|
|
|
|
], |
|
|
|
|
NEXT_DUMP |
|
|
|
|
) . PHP_EOL |
|
|
|
@ -308,6 +316,6 @@ $server->start(
@@ -308,6 +316,6 @@ $server->start(
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Send response |
|
|
|
|
return empty($response) ? NEXT_FAIL : $response; |
|
|
|
|
return is_null($response) ? NEXT_FAIL : $response; |
|
|
|
|
} |
|
|
|
|
); |