mirror of https://github.com/YGGverse/next.git
yggverse
7 months ago
8 changed files with 706 additions and 386 deletions
@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
|
||||
{ |
||||
"host":"127.0.0.1", |
||||
"list":true, |
||||
"dump":true |
||||
} |
@ -0,0 +1,263 @@
@@ -0,0 +1,263 @@
|
||||
<?php |
||||
|
||||
namespace Yggverse\Next\Controller; |
||||
|
||||
use \Ratchet\MessageComponentInterface; |
||||
|
||||
class Nex implements MessageComponentInterface |
||||
{ |
||||
private \Yggverse\Next\Model\Environment $_environment; |
||||
private \Yggverse\Next\Model\Filesystem $_filesystem; |
||||
|
||||
public function __construct( |
||||
\Yggverse\Next\Model\Environment $environment, |
||||
\Yggverse\Next\Model\Filesystem $filesystem |
||||
) { |
||||
// Init environment |
||||
$this->_environment = $environment; |
||||
|
||||
// Init filesystem |
||||
$this->_filesystem = $filesystem; |
||||
|
||||
// Check port is defined |
||||
if (!$this->_environment->get('port')) |
||||
{ |
||||
// Set protocol defaults |
||||
$this->_environment->set('port', 1900); |
||||
} |
||||
|
||||
// Dump event |
||||
if ($this->_environment->get('dump')) |
||||
{ |
||||
print( |
||||
str_replace( |
||||
[ |
||||
'{time}', |
||||
'{host}', |
||||
'{port}', |
||||
'{root}' |
||||
], |
||||
[ |
||||
(string) date('c'), |
||||
(string) $this->_environment->get('host'), |
||||
(string) $this->_environment->get('port'), |
||||
(string) $this->_filesystem->root() |
||||
], |
||||
_('[{time}] [init] server started at {host}:{port}{root}') |
||||
) . PHP_EOL |
||||
); |
||||
} |
||||
} |
||||
|
||||
public function onOpen( |
||||
\Ratchet\ConnectionInterface $connection |
||||
) { |
||||
// Dump event |
||||
if ($this->_environment->get('dump')) |
||||
{ |
||||
print( |
||||
str_replace( |
||||
[ |
||||
'{time}', |
||||
'{host}', |
||||
'{crid}' |
||||
], |
||||
[ |
||||
(string) date('c'), |
||||
(string) $connection->remoteAddress, |
||||
(string) $connection->resourceId |
||||
], |
||||
_('[{time}] [open] incoming connection {host}#{crid}') |
||||
) . PHP_EOL |
||||
); |
||||
} |
||||
} |
||||
|
||||
public function onMessage( |
||||
\Ratchet\ConnectionInterface $connection, |
||||
$request |
||||
) { |
||||
// Define response |
||||
$response = null; |
||||
|
||||
// Filter request |
||||
$request = trim( |
||||
$request |
||||
); |
||||
|
||||
// Build absolute realpath |
||||
$realpath = $this->_filesystem->absolute( |
||||
$request |
||||
); |
||||
|
||||
// Make sure realpath valid to continue |
||||
if ($this->_filesystem->valid($realpath)) |
||||
{ |
||||
// Route |
||||
switch (true) |
||||
{ |
||||
// File request |
||||
case $file = $this->_filesystem->file($realpath): |
||||
|
||||
// Return file content |
||||
$response = $file; |
||||
|
||||
break; |
||||
|
||||
// Directory request |
||||
case $list = $this->_filesystem->list($realpath): |
||||
|
||||
// Try index file on defined |
||||
if ($index = $this->_filesystem->file($realpath . $this->_environment->get('file'))) |
||||
{ |
||||
// Return index file content |
||||
$response = $index; |
||||
} |
||||
|
||||
// Listing enabled |
||||
else if ($this->_environment->get('list')) |
||||
{ |
||||
// FS map |
||||
$line = []; |
||||
|
||||
foreach ($list as $item) |
||||
{ |
||||
// Build gemini text link |
||||
$link = ['=>']; |
||||
|
||||
if ($item['name']) |
||||
{ |
||||
$link[] = $item['file'] ? $item['name'] |
||||
: $item['name'] . '/'; |
||||
} |
||||
|
||||
if ($item['time'] && $this->_environment->get('time')) |
||||
{ |
||||
$link[] = date('Y-m-d', $item['time']); |
||||
} |
||||
|
||||
// Append link to the new line |
||||
$line[] = implode(' ', $link); |
||||
} |
||||
|
||||
// Merge lines to response |
||||
$response = implode( |
||||
PHP_EOL, |
||||
$line |
||||
); |
||||
} |
||||
|
||||
break; |
||||
} |
||||
} |
||||
|
||||
// Dump event |
||||
if ($this->_environment->get('dump')) |
||||
{ |
||||
// Print debug from template |
||||
print( |
||||
str_ireplace( |
||||
[ |
||||
'{time}', |
||||
'{host}', |
||||
'{crid}', |
||||
'{path}', |
||||
'{real}', |
||||
'{size}' |
||||
], |
||||
[ |
||||
(string) date('c'), |
||||
(string) $connection->remoteAddress, |
||||
(string) $connection->resourceId, |
||||
(string) str_replace( |
||||
'%', |
||||
'%%', |
||||
$request |
||||
), |
||||
(string) str_replace( |
||||
'%', |
||||
'%%', |
||||
$realpath |
||||
), |
||||
(string) mb_strlen( |
||||
$response |
||||
) |
||||
], |
||||
_('[{time}] [message] incoming connection {host}#{crid} "{path}" > "{real}" {size} bytes') |
||||
) . PHP_EOL |
||||
); |
||||
} |
||||
|
||||
// Noting to return? |
||||
if (empty($response)) |
||||
{ |
||||
// Try failure file on defined |
||||
if ($fail = $this->_filesystem->file($this->_environment->get('fail'))) |
||||
{ |
||||
$response = $fail; |
||||
} |
||||
} |
||||
|
||||
// Send response |
||||
$connection->send( |
||||
$response |
||||
); |
||||
|
||||
// Disconnect |
||||
$connection->close(); |
||||
} |
||||
|
||||
public function onClose( |
||||
\Ratchet\ConnectionInterface $connection |
||||
) { |
||||
// Dump event |
||||
if ($this->_environment->get('dump')) |
||||
{ |
||||
print( |
||||
str_replace( |
||||
[ |
||||
'{time}', |
||||
'{host}', |
||||
'{crid}' |
||||
], |
||||
[ |
||||
(string) date('c'), |
||||
(string) $connection->remoteAddress, |
||||
(string) $connection->resourceId |
||||
], |
||||
_('[{time}] [close] incoming connection {host}#{crid}') |
||||
) . PHP_EOL |
||||
); |
||||
} |
||||
} |
||||
|
||||
public function onError( |
||||
\Ratchet\ConnectionInterface $connection, |
||||
\Exception $exception |
||||
) { |
||||
// Dump event |
||||
if ($this->_environment->get('dump')) |
||||
{ |
||||
print( |
||||
str_replace( |
||||
[ |
||||
'{time}', |
||||
'{host}', |
||||
'{crid}', |
||||
'{info}' |
||||
], |
||||
[ |
||||
(string) date('c'), |
||||
(string) $connection->remoteAddress, |
||||
(string) $connection->resourceId, |
||||
(string) $exception->getMessage() |
||||
], |
||||
_('[{time}] [error] incoming connection {host}#{crid} reason: {info}') |
||||
) . PHP_EOL |
||||
); |
||||
} |
||||
|
||||
// Disconnect |
||||
$connection->close(); |
||||
} |
||||
} |
@ -0,0 +1,84 @@
@@ -0,0 +1,84 @@
|
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Yggverse\Next\Model; |
||||
|
||||
class Environment |
||||
{ |
||||
private array $_config; |
||||
|
||||
public function __construct( |
||||
array $argv, |
||||
array $default = [] |
||||
) { |
||||
foreach ($default as $key => $value) |
||||
{ |
||||
$this->_config[$key] = (string) $value; |
||||
} |
||||
|
||||
foreach ($argv as $value) |
||||
{ |
||||
if (preg_match('/^(?<key>[^=]+)=(?<value>.*)$/', $value, $argument)) |
||||
{ |
||||
$this->_config[mb_strtolower($argument['key'])] = (string) $argument['value']; |
||||
} |
||||
} |
||||
} |
||||
|
||||
public function get( |
||||
string $key |
||||
): mixed |
||||
{ |
||||
$key = mb_strtolower( |
||||
$key |
||||
); |
||||
|
||||
return isset($this->_config[$key]) ? $this->_config[$key] |
||||
: null; |
||||
} |
||||
|
||||
public function set( |
||||
string $key, |
||||
string $value, |
||||
bool $semantic = true |
||||
): void |
||||
{ |
||||
if ($semantic) |
||||
{ |
||||
$_value = mb_strtolower( |
||||
$value |
||||
); |
||||
|
||||
switch (true) |
||||
{ |
||||
case in_array( |
||||
$_value, |
||||
[ |
||||
'1', |
||||
'yes', |
||||
'true', |
||||
'enable' |
||||
] |
||||
): $value = true; |
||||
|
||||
break; |
||||
|
||||
case in_array( |
||||
$_value, |
||||
[ |
||||
'0', |
||||
'no', |
||||
'null', |
||||
'false', |
||||
'disable' |
||||
] |
||||
): $value = false; |
||||
|
||||
break; |
||||
} |
||||
} |
||||
|
||||
$this->_config[mb_strtolower($key)] = $value; |
||||
} |
||||
} |
@ -0,0 +1,253 @@
@@ -0,0 +1,253 @@
|
||||
<?php |
||||
|
||||
declare(strict_types=1); |
||||
|
||||
namespace Yggverse\Next\Model; |
||||
|
||||
class Filesystem |
||||
{ |
||||
private string $_root; |
||||
|
||||
public function __construct(?string $path) |
||||
{ |
||||
// Require path value to continue |
||||
if (empty($path)) |
||||
{ |
||||
throw new \Exception( |
||||
_('root path required!') |
||||
); |
||||
} |
||||
|
||||
// Require absolute path |
||||
if (!str_starts_with($path, DIRECTORY_SEPARATOR)) |
||||
{ |
||||
throw new \Exception( |
||||
_('root path not absolute!') |
||||
); |
||||
} |
||||
|
||||
// Exclude symlinks and relative entities, append slash |
||||
if (!$realpath = $this->_realpath($path)) |
||||
{ |
||||
throw new \Exception( |
||||
_('could not build root realpath!') |
||||
); |
||||
} |
||||
|
||||
// Root must be directory |
||||
if (!is_dir($realpath)) |
||||
{ |
||||
throw new \Exception( |
||||
_('root path is not directory!') |
||||
); |
||||
} |
||||
|
||||
// Check root path does not contain hidden context |
||||
if (str_contains($realpath, DIRECTORY_SEPARATOR . '.')) |
||||
{ |
||||
throw new \Exception( |
||||
_('root path must not contain hidden context!') |
||||
); |
||||
} |
||||
|
||||
// Done! |
||||
$this->_root = $realpath; |
||||
} |
||||
|
||||
public function root(): string |
||||
{ |
||||
return $this->_root; |
||||
} |
||||
|
||||
public function file(?string $realpath): ?string |
||||
{ |
||||
if (!$this->valid($realpath)) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
if (!is_file($realpath)) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
return file_get_contents( |
||||
$realpath |
||||
); |
||||
} |
||||
|
||||
public function list( |
||||
?string $realpath, |
||||
string $sort = 'name', |
||||
int $order = SORT_ASC, |
||||
int $method = SORT_STRING | SORT_NATURAL | SORT_FLAG_CASE |
||||
): ?array |
||||
{ |
||||
// Validate requested path |
||||
if (!$this->valid($realpath)) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
// Make sure requested path is directory |
||||
if (!is_dir($realpath)) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
// Begin list builder |
||||
$directories = []; |
||||
$files = []; |
||||
|
||||
foreach ((array) scandir($realpath) as $name) |
||||
{ |
||||
// Skip system locations |
||||
if (empty($name) || $name == '.') |
||||
{ |
||||
continue; |
||||
} |
||||
|
||||
// Build destination path |
||||
if (!$path = $this->_realpath($realpath . $name)) |
||||
{ |
||||
continue; |
||||
} |
||||
|
||||
// Validate destination path |
||||
if (!$this->valid($path)) |
||||
{ |
||||
continue; |
||||
} |
||||
|
||||
// Context |
||||
switch (true) |
||||
{ |
||||
case is_dir($path): |
||||
|
||||
$directories[] = |
||||
[ |
||||
'file' => false, |
||||
'name' => $name, |
||||
'path' => $path, |
||||
'time' => filemtime( |
||||
$path |
||||
) |
||||
]; |
||||
|
||||
break; |
||||
|
||||
case is_file($path): |
||||
|
||||
$files[] = |
||||
[ |
||||
'file' => true, |
||||
'name' => $name, |
||||
'path' => $path, |
||||
'time' => filemtime( |
||||
$path |
||||
) |
||||
]; |
||||
|
||||
break; |
||||
} |
||||
} |
||||
|
||||
// Sort order |
||||
array_multisort( |
||||
array_column( |
||||
$directories, |
||||
$sort |
||||
), |
||||
$order, |
||||
$method, |
||||
$directories |
||||
); |
||||
|
||||
// Sort files by name ASC |
||||
array_multisort( |
||||
array_column( |
||||
$directories, |
||||
$sort |
||||
), |
||||
$order, |
||||
$method, |
||||
$directories |
||||
); |
||||
|
||||
// Merge list |
||||
return array_merge( |
||||
$directories, |
||||
$files |
||||
); |
||||
} |
||||
|
||||
public function valid(?string $realpath): bool |
||||
{ |
||||
if (empty($realpath)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if ($realpath != $this->_realpath($realpath)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if (!str_starts_with($realpath, $this->_root)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if (str_contains($realpath, DIRECTORY_SEPARATOR . '.')) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
if (!is_readable($realpath)) |
||||
{ |
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
// Return absolute realpath with root constructed |
||||
public function absolute(?string $path): ?string |
||||
{ |
||||
if (!$realpath = $this->_realpath($this->_root . $path)) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
return $realpath; |
||||
} |
||||
|
||||
// PHP::realpath extension appending slash to dir paths |
||||
private function _realpath(?string $path): ?string |
||||
{ |
||||
if (empty($path)) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
if (!$realpath = realpath($path)) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
if (!is_readable($realpath)) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
if (is_dir($realpath)) |
||||
{ |
||||
$realpath = rtrim( |
||||
$realpath, |
||||
DIRECTORY_SEPARATOR |
||||
) . DIRECTORY_SEPARATOR; |
||||
} |
||||
|
||||
return $realpath; |
||||
} |
||||
} |
@ -1,355 +0,0 @@
@@ -1,355 +0,0 @@
|
||||
<?php |
||||
|
||||
// Load dependencies |
||||
require_once __DIR__ . |
||||
DIRECTORY_SEPARATOR . '..'. |
||||
DIRECTORY_SEPARATOR . 'vendor' . |
||||
DIRECTORY_SEPARATOR . 'autoload.php'; |
||||
|
||||
// Parse startup arguments |
||||
foreach ((array) $argv as $item) |
||||
{ |
||||
if (preg_match('/^(?<key>[^=]+)=(?<value>.*)$/', $item, $argument)) |
||||
{ |
||||
switch ($argument['key']) |
||||
{ |
||||
case 'host': |
||||
|
||||
define( |
||||
'NEXT_HOST', |
||||
(string) $argument['value'] |
||||
); |
||||
|
||||
break; |
||||
|
||||
case 'port': |
||||
|
||||
define( |
||||
'NEXT_PORT', |
||||
(int) $argument['value'] |
||||
); |
||||
|
||||
break; |
||||
|
||||
case 'path': |
||||
|
||||
$path = rtrim( |
||||
(string) $argument['value'], |
||||
DIRECTORY_SEPARATOR |
||||
) . DIRECTORY_SEPARATOR; |
||||
|
||||
if (!str_starts_with($path, DIRECTORY_SEPARATOR)) |
||||
{ |
||||
print( |
||||
_('absolute path required') |
||||
) . PHP_EOL; |
||||
|
||||
exit; |
||||
} |
||||
|
||||
if (!is_dir($path) || !is_readable($path)) |
||||
{ |
||||
print( |
||||
_('path not accessible') |
||||
) . PHP_EOL; |
||||
|
||||
exit; |
||||
} |
||||
|
||||
define( |
||||
'NEXT_PATH', |
||||
(string) $path |
||||
); |
||||
|
||||
break; |
||||
|
||||
case 'file': |
||||
|
||||
define( |
||||
'NEXT_FILE', |
||||
(string) $argument['value'] |
||||
); |
||||
|
||||
break; |
||||
|
||||
case 'fail': |
||||
|
||||
$fail = (string) $argument['value']; |
||||
|
||||
if (!str_starts_with($fail, DIRECTORY_SEPARATOR)) |
||||
{ |
||||
print( |
||||
_('absolute path required') |
||||
) . PHP_EOL; |
||||
|
||||
exit; |
||||
} |
||||
|
||||
if (!is_file($fail) || !is_readable($fail)) |
||||
{ |
||||
print( |
||||
_('fail template not accessible') |
||||
) . PHP_EOL; |
||||
|
||||
exit; |
||||
} |
||||
|
||||
define( |
||||
'NEXT_FAIL', |
||||
(string) file_get_contents( |
||||
$fail |
||||
) |
||||
); |
||||
|
||||
break; |
||||
|
||||
case 'list': |
||||
|
||||
define( |
||||
'NEXT_LIST', |
||||
in_array( |
||||
mb_strtolower( |
||||
(string) $argument['value'] |
||||
), |
||||
[ |
||||
'true', |
||||
'yes', |
||||
'1' |
||||
] |
||||
) |
||||
); |
||||
|
||||
break; |
||||
|
||||
case 'size': |
||||
|
||||
define( |
||||
'NEXT_SIZE', |
||||
(int) $argument['value'] |
||||
); |
||||
|
||||
break; |
||||
|
||||
case 'dump': |
||||
|
||||
define( |
||||
'NEXT_DUMP', |
||||
(string) $argument['value'] |
||||
); |
||||
|
||||
break; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Validate required arguments and set optional defaults |
||||
if (!defined('NEXT_HOST')) define('NEXT_HOST', '127.0.0.1'); |
||||
|
||||
if (!defined('NEXT_PORT')) define('NEXT_PORT', 1900); |
||||
|
||||
if (!defined('NEXT_PATH')) |
||||
{ |
||||
print( |
||||
_('path required') |
||||
) . PHP_EOL; |
||||
|
||||
exit; |
||||
} |
||||
|
||||
if (!defined('NEXT_FILE')) define('NEXT_FILE', false); |
||||
|
||||
if (!defined('NEXT_LIST')) define('NEXT_LIST', true); |
||||
|
||||
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} {real} {size} bytes'); |
||||
|
||||
// Init server |
||||
$server = new \Yggverse\Nex\Server( |
||||
NEXT_HOST, |
||||
NEXT_PORT, |
||||
NEXT_SIZE |
||||
); |
||||
|
||||
$server->start( |
||||
function ( |
||||
string $request, |
||||
string $connect |
||||
): ?string |
||||
{ |
||||
// Define response |
||||
$response = null; |
||||
|
||||
// Filter request |
||||
$request = trim( |
||||
$request |
||||
); |
||||
|
||||
$request = empty($request) ? '/' : $request; |
||||
|
||||
// Build realpath |
||||
$realpath = realpath( |
||||
NEXT_PATH . |
||||
urldecode( |
||||
filter_var( |
||||
$request, |
||||
FILTER_SANITIZE_URL |
||||
) |
||||
) |
||||
); |
||||
|
||||
// Make sure directory path ending with slash |
||||
if (is_dir($realpath)) |
||||
{ |
||||
$realpath = rtrim( |
||||
$realpath, |
||||
DIRECTORY_SEPARATOR |
||||
) . DIRECTORY_SEPARATOR; |
||||
} |
||||
|
||||
// Validate realpath exists, started with path defined and does not contain hidden entities |
||||
if ($realpath && str_starts_with($realpath, NEXT_PATH) && !str_contains($realpath, DIRECTORY_SEPARATOR . '.')) |
||||
{ |
||||
// Try directory |
||||
if (is_dir($realpath)) |
||||
{ |
||||
// Try index file on enabled |
||||
if (NEXT_FILE && file_exists($realpath . NEXT_FILE) && is_readable($realpath . NEXT_FILE)) |
||||
{ |
||||
// Update realpath returned on default file response |
||||
$realpath = $realpath . NEXT_FILE; |
||||
|
||||
$response = file_get_contents( |
||||
$realpath |
||||
); |
||||
} |
||||
|
||||
// Try directory listing on enabled |
||||
else if (NEXT_LIST) |
||||
{ |
||||
$directories = []; |
||||
|
||||
$files = []; |
||||
|
||||
foreach ((array) scandir($realpath) as $filename) |
||||
{ |
||||
// Process system entities |
||||
if (str_starts_with($filename, '.')) |
||||
{ |
||||
// Parent navigation |
||||
if ($filename == '..' && $parent = realpath($realpath . $filename)) |
||||
{ |
||||
$parent = rtrim( |
||||
$parent, |
||||
DIRECTORY_SEPARATOR |
||||
) . DIRECTORY_SEPARATOR; |
||||
|
||||
if (str_starts_with($parent, NEXT_PATH)) |
||||
{ |
||||
$directories[$filename] = '=> ../'; |
||||
} |
||||
} |
||||
|
||||
continue; // skip everything else |
||||
} |
||||
|
||||
// Directory |
||||
if (is_dir($realpath . $filename)) |
||||
{ |
||||
if (is_readable($realpath . $filename)) |
||||
{ |
||||
$directories[$filename] = sprintf( |
||||
'=> %s/', |
||||
urlencode( |
||||
$filename |
||||
) |
||||
); |
||||
} |
||||
|
||||
continue; |
||||
} |
||||
|
||||
// File |
||||
if (is_readable($realpath . $filename)) |
||||
{ |
||||
$files[$filename] = sprintf( |
||||
'=> %s', |
||||
urlencode( |
||||
$filename |
||||
) |
||||
); |
||||
} |
||||
} |
||||
|
||||
// Sort by keys ASC |
||||
ksort( |
||||
$directories, |
||||
SORT_STRING | SORT_FLAG_CASE | SORT_NATURAL |
||||
); |
||||
|
||||
ksort( |
||||
$files, |
||||
SORT_STRING | SORT_FLAG_CASE | SORT_NATURAL |
||||
); |
||||
|
||||
// Merge items |
||||
$response = implode( |
||||
PHP_EOL, |
||||
array_merge( |
||||
$directories, |
||||
$files |
||||
) |
||||
); |
||||
} |
||||
} |
||||
|
||||
// Try file |
||||
else |
||||
{ |
||||
$response = file_get_contents( |
||||
$realpath |
||||
); |
||||
} |
||||
} |
||||
|
||||
// Dump request on enabled |
||||
if (NEXT_DUMP) |
||||
{ |
||||
// Build connection URL #72811 |
||||
$url = sprintf( |
||||
'nex://%s', |
||||
$connect |
||||
); |
||||
|
||||
// Print dump from template |
||||
printf( |
||||
str_ireplace( |
||||
[ |
||||
'{time}', |
||||
'{code}', |
||||
'{host}', |
||||
'{port}', |
||||
'{path}', |
||||
'{real}', |
||||
'{size}' |
||||
], |
||||
[ |
||||
(string) date('c'), |
||||
(string) (int) is_string($response), |
||||
(string) parse_url($url, PHP_URL_HOST), |
||||
(string) parse_url($url, PHP_URL_PORT), |
||||
(string) str_replace('%', '%%', $request), |
||||
(string) str_replace('%', '%%', empty($realpath) ? '!' : $realpath), |
||||
(string) mb_strlen((string) $response) |
||||
], |
||||
NEXT_DUMP |
||||
) . PHP_EOL |
||||
); |
||||
} |
||||
|
||||
// Send response |
||||
return is_string($response) ? $response : NEXT_FAIL; |
||||
} |
||||
); |
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
<?php |
||||
|
||||
// Load dependencies |
||||
require_once __DIR__ . |
||||
DIRECTORY_SEPARATOR . '..'. |
||||
DIRECTORY_SEPARATOR . 'vendor' . |
||||
DIRECTORY_SEPARATOR . 'autoload.php'; |
||||
|
||||
// Init environment |
||||
$environment = new \Yggverse\Next\Model\Environment( |
||||
$argv, |
||||
json_decode( |
||||
file_get_contents( |
||||
__DIR__ . |
||||
DIRECTORY_SEPARATOR . '..'. |
||||
DIRECTORY_SEPARATOR . 'default.json' |
||||
), |
||||
true |
||||
) |
||||
); |
||||
|
||||
// Init filesystem |
||||
$filesystem = new \Yggverse\Next\Model\Filesystem( |
||||
$environment->get('path') |
||||
); |
||||
|
||||
// Start server |
||||
try |
||||
{ |
||||
switch ($environment->get('type')) |
||||
{ |
||||
case 'nex': |
||||
|
||||
$server = \Ratchet\Server\IoServer::factory( |
||||
new \Yggverse\Next\Controller\Nex( |
||||
$environment, |
||||
$filesystem |
||||
), |
||||
$environment->get('port'), |
||||
$environment->get('host') |
||||
); |
||||
|
||||
$server->run(); |
||||
|
||||
break; |
||||
|
||||
default: |
||||
|
||||
throw new \Exception( |
||||
_('valid server type required!') |
||||
); |
||||
} |
||||
} |
||||
|
||||
// Show help |
||||
catch (\Exception $exception) |
||||
{ |
||||
// @TODO |
||||
} |
Loading…
Reference in new issue