X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=Lucu.git;a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FResponseWriter.hs;h=0af4a69df02f1a78604b0bc46d3b71077a545768;hp=25f2ffbead481571c609fcd221d877390a6031d5;hb=246d66d6d3130e03834a6c3badc38711a1879aae;hpb=1b822bc79ce9fd0ee537fe81819e7501af83f7bd diff --git a/Network/HTTP/Lucu/ResponseWriter.hs b/Network/HTTP/Lucu/ResponseWriter.hs index 25f2ffb..0af4a69 100644 --- a/Network/HTTP/Lucu/ResponseWriter.hs +++ b/Network/HTTP/Lucu/ResponseWriter.hs @@ -14,8 +14,9 @@ import Control.Concurrent import Control.Concurrent.STM import Control.Exception import Control.Monad +import Data.Ascii (AsciiBuilder) +import Data.Convertible.Utils import GHC.IO.Exception (IOException(..), IOErrorType(..)) -import qualified Data.Ascii as A import Data.Monoid.Unicode import qualified Data.Sequence as S import Data.Sequence (ViewR(..)) @@ -23,6 +24,7 @@ import Network.HTTP.Lucu.Config import Network.HTTP.Lucu.HandleLike import Network.HTTP.Lucu.HttpVersion import Network.HTTP.Lucu.Interaction +import Network.HTTP.Lucu.Request import Network.HTTP.Lucu.Response import Prelude.Unicode import System.IO (hPutStrLn, stderr) @@ -40,7 +42,6 @@ responseWriter cnf h tQueue readerTID `catches` [ Handler handleIOE , Handler handleAsyncE - , Handler handleBIOS , Handler handleOthers ] `finally` @@ -56,15 +57,12 @@ responseWriter cnf h tQueue readerTID handleAsyncE ThreadKilled = return () handleAsyncE e = dump e - handleBIOS ∷ BlockedIndefinitelyOnSTM → IO () - handleBIOS = dump - handleOthers ∷ SomeException → IO () handleOthers = dump dump ∷ Exception e ⇒ e → IO () dump e - = do hPutStrLn stderr "requestWriter caught an exception:" + = do hPutStrLn stderr "Lucu: responseWriter caught an exception:" hPutStrLn stderr $ show e awaitSomethingToWrite ∷ HandleLike h ⇒ Context h → IO () @@ -106,7 +104,7 @@ writeContinueIfNeeded ctx@(Context {..}) ni@(NI {..}) , resStatus = fromStatusCode Continue , resHeaders = (∅) } - hPutBuilder cHandle $ A.toBuilder $ printResponse cont + hPutBuilder cHandle $ convertSuccessVia ((⊥) ∷ AsciiBuilder) cont hFlush cHandle writeHeader ctx ni @@ -121,7 +119,7 @@ writeHeader ctx@(Context {..}) ni@(NI {..}) readTVar niResponse else retry -- Too early to write header fields. - hPutBuilder cHandle $ A.toBuilder $ printResponse res + hPutBuilder cHandle $ convertSuccessVia ((⊥) ∷ AsciiBuilder) res hFlush cHandle writeBodyIfNeeded ctx ni @@ -132,14 +130,14 @@ writeBodyIfNeeded ∷ HandleLike h writeBodyIfNeeded ctx ni@(NI {..}) = join $ atomically $ - do willDiscardBody ← readTVar niWillDiscardBody - if willDiscardBody then - return $ discardBody ctx ni - else + do canHaveBody ← resCanHaveBody <$> readTVar niResponse + if canHaveBody ∧ reqMethod niRequest ≢ HEAD then if niWillChunkBody then return $ writeChunkedBody ctx ni else return $ writeNonChunkedBody ctx ni + else + return $ discardBody ctx ni discardBody ∷ HandleLike h ⇒ Context h @@ -235,8 +233,8 @@ writeResponseForSEI ∷ HandleLike h → SemanticallyInvalidInteraction → IO () writeResponseForSEI ctx@(Context {..}) (SEI {..}) - = do hPutBuilder cHandle $ A.toBuilder $ printResponse seiResponse - unless seiWillDiscardBody $ + = do hPutBuilder cHandle $ convertSuccessVia ((⊥) ∷ AsciiBuilder) seiResponse + when (reqMethod seiRequest ≢ HEAD) $ if seiWillChunkBody then do hPutBuilder cHandle $ BB.chunkedTransferEncoding seiBodyToSend hPutBuilder cHandle BB.chunkedTransferTerminator @@ -253,7 +251,7 @@ writeResponseForSYI ∷ HandleLike h → SyntacticallyInvalidInteraction → IO () writeResponseForSYI (Context {..}) (SYI {..}) - = do hPutBuilder cHandle $ A.toBuilder $ printResponse syiResponse + = do hPutBuilder cHandle $ convertSuccessVia ((⊥) ∷ AsciiBuilder) syiResponse hPutBuilder cHandle syiBodyToSend hFlush cHandle return ()