+ observeRequest itr input
+ = do isChunked <- atomically $ readItr itr itrRequestIsChunked id
+ if isChunked then
+ observeChunkedRequest itr input
+ else
+ observeNonChunkedRequest itr input
+
+ observeChunkedRequest :: Interaction -> ByteString -> IO ()
+ observeChunkedRequest itr input
+ = fail "FIXME: not implemented"
+
+ observeNonChunkedRequest :: Interaction -> ByteString -> IO ()
+ observeNonChunkedRequest itr input
+ = do action
+ <- atomically $
+ do wantedM <- readItr itr itrReqBodyWanted id
+ if wantedM == Nothing then
+ do wasteAll <- readItr itr itrReqBodyWasteAll id
+ if wasteAll then
+ -- 破棄要求が來た
+ do remainingM <- readItr itr itrReqChunkRemaining id
+
+ let (_, input') = if remainingM == Nothing then
+ (B.takeWhile (\ _ -> True) input, B.empty)
+ else
+ B.splitAt (fromIntegral $ fromJust remainingM) input
+
+ writeItr itr itrReqChunkRemaining $ Just 0
+ writeItr itr itrReqChunkIsOver True
+ writeItr itr itrReqBodyWanted Nothing
+ writeItr itr itrReceivedBody B.empty
+
+ return $ acceptRequest input'
+ else
+ -- 要求がまだ来ない
+ retry
+ else
+ -- 受信要求が來た
+ do remainingM <- readItr itr itrReqChunkRemaining id
+
+ let wanted = fromJust wantedM
+ expectedChunkLen = fromIntegral $ maybe wanted (min wanted) remainingM
+ (chunk, input') = B.splitAt expectedChunkLen input
+ newRemaining = fmap
+ (\ x -> x - (fromIntegral $ B.length chunk))
+ remainingM
+ isOver = B.length chunk < expectedChunkLen
+
+ writeItr itr itrReqChunkRemaining newRemaining
+ writeItr itr itrReqChunkIsOver isOver
+ writeItr itr itrReqBodyWanted Nothing
+ writeItr itr itrReceivedBody chunk
+
+ if isOver then
+ return $ acceptRequest input'
+ else
+ return $ observeNonChunkedRequest itr input'
+ action