* expressive version uplift

* loslog added
This commit is contained in:
Danyi Dávid 2018-07-09 01:01:22 +02:00
parent efad8765c8
commit 12c98c0519
18 changed files with 885 additions and 597 deletions

View File

@ -11,18 +11,18 @@
"prefer-stable": true, "prefer-stable": true,
"require": { "require": {
"php": "^7.1", "php": "^7.1",
"dasprid/container-interop-doctrine": "^1.0", "dasprid/container-interop-doctrine": "^1.1",
"guzzlehttp/guzzle": "^6.3", "guzzlehttp/guzzle": "^6.3",
"http-interop/http-middleware": "^0.4.1", "los/loslog": "^3.1",
"roave/security-advisories": "dev-master", "roave/security-advisories": "dev-master",
"zendframework/zend-component-installer": "^1.0", "zendframework/zend-component-installer": "^2.1.1",
"zendframework/zend-config-aggregator": "^1.0", "zendframework/zend-config-aggregator": "^1.0",
"zendframework/zend-eventmanager": "^3.2", "zendframework/zend-eventmanager": "^3.2",
"zendframework/zend-expressive": "^2.0.2", "zendframework/zend-expressive": "^3.0.1",
"zendframework/zend-expressive-fastroute": "^2.0", "zendframework/zend-expressive-fastroute": "^3.0",
"zendframework/zend-expressive-helpers": "^4.0", "zendframework/zend-expressive-helpers": "^5.0",
"zendframework/zend-http": "^2.6", "zendframework/zend-http": "^2.7",
"zendframework/zend-json": "^3.0", "zendframework/zend-json": "^3.1",
"zendframework/zend-servicemanager": "^3.3", "zendframework/zend-servicemanager": "^3.3",
"zendframework/zend-stdlib": "^3.1" "zendframework/zend-stdlib": "^3.1"
}, },

1107
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
<?php
use Zend\Stratigility\Middleware\ErrorHandler;
return [
'dependencies' => [
'factories' => [
LosMiddleware\LosLog\LosLog::class => LosMiddleware\LosLog\LosLogFactory::class,
LosMiddleware\LosLog\HttpLog::class => LosMiddleware\LosLog\HttpLogFactory::class,
Psr\Log\LoggerInterface::class => LosMiddleware\LosLog\LoggerFactory::class,
],
'delegators' => [
ErrorHandler::class => [
LosMiddleware\LosLog\ErrorHandlerListenerDelegatorFactory::class,
],
],
],
'loslog' => [
'log_dir' => 'data/logs',
'error_logger_file' => 'error.log',
'exception_logger_file' => 'exception.log',
'static_logger_file' => 'static.log',
'http_logger_file' => 'http.log',
'log_request' => false,
'log_response' => false,
'full' => false,
],
];

View File

