diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,7 +1,19 @@
+2009.4.21
+------------
+
+### Feature
+
+* demo SimpleRoute middleware
+
+### Fix
+
+* env for kibro adapter
+* homepage in hack.cabal
+
 2009.4.20
 -----------
 
-## Feature
+### Feature
 
 * raw specification
 * shiny kibro hack handler
diff --git a/hack.cabal b/hack.cabal
--- a/hack.cabal
+++ b/hack.cabal
@@ -1,5 +1,5 @@
 Name:                 hack
-Version:              2009.4.20
+Version:              2009.4.21
 Build-type:           Simple
 Synopsis:             a sexy Haskell Webserver Interface
 Description:          a sexy Haskell Webserver Interface
@@ -10,12 +10,15 @@
 Build-Depends:        base
 Cabal-version:        >= 1.2
 category:             Web
-homepage:             http://www.haskell.org/haskellwiki/Panda
+homepage:             http://github.com/nfjinjing/hack/tree/master
 data-files:           readme.md, changelog.md
 
 library
   ghc-options: -Wall -fno-warn-missing-signatures -fno-warn-name-shadowing -fno-warn-orphans -fno-warn-type-defaults
-  build-depends: base, cgi, network, haskell98, old-locale, old-time, directory, filepath, containers, mps >= 2009.4.20, kibro >= 0.4.3, data-default >= 0.2
+  build-depends: base, cgi, network, haskell98, old-locale, old-time, directory, filepath, containers, mps >= 2009.4.21, kibro >= 0.4.3, data-default >= 0.2
   hs-source-dirs: src/
   exposed-modules:  
-                    Hack, Hack.Handler.Kibro
+                    Hack
+                    Hack.Handler.Kibro
+                    Hack.SimpleRoute
+                    Hack.Utils
diff --git a/readme.md b/readme.md
--- a/readme.md
+++ b/readme.md
@@ -41,12 +41,12 @@
 
     kibro new hello-world
 
-### Test if Kibro works
+#### Test if Kibro works
 
     cd hello-world
     kibro start
 
-### Create our hack app
+#### Create our hack app
 
 put the following code in `src/Main.hs`
 
@@ -68,3 +68,28 @@
 restart kibro
 
     kibro restart
+
+### demo usage of middle-ware
+
+    import Hack.SimpleRoute
+    import Hack.Utils
+    
+    hello :: Application
+    hello = \env -> def {body = env.show} .return
+
+    app :: Application
+    app = route [("/hello", hello), ("", hello)] empty_app
+
+    main = run app
+
+### make a middle-ware
+
+inside Hack.hs:
+
+    type MiddleWare = Application -> Application
+
+since Haskell has curry, middle-ware api can be of type
+
+    Params -> Application -> Application
+
+just pass an applied middle-ware into a chain.
diff --git a/src/Hack.hs b/src/Hack.hs
--- a/src/Hack.hs
+++ b/src/Hack.hs
@@ -26,7 +26,7 @@
   server_port :: Int,
   http_ :: Map,
   hack_version :: [Int],
-  hack_url_scheme :: String,
+  hack_url_scheme :: Hack_UrlScheme,
   hack_input :: String,
   hack_errors :: String,
   hack_multithread :: String,
@@ -60,6 +60,4 @@
 
 type Application = Env -> IO Response
 
-type MiddleWareParams = Map
-
-type MiddleWare = MiddleWareParams -> Application -> Application
+type MiddleWare = Application -> Application
diff --git a/src/Hack/Handler/Kibro.hs b/src/Hack/Handler/Kibro.hs
--- a/src/Hack/Handler/Kibro.hs
+++ b/src/Hack/Handler/Kibro.hs
@@ -5,27 +5,33 @@
 import Hack
 import Kibro
 import Network.CGI hiding (Html)
+import Network.URI
 import Data.Default
-import Prelude hiding ((.))
+import Prelude hiding ((.), (^))
 import MPS
 
 get_env = do
+  uri <- requestURI
   request_method' <- requestMethod
-  script_name' <- scriptName
-  path_info' <- pathInfo
-  query_string' <- queryString
+  let script_name' = ""
+  let path_info' = uri.uriPath
+  let query_string' = uri.uriQuery
   server_name' <- serverName
   server_port' <- serverPort
+  hack_input' <- getBody
   
-  def {
-    request_method = request_method'.read,
-    script_name = script_name',
-    path_info = path_info',
-    query_string = query_string',
-    server_name = server_name',
-    server_port = server_port'
+  def 
+    {  request_method = request_method'.read
+    ,  script_name = script_name'
+    ,  path_info = path_info'
+    ,  query_string = query_string'.remove_question_mark
+    ,  server_name = server_name'
+    ,  server_port = server_port'
+    ,  hack_input = hack_input'
     }
     .return
+  where 
+    remove_question_mark = dropWhile (is '?')
 
 handle app = do
   env <- get_env
diff --git a/src/Hack/SimpleRoute.hs b/src/Hack/SimpleRoute.hs
new file mode 100644
--- /dev/null
+++ b/src/Hack/SimpleRoute.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE NoMonomorphismRestriction#-}
+{-# LANGUAGE QuasiQuotes #-}
+
+module Hack.SimpleRoute where
+
+import Hack
+import Hack.Utils
+import List (find)
+import Prelude hiding ((.), (^), (>))
+import MPS
+
+type RoutePath = (String, Application)
+
+route :: [RoutePath] -> Application -> Application
+route h _ = \env ->
+  let path = env.path_info
+      script = env.script_name
+      mod_env location = env 
+        { script_name = script ++ location
+        , path_info = path.drop (location.length)
+        }
+  in
+  case h.find (fst > flip starts_with path) of
+    Nothing -> not_found [$here|Not Found: #{path}|]
+    Just (location, app) -> app (mod_env location)
diff --git a/src/Hack/Utils.hs b/src/Hack/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/Hack/Utils.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE NoMonomorphismRestriction#-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE QuasiQuotes #-}
+
+module Hack.Utils where
+
+import Hack
+import Network.CGI hiding (Html)
+import Network.URI
+import Data.Default
+import Prelude hiding ((.), (^), (>))
+import MPS
+import Control.Arrow ((>>>))
+
+(>) = (>>>)
+infixl 8 >
+  
+not_found x = return $ Response
+  { status = 404
+  , headers = [("Content-Type", "text/plain")]
+  , body = x
+  }
+
+empty_app :: Application
+empty_app = return def
