]> git.andy128k.dev Git - ipf.git/commitdiff
move error handling and url dispatching to middlewares
authorAndrey Kutejko <andy128k@gmail.com>
Sun, 21 Dec 2014 23:25:49 +0000 (01:25 +0200)
committerAndrey Kutejko <andy128k@gmail.com>
Sun, 21 Dec 2014 23:38:51 +0000 (01:38 +0200)
ipf/auth/middleware.php
ipf/middleware/base.php [new file with mode: 0644]
ipf/middleware/common.php
ipf/middleware/dispatch.php [new file with mode: 0644]
ipf/middleware/error.php [new file with mode: 0644]
ipf/middleware/serve_static.php
ipf/project.php
ipf/router.php
ipf/session/middleware.php

index c50d5c2b209504139976fbaea748f12b3e53e7be..203642c3bdce24b01f5f79a08739134f80921783 100644 (file)
@@ -2,7 +2,7 @@
 
 namespace IPF\Auth;
 
-class Middleware
+class Middleware extends \IPF_Middleware
 {
     const SessionKey = 'IPF_User_auth';
 
diff --git a/ipf/middleware/base.php b/ipf/middleware/base.php
new file mode 100644 (file)
index 0000000..39731a7
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+class IPF_Middleware
+{
+    protected $next, $settings;
+
+    function __construct($next, $settings)
+    {
+        $this->next = $next;
+        $this->settings = $settings;
+    }
+
+    function processRequest($request)
+    {
+        return false;
+    }
+
+    function processResponse($request, $response)
+    {
+        return $response;
+    }
+
+    function call($request)
+    {
+        $response = $this->processRequest($request);
+        if ($response !== false) {
+            return $response;
+        }
+
+        if ($this->next) {
+            $response = $this->next->call($request);
+        }
+
+        return $this->processResponse($request, $response);
+    }
+}
+
index 1b16bea1b7e123df488553fb414ee3fb9f259295..e61d1d1ab4d8a2d96b420791f08dc53d90f12969 100644 (file)
@@ -1,13 +1,14 @@
 <?php
 
-class IPF_Middleware_Common
+class IPF_Middleware_Common extends IPF_Middleware
 {
     function processRequest($request)
     {
-        if (IPF::get('append_slash', true)) {
+        if ($this->settings->get('append_slash', true)) {
             $url = $request->absoluteUrl();
-            if (substr($url, -1) !== '/')
+            if (substr($url, -1) !== '/') {
                 return new IPF_HTTP_Response_Redirect($url.'/');
+            }
         }
         return false;
     }
diff --git a/ipf/middleware/dispatch.php b/ipf/middleware/dispatch.php
new file mode 100644 (file)
index 0000000..b63bd2c
--- /dev/null
@@ -0,0 +1,24 @@
+<?php
+
+class IPF_Dispatch_Middleware extends IPF_Middleware
+{
+    function processRequest($request)
+    {
+        $router = \IPF_Project::getInstance()->router;
+
+        $m = $router->match($request);
+        if (!$m) {
+            return new IPF_HTTP_Response_NotFound($request);
+        }
+
+        list($route, $match) = $m;
+        $request->params = $match;
+
+        try {
+            return IPF::callFunction($route->func, array($request, $match));
+        } catch (IPF_Router_Shortcut $e) {
+            return $e->response($request);
+        }
+    }
+}
+
diff --git a/ipf/middleware/error.php b/ipf/middleware/error.php
new file mode 100644 (file)
index 0000000..b69dca5
--- /dev/null
@@ -0,0 +1,27 @@
+<?php
+
+class IPF_Error_Middleware extends IPF_Middleware
+{
+    function call($request)
+    {
+        try {
+            $response = null;
+            if ($this->next) {
+                $response = $this->next->call($request);
+            }
+
+            if (!($response instanceof IPF_HTTP_Response)) {
+                throw new \Exception('Response in not a IPF_HTTP_Response');
+            }
+
+            return $response;
+        } catch (\Exception $exception) {
+            error_log($exception);
+            if ($this->settings->get('debug'))
+                return new IPF_HTTP_Response_ServerErrorDebug($request, $exception);
+            else
+                return new IPF_HTTP_Response_ServerError($request, $exception);
+        }
+    }
+}
+
index 916ec8a8baa230ca6e9cb6b14d8c8e8e079ad3fc..7e32002212ebcc332739b1a538f0a61a47a7e4c4 100644 (file)
@@ -1,10 +1,10 @@
 <?php
 
-class IPF_Serve_Static_Middleware
+class IPF_Serve_Static_Middleware extends IPF_Middleware
 {
     function processRequest($request)
     {
-        $staticUrl = IPF::get('static_url');
+        $staticUrl = $this->settings->get('static_url');
 
         if (!preg_match('#^'.preg_quote($staticUrl).'(.*)$#', $request->query, $matches))
             return false;
index 9bf307ddf4520c1c3929a319a027e95ef2199d55..1d678922cf393ed5e4263476184f3845972f5cdd 100644 (file)
@@ -34,6 +34,19 @@ final class IPF_Project
         return $this->apps;
     }
 
+    private function chainMiddlewares()
+    {
+        $middlewares = IPF::get('middlewares', array());
+        array_unshift($middlewares, 'IPF_Error_Middleware');
+        array_push($middlewares, 'IPF_Dispatch_Middleware');
+
+        $m = null;
+        foreach (array_reverse($middlewares) as $mw) {
+            $m = new $mw($m, IPF::$settings);
+        }
+        return $m;
+    }
+
     public function run()
     {
         \PFF\Container::setFactory('databaseConnection', array('IPF_Database', 'connect'));
@@ -51,7 +64,10 @@ final class IPF_Project
             $cli->run();
         } else {
             $this->request = new IPF_HTTP_Request;
-            $this->router->dispatch($this->request);
+
+            $response = $this->chainMiddlewares()->call($this->request);
+            $response->render($this->request->method !== 'HEAD');
+
             $this->request = null;
         }
 
index f644271480e8f057a4b2c1e3467b9eaa0275e02f..99be41ba3a254919683cfbe5e8d290e61ebd1082 100644 (file)
@@ -24,82 +24,15 @@ class IPF_Router
         }
     }
 
-    public static function response500($request, $exception)
-    {
-        error_log($exception);
-        if (IPF::get('debug'))
-            return new IPF_HTTP_Response_ServerErrorDebug($request, $exception);
-        else
-            return new IPF_HTTP_Response_ServerError($request, $exception);
-    }
-
-    public function dispatch($req)
-    {
-        try {
-            $middleware = array();
-            foreach (IPF::get('middlewares', array()) as $mw) {
-                $middleware[] = new $mw();
-            }
-            $skip = false;
-            foreach ($middleware as $mw) {
-                if (method_exists($mw, 'processRequest')) {
-                    $response = $mw->processRequest($req);
-                    if ($response !== false) {
-                        // $response is a response
-                        $response->render($req->method != 'HEAD' and !defined('IN_UNIT_TESTS'));
-                        $skip = true;
-                        break;
-                    }    
-                }
-            }
-            if ($skip === false) {   
-                $response = $this->match($req);
-                if (!empty($req->response_vary_on)) {
-                    $response->headers['Vary'] = $req->response_vary_on;
-                }
-                $middleware = array_reverse($middleware);
-                foreach ($middleware as $mw) {
-                    if (method_exists($mw, 'processResponse')) {
-                        $response = $mw->processResponse($req, $response);
-                    }    
-                }
-                //var_dump($response);
-                $response->render($req->method != 'HEAD');
-            }
-            return array($req, $response);
-        } catch (IPF_Exception $e) {
-            $response = self::response500($req, $e);
-            $response->render();
-        }
-    }
-
     public function match($req)
     {
-        $func = null;
         foreach ($this->routes as $route) {
             $match = array();
             if ($route->matcher()->match($req->query, $match)) {
-                $func = $route->func;
-                $req->params = $match;
-                break;
+                return array($route, $match);
             }
         }
-
-        if ($func) {
-            try {
-                $r = IPF::callFunction($func, array($req, $match));
-                if (!is_a($r, 'IPF_HTTP_Response')) {
-                    return self::response500($req, new IPF_Exception('function '.$func.'() must return IPF_HTTP_Response instance'));
-                }
-                return $r;
-            } catch (IPF_Router_Shortcut $e) {
-                return $e->response($req);
-            } catch (IPF_Exception $e) {
-                return self::response500($req, $e);
-            }
-        }
-
-        return new IPF_HTTP_Response_NotFound($req);
+        return null;
     }
 
     public function describe()
index 8c5497bc9315760bff87a1a380ebf0a84e94bf15..5048976225bae0d9ee8e5fec2ea96f9df9759242 100644 (file)
@@ -1,10 +1,10 @@
 <?php
 
-class IPF_Session_Middleware
+class IPF_Session_Middleware extends IPF_Middleware
 {
-    function processRequest(&$request)
+    function processRequest($request)
     {
-        $session_cookie = \PFF\Arr::get($request->COOKIE, IPF::get('session_cookie_id'));
+        $session_cookie = \PFF\Arr::get($request->COOKIE, $this->settings->get('session_cookie_id'));
 
         $request->session = Session::get($session_cookie);
         if (!$request->session)
@@ -16,7 +16,7 @@ class IPF_Session_Middleware
     function processResponse($request, $response)
     {
         $session_cookie = $request->session->cookie();
-        $response->cookies[IPF::get('session_cookie_id')] = $session_cookie;
+        $response->cookies[$this->settings->get('session_cookie_id')] = $session_cookie;
         return $response;
     }
 }