7 module Network.HTTP.Lucu.DefaultPage
14 import Control.Arrow.ArrowList
15 import Control.Arrow.Unicode
16 import Control.Concurrent.STM
18 import qualified Data.Ascii as A
19 import qualified Data.ByteString.Char8 as C8
21 import qualified Data.Sequence as S
22 import qualified Data.Text as T
23 import Data.Text.Encoding
24 import Network.HTTP.Lucu.Config
25 import Network.HTTP.Lucu.Format
26 import Network.HTTP.Lucu.Headers
27 import Network.HTTP.Lucu.Interaction
28 import Network.HTTP.Lucu.Request
29 import Network.HTTP.Lucu.Response
30 import Network.URI hiding (path)
31 import System.IO.Unsafe
32 import Prelude.Unicode
33 import Text.XML.HXT.Arrow.WriteDocument
34 import Text.XML.HXT.Arrow.XmlArrow
35 import Text.XML.HXT.Arrow.XmlState
36 import Text.XML.HXT.DOM.TypeDefs
38 getDefaultPage ∷ Config → Maybe Request → Response → String
39 getDefaultPage !conf !req !res
40 = let msgA = getMsg req res
43 do [xmlStr] ← runX ( mkDefaultPage conf (resStatus res) msgA
45 writeDocumentToString [ withIndent True ]
49 writeDefaultPage ∷ Interaction → STM ()
51 -- Content-Type が正しくなければ補完できない。
52 = do res ← readItr itr itrResponse id
53 when (getHeader "Content-Type" res == Just defaultPageContentType)
54 $ do reqM ← readItr itr itrRequest id
56 let conf = itrConfig itr
57 page = T.pack $ getDefaultPage conf reqM res
59 writeTVar (itrBodyToSend itr)
60 (S.singleton (encodeUtf8 page))
62 mkDefaultPage ∷ (ArrowXml a) ⇒ Config → StatusCode → a b XmlTree → a b XmlTree
63 {-# INLINEABLE mkDefaultPage #-}
64 mkDefaultPage !conf !status !msgA
65 = let (# sCode, sMsg #) = statusCode status
66 sig = concat [ C8.unpack (cnfServerSoftware conf)
68 , C8.unpack (cnfServerHost conf)
72 += sattr "xmlns" "http://www.w3.org/1999/xhtml"
75 += txt (fmtDec 3 sCode ⧺ " " ⧺ C8.unpack sMsg)
79 += txt (C8.unpack sMsg)
81 += ( eelem "p" += msgA )
83 += ( eelem "address" += txt sig ))))
85 getMsg ∷ (ArrowXml a) ⇒ Maybe Request → Response → a b XmlTree
86 {-# INLINEABLE getMsg #-}
88 = case resStatus res of
94 → txt ("The resource at " ⧺ path ⧺ " has been moved to ")
96 eelem "a" += sattr "href" loc
102 → txt ("The resource at " ⧺ path ⧺ " is currently located at ")
104 eelem "a" += sattr "href" loc
107 txt ". This is not a permanent relocation."
110 → txt ("The resource at " ⧺ path ⧺ " can be found at ")
112 eelem "a" += sattr "href" loc
118 → txt ("The resource at " ⧺ path ⧺ " is temporarily located at ")
120 eelem "a" += sattr "href" loc
127 → txt "The server could not understand the request you sent."
130 → txt ("You need a valid authentication to access " ⧺ path)
133 → txt ("You don't have permission to access " ⧺ path)
136 → txt ("The requested URL " ⧺ path ⧺ " was not found on this server.")
139 → txt ("The resource at " ⧺ path ⧺ " was here in past times, but has gone permanently.")
141 RequestEntityTooLarge
142 → txt ("The request entity you sent for " ⧺ path ⧺ " was too large to accept.")
145 → txt "The request URI you sent was too large to accept."
149 → txt ("An internal server error has occured during the process of your request to " ⧺ path)
152 → txt "The service is temporarily unavailable. Try later."
158 path = let uri = reqURI $ fromJust req
163 loc = A.toString $ fromJust $ getHeader "Location" res