1 module Network.HTTP.Lucu.DefaultPage
9 import Control.Arrow.ArrowList
10 import Control.Concurrent.STM
12 import qualified Data.ByteString.Char8 as C8
13 import qualified Data.ByteString.Lazy.Char8 as L8
16 import Network.HTTP.Lucu.Config
17 import Network.HTTP.Lucu.Format
18 import Network.HTTP.Lucu.Headers
19 import Network.HTTP.Lucu.Interaction
20 import Network.HTTP.Lucu.Request
21 import Network.HTTP.Lucu.Response
22 import Network.URI hiding (path)
23 import System.IO.Unsafe
24 import Text.XML.HXT.Arrow.WriteDocument
25 import Text.XML.HXT.Arrow.XmlArrow
26 import Text.XML.HXT.Arrow.XmlIOStateArrow
27 import Text.XML.HXT.DOM.TypeDefs
28 import Text.XML.HXT.DOM.XmlKeywords
31 getDefaultPage :: Config -> Maybe Request -> Response -> String
32 getDefaultPage !conf !req !res
33 = let msgA = getMsg req res
36 do [xmlStr] <- runX ( mkDefaultPage conf (resStatus res) msgA
38 writeDocumentToString [ (a_indent, v_1) ]
43 writeDefaultPage :: Interaction -> STM ()
45 -- Content-Type が正しくなければ補完できない。
46 = do res <- readItr itr itrResponse id
47 when (getHeader (C8.pack "Content-Type") res == Just defaultPageContentType)
48 $ do reqM <- readItr itr itrRequest id
50 let conf = itrConfig itr
51 page = L8.pack $ getDefaultPage conf reqM res
53 writeTVar (itrBodyToSend itr)
57 mkDefaultPage :: (ArrowXml a) => Config -> StatusCode -> a b XmlTree -> a b XmlTree
58 mkDefaultPage !conf !status !msgA
59 = let (# sCode, sMsg #) = statusCode status
60 sig = C8.unpack (cnfServerSoftware conf)
62 ++ C8.unpack (cnfServerHost conf)
63 ++ ( case cnfServerPort conf of
64 Service serv -> ", service " ++ serv
65 PortNumber num -> ", port " ++ show num
66 UnixSocket path -> ", unix socket " ++ show path
70 += sattr "xmlns" "http://www.w3.org/1999/xhtml"
73 += txt (fmtDec 3 sCode ++ " " ++ C8.unpack sMsg)
77 += txt (C8.unpack sMsg)
79 += ( eelem "p" += msgA )
81 += ( eelem "address" += txt sig ))))
82 {-# SPECIALIZE mkDefaultPage :: Config -> StatusCode -> IOSArrow b XmlTree -> IOSArrow b XmlTree #-}
84 getMsg :: (ArrowXml a) => Maybe Request -> Response -> a b XmlTree
86 = case resStatus res of
92 -> txt ("The resource at " ++ path ++ " has been moved to ")
94 eelem "a" += sattr "href" loc
100 -> txt ("The resource at " ++ path ++ " is currently located at ")
102 eelem "a" += sattr "href" loc
105 txt ". This is not a permanent relocation."
108 -> txt ("The resource at " ++ path ++ " can be found at ")
110 eelem "a" += sattr "href" loc
116 -> txt ("The resource at " ++ path ++ " is temporarily located at ")
118 eelem "a" += sattr "href" loc
125 -> txt "The server could not understand the request you sent."
128 -> txt ("You need a valid authentication to access " ++ path)
131 -> txt ("You don't have permission to access " ++ path)
134 -> txt ("The requested URL " ++ path ++ " was not found on this server.")
137 -> txt ("The resource at " ++ path ++ " was here in past times, but has gone permanently.")
139 RequestEntityTooLarge
140 -> txt ("The request entity you sent for " ++ path ++ " was too big to accept.")
143 -> txt "The request URI you sent was too big to accept."
147 -> txt ("An internal server error has occured during the process of your request to " ++ path)
150 -> txt "The service is temporarily unavailable. Try later."
157 path = let uri = reqURI $! fromJust req
162 loc = C8.unpack $! fromJust $! getHeader (C8.pack "Location") res
164 {-# SPECIALIZE getMsg :: Maybe Request -> Response -> IOSArrow b XmlTree #-}