base64-bytestring == 0.1.*,
blaze-builder == 0.3.*,
bytestring == 0.9.*,
+ case-insensitive == 0.3.*,
containers == 0.4.*,
containers-unicode-symbols == 0.3.*,
directory == 1.1.*,
Network.HTTP.Lucu.Parser
Network.HTTP.Lucu.Request
Network.HTTP.Lucu.Resource
+ Network.HTTP.Lucu.Resource.Dispatcher
Network.HTTP.Lucu.Resource.Tree
Network.HTTP.Lucu.Response
Network.HTTP.Lucu.SocketLike
)
where
import Data.Ascii (Ascii)
+import Data.CaseInsensitive (CI)
+import qualified Data.CaseInsensitive as CI
import Data.Text (Text)
import qualified Data.Text as T
import Network
-- |The host name of the server. This value will be used in
-- built-in pages like \"404 Not Found\".
- , cnfServerHost ∷ !Text
+ , cnfServerHost ∷ !(CI Text)
-- |A port number (or a service name) to listen to HTTP clients.
, cnfServerPort ∷ !ServiceName
defaultConfig ∷ Config
defaultConfig = Config {
cnfServerSoftware = "Lucu/1.0"
- , cnfServerHost = T.pack (unsafePerformIO getHostName)
+ , cnfServerHost = CI.mk $ T.pack $ unsafePerformIO getHostName
, cnfServerPort = "http"
, cnfServerV4Addr = Just "0.0.0.0"
, cnfServerV6Addr = Just "::"
import Control.Arrow.Unicode
import Data.Ascii (Ascii)
import qualified Data.Ascii as A
+import qualified Data.CaseInsensitive as CI
import Data.Maybe
import qualified Data.Text as T
import Network.HTTP.Lucu.Config
= let sStr = A.toString $ A.fromAsciiBuilder $ printStatusCode status
sig = concat [ A.toString (cnfServerSoftware conf)
, " at "
- , T.unpack (cnfServerHost conf)
+ , T.unpack $ CI.original $ cnfServerHost conf
]
in ( eelem "/"
+= ( eelem "html"
import Data.Ascii (Ascii)
import qualified Data.Ascii as A
import qualified Data.ByteString.Char8 as C8
+import Data.CaseInsensitive (CI)
+import qualified Data.CaseInsensitive as CI
import Data.Maybe
import Data.Text (Text)
import qualified Data.Text as T
| Chunked
deriving (Eq, Show)
-preprocess ∷ Text → PortNumber → Request → AugmentedRequest
+preprocess ∷ CI Text → PortNumber → Request → AugmentedRequest
preprocess localHost localPort req@(Request {..})
= execState go initialAR
where
DELETE → return ()
_ → setStatus NotImplemented
-examineAuthority ∷ Text → PortNumber → State AugmentedRequest ()
+examineAuthority ∷ CI Text → PortNumber → State AugmentedRequest ()
examineAuthority localHost localPort
= do req ← gets arRequest
when (isNothing $ uriAuthority $ reqURI req) $
-- Should never reach here...
ver → fail ("internal error: unknown version: " ⧺ show ver)
-parseHost ∷ Ascii → (Text, Ascii)
+parseHost ∷ Ascii → (CI Text, Ascii)
parseHost hp
= let (h, p) = C8.break (≡ ':') $ A.toByteString hp
-- FIXME: should decode punycode here.
- hText = T.decodeUtf8 h
+ hText = CI.mk $ T.decodeUtf8 h
pAscii = A.unsafeFromByteString p
in
(hText, pAscii)
-updateAuthority ∷ Text → Ascii → Request → Request
+updateAuthority ∷ CI Text → Ascii → Request → Request
updateAuthority host port req
= let uri = reqURI req
uri' = uri {
uriAuthority = Just URIAuth {
uriUserInfo = ""
- , uriRegName = T.unpack host
+ , uriRegName = T.unpack $ CI.original host
, uriPort = A.toString port
}
}
--- /dev/null
+{-# LANGUAGE
+ ExistentialQuantification
+ , FlexibleInstances
+ , UnicodeSyntax
+ #-}
+-- |FIXME: doc
+module Network.HTTP.Lucu.Resource.Dispatcher
+ ( Dispatchable(..)
+ , Dispatcher
+ )
+ where
+import Control.Applicative
+import Data.ByteString (ByteString)
+import Data.CaseInsensitive (CI)
+import Data.Monoid
+import Data.Text (Text)
+import Network.HTTP.Lucu.Resource.Internal
+import Prelude.Unicode
+
+-- |FIXME: docs
+class Dispatchable α where
+ findResource ∷ α
+ → CI Text
+ → [ByteString]
+ → IO (Maybe ([ByteString], ResourceDef))
+
+ dispatcher ∷ α → Dispatcher
+ {-# INLINE dispatcher #-}
+ dispatcher = Dispatcher
+
+-- |FIXME: doc
+data Dispatcher = ∀α. Dispatchable α ⇒ Dispatcher α
+
+instance Dispatchable Dispatcher where
+ findResource (Dispatcher α) = findResource α
+ dispatcher = id
+
+-- |FIXME: doc
+instance Monoid Dispatcher where
+ {-# INLINE mempty #-}
+ mempty = dispatcher f
+ where
+ f ∷ CI Text → [ByteString] → IO (Maybe ([ByteString], ResourceDef))
+ f _ _ = return Nothing
+
+ {-# INLINEABLE mappend #-}
+ mappend (Dispatcher α) (Dispatcher β)
+ = dispatcher
+ $ \host path → do r ← findResource α host path
+ case r of
+ Just _ → return r
+ Nothing → findResource β host path
+
+instance Dispatchable (CI Text
+ → [ByteString]
+ → IO (Maybe ([ByteString], ResourceDef))) where
+ findResource = id
+
+instance Dispatchable (CI Text
+ → [ByteString]
+ → Maybe ([ByteString], ResourceDef)) where
+ findResource = ((return ∘) ∘)
+
+instance Dispatchable (CI Text
+ → [ByteString]
+ → IO (Maybe ResourceDef)) where
+ findResource = ((((<$>) ∘ (<$>)) ((,) []) ∘) ∘)
+
+instance Dispatchable (CI Text
+ → [ByteString]
+ → Maybe ResourceDef) where
+ findResource = (((return ∘ ((,) [] <$>)) ∘) ∘)
+
+instance Dispatchable ([ByteString]
+ → IO (Maybe ([ByteString], ResourceDef))) where
+ findResource = const
+
+instance Dispatchable ([ByteString]
+ → Maybe ([ByteString], ResourceDef)) where
+ findResource = const ∘ (return ∘)
+
+instance Dispatchable ([ByteString]
+ → IO (Maybe ResourceDef)) where
+ findResource = const ∘ (((<$>) ∘ (<$>)) ((,) []) ∘)
+
+instance Dispatchable ([ByteString]
+ → Maybe ResourceDef) where
+ findResource = const ∘ ((return ∘ ((,) [] <$>)) ∘)
+
+instance Dispatchable (IO (Maybe ([ByteString], ResourceDef))) where
+ findResource = const ∘ const
+
+instance Dispatchable ([ByteString], ResourceDef) where
+ findResource = const ∘ const ∘ return ∘ Just
+
+instance Dispatchable (IO (Maybe ResourceDef)) where
+ findResource = const ∘ const ∘ ((<$>) ∘ (<$>)) ((,) [])
+
+instance Dispatchable ResourceDef where
+ findResource = const ∘ const ∘ return ∘ Just ∘ (,) []
component: Lucu
release: Lucu-1.0
reporter: PHO <pho@cielonegro.org>
-status: :unstarted
+status: :in_progress
disposition:
creation_time: 2011-10-17 02:46:21.854704 Z
references: []
- PHO <pho@cielonegro.org>
- commented
- FallbackHandler should be either a non-pure function (MonadIO) or a pure function returning Maybe ResourceDef.
+- - 2011-11-14 02:29:03.053128 Z
+ - PHO <pho@cielonegro.org>
+ - changed status from unstarted to in_progress
+ - ""
git_branch: