packages feed

hack 2009.4.21 → 2009.4.22

raw patch · 10 files changed

+166/−77 lines, 10 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Hack: instance Default Bool
- Hack.SimpleRoute: route :: [RoutePath] -> Application -> Application
- Hack.SimpleRoute: type RoutePath = (String, Application)
+ Hack.Contrib.ContentType: content_type :: String -> MiddleWare
+ Hack.Contrib.RawRouter: route :: [RoutePath] -> MiddleWare
+ Hack.Contrib.RawRouter: type RoutePath = (String, Application)
+ Hack.Contrib.SimpleRouter: route :: [RoutePath] -> MiddleWare
+ Hack.Contrib.SimpleRouter: type RoutePath = (String, Application)
+ Hack.Handler.Kibro: run :: Application -> IO ()
+ Hack.Utils: not_found :: String -> IO Response
+ Hack.Utils: not_found_app :: Application
+ Hack.Utils: use :: [MiddleWare] -> MiddleWare
- Hack: Env :: RequestMethod -> String -> String -> String -> String -> Int -> Map -> [Int] -> Hack_UrlScheme -> String -> String -> String -> String -> String -> Map -> Env
+ Hack: Env :: RequestMethod -> String -> String -> String -> String -> Int -> Map -> [Int] -> Hack_UrlScheme -> String -> String -> Bool -> Bool -> Bool -> Map -> Env
- Hack: hack_multiprocess :: Env -> String
+ Hack: hack_multiprocess :: Env -> Bool
- Hack: hack_multithread :: Env -> String
+ Hack: hack_multithread :: Env -> Bool
- Hack: hack_run_once :: Env -> String
+ Hack: hack_run_once :: Env -> Bool

Files

