X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FResource%2FInternal.hs;h=f8ea1b2aaf5b3b35edad73d7b3da2731d4b08d18;hb=b2da45926a7900603a5426e0c6d65e3ca630a1a2;hp=9df36a601cf7dc460dd8b98f92ed084054719504;hpb=ece223c516e66223ef1d5d8e6bbe4054a235d983;p=Lucu.git diff --git a/Network/HTTP/Lucu/Resource/Internal.hs b/Network/HTTP/Lucu/Resource/Internal.hs index 9df36a6..f8ea1b2 100644 --- a/Network/HTTP/Lucu/Resource/Internal.hs +++ b/Network/HTTP/Lucu/Resource/Internal.hs @@ -1,5 +1,6 @@ {-# LANGUAGE - DoAndIfThenElse + CPP + , DoAndIfThenElse , GeneralizedNewtypeDeriving , OverloadedStrings , RecordWildCards @@ -13,7 +14,9 @@ module Network.HTTP.Lucu.Resource.Internal , getConfig , getRemoteAddr +#if defined(HAVE_SSL) , getRemoteCertificate +#endif , getRequest , getResourcePath @@ -33,13 +36,15 @@ import Control.Applicative import Control.Concurrent import Control.Concurrent.STM import Control.Exception +import Control.Monad hiding (mapM_) import Control.Monad.IO.Class -import Control.Monad.Reader +import Control.Monad.Reader (ReaderT, runReaderT, ask) import Control.Monad.Unicode import Data.Ascii (Ascii, CIAscii) import qualified Data.Ascii as A import qualified Data.ByteString as Strict -import Data.List +import Data.Collections +import Data.List (intersperse, nub) import Data.Maybe import Data.Monoid import Data.Monoid.Unicode @@ -54,8 +59,10 @@ import Network.HTTP.Lucu.Postprocess import Network.HTTP.Lucu.Request import Network.HTTP.Lucu.Response import Network.Socket +#if defined(HAVE_SSL) import OpenSSL.X509 -import Prelude hiding (catch) +#endif +import Prelude hiding (catch, concat, mapM_, tail) import Prelude.Unicode import System.IO @@ -202,7 +209,7 @@ spawnResource (ResourceDef {..}) ni@(NI {..}) -- in the response. Hooray! flip runResource ni $ do setStatus $ aboStatus abo - mapM_ (uncurry setHeader) $ H.fromHeaders $ aboHeaders abo + mapM_ (uncurry setHeader) (aboHeaders abo) setHeader "Content-Type" defaultPageContentType deleteHeader "Content-Encoding" putBuilder $ abortPage niConfig (Just niRequest) res abo @@ -230,6 +237,7 @@ getConfig = niConfig <$> getInteraction getRemoteAddr ∷ Resource SockAddr getRemoteAddr = niRemoteAddr <$> getInteraction +#if defined(HAVE_SSL) -- | Return the X.509 certificate of the client, or 'Nothing' if: -- -- * This request didn't came through an SSL stream. @@ -241,6 +249,7 @@ getRemoteAddr = niRemoteAddr <$> getInteraction -- 'OpenSSL.Session.VerifyPeer'. getRemoteCertificate ∷ Resource (Maybe X509) getRemoteCertificate = niRemoteCert <$> getInteraction +#endif -- |Return the 'Request' value representing the request header. You -- usually don't need to call this function directly. @@ -304,14 +313,15 @@ getChunk' n -- |Declare the response status code. If you don't call this function, -- the status code will be defaulted to \"200 OK\". -setStatus ∷ StatusCode → Resource () +setStatus ∷ StatusCode sc ⇒ sc → Resource () setStatus sc = do ni ← getInteraction liftIO $ atomically $ do state ← readTVar $ niState ni when (state > DecidingHeader) $ fail "Too late to declare the response status." - setResponseStatus ni sc + res ← readTVar $ niResponse ni + writeTVar (niResponse ni) $ setStatusCode sc res -- |@'setHeader' name value@ declares the value of the response header -- @name@ as @value@. Note that this function is not intended to be @@ -329,9 +339,7 @@ setStatus sc -- body and thinks that the residual 10 bytes is a part of the header -- of the next response. setHeader ∷ CIAscii → Ascii → Resource () -setHeader name value - = do ni ← getInteraction - liftIO $ atomically $ go ni +setHeader name value = liftIO ∘ atomically ∘ go =≪ getInteraction where go ∷ NormalInteraction → STM () go (NI {..}) @@ -346,9 +354,7 @@ setHeader name value -- |@'deleteHeader' name@ deletes a response header @name@ if -- any. This function is not intended to be used so frequently. deleteHeader ∷ CIAscii → Resource () -deleteHeader name - = do ni ← getInteraction - liftIO $ atomically $ go ni +deleteHeader name = liftIO ∘ atomically ∘ go =≪ getInteraction where go ∷ NormalInteraction → STM () go (NI {..}) @@ -365,13 +371,12 @@ deleteHeader name -- infinitely long stream of octets. -- -- Note that you must first declare the response header --- \"Content-Type\" before applying this function. See --- 'setContentType'. +-- \"Content-Type\" before applying this function. See: +-- 'setContentType' putBuilder ∷ Builder → Resource () -putBuilder b - = do ni ← getInteraction - liftIO $ atomically $ go ni +putBuilder b = liftIO ∘ atomically ∘ go =≪ getInteraction where + -- FIXME: should see if resCanHaveBody. go ∷ NormalInteraction → STM () go ni@(NI {..}) = do driftTo' ni SendingBody @@ -383,9 +388,7 @@ putBuilder b putTMVar niBodyToSend b driftTo ∷ InteractionState → Resource () -driftTo newState - = do ni ← getInteraction - liftIO $ atomically $ driftTo' ni newState +driftTo = (getInteraction ≫=) ∘ ((liftIO ∘ atomically) ∘) ∘ flip driftTo' driftTo' ∷ NormalInteraction → InteractionState → STM () driftTo' ni@(NI {..}) newState