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",
"version": "1.0.1",
"license": "MIT",
"require": {
"nikic/fast-route": "^1.2",
@ -10,6 +9,7 @@
"autoload": {
"psr-4": {
"BitCommunism\\Http\\": "src/"
}
},
"files": ["src/functions.php"]
}
}

@ -2,24 +2,23 @@
namespace BitCommunism\Http;
use BitCommunism\Marx\Instance;
use function DI\add;
use function DI\autowire;
use function DI\get;
use function DI\object;
use function DI\value;
return [
'marx.calls' => add([
'http' => function(Server $server) {
'http' => value(function(Server $server) {
return $server;
}
})
]),
'marx.loaders' => add([
function(Server $server) {
value(function(Server $server) {
$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\ServerRequestInterface;
class Context
class Context implements \ArrayAccess
{
/**
* @var ServerRequestInterface
@ -112,29 +112,37 @@ class Context
return $this->settings;
}
/**
* @param array $settings
*/
public function setSettings(array $settings): void
{
$this->settings = $settings;
}
public function redirect($to, $status = 302): void {
$this->withResponse(function (ResponseInterface $response) use ($to, $status) {
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\ContainerBuilder;
use function DI\value;
use FastRoute\Dispatcher;
use FastRoute\RouteCollector;
use function FastRoute\simpleDispatcher;
use function GuzzleHttp\Psr7\copy_to_stream;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\ServerRequest;
use function GuzzleHttp\Psr7\stream_for;
use Psr\Http\Message\RequestInterface;
use Invoker\Invoker;
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\ServerRequestInterface;
use function FastRoute\simpleDispatcher;
use function GuzzleHttp\Psr7\copy_to_stream;
use function GuzzleHttp\Psr7\stream_for;
class Server
{
private $routes = [];
private $container;
/**
* @var Invoker
*/
private $invoker;
/**
* @var Dispatcher
@ -31,6 +39,7 @@ class Server
{
$this->routes = $routes;
$this->container = $container;
$this->invoker = $this->createDefaultInvoker();
}
private function iterateRoutes()
@ -40,17 +49,26 @@ class Server
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) {
if ($key === 'middleware') {
$middleware = array_merge($middleware, $route);
continue;
}
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;
}
if (is_array($route) || is_string($route)) {
if (!$route instanceof Handle) {
$route = new Handle($route);
}
@ -123,6 +141,16 @@ class Server
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
{
$middlewareArray = $handler->getMiddleware();
@ -134,29 +162,33 @@ class Server
$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) {
$output = null;
if (count($middlewareArray) >= $middlewarePointer) {
$call = $handler->getCall();
if (is_array($call)) {
$obj = $this->container->get($call[0]);
$call = [$obj, $call[1]];
}
} else {
[$name, $func] = $middlewareArray[$middlewarePointer++];
$middleware = $this->container->get($name);
$call = [$middleware, $func];
if (count($middlewareArray) > $middlewarePointer) {
$handler = $middlewareArray[$middlewarePointer++];
}
$call = $handler->getCall();
if (is_array($call)) {
$obj = $this->container->get($call[0]);
$call = [$obj, $call[1]];
}
$output = $this->container->call($call, [
$context->setSettings($handler->getSettings());
$output = $this->invoker->call($call, [
'request' => $context->getRequest(),
ServerRequestInterface::class => $context->getRequest(),
'response' => $context->getResponse(),
ResponseInterface::class => $context->getResponse(),
'context' => $context,
Context::class => $context,
'vars' => $context->getVars(),
'settings' => $context->getSettings(),
'next' => $next,
]);
$this->normalizeResponse($output, $context);
@ -169,6 +201,10 @@ class Server
private function normalizeResponse($response, Context $context)
{
if ($response === null) {
return;
}
if ($response instanceof ResponseInterface) {
$context->setResponse($response);
return;

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