X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=Lucu.git;a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FInteraction.hs;h=35c9f06493d45c4cb92f65d9271c82280100d8fe;hp=6aee0f7296ac6bf0ff34da081e3f3413a8e72653;hb=3b448555e621530c3483f03b4b5156dc606b2035;hpb=b495d6b8b7647b719eceef2f3e50d5bf87c430cf diff --git a/Network/HTTP/Lucu/Interaction.hs b/Network/HTTP/Lucu/Interaction.hs index 6aee0f7..35c9f06 100644 --- a/Network/HTTP/Lucu/Interaction.hs +++ b/Network/HTTP/Lucu/Interaction.hs @@ -26,17 +26,20 @@ module Network.HTTP.Lucu.Interaction , mkInteractionQueue , getCurrentDate + , formatUTCTime ) where import Blaze.ByteString.Builder (Builder) import Control.Applicative import Control.Concurrent.STM import Data.Ascii (Ascii) -import qualified Data.ByteString as Strict +import Data.ByteString (ByteString) +import Data.Convertible.Base import Data.Monoid.Unicode import Data.Sequence (Seq) +import Data.Tagged import Data.Time -import qualified Data.Time.HTTP as HTTP +import Data.Time.Format.HTTP import Data.Typeable import Network.Socket import Network.HTTP.Lucu.Config @@ -45,9 +48,12 @@ import Network.HTTP.Lucu.Headers import Network.HTTP.Lucu.Preprocess import Network.HTTP.Lucu.Request import Network.HTTP.Lucu.Response +import Network.HTTP.Lucu.Response.StatusCode +import Network.HTTP.Lucu.Utils #if defined(HAVE_SSL) import OpenSSL.X509 #endif +import Prelude.Unicode class Typeable i ⇒ Interaction i where toInteraction ∷ i → SomeInteraction @@ -84,13 +90,13 @@ instance Interaction SyntacticallyInvalidInteraction mkSyntacticallyInvalidInteraction ∷ Config → IO SyntacticallyInvalidInteraction -mkSyntacticallyInvalidInteraction config@(Config {..}) +mkSyntacticallyInvalidInteraction conf@(Config {..}) = do date ← getCurrentDate let res = setHeader "Server" cnfServerSoftware $ setHeader "Date" date $ setHeader "Content-Type" defaultPageContentType $ emptyResponse BadRequest - body = getDefaultPage config Nothing res + body = defaultPageForResponse conf Nothing res return SYI { syiResponse = res , syiBodyToSend = body @@ -107,7 +113,6 @@ data SemanticallyInvalidInteraction , seiResponse ∷ !Response , seiWillChunkBody ∷ !Bool - , seiWillDiscardBody ∷ !Bool , seiWillClose ∷ !Bool , seiBodyToSend ∷ !Builder } @@ -122,8 +127,16 @@ mkSemanticallyInvalidInteraction config@(Config {..}) (AugmentedRequest {..}) let res = setHeader "Server" cnfServerSoftware $ setHeader "Date" date $ setHeader "Content-Type" defaultPageContentType $ + ( if arWillChunkBody + then setHeader "Transfer-Encoding" "chunked" + else id + ) $ + ( if arWillClose + then setHeader "Connection" "close" + else id + ) $ emptyResponse arInitialStatus - body = getDefaultPage config (Just arRequest) res + body = defaultPageForResponse config (Just arRequest) res return SEI { seiRequest = arRequest , seiExpectedContinue = arExpectedContinue @@ -131,7 +144,6 @@ mkSemanticallyInvalidInteraction config@(Config {..}) (AugmentedRequest {..}) , seiResponse = res , seiWillChunkBody = arWillChunkBody - , seiWillDiscardBody = arWillDiscardBody , seiWillClose = arWillClose , seiBodyToSend = body } @@ -146,17 +158,16 @@ data NormalInteraction , niRemoteCert ∷ !(Maybe X509) #endif , niRequest ∷ !Request - , niResourcePath ∷ ![Strict.ByteString] + , niResourcePath ∷ !Path , niExpectedContinue ∷ !Bool , niReqBodyLength ∷ !(Maybe RequestBodyLength) , niReceiveBodyReq ∷ !(TMVar ReceiveBodyRequest) - , niReceivedBody ∷ !(TMVar Strict.ByteString) + , niReceivedBody ∷ !(TMVar ByteString) , niResponse ∷ !(TVar Response) , niSendContinue ∷ !(TMVar Bool) , niWillChunkBody ∷ !Bool - , niWillDiscardBody ∷ !(TVar Bool) , niWillClose ∷ !(TVar Bool) , niResponseHasCType ∷ !(TVar Bool) -- FIXME: use TBChan Builder (in stm-chans package) @@ -188,7 +199,7 @@ mkNormalInteraction ∷ Config → Maybe X509 #endif → AugmentedRequest - → [Strict.ByteString] + → Path → IO NormalInteraction #if defined(HAVE_SSL) mkNormalInteraction config remoteAddr remoteCert (AugmentedRequest {..}) rsrcPath @@ -200,7 +211,6 @@ mkNormalInteraction config remoteAddr (AugmentedRequest {..}) rsrcPath response ← newTVarIO $ emptyResponse arInitialStatus sendContinue ← newEmptyTMVarIO - willDiscardBody ← newTVarIO arWillDiscardBody willClose ← newTVarIO arWillClose responseHasCType ← newTVarIO False bodyToSend ← newEmptyTMVarIO @@ -224,7 +234,6 @@ mkNormalInteraction config remoteAddr (AugmentedRequest {..}) rsrcPath , niResponse = response , niSendContinue = sendContinue , niWillChunkBody = arWillChunkBody - , niWillDiscardBody = willDiscardBody , niWillClose = willClose , niResponseHasCType = responseHasCType , niBodyToSend = bodyToSend @@ -235,7 +244,16 @@ mkNormalInteraction config remoteAddr (AugmentedRequest {..}) rsrcPath type InteractionQueue = TVar (Seq SomeInteraction) mkInteractionQueue ∷ IO InteractionQueue +{-# INLINE mkInteractionQueue #-} mkInteractionQueue = newTVarIO (∅) getCurrentDate ∷ IO Ascii -getCurrentDate = HTTP.toAscii <$> getCurrentTime +{-# INLINE getCurrentDate #-} +getCurrentDate = formatUTCTime <$> getCurrentTime + +formatUTCTime ∷ UTCTime → Ascii +{-# INLINE formatUTCTime #-} +formatUTCTime = cs' ∘ Tagged + where + cs' ∷ Tagged HTTP UTCTime → Ascii + cs' = cs