Fix some things

master
eater 6 years ago
parent 91d17f713a
commit 9d8ab04348
Signed by: eater
GPG Key ID: AD2560A0F84F0759

@ -1,6 +1,5 @@
{ {
"name": "bitcommunism/http", "name": "bitcommunism/http",
"version": "1.0.1",
"license": "MIT", "license": "MIT",
"require": { "require": {
"nikic/fast-route": "^1.2", "nikic/fast-route": "^1.2",
@ -10,6 +9,7 @@
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"BitCommunism\\Http\\": "src/" "BitCommunism\\Http\\": "src/"
} },
"files": ["src/functions.php"]
} }
} }

@ -2,24 +2,23 @@
namespace BitCommunism\Http; namespace BitCommunism\Http;
use BitCommunism\Marx\Instance;
use function DI\add; use function DI\add;
use function DI\autowire; use function DI\autowire;
use function DI\get; use function DI\get;
use function DI\object; use function DI\value;
return [ return [
'marx.calls' => add([ 'marx.calls' => add([
'http' => function(Server $server) { 'http' => value(function(Server $server) {
return $server; return $server;
} })
]), ]),
'marx.loaders' => add([ 'marx.loaders' => add([
function(Server $server) { value(function(Server $server) {
$server->buildRoutes(); $server->buildRoutes();
} })
]), ]),
Server::class => object()->constructorParameter('routes', get('routes')), Server::class => autowire()->constructorParameter('routes', get('routes')),
]; ];

@ -7,7 +7,7 @@ use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
class Context class Context implements \ArrayAccess
{ {
/** /**
* @var ServerRequestInterface * @var ServerRequestInterface
@ -112,29 +112,37 @@ class Context
return $this->settings; return $this->settings;
} }
/**
* @param array $settings
*/
public function setSettings(array $settings): void
{
$this->settings = $settings;
}
public function redirect($to, $status = 302): void { public function redirect($to, $status = 302): void {
$this->withResponse(function (ResponseInterface $response) use ($to, $status) { $this->withResponse(function (ResponseInterface $response) use ($to, $status) {
return $response->withStatus($status)->withHeader('Location', $to); return $response->withStatus($status)->withHeader('Location', $to);
}); });
} }
public function __get($name) public function offsetExists($offset)
{ {
return $this->context[$name]; return isset($this->context[$offset]);
} }
public function __set($name, $value) public function offsetGet($offset)
{ {
$this->context[$name] = $value; return $this->context[$offset];
} }
public function __isset($name) public function offsetSet($offset, $value)
{ {
return isset($this->context[$name]); $this->context[$offset] = $value;
} }
public function __unset($name) public function offsetUnset($offset)
{ {
unset($this->context[$name]); unset($this->context[$offset]);
} }
} }

