mirror of
https://github.com/bitinflow/expose.git
synced 2026-03-13 21:45:55 +00:00
wip
This commit is contained in:
40
app/Http/App.php
Normal file
40
app/Http/App.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Ratchet\Http\Router;
|
||||
use Ratchet\Server\IoServer;
|
||||
use React\EventLoop\LoopInterface;
|
||||
use React\Socket\Server as Reactor;
|
||||
use Symfony\Component\Routing\Matcher\UrlMatcher;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
class App extends \Ratchet\App
|
||||
{
|
||||
/** @var Server */
|
||||
protected $socket;
|
||||
|
||||
public function __construct($httpHost, $port, $address, LoopInterface $loop)
|
||||
{
|
||||
$this->httpHost = $httpHost;
|
||||
$this->port = $port;
|
||||
|
||||
$this->socket = new Reactor($address.':'.$port, $loop);
|
||||
|
||||
$this->routes = new RouteCollection;
|
||||
|
||||
$urlMatcher = new UrlMatcher($this->routes, new RequestContext);
|
||||
|
||||
$router = new Router($urlMatcher);
|
||||
|
||||
$httpServer = new Server($router);
|
||||
|
||||
$this->_server = new IoServer($httpServer, $this->socket, $loop);
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
$this->socket->close();
|
||||
}
|
||||
}
|
||||
42
app/Http/Controllers/Controller.php
Normal file
42
app/Http/Controllers/Controller.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Ratchet\ConnectionInterface;
|
||||
use Ratchet\Http\HttpServerInterface;
|
||||
use Twig\Environment;
|
||||
use Twig\Loader\ArrayLoader;
|
||||
use function GuzzleHttp\Psr7\stream_for;
|
||||
|
||||
abstract class Controller implements HttpServerInterface
|
||||
{
|
||||
public function onClose(ConnectionInterface $connection)
|
||||
{
|
||||
unset($connection->requestBuffer);
|
||||
unset($connection->contentLength);
|
||||
unset($connection->request);
|
||||
}
|
||||
|
||||
public function onError(ConnectionInterface $connection, Exception $e)
|
||||
{
|
||||
}
|
||||
|
||||
public function onMessage(ConnectionInterface $from, $msg)
|
||||
{
|
||||
}
|
||||
|
||||
protected function getView(string $view, array $data = [])
|
||||
{
|
||||
$templatePath = implode(DIRECTORY_SEPARATOR, explode('.', $view));
|
||||
|
||||
$twig = new Environment(
|
||||
new ArrayLoader([
|
||||
'app' => file_get_contents(base_path('resources/views/server/layouts/app.twig')),
|
||||
'template' => file_get_contents(base_path('resources/views/'.$templatePath.'.twig')),
|
||||
])
|
||||
);
|
||||
|
||||
return stream_for($twig->render('template', $data));
|
||||
}
|
||||
}
|
||||
92
app/Http/Controllers/PostController.php
Normal file
92
app/Http/Controllers/PostController.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\QueryParameters;
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Collection;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Ratchet\ConnectionInterface;
|
||||
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
|
||||
use function GuzzleHttp\Psr7\parse_request;
|
||||
|
||||
abstract class PostController extends Controller
|
||||
{
|
||||
protected $keepConnectionOpen = false;
|
||||
|
||||
public function onOpen(ConnectionInterface $connection, RequestInterface $request = null)
|
||||
{
|
||||
$connection->contentLength = $this->findContentLength($request->getHeaders());
|
||||
|
||||
$connection->requestBuffer = (string) $request->getBody();
|
||||
|
||||
$connection->request = $request;
|
||||
|
||||
$this->checkContentLength($connection);
|
||||
}
|
||||
|
||||
public function onMessage(ConnectionInterface $from, $msg)
|
||||
{
|
||||
if (! isset($from->requestBuffer)) {
|
||||
$request = parse_request($msg);
|
||||
$from->contentLength = $this->findContentLength($request->getHeaders());
|
||||
$from->request = $request;
|
||||
$from->requestBuffer = (string) $request->getBody();
|
||||
} else {
|
||||
$from->requestBuffer .= $msg;
|
||||
}
|
||||
|
||||
$this->checkContentLength($from);
|
||||
}
|
||||
|
||||
protected function findContentLength(array $headers): int
|
||||
{
|
||||
return Collection::make($headers)->first(function ($values, $header) {
|
||||
return strtolower($header) === 'content-length';
|
||||
})[0] ?? 0;
|
||||
}
|
||||
|
||||
protected function checkContentLength(ConnectionInterface $connection)
|
||||
{
|
||||
if (strlen($connection->requestBuffer) === $connection->contentLength) {
|
||||
$laravelRequest = $this->createLaravelRequest($connection);
|
||||
|
||||
$this->handle($laravelRequest, $connection);
|
||||
|
||||
if (! $this->keepConnectionOpen) {
|
||||
$connection->close();
|
||||
}
|
||||
|
||||
unset($connection->requestBuffer);
|
||||
unset($connection->contentLength);
|
||||
unset($connection->request);
|
||||
}
|
||||
}
|
||||
|
||||
abstract public function handle(Request $request, ConnectionInterface $httpConnection);
|
||||
|
||||
protected function createLaravelRequest(ConnectionInterface $connection): Request
|
||||
{
|
||||
try {
|
||||
parse_str($connection->requestBuffer, $bodyParameters);
|
||||
} catch (\Throwable $e) {
|
||||
$bodyParameters = [];
|
||||
}
|
||||
|
||||
$serverRequest = (new ServerRequest(
|
||||
$connection->request->getMethod(),
|
||||
$connection->request->getUri(),
|
||||
$connection->request->getHeaders(),
|
||||
$connection->requestBuffer,
|
||||
$connection->request->getProtocolVersion(),
|
||||
[
|
||||
'REMOTE_ADDR' => $connection->remoteAddress
|
||||
]
|
||||
))
|
||||
->withQueryParams(QueryParameters::create($connection->request)->all())
|
||||
->withParsedBody($bodyParameters);
|
||||
|
||||
return Request::createFromBase((new HttpFoundationFactory)->createRequest($serverRequest));
|
||||
}
|
||||
}
|
||||
35
app/Http/QueryParameters.php
Normal file
35
app/Http/QueryParameters.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
|
||||
class QueryParameters
|
||||
{
|
||||
/** @var \Psr\Http\Message\RequestInterface */
|
||||
protected $request;
|
||||
|
||||
public static function create(RequestInterface $request)
|
||||
{
|
||||
return new static($request);
|
||||
}
|
||||
|
||||
public function __construct(RequestInterface $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
public function all(): array
|
||||
{
|
||||
$queryParameters = [];
|
||||
|
||||
parse_str($this->request->getUri()->getQuery(), $queryParameters);
|
||||
|
||||
return $queryParameters;
|
||||
}
|
||||
|
||||
public function get(string $name): string
|
||||
{
|
||||
return $this->all()[$name] ?? '';
|
||||
}
|
||||
}
|
||||
65
app/Http/RouteGenerator.php
Normal file
65
app/Http/RouteGenerator.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Ratchet\WebSocket\MessageComponentInterface;
|
||||
use Ratchet\WebSocket\WsServer;
|
||||
use React\EventLoop\LoopInterface;
|
||||
use Symfony\Component\Routing\Route;
|
||||
use Symfony\Component\Routing\RouteCollection;
|
||||
|
||||
class RouteGenerator
|
||||
{
|
||||
/** @var \Symfony\Component\Routing\RouteCollection */
|
||||
protected $routes;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->routes = new RouteCollection;
|
||||
}
|
||||
|
||||
public function getRoutes(): RouteCollection
|
||||
{
|
||||
return $this->routes;
|
||||
}
|
||||
|
||||
public function get(string $uri, $action, string $condition = '')
|
||||
{
|
||||
$this->addRoute('GET', $uri, $action, $condition);
|
||||
}
|
||||
|
||||
public function post(string $uri, $action, string $condition = '')
|
||||
{
|
||||
$this->addRoute('POST', $uri, $action, $condition);
|
||||
}
|
||||
|
||||
public function put(string $uri, $action, string $condition = '')
|
||||
{
|
||||
$this->addRoute('PUT', $uri, $action, $condition);
|
||||
}
|
||||
|
||||
public function patch(string $uri, $action, string $condition = '')
|
||||
{
|
||||
$this->addRoute('PATCH', $uri, $action, $condition);
|
||||
}
|
||||
|
||||
public function delete(string $uri, $action, string $condition = '')
|
||||
{
|
||||
$this->addRoute('DELETE', $uri, $action, $condition);
|
||||
}
|
||||
|
||||
public function addRoute(string $method, string $uri, $action, string $condition = '')
|
||||
{
|
||||
$this->routes->add("{$method}-($uri}", $this->getRoute($method, $uri, $action, $condition));
|
||||
}
|
||||
|
||||
public function addSymfonyRoute(string $name, Route $route)
|
||||
{
|
||||
$this->routes->add($name, $route);
|
||||
}
|
||||
|
||||
protected function getRoute(string $method, string $uri, $action, string $condition = ''): Route
|
||||
{
|
||||
return new Route($uri, ['_controller' => app($action)], [], [], null, [], [$method], $condition);
|
||||
}
|
||||
}
|
||||
15
app/Http/Server.php
Normal file
15
app/Http/Server.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Ratchet\Http\HttpServerInterface;
|
||||
|
||||
class Server extends \Ratchet\Http\HttpServer
|
||||
{
|
||||
public function __construct(HttpServerInterface $component)
|
||||
{
|
||||
parent::__construct($component);
|
||||
|
||||
$this->_reqParser->maxSize = 15242880000;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user