X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=Lucu.git;a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FDefaultPage.hs;h=5fd170564ef0dd5cb2ff1282bef839a1a71b5964;hp=988329d28757d62a600ede2ac7aa66df1a499a61;hb=8bdd1da1ee1f3e453dbe2bce246618e12e26d30c;hpb=b340a77fa7bd051dd13a41d0a5b1ad30220bc6b6 diff --git a/Network/HTTP/Lucu/DefaultPage.hs b/Network/HTTP/Lucu/DefaultPage.hs index 988329d..5fd1705 100644 --- a/Network/HTTP/Lucu/DefaultPage.hs +++ b/Network/HTTP/Lucu/DefaultPage.hs @@ -1,4 +1,3 @@ --- #hide, prune module Network.HTTP.Lucu.DefaultPage ( getDefaultPage , writeDefaultPage @@ -10,99 +9,80 @@ import Control.Arrow import Control.Arrow.ArrowList import Control.Concurrent.STM import Control.Monad -import qualified Data.ByteString.Lazy.Char8 as B -import Data.ByteString.Lazy.Char8 (ByteString) +import qualified Data.ByteString.Char8 as C8 +import qualified Data.ByteString.Lazy.Char8 as L8 import Data.Maybe -import Network import Network.HTTP.Lucu.Config +import Network.HTTP.Lucu.Format import Network.HTTP.Lucu.Headers import Network.HTTP.Lucu.Interaction import Network.HTTP.Lucu.Request import Network.HTTP.Lucu.Response -import Network.URI +import Network.URI hiding (path) import System.IO.Unsafe -import Text.Printf import Text.XML.HXT.Arrow.WriteDocument import Text.XML.HXT.Arrow.XmlArrow -import Text.XML.HXT.Arrow.XmlIOStateArrow +import Text.XML.HXT.Arrow.XmlState import Text.XML.HXT.DOM.TypeDefs -import Text.XML.HXT.DOM.XmlKeywords getDefaultPage :: Config -> Maybe Request -> Response -> String -getDefaultPage conf req res +getDefaultPage !conf !req !res = let msgA = getMsg req res in unsafePerformIO $ do [xmlStr] <- runX ( mkDefaultPage conf (resStatus res) msgA >>> - writeDocumentToString [ (a_indent, v_1) ] + writeDocumentToString [ withIndent True ] ) return xmlStr writeDefaultPage :: Interaction -> STM () -writeDefaultPage itr - = do wroteHeader <- readTVar (itrWroteHeader itr) +writeDefaultPage !itr + -- Content-Type が正しくなければ補完できない。 + = do res <- readItr itr itrResponse id + when (getHeader (C8.pack "Content-Type") res == Just defaultPageContentType) + $ do reqM <- readItr itr itrRequest id - -- ヘッダが出力濟だったら意味が無い。 - when wroteHeader - $ fail "writeDefaultPage: the header has already been written" + let conf = itrConfig itr + page = L8.pack $ getDefaultPage conf reqM res - resM <- readTVar (itrResponse itr) - - -- Response が不明ならばページ書込も不可 - when (resM == Nothing) - $ fail "writeDefaultPage: response was Nothing" - - let reqM = itrRequest itr - res = fromJust resM - conf = itrConfig itr - page = B.pack $ getDefaultPage conf reqM res - - writeTVar (itrResponse itr) - $ Just $ setHeader "Content-Type" "application/xhtml+xml" res - - writeTVar (itrBodyToSend itr) - $ page + writeTVar (itrBodyToSend itr) + $ page mkDefaultPage :: (ArrowXml a) => Config -> StatusCode -> a b XmlTree -> a b XmlTree -mkDefaultPage conf status msgA - = let (sCode, sMsg) = statusCode status - sig = cnfServerSoftware conf - ++ " at " - ++ cnfServerHost conf - ++ ( case cnfServerPort conf of - Service serv -> ", service " ++ serv - PortNumber num -> ", port " ++ show num - UnixSocket path -> ", unix socket " ++ show path - ) +mkDefaultPage !conf !status !msgA + = let (# sCode, sMsg #) = statusCode status + sig = C8.unpack (cnfServerSoftware conf) + ++ " at " + ++ C8.unpack (cnfServerHost conf) in ( eelem "/" += ( eelem "html" += sattr "xmlns" "http://www.w3.org/1999/xhtml" += ( eelem "head" += ( eelem "title" - += txt (printf "%03d %s" sCode sMsg) + += txt (fmtDec 3 sCode ++ " " ++ C8.unpack sMsg) )) += ( eelem "body" += ( eelem "h1" - += txt sMsg + += txt (C8.unpack sMsg) ) += ( eelem "p" += msgA ) += eelem "hr" += ( eelem "address" += txt sig )))) - +{-# SPECIALIZE mkDefaultPage :: Config -> StatusCode -> IOSArrow b XmlTree -> IOSArrow b XmlTree #-} getMsg :: (ArrowXml a) => Maybe Request -> Response -> a b XmlTree -getMsg req res +getMsg !req !res = case resStatus res of -- 1xx は body を持たない -- 2xx の body は補完しない -- 3xx MovedPermanently - -> txt (printf "The resource at %s has been moved to " path) + -> txt ("The resource at " ++ path ++ " has been moved to ") <+> eelem "a" += sattr "href" loc += txt loc @@ -110,7 +90,7 @@ getMsg req res txt " permanently." Found - -> txt (printf "The resource at %s is currently located at " path) + -> txt ("The resource at " ++ path ++ " is currently located at ") <+> eelem "a" += sattr "href" loc += txt loc @@ -118,7 +98,7 @@ getMsg req res txt ". This is not a permanent relocation." SeeOther - -> txt (printf "The resource at %s can be found at " path) + -> txt ("The resource at " ++ path ++ " can be found at ") <+> eelem "a" += sattr "href" loc += txt loc @@ -126,7 +106,7 @@ getMsg req res txt "." TemporaryRedirect - -> txt (printf "The resource at %s is temporarily located at " path) + -> txt ("The resource at " ++ path ++ " is temporarily located at ") <+> eelem "a" += sattr "href" loc += txt loc @@ -138,26 +118,26 @@ getMsg req res -> txt "The server could not understand the request you sent." Unauthorized - -> txt (printf "You need a valid authentication to access %s" path) + -> txt ("You need a valid authentication to access " ++ path) Forbidden - -> txt (printf "You don't have permission to access %s" path) + -> txt ("You don't have permission to access " ++ path) NotFound - -> txt (printf "The requested URL %s was not found on this server." path) + -> txt ("The requested URL " ++ path ++ " was not found on this server.") Gone - -> txt (printf "The resource at %s was here in past times, but has gone permanently." path) + -> txt ("The resource at " ++ path ++ " was here in past times, but has gone permanently.") RequestEntityTooLarge - -> txt (printf "The request entity you sent for %s was too big to accept." path) + -> txt ("The request entity you sent for " ++ path ++ " was too big to accept.") RequestURITooLarge -> txt "The request URI you sent was too big to accept." -- 5xx InternalServerError - -> txt (printf "An internal server error has occured during the process of your request to %s" path) + -> txt ("An internal server error has occured during the process of your request to " ++ path) ServiceUnavailable -> txt "The service is temporarily unavailable. Try later." @@ -167,9 +147,11 @@ getMsg req res where path :: String - path = let uri = reqURI $ fromJust req + path = let uri = reqURI $! fromJust req in uriPath uri loc :: String - loc = fromJust $ getHeader "Location" res + loc = C8.unpack $! fromJust $! getHeader (C8.pack "Location") res + +{-# SPECIALIZE getMsg :: Maybe Request -> Response -> IOSArrow b XmlTree #-} \ No newline at end of file