X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FInteraction.hs;h=491c029b60ffbd51e2e7e425e3911325409cf389;hb=e624f0db8c4610b36da9e4463a656e0cb8a104dd;hp=44f4243b6ebe2abb5b02cb0891d783bd60f60655;hpb=3c7a58ab749a55a30466a033b170536bcdf18b98;p=Lucu.git diff --git a/Network/HTTP/Lucu/Interaction.hs b/Network/HTTP/Lucu/Interaction.hs index 44f4243..491c029 100644 --- a/Network/HTTP/Lucu/Interaction.hs +++ b/Network/HTTP/Lucu/Interaction.hs @@ -3,7 +3,13 @@ module Network.HTTP.Lucu.Interaction , InteractionState(..) , InteractionQueue , newInteractionQueue -- IO InteractionQueue - , newInteraction -- HostName -> Maybe Request -> IO Interaction + , newInteraction -- Config -> HostName -> Maybe Request -> IO Interaction + + , writeItr -- Interaction -> (Interaction -> TVar a) -> a -> STM () + , readItr -- Interaction -> (Interaction -> TVar a) -> (a -> b) -> STM b + , readItrF -- (Functor f) => Interaction -> (Interaction -> TVar (f a)) -> (a -> b) -> STM (f b) + , updateItr -- Interaction -> (Interaction -> TVar a) -> (a -> a) -> STM () + , updateItrF -- (Functor f) => Interaction -> (Interaction -> TVar (f a)) -> (a -> a) -> STM () ) where @@ -13,25 +19,34 @@ import Data.ByteString.Lazy.Char8 (ByteString) import qualified Data.Sequence as S import Data.Sequence (Seq) import Network +import Network.HTTP.Lucu.Config import Network.HTTP.Lucu.Request import Network.HTTP.Lucu.Response data Interaction = Interaction { - itrRemoteHost :: HostName + itrConfig :: Config + , itrRemoteHost :: HostName , itrRequest :: Maybe Request , itrResponse :: TVar (Maybe Response) , itrRequestHasBody :: TVar Bool - , itrRequestBodyLength :: TVar (Maybe Integer) -- chunked の場合は不明 , itrRequestIsChunked :: TVar Bool - , itrReceivedBody :: TVar ByteString -- Resource が受領した部分は削除される - , itrExpectedContinue :: TVar Bool - , itrWillChunkBody :: TVar Bool - , itrWillDiscardBody :: TVar Bool - , itrWillClose :: TVar Bool - , itrBodyToSend :: TVar ByteString + , itrReqChunkLength :: TVar (Maybe Int) + , itrReqChunkRemaining :: TVar (Maybe Int) + , itrReqChunkIsOver :: TVar Bool + , itrReqBodyWanted :: TVar (Maybe Int) + , itrReqBodyWasteAll :: TVar Bool + , itrReceivedBody :: TVar ByteString -- Resource が受領した部分は削除される + + , itrWillReceiveBody :: TVar Bool + , itrWillChunkBody :: TVar Bool + , itrWillDiscardBody :: TVar Bool + , itrWillClose :: TVar Bool + + , itrBodyToSend :: TVar ByteString + , itrBodyIsNull :: TVar Bool , itrState :: TVar InteractionState @@ -47,7 +62,7 @@ data InteractionState = ExaminingHeader | DecidingHeader | DecidingBody | Done - deriving (Show, Eq, Ord) + deriving (Show, Eq, Ord, Enum) type InteractionQueue = TVar (Seq Interaction) @@ -56,21 +71,28 @@ newInteractionQueue :: IO InteractionQueue newInteractionQueue = newTVarIO S.empty -newInteraction :: HostName -> Maybe Request -> IO Interaction -newInteraction host req +newInteraction :: Config -> HostName -> Maybe Request -> IO Interaction +newInteraction conf host req = do responce <- newTVarIO Nothing - requestHasBody <- newTVarIO False - requestBodyLength <- newTVarIO Nothing - requestIsChunked <- newTVarIO False - receivedBody <- newTVarIO B.empty - - expectedContinue <- newTVarIO False - - willChunkBody <- newTVarIO False - willDiscardBody <- newTVarIO False - willClose <- newTVarIO False - bodyToSend <- newTVarIO B.empty + requestHasBody <- newTVarIO False + requestIsChunked <- newTVarIO False + expectedContinue <- newTVarIO False + + reqChunkLength <- newTVarIO Nothing -- 現在のチャンク長 + reqChunkRemaining <- newTVarIO Nothing -- 現在のチャンクの殘り + reqChunkIsOver <- newTVarIO False -- 最後のチャンクを讀み終へた + reqBodyWanted <- newTVarIO Nothing -- Resource が要求してゐるチャンク長 + reqBodyWasteAll <- newTVarIO False -- 殘りの body を讀み捨てよと云ふ要求 + receivedBody <- newTVarIO B.empty + + willReceiveBody <- newTVarIO False + willChunkBody <- newTVarIO False + willDiscardBody <- newTVarIO False + willClose <- newTVarIO False + + bodyToSend <- newTVarIO B.empty + bodyIsNull <- newTVarIO True -- 一度でも bodyToSend が空でなくなったら False state <- newTVarIO undefined @@ -78,24 +100,58 @@ newInteraction host req wroteHeader <- newTVarIO False return $ Interaction { - itrRemoteHost = host + itrConfig = conf + , itrRemoteHost = host , itrRequest = req , itrResponse = responce , itrRequestHasBody = requestHasBody - , itrRequestBodyLength = requestBodyLength , itrRequestIsChunked = requestIsChunked + , itrExpectedContinue = expectedContinue + + , itrReqChunkLength = reqChunkLength + , itrReqChunkRemaining = reqChunkRemaining + , itrReqChunkIsOver = reqChunkIsOver + , itrReqBodyWanted = reqBodyWanted + , itrReqBodyWasteAll = reqBodyWasteAll , itrReceivedBody = receivedBody - , itrExpectedContinue = expectedContinue + , itrWillReceiveBody = willReceiveBody + , itrWillChunkBody = willChunkBody + , itrWillDiscardBody = willDiscardBody + , itrWillClose = willClose - , itrWillChunkBody = willChunkBody - , itrWillDiscardBody = willDiscardBody - , itrWillClose = willClose - , itrBodyToSend = bodyToSend + , itrBodyToSend = bodyToSend + , itrBodyIsNull = bodyIsNull , itrState = state , itrWroteContinue = wroteContinue , itrWroteHeader = wroteHeader } + + +writeItr :: Interaction -> (Interaction -> TVar a) -> a -> STM () +writeItr itr accessor value + = writeTVar (accessor itr) value + + +readItr :: Interaction -> (Interaction -> TVar a) -> (a -> b) -> STM b +readItr itr accessor reader + = readTVar (accessor itr) >>= return . reader + + +readItrF :: (Functor f) => Interaction -> (Interaction -> TVar (f a)) -> (a -> b) -> STM (f b) +readItrF itr accessor reader + = readItr itr accessor (fmap reader) + + +updateItr :: Interaction -> (Interaction -> TVar a) -> (a -> a) -> STM () +updateItr itr accessor updator + = do old <- readItr itr accessor id + writeItr itr accessor (updator old) + + +updateItrF :: (Functor f) => Interaction -> (Interaction -> TVar (f a)) -> (a -> a) -> STM () +updateItrF itr accessor updator + = updateItr itr accessor (fmap updator)