let input = B.append soFar chunk
case parse requestP input of
(Success req , input') -> acceptParsableRequest req input'
- (IllegalInput, _ ) -> acceptNonparsableRequest
+ (IllegalInput, _ ) -> acceptNonparsableRequest BadRequest
(ReachedEOF , _ ) -> if B.length input >= 1024 * 1024 then
-- ヘッダ長過ぎ
- acceptNonparsableRequest
+ acceptNonparsableRequest RequestEntityTooLarge
else
acceptRequest input
-
- acceptNonparsableRequest :: IO ()
- acceptNonparsableRequest
- = do itr <- newInteraction host Nothing
+ acceptNonparsableRequest :: StatusCode -> IO ()
+ acceptNonparsableRequest status
+ = do itr <- newInteraction cnf host Nothing
let res = Response {
resVersion = HttpVersion 1 1
- , resStatus = BadRequest
+ , resStatus = status
, resHeaders = []
}
atomically $ do writeItr itr itrResponse $ Just res
acceptParsableRequest :: Request -> ByteString -> IO ()
acceptParsableRequest req soFar
- = do itr <- newInteraction host (Just req)
+ = do itr <- newInteraction cnf host (Just req)
action
<- atomically $
do preprocess itr
acceptRequest soFar
observeRequest :: Interaction -> ByteString -> IO ()
- observeRequest itr soFar = fail "FIXME: Not Implemented"
+ observeRequest itr soFar
+ = do isChunked <- atomically $ readItr itr itrRequestIsChunked id
+ if isChunked then
+ observeChunkedRequest itr soFar
+ else
+ observeNonChunkedRequest itr soFar
+
+ observeChunkedRequest :: Interaction -> ByteString -> IO ()
+ observeChunkedRequest itr soFar
+ = fail "FIXME: not implemented"
+
+ observeNonChunkedRequest :: Interaction -> ByteString -> IO ()
+ observeNonChunkedRequest itr soFar
+ = fail "FIXME: not implemented"
+{-
+ = do action
+ <- atomically $
+ do wantedM <- readItr itr itrReqBodyWanted id
+ if wantedM == Nothing then
+ do wasteAll <- readItr itr itrReqBodyWasteAll id
+ if wasteAll then
+ return $ wasteAllReqBody itr soFar
+ else
+ retry
+ else
+ -- 受信要求が來た。
+ if B.empty soFar then
+ return $ receiveNonChunkedReqBody itr
+ else
+ do remaining <- readItr itr itrReqChunkRemaining fromJust
+
+ let wanted = fromJust wanted
+ (chunk, input') = B.splitAt (min wanted remaining) soFar
+ newRemaining = remaining - B.length chunk
+ isOver = newRemaining == 0
+
+ writeItr itr itrReqChunkRemaining newRemaining
+ writeItr itr itrReqChunkIsOver isOver
+ writeItr itr itrReqBodyWanted (if isOver then
+ Nothing
+ else
+ Just wanted)
+ writeItr itr itrReceivedBody chunk
+
+ if isOver then
+ return $ acceptRequest input'
+ else
+ return $ observeNonChunkedRequest itr input'
+ action
+
+ receiveNonChunkedReqBody :: Interaction -> IO ()
+ receiveNonChunkedReqBody itr
+ = do wanted <- atomically $ readItr itr itrReqBodyWanted fromJust
+ remaining <- atomically $ readItr itr itrReqChunkRemaining fromJust
+
+ hWaitForInput h (-1)
+ chunk <- B.hGetNonBlocking h (min wanted remaining)
+
+ let newRemaining = remaining - B.length chunk
+ isOver = newRemaining == 0
+
+ atomically $ do writeItr itr itrReqChunkRemaining newRemaining
+ writeItr itr itrReqChunkIsOver isOver
+ writeItr itr itrReqBodyWanted (if isOver then
+ Nothing
+ else
+ Just wanted)
+ writeItr itr itrReceivedBody chunk
+
+ if isOver then
+ return $ acceptRequest B.empty
+ else
+ return $ observeNonChunkedRequest itr B.empty
+
+
+ wasteAllReqBody :: Interaction -> ByteString -> IO ()
+ wasteAllReqBody itr soFar
+ =
+
+-}
enqueue :: Interaction -> STM ()
enqueue itr = do queue <- readTVar tQueue