X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FResponseWriter.hs;h=1e2eacb2df7f462b99316c2c5e3a11608f3c3b1c;hb=a44a96d95b5fcbaf24a21c0336046ce0c3bab614;hp=ebd97e79d4d6c16584f354d50588abdbd8859e04;hpb=1e48e402adec79653203dc19a1800efa7b1c467b;p=Lucu.git diff --git a/Network/HTTP/Lucu/ResponseWriter.hs b/Network/HTTP/Lucu/ResponseWriter.hs index ebd97e7..1e2eacb 100644 --- a/Network/HTTP/Lucu/ResponseWriter.hs +++ b/Network/HTTP/Lucu/ResponseWriter.hs @@ -1,5 +1,5 @@ module Network.HTTP.Lucu.ResponseWriter - ( responseWriter -- Handle -> InteractionQueue -> IO () + ( responseWriter -- Config -> Handle -> InteractionQueue -> IO () ) where @@ -11,7 +11,10 @@ import Control.Monad import Data.Maybe import qualified Data.Sequence as S import Data.Sequence (Seq, ViewR(..)) +import Network.HTTP.Lucu.Config +import Network.HTTP.Lucu.HttpVersion import Network.HTTP.Lucu.Interaction +import Network.HTTP.Lucu.Postprocess import Network.HTTP.Lucu.Response import Prelude hiding (catch) import System.IO @@ -19,10 +22,11 @@ import Text.Printf import Control.Concurrent import Debug.Trace +import GHC.Conc (unsafeIOToSTM) -responseWriter :: Handle -> InteractionQueue -> ThreadId -> IO () -responseWriter h tQueue readerTID +responseWriter :: Config -> Handle -> InteractionQueue -> ThreadId -> IO () +responseWriter cnf h tQueue readerTID = catch awaitSomethingToWrite $ \ exc -> case exc of IOException _ -> return () @@ -58,13 +62,16 @@ responseWriter h tQueue readerTID writeContinueIfNecessary itr = do expectedContinue <- readItr itr itrExpectedContinue id if expectedContinue then - do wroteContinue <- readItr itr itrWroteContinue id if wroteContinue then -- 既に Continue を書込み濟 retry else - return $ writeContinue itr + do reqBodyWanted <- readItr itr itrReqBodyWanted id + if reqBodyWanted /= Nothing then + return $ writeContinue itr + else + retry else retry @@ -92,7 +99,17 @@ responseWriter h tQueue readerTID return $ writeBodyChunk itr writeContinue :: Interaction -> IO () - writeContinue itr = fail "FIXME: not implemented" + writeContinue itr + = do let cont = Response { + resVersion = HttpVersion 1 1 + , resStatus = Continue + , resHeaders = [] + } + cont' <- completeUnconditionalHeaders cnf cont + hPutResponse h cont' + hFlush h + atomically $ writeItr itr itrWroteContinue True + awaitSomethingToWrite writeHeader :: Interaction -> IO () writeHeader itr @@ -124,7 +141,7 @@ responseWriter h tQueue readerTID = do willDiscardBody <- atomically $ readItr itr itrWillDiscardBody id willChunkBody <- atomically $ readItr itr itrWillChunkBody id when (not willDiscardBody && willChunkBody) - $ hPutStr h "0\r\n" >> hFlush h + $ hPutStr h "0\r\n\r\n" >> hFlush h finalize :: Interaction -> IO () finalize itr @@ -136,6 +153,8 @@ responseWriter h tQueue readerTID readItr itr itrWillClose id if willClose then + -- reader は恐らく hWaitForInput してゐる最中なので、 + -- スレッドを豫め殺して置かないとをかしくなる。 do killThread readerTID hClose h else