X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FResource%2FTree.hs;h=be51282c910ad11c78754190b7f96b35563a7d9a;hb=34b0ad7f2ffc5e7ca67fa3468d01c5551edc8a8b;hp=28a94a4791d08235a1ff98abe2e8adf91a78c8eb;hpb=a44a96d95b5fcbaf24a21c0336046ce0c3bab614;p=Lucu.git diff --git a/Network/HTTP/Lucu/Resource/Tree.hs b/Network/HTTP/Lucu/Resource/Tree.hs index 28a94a4..be51282 100644 --- a/Network/HTTP/Lucu/Resource/Tree.hs +++ b/Network/HTTP/Lucu/Resource/Tree.hs @@ -1,10 +1,9 @@ module Network.HTTP.Lucu.Resource.Tree ( ResourceDef(..) - , Resource , ResTree , mkResTree -- [ ([String], ResourceDef) ] -> ResTree - , findResource -- ResTree -> URI -> Maybe ResourceDef + , findResource -- ResTree -> URI -> Maybe ([String], ResourceDef) , runResource -- ResourceDef -> Interaction -> IO ThreadId ) where @@ -20,6 +19,7 @@ import Data.Map (Map) import Data.Maybe import Network.HTTP.Lucu.Abortion import Network.HTTP.Lucu.Config +import Network.HTTP.Lucu.MIMEType import Network.HTTP.Lucu.Request import Network.HTTP.Lucu.Resource import Network.HTTP.Lucu.Response @@ -31,10 +31,10 @@ import System.IO.Error hiding (catch) import Prelude hiding (catch) -{- /aaa/bbb/ccc にアクセスされた時、もし /aaa/bbb に貪欲なリソースがあ - れば、假に /aaa/bbb/ccc に何らかのリソースがあったとしても必ず - /aaa/bbb が撰ばれる。/aaa/bbb のリソースが貪欲でなければ、それは無視 - される。 -} +-- "/aaa/bbb/ccc" にアクセスされた時、もし "/aaa/bbb" に貪欲なリソース +-- があれば、假に "/aaa/bbb/ccc" に何らかのリソースがあったとしても必ず +-- "/aaa/bbb" が撰ばれる。"/aaa/bbb" のリソースが貪欲でなければ、それは +-- 無視される。 data ResourceDef = ResourceDef { resUsesNativeThread :: Bool , resIsGreedy :: Bool @@ -58,10 +58,10 @@ mkResTree list = processRoot list children = processNonRoot nonRoots in if null roots then - -- / にリソースが定義されない。/foo とかにはあるかも。 + -- "/" にリソースが定義されない。"/foo" とかにはあるかも。 ResNode Nothing children else - -- / がある。 + -- "/" がある。 let (_, def) = last roots in ResNode (Just def) children @@ -86,30 +86,33 @@ mkResTree list = processRoot list subtree -findResource :: ResTree -> URI -> Maybe ResourceDef +findResource :: ResTree -> URI -> Maybe ([String], ResourceDef) findResource (ResNode rootDefM subtree) uri = let pathStr = uriPath uri path = [x | x <- splitBy (== '/') pathStr, x /= ""] in if null path then - rootDefM + do def <- rootDefM + return (path, def) else - walkTree subtree path + walkTree subtree path [] where - walkTree :: ResSubtree -> [String] -> Maybe ResourceDef + walkTree :: ResSubtree -> [String] -> [String] -> Maybe ([String], ResourceDef) - walkTree subtree (name:[]) + walkTree subtree (name:[]) soFar = case M.lookup name subtree of Nothing -> Nothing - Just (ResNode defM _) -> defM + Just (ResNode defM _) -> do def <- defM + return (soFar ++ [name], def) - walkTree subtree (x:xs) + walkTree subtree (x:xs) soFar = case M.lookup x subtree of Nothing -> Nothing Just (ResNode defM children) -> case defM of Just (ResourceDef { resIsGreedy = True }) - -> defM - _ -> walkTree children xs + -> do def <- defM + return (soFar ++ [x], def) + _ -> walkTree children xs (soFar ++ [x]) runResource :: ResourceDef -> Interaction -> IO ThreadId @@ -170,15 +173,14 @@ runResource def itr -- を應答に反映させる餘地がある。さうでなければ stderr -- にでも吐くしか無い。 state <- atomically $ readItr itr itrState id - resM <- atomically $ readItr itr itrResponse id + res <- atomically $ readItr itr itrResponse id if state <= DecidingHeader then flip runReaderT itr $ do setStatus $ aboStatus abo -- FIXME: 同じ名前で複數の値があった時は、こ -- れではまずいと思ふ。 mapM_ (\ (name, value) -> setHeader name value) $ aboHeaders abo - setHeader "Content-Type" "application/xhtml+xml" - output $ abortPage conf reqM resM abo + output $ abortPage conf reqM res abo else hPutStrLn stderr $ show abo