changelog.md view
@@ -1,3 +1,10 @@+2009.4.22+---------++### Feature++* more middleware: RawRouter, ContentType+ 2009.4.21 ------------ 
hack.cabal view
@@ -1,5 +1,5 @@ Name:                 hack-Version:              2009.4.21+Version:              2009.4.22 Build-type:           Simple Synopsis:             a sexy Haskell Webserver Interface Description:          a sexy Haskell Webserver Interface@@ -20,5 +20,7 @@   exposed-modules:                       Hack                     Hack.Handler.Kibro-                    Hack.SimpleRoute+                    Hack.Contrib.SimpleRouter+                    Hack.Contrib.RawRouter+                    Hack.Contrib.ContentType                     Hack.Utils
readme.md view
@@ -1,8 +1,8 @@ ## Hack: a sexy Haskell Webserver Interface -Hack is a lazy port of [Rack](http://rack.rubyforge.org/): the ruby webserver interface.+Hack is a brain-dead port of the brilliant Ruby [Rack](http://rack.rubyforge.org/) webserver interface. -### What does a hack app look like+### What does a Hack app look like      module Main where @@ -71,8 +71,16 @@  ### demo usage of middle-ware -    import Hack.SimpleRoute+    module Main where++    import Hack     import Hack.Utils+    import Hack.SimpleRoute+    import Hack.Handler.Kibro++    import Data.Default+    import MPS+    import Prelude hiding ((.))          hello :: Application     hello = \env -> def {body = env.show} .return@@ -93,3 +101,31 @@     Params -> Application -> Application  just pass an applied middle-ware into a chain.++finally the source code of SimpleRoute.hs:++    {-# 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)
src/Hack.hs view
@@ -2,44 +2,44 @@  import Data.Default -data RequestMethod = -    OPTIONS-  | GET-  | HEAD-  | POST-  | PUT-  | DELETE-  | TRACE-  | CONNECT+data RequestMethod =+     OPTIONS+  |  GET+  |  HEAD+  |  POST+  |  PUT+  |  DELETE+  |  TRACE+  |  CONNECT   deriving (Show, Read, Eq)  data Hack_UrlScheme = HTTP | HTTPS deriving (Show, Eq)  type Map = [(String, String)] -data Env = Env {-  request_method :: RequestMethod,-  script_name :: String,-  path_info :: String,-  query_string :: String,-  server_name :: String,-  server_port :: Int,-  http_ :: Map,-  hack_version :: [Int],-  hack_url_scheme :: Hack_UrlScheme,-  hack_input :: String,-  hack_errors :: String,-  hack_multithread :: String,-  hack_multiprocess :: String,-  hack_run_once :: String,-  custom :: Map+data Env = Env +  {  request_method :: RequestMethod+  ,  script_name :: String+  ,  path_info :: String+  ,  query_string :: String+  ,  server_name :: String+  ,  server_port :: Int+  ,  http_ :: Map+  ,  hack_version :: [Int]+  ,  hack_url_scheme :: Hack_UrlScheme+  ,  hack_input :: String+  ,  hack_errors :: String+  ,  hack_multithread :: Bool+  ,  hack_multiprocess :: Bool+  ,  hack_run_once :: Bool+  ,  custom :: Map   }   deriving (Show) -data Response = Response {-  status :: Int,-  headers :: Map,-  body :: String+data Response = Response +  {  status :: Int+  ,  headers :: Map+  ,  body :: String   }   deriving (Show) @@ -49,14 +49,11 @@ instance Default Hack_UrlScheme where   def = HTTP -instance Default Bool where-  def = False- instance Default Response where   def = Response def def def  instance Default Env where-  def = Env def def def def def def def def def def def def def def def+  def = Env def def def def def def def def def def def False False False def  type Application = Env -> IO Response 
+ src/Hack/Contrib/ContentType.hs view
@@ -0,0 +1,19 @@+module Hack.Contrib.ContentType where++import Hack+import Hack.Utils+import Prelude hiding ((.), (^), (>))+import MPS++content_type :: String -> MiddleWare+content_type s app = \env -> do+  response <- app env+  case response.headers+        .filter (fst > is "Content-Type")+        .reject (snd > empty) of++    [] -> response +      { headers = response.headers ++ [("Content-Type", s)] }+      .return++    otherwise -> response .return
+ src/Hack/Contrib/RawRouter.hs view
@@ -0,0 +1,18 @@+module Hack.Contrib.RawRouter where++import Hack+import Hack.Utils+import List (find)+import Prelude hiding ((.), (^), (>))+import MPS+import Data.Maybe (isJust)++type RoutePath = (String, Application)++route :: [RoutePath] -> MiddleWare+route h app = \env ->+  let path = env.path_info+  in+  case h.find (fst > flip match path > isJust) of+    Nothing -> app env+    Just (_, found_app) -> found_app env
+ src/Hack/Contrib/SimpleRouter.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE NoMonomorphismRestriction#-}+{-# LANGUAGE QuasiQuotes #-}++module Hack.Contrib.SimpleRouter where++import Hack+import Hack.Utils+import List (find)+import Prelude hiding ((.), (^), (>))+import MPS++type RoutePath = (String, Application)++route :: [RoutePath] -> MiddleWare+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)
src/Hack/Handler/Kibro.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE NoMonomorphismRestriction#-} -module Hack.Handler.Kibro where+module Hack.Handler.Kibro (run) where  import Hack import Kibro@@ -22,12 +22,12 @@      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'+    ,  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 @@ -42,4 +42,5 @@   response.status.show.setHeader "Status"   response.body.output +run :: Application -> IO () run app = startKibro [("", handle app)]
− src/Hack/SimpleRoute.hs
@@ -1,25 +0,0 @@-{-# 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)
src/Hack/Utils.hs view
@@ -1,6 +1,6 @@-{-# LANGUAGE NoMonomorphismRestriction#-}-{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE QuasiQuotes #-}+{-# LANGUAGE TypeSynonymInstances #-}  module Hack.Utils where @@ -8,18 +8,27 @@ import Network.CGI hiding (Html) import Network.URI import Data.Default+import Data.Monoid import Prelude hiding ((.), (^), (>)) import MPS-import Control.Arrow ((>>>))+import Control.Arrow ((>>>), (<<<))  (>) = (>>>) infixl 8 >-  ++not_found :: String -> IO Response   not_found x = return $ Response-  { status = 404-  , headers = [("Content-Type", "text/plain")]-  , body = x+  {  status  = 404+  ,  headers = [("Content-Type", "text/plain")]+  ,  body    = x   }  empty_app :: Application empty_app = return def++-- usage: app.use [content_type, cache]+use :: [MiddleWare] -> MiddleWare+use = reduce (<<<)++not_found_app :: Application+not_found_app = \env -> not_found [$here|Not Found: #{env.path_info}|]