@ -1,5 +1,7 @@
<?php <?php
declare(strict_types=1);
use Zend\ConfigAggregator\ArrayProvider; use Zend\ConfigAggregator\ArrayProvider;
use Zend\ConfigAggregator\ConfigAggregator; use Zend\ConfigAggregator\ConfigAggregator;
use Zend\ConfigAggregator\PhpFileProvider; use Zend\ConfigAggregator\PhpFileProvider;
@ -11,10 +13,16 @@ $cacheConfig = [
]; ];
$aggregator = new ConfigAggregator([ $aggregator = new ConfigAggregator([
\Zend\Log\ConfigProvider::class,
\Zend\HttpHandlerRunner\ConfigProvider::class,
\Zend\Validator\ConfigProvider::class, \Zend\Validator\ConfigProvider::class,
// Include cache configuration // Include cache configuration
new ArrayProvider($cacheConfig), new ArrayProvider($cacheConfig),
\Zend\Expressive\Helper\ConfigProvider::class,
\Zend\Expressive\ConfigProvider::class,
\Zend\Expressive\Router\ConfigProvider::class,
// Default App module config // Default App module config
App\ConfigProvider::class, App\ConfigProvider::class,

View File

@ -1,16 +1,14 @@
<?php <?php
use Zend\ServiceManager\Config; declare(strict_types=1);
use Zend\ServiceManager\ServiceManager; use Zend\ServiceManager\ServiceManager;
// Load configuration // Load configuration
$config = require __DIR__ . '/config.php'; $config = require __DIR__ . '/config.php';
$dependencies = $config['dependencies'];
$dependencies['services']['config'] = $config;
// Build container // Build container
$container = new ServiceManager(); return new ServiceManager($dependencies);
(new Config($config['dependencies']))->configureServiceManager($container);
// Inject config
$container->setService('config', $config);
return $container;

View File

@ -1,5 +1,4 @@
<?php <?php
/** /**
* File required to allow enablement of development mode. * File required to allow enablement of development mode.
* *
@ -21,6 +20,8 @@
* - Configuration caching is _disabled_. * - Configuration caching is _disabled_.
*/ */
declare(strict_types=1);
use Zend\ConfigAggregator\ConfigAggregator; use Zend\ConfigAggregator\ConfigAggregator;
return [ return [

View File

@ -1,58 +1,78 @@
<?php <?php
declare(strict_types=1);
use Psr\Container\ContainerInterface;
use Zend\Expressive\Application;
use Zend\Expressive\Handler\NotFoundHandler;
use Zend\Expressive\Helper\ServerUrlMiddleware; use Zend\Expressive\Helper\ServerUrlMiddleware;
use Zend\Expressive\Helper\UrlHelperMiddleware; use Zend\Expressive\Helper\UrlHelperMiddleware;
use Zend\Expressive\Middleware\ImplicitHeadMiddleware; use Zend\Expressive\MiddlewareFactory;
use Zend\Expressive\Middleware\ImplicitOptionsMiddleware; use Zend\Expressive\Router\Middleware\DispatchMiddleware;
use Zend\Expressive\Middleware\NotFoundHandler; use Zend\Expressive\Router\Middleware\ImplicitHeadMiddleware;
use Zend\Expressive\Router\Middleware\ImplicitOptionsMiddleware;
use Zend\Expressive\Router\Middleware\MethodNotAllowedMiddleware;
use Zend\Expressive\Router\Middleware\RouteMiddleware;
use Zend\Stratigility\Middleware\ErrorHandler; use Zend\Stratigility\Middleware\ErrorHandler;
/** /**
* Setup middleware pipeline: * Setup middleware pipeline:
*/ */
return function (Application $app, MiddlewareFactory $factory, ContainerInterface $container) : void {
// The error handler should be the first (most outer) middleware to catch
// all Exceptions.
$app->pipe(ErrorHandler::class);
$app->pipe(App\Middleware\PreFlightMiddleware::class);
$app->pipe(App\Middleware\EventSubscriberMiddleware::class);
$app->pipe(ServerUrlMiddleware::class);
// The error handler should be the first (most outer) middleware to catch // Pipe more middleware here that you want to execute on every request:
// all Exceptions. // - bootstrapping
$app->pipe(ErrorHandler::class); // - pre-conditions
$app->pipe(App\Middleware\PreFlightMiddleware::class); // - modifications to outgoing responses
$app->pipe(App\Middleware\EventSubscriberMiddleware::class); //
//$app->pipe(LosMiddleware\BasePath\BasePath::class); // Piped Middleware may be either callables or service names. Middleware may
$app->pipe(ServerUrlMiddleware::class); // also be passed as an array; each item in the array must resolve to
// middleware eventually (i.e., callable or service name).
//
// Middleware can be attached to specific paths, allowing you to mix and match
// applications under a common domain. The handlers in each middleware
// attached this way will see a URI with the matched path segment removed.
//
// i.e., path of "/api/member/profile" only passes "/member/profile" to $apiMiddleware
// - $app->pipe('/api', $apiMiddleware);
// - $app->pipe('/docs', $apiDocMiddleware);
// - $app->pipe('/files', $filesMiddleware);
// Pipe more middleware here that you want to execute on every request: // Register the routing middleware in the middleware pipeline.
// - bootstrapping // This middleware registers the Zend\Expressive\Router\RouteResult request attribute.
// - pre-conditions $app->pipe(RouteMiddleware::class);
// - modifications to outgoing responses
//
// Piped Middleware may be either callables or service names. Middleware may
// also be passed as an array; each item in the array must resolve to
// middleware eventually (i.e., callable or service name).
//
// Middleware can be attached to specific paths, allowing you to mix and match
// applications under a common domain. The handlers in each middleware
// attached this way will see a URI with the MATCHED PATH SEGMENT REMOVED!!!
//
// - $app->pipe('/api', $apiMiddleware);
// - $app->pipe('/docs', $apiDocMiddleware);
// - $app->pipe('/files', $filesMiddleware);
// Register the routing middleware in the middleware pipeline // The following handle routing failures for common conditions:
$app->pipeRoutingMiddleware(); // - HEAD request but no routes answer that method
$app->pipe(ImplicitHeadMiddleware::class); // - OPTIONS request but no routes answer that method
$app->pipe(ImplicitOptionsMiddleware::class); // - method not allowed
$app->pipe(UrlHelperMiddleware::class); // Order here matters; the MethodNotAllowedMiddleware should be placed
// after the Implicit*Middleware.
$app->pipe(ImplicitHeadMiddleware::class);
$app->pipe(ImplicitOptionsMiddleware::class);
$app->pipe(MethodNotAllowedMiddleware::class);
// Add more middleware here that needs to introspect the routing results; this // Seed the UrlHelper with the routing results:
// might include: $app->pipe(UrlHelperMiddleware::class);
//
// - route-based authentication
// - route-based validation
// - etc.
// Register the dispatch middleware in the middleware pipeline // Add more middleware here that needs to introspect the routing results; this
$app->pipeDispatchMiddleware(); // might include:
//
// - route-based authentication
// - route-based validation
// - etc.
// At this point, if no Response is return by any middleware, the // Register the dispatch middleware in the middleware pipeline
// NotFoundHandler kicks in; alternately, you can provide other fallback $app->pipe(DispatchMiddleware::class);
// middleware to execute.
$app->pipe(NotFoundHandler::class); // At this point, if no Response is returned by any middleware, the
// NotFoundHandler kicks in; alternately, you can provide other fallback
// middleware to execute.
$app->pipe(NotFoundHandler::class);
};

View File

@ -1,31 +1,39 @@
<?php <?php
declare(strict_types=1);
use Psr\Container\ContainerInterface;
use Zend\Expressive\Application;
use Zend\Expressive\MiddlewareFactory;
/** /**
* Setup routes with a single request method: * Setup routes with a single request method:
* *
* $app->get('/', App\Action\HomePageAction::class, 'home'); * $app->get('/', App\Handler\HomePageHandler::class, 'home');
* $app->post('/album', App\Action\AlbumCreateAction::class, 'album.create'); * $app->post('/album', App\Handler\AlbumCreateHandler::class, 'album.create');
* $app->put('/album/:id', App\Action\AlbumUpdateAction::class, 'album.put'); * $app->put('/album/:id', App\Handler\AlbumUpdateHandler::class, 'album.put');
* $app->patch('/album/:id', App\Action\AlbumUpdateAction::class, 'album.patch'); * $app->patch('/album/:id', App\Handler\AlbumUpdateHandler::class, 'album.patch');
* $app->delete('/album/:id', App\Action\AlbumDeleteAction::class, 'album.delete'); * $app->delete('/album/:id', App\Handler\AlbumDeleteHandler::class, 'album.delete');
* *
* Or with multiple request methods: * Or with multiple request methods:
* *
* $app->route('/contact', App\Action\ContactAction::class, ['GET', 'POST', ...], 'contact'); * $app->route('/contact', App\Handler\ContactHandler::class, ['GET', 'POST', ...], 'contact');
* *
* Or handling all request methods: * Or handling all request methods:
* *
* $app->route('/contact', App\Action\ContactAction::class)->setName('contact'); * $app->route('/contact', App\Handler\ContactHandler::class)->setName('contact');
* *
* or: * or:
* *
* $app->route( * $app->route(
* '/contact', * '/contact',
* App\Action\ContactAction::class, * App\Handler\ContactHandler::class,
* Zend\Expressive\Router\Route::HTTP_METHOD_ANY, * Zend\Expressive\Router\Route::HTTP_METHOD_ANY,
* 'contact' * 'contact'
* ); * );
*/ */
return function (Application $app, MiddlewareFactory $factory, ContainerInterface $container) : void {
$app->get('/', App\Action\HomePageAction::class, 'home'); $app->get('/', App\Action\HomePageAction::class, 'home');
$app->get('/list', App\Action\PingAction::class, 'api.list'); $app->get('/list', App\Action\PingAction::class, 'api.list');
$app->post('/store/{direction:sent|received}/{hashKey}', App\Action\StoreAction::class, 'api.store'); $app->post('/store/{direction:sent|received}/{hashKey}', App\Action\StoreAction::class, 'api.store');
};

1
data/.gitignore vendored
View File

@ -1,2 +1,3 @@
*.db *.db
config-cache.php config-cache.php
logs

View File

@ -8,7 +8,7 @@ set('ssh_multiplexing', true);
set('repository', 'ssh://gogs@gogs.ragnarok.yvan.hu:2206/yvan/sms-store.git'); set('repository', 'ssh://gogs@gogs.ragnarok.yvan.hu:2206/yvan/sms-store.git');
set('shared_dirs', [ set('shared_dirs', [
// 'data/tmp', 'data/logs',
]); ]);
set('shared_files', [ set('shared_files', [
'config/autoload/local.php', 'config/autoload/local.php',

View File

@ -1,9 +1,9 @@
<?php <?php
declare(strict_types=1);
// Delegate static file requests back to the PHP built-in webserver // Delegate static file requests back to the PHP built-in webserver
if (php_sapi_name() === 'cli-server' if (PHP_SAPI === 'cli-server' && $_SERVER['SCRIPT_FILENAME'] !== __FILE__) {
&& is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))
) {
return false; return false;
} }
@ -13,17 +13,18 @@ require 'vendor/autoload.php';
/** /**
* Self-called anonymous function that creates its own scope and keep the global namespace clean. * Self-called anonymous function that creates its own scope and keep the global namespace clean.
*/ */
call_user_func(function () { (function () {
/** @var \Interop\Container\ContainerInterface $container */ /** @var \Psr\Container\ContainerInterface $container */
$container = require 'config/container.php'; $container = require 'config/container.php';
/** @var \Zend\Expressive\Application $app */ /** @var \Zend\Expressive\Application $app */
$app = $container->get(\Zend\Expressive\Application::class); $app = $container->get(\Zend\Expressive\Application::class);
$factory = $container->get(\Zend\Expressive\MiddlewareFactory::class);
// Import programmatic/declarative middleware pipeline and routing // Execute programmatic/declarative middleware pipeline and routing
// configuration statements // configuration statements
require 'config/pipeline.php'; (require 'config/pipeline.php')($app, $factory, $container);
require 'config/routes.php'; (require 'config/routes.php')($app, $factory, $container);
$app->run(); $app->run();
}); })();

View File

@ -2,17 +2,17 @@
namespace App\Action; namespace App\Action;
use Interop\Http\ServerMiddleware\DelegateInterface; use Psr\Http\Message\ResponseInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
use Zend\Json\Json; use Zend\Json\Json;
abstract class AbstractAction implements ServerMiddlewareInterface abstract class AbstractAction implements RequestHandlerInterface
{ {
const IDENTIFIER_NAME = 'id'; const IDENTIFIER_NAME = 'id';
public function process(ServerRequestInterface $request, DelegateInterface $delegate) public function handle(ServerRequestInterface $request): ResponseInterface
{ {
$requestMethod = strtoupper($request->getMethod()); $requestMethod = strtoupper($request->getMethod());
$id = $request->getAttribute(static::IDENTIFIER_NAME); $id = $request->getAttribute(static::IDENTIFIER_NAME);
@ -20,73 +20,71 @@ abstract class AbstractAction implements ServerMiddlewareInterface
switch ($requestMethod) { switch ($requestMethod) {
case 'GET': case 'GET':
return isset($id) return isset($id)
? $this->get($request, $delegate) ? $this->get($request)
: $this->getList($request, $delegate); : $this->getList($request);
case 'POST': case 'POST':
return $this->create($request, $delegate); return $this->create($request);
case 'PUT': case 'PUT':
return $this->update($request, $delegate); return $this->update($request);
case 'DELETE': case 'DELETE':
return isset($id) return isset($id)
? $this->delete($request, $delegate) ? $this->delete($request)
: $this->deleteList($request, $delegate); : $this->deleteList($request);
case 'HEAD': case 'HEAD':
return $this->head($request, $delegate); return $this->head($request);
case 'OPTIONS': case 'OPTIONS':
return $this->options($request, $delegate); return $this->options($request);
case 'PATCH': case 'PATCH':
return $this->patch($request, $delegate); return $this->patch($request);
default:
return $delegate->process($request);
} }
} }
public function get(ServerRequestInterface $request, DelegateInterface $delegate) public function get(ServerRequestInterface $request): ResponseInterface
{ {
return $this->createResponse(['content' => 'Method not allowed'], 405); return $this->createResponse(['content' => 'Method not allowed'], 405);
} }
public function getList(ServerRequestInterface $request, DelegateInterface $delegate) public function getList(ServerRequestInterface $request): ResponseInterface
{ {
return $this->createResponse(['content' => 'Method not allowed'], 405); return $this->createResponse(['content' => 'Method not allowed'], 405);
} }
public function create(ServerRequestInterface $request, DelegateInterface $delegate) public function create(ServerRequestInterface $request): ResponseInterface
{ {
return $this->createResponse(['content' => 'Method not allowed'], 405); return $this->createResponse(['content' => 'Method not allowed'], 405);
} }
public function update(ServerRequestInterface $request, DelegateInterface $delegate) public function update(ServerRequestInterface $request): ResponseInterface
{ {
return $this->createResponse(['content' => 'Method not allowed'], 405); return $this->createResponse(['content' => 'Method not allowed'], 405);
} }
public function delete(ServerRequestInterface $request, DelegateInterface $delegate) public function delete(ServerRequestInterface $request): ResponseInterface
{ {
return $this->createResponse(['content' => 'Method not allowed'], 405); return $this->createResponse(['content' => 'Method not allowed'], 405);
} }
public function deleteList(ServerRequestInterface $request, DelegateInterface $delegate) public function deleteList(ServerRequestInterface $request): ResponseInterface
{ {
return $this->createResponse(['content' => 'Method not allowed'], 405); return $this->createResponse(['content' => 'Method not allowed'], 405);
} }
public function head(ServerRequestInterface $request, DelegateInterface $delegate) public function head(ServerRequestInterface $request): ResponseInterface
{ {
return $this->createResponse(['content' => 'Method not allowed'], 405); return $this->createResponse(['content' => 'Method not allowed'], 405);
} }
public function options(ServerRequestInterface $request, DelegateInterface $delegate) public function options(ServerRequestInterface $request): ResponseInterface
{ {
return $this->createResponse(['content' => 'Method not allowed'], 405); return $this->createResponse(['content' => 'Method not allowed'], 405);
} }
public function patch(ServerRequestInterface $request, DelegateInterface $delegate) public function patch(ServerRequestInterface $request): ResponseInterface
{ {
return $this->createResponse(['content' => 'Method not allowed'], 405); return $this->createResponse(['content' => 'Method not allowed'], 405);
} }
final protected function createResponse($data, $status = 200) final protected function createResponse($data, $status = 200): ResponseInterface
{ {
return new JsonResponse($data, $status); return new JsonResponse($data, $status);
} }

View File

@ -3,12 +3,12 @@
namespace App\Action; namespace App\Action;
use App\Service\KoinService; use App\Service\KoinService;
use Interop\Http\ServerMiddleware\DelegateInterface; use Psr\Http\Message\ResponseInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response\TextResponse; use Zend\Diactoros\Response\TextResponse;
class HomePageAction implements ServerMiddlewareInterface class HomePageAction implements RequestHandlerInterface
{ {
private $tmp; private $tmp;
@ -17,7 +17,12 @@ class HomePageAction implements ServerMiddlewareInterface
$this->tmp = $tmp; $this->tmp = $tmp;
} }
public function process(ServerRequestInterface $request, DelegateInterface $delegate) /**
* Handle the request and return a response.
* @param ServerRequestInterface $request
* @return ResponseInterface
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{ {
return new TextResponse("Nuff"); return new TextResponse("Nuff");
} }

View File

@ -2,14 +2,14 @@
namespace App\Action; namespace App\Action;
use Interop\Http\ServerMiddleware\DelegateInterface; use Psr\Http\Message\ResponseInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
class PingAction implements ServerMiddlewareInterface class PingAction implements RequestHandlerInterface
{ {
public function process(ServerRequestInterface $request, DelegateInterface $delegate) public function handle(ServerRequestInterface $request): ResponseInterface
{ {
return new JsonResponse(['ack' => time()]); return new JsonResponse(['ack' => time()]);
} }

View File

@ -5,7 +5,7 @@ namespace App\Action;
use App\Entity\Sms; use App\Entity\Sms;
use App\Response\JsonCorsResponse; use App\Response\JsonCorsResponse;
use App\Service\SmsStoreService; use App\Service\SmsStoreService;
use Interop\Http\ServerMiddleware\DelegateInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
class StoreAction extends AbstractAction class StoreAction extends AbstractAction
@ -17,7 +17,7 @@ class StoreAction extends AbstractAction
$this->smsStore = $smsStore; $this->smsStore = $smsStore;
} }
public function create(ServerRequestInterface $request, DelegateInterface $delegate) public function create(ServerRequestInterface $request): ResponseInterface
{ {
$hashKey = $request->getAttribute('hashKey'); $hashKey = $request->getAttribute('hashKey');
$direction = $request->getAttribute('direction'); $direction = $request->getAttribute('direction');

View File

@ -2,10 +2,10 @@
namespace App\Middleware; namespace App\Middleware;
use Interop\Http\ServerMiddleware\DelegateInterface;
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface as ServerMiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class EventSubscriberMiddleware implements ServerMiddlewareInterface class EventSubscriberMiddleware implements ServerMiddlewareInterface
{ {
@ -13,12 +13,11 @@ class EventSubscriberMiddleware implements ServerMiddlewareInterface
* This actually does nothing, just wraps the next middleware in the pipe. * This actually does nothing, just wraps the next middleware in the pipe.
* *
* @param ServerRequestInterface $request * @param ServerRequestInterface $request
* @param DelegateInterface $delegate * @param RequestHandlerInterface $handler
*
* @return ResponseInterface * @return ResponseInterface
*/ */
public function process(ServerRequestInterface $request, DelegateInterface $delegate) public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{ {
return $delegate->process($request); return $handler->handle($request);
} }
} }

View File

@ -2,10 +2,12 @@
namespace App\Middleware; namespace App\Middleware;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface as ServerMiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
class PreFlightMiddleware class PreFlightMiddleware implements ServerMiddlewareInterface
{ {
const ALLOW_HEADERS = [ const ALLOW_HEADERS = [
'DNT', 'DNT',
@ -19,16 +21,24 @@ class PreFlightMiddleware
'Authorization', 'Authorization',
]; ];
public function __invoke(RequestInterface $request, ResponseInterface $response, callable $next) /**
* Set CORS headers the ugly way.
* @param ServerRequestInterface $request
* @param RequestHandlerInterface $handler
* @return ResponseInterface
* @todo replace with cors middleware tuupola?
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{ {
$requestMethod = strtoupper($request->getMethod()); $requestMethod = strtoupper($request->getMethod());
if ($requestMethod == 'OPTIONS') { if ($requestMethod == 'OPTIONS') {
return $response $response = $request
->withHeader('Accept', 'OPTIONS,GET,POST,PUT,PATCH,DELETE') ->withHeader('Accept', 'OPTIONS,GET,POST,PUT,PATCH,DELETE')
->withHeader('Access-Control-Allow-Origin', '*') ->withHeader('Access-Control-Allow-Origin', '*')
->withHeader('Access-Control-Allow-Methods', 'OPTIONS,GET,POST,PUT,PATCH,DELETE') ->withHeader('Access-Control-Allow-Methods', 'OPTIONS,GET,POST,PUT,PATCH,DELETE')
->withHeader('Access-Control-Allow-Headers', implode(",", self::ALLOW_HEADERS)); ->withHeader('Access-Control-Allow-Headers', implode(",", self::ALLOW_HEADERS));
return $handler->handle($response);
} }
return $next($request, $response); return $handler->handle($request);
} }
} }