@ -4,23 +4,31 @@ namespace BitCommunism\Http;
use DI\Container; use DI\Container;
use DI\ContainerBuilder;
use function DI\value;
use FastRoute\Dispatcher; use FastRoute\Dispatcher;
use FastRoute\RouteCollector; use FastRoute\RouteCollector;
use function FastRoute\simpleDispatcher;
use function GuzzleHttp\Psr7\copy_to_stream;
use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\ServerRequest; use GuzzleHttp\Psr7\ServerRequest;
use function GuzzleHttp\Psr7\stream_for; use Invoker\Invoker;
use Psr\Http\Message\RequestInterface; use Invoker\ParameterResolver\AssociativeArrayResolver;
use Invoker\ParameterResolver\Container\TypeHintContainerResolver;
use Invoker\ParameterResolver\DefaultValueResolver;
use Invoker\ParameterResolver\NumericArrayResolver;
use Invoker\ParameterResolver\ResolverChain;
use Invoker\ParameterResolver\TypeHintResolver;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use function FastRoute\simpleDispatcher;
use function GuzzleHttp\Psr7\copy_to_stream;
use function GuzzleHttp\Psr7\stream_for;
class Server class Server
{ {
private $routes = []; private $routes = [];
private $container; private $container;
/**
* @var Invoker
*/
private $invoker;
/** /**
* @var Dispatcher * @var Dispatcher
@ -31,6 +39,7 @@ class Server
{ {
$this->routes = $routes; $this->routes = $routes;
$this->container = $container; $this->container = $container;
$this->invoker = $this->createDefaultInvoker();
} }
private function iterateRoutes() private function iterateRoutes()
@ -40,17 +49,26 @@ class Server
private function iterateRoutesFromArray($routeArr, $prefix = '', $known = [], $middleware = []) private function iterateRoutesFromArray($routeArr, $prefix = '', $known = [], $middleware = [])
{ {
$route = $routeArr['middleware'] ?? [];
$middleware = array_merge($middleware, array_map(function ($route) {
if (!$route instanceof Handle) {
return new Handle($route);
}
return $route;
}, (array)$route));
foreach ($routeArr as $key => $route) { foreach ($routeArr as $key => $route) {
if ($key === 'middleware') { if ($key === 'middleware') {
$middleware = array_merge($middleware, $route); continue;
} }
if (is_array($route) && !(isset($route[0]) && isset($route[1]))) { if (is_array($route) && !(isset($route[0]) && isset($route[1]))) {
yield from $this->iterateRoutesFromArray($route, $prefix . $key, $known); yield from $this->iterateRoutesFromArray($route, $prefix . $key, $known, $middleware);
continue; continue;
} }
if (is_array($route) || is_string($route)) { if (!$route instanceof Handle) {
$route = new Handle($route); $route = new Handle($route);
} }
@ -123,6 +141,16 @@ class Server
return $response; return $response;
} }
private function createDefaultInvoker() {
return new Invoker(new ResolverChain(array(
new NumericArrayResolver(),
new AssociativeArrayResolver(),
new DefaultValueResolver(),
new TypeHintResolver(),
new TypeHintContainerResolver($this->container),
)), $this->container);
}
public function handleHttp(ServerRequestInterface $request, Handle $handler, array $vars, ResponseInterface $response = null): ResponseInterface public function handleHttp(ServerRequestInterface $request, Handle $handler, array $vars, ResponseInterface $response = null): ResponseInterface
{ {
$middlewareArray = $handler->getMiddleware(); $middlewareArray = $handler->getMiddleware();
@ -134,29 +162,33 @@ class Server
$response = new Response(200, [], stream_for('Empty response')); $response = new Response(200, [], stream_for('Empty response'));
} }
$context = new Context($request, $response); $context = new Context($request, $response, $vars);
$next = function (Context $context) use ($handler, $middlewareArray, &$middlewarePointer, &$next) { $next = function (Context $context) use ($handler, $middlewareArray, &$middlewarePointer, &$next) {
$output = null; $output = null;
if (count($middlewareArray) >= $middlewarePointer) { if (count($middlewareArray) > $middlewarePointer) {
$call = $handler->getCall(); $handler = $middlewareArray[$middlewarePointer++];
if (is_array($call)) { }
$obj = $this->container->get($call[0]);
$call = [$obj, $call[1]]; $call = $handler->getCall();
} if (is_array($call)) {
} else { $obj = $this->container->get($call[0]);
[$name, $func] = $middlewareArray[$middlewarePointer++]; $call = [$obj, $call[1]];
$middleware = $this->container->get($name);
$call = [$middleware, $func];
} }
$output = $this->container->call($call, [ $context->setSettings($handler->getSettings());
$output = $this->invoker->call($call, [
'request' => $context->getRequest(), 'request' => $context->getRequest(),
ServerRequestInterface::class => $context->getRequest(),
'response' => $context->getResponse(), 'response' => $context->getResponse(),
ResponseInterface::class => $context->getResponse(),
'context' => $context, 'context' => $context,
Context::class => $context,
'vars' => $context->getVars(), 'vars' => $context->getVars(),
'settings' => $context->getSettings(), 'settings' => $context->getSettings(),
'next' => $next,
]); ]);
$this->normalizeResponse($output, $context); $this->normalizeResponse($output, $context);
@ -169,6 +201,10 @@ class Server
private function normalizeResponse($response, Context $context) private function normalizeResponse($response, Context $context)
{ {
if ($response === null) {
return;
}
if ($response instanceof ResponseInterface) { if ($response instanceof ResponseInterface) {
$context->setResponse($response); $context->setResponse($response);
return; return;

@ -2,20 +2,18 @@
namespace BitCommunism\Http; namespace BitCommunism\Http;
use Psr\Http\Message\ResponseInterface; if (!function_exists(__NAMESPACE__ . '\\handle')) {
function handle($call, $settings = []): Handle
if (function_exists(__NAMESPACE__ . '\\handle')) {
function handle($call, $settings = [])
{ {
return new Handle($call, $settings); return new Handle($call, $settings);
} }
} }
if (function_exists(__NAMESPACE__ . '\\redirect')) { if (!function_exists(__NAMESPACE__ . '\\redirect')) {
function redirect($to, $status = 302) function redirect($to, $status = 302)
{ {
return function (Context $c) use ($to, $status) { return handle(function (Context $c) use ($to, $status) {
$c->redirect($to, $status); $c->redirect($to, $status);
}; });
} }
} }
Loading…
Cancel
Save