@@ -29,7 +29,7 @@ import Control.Exception (bracket, finally, Exception)
2929import System.IO (Handle, hClose)
3030import Control.Concurrent
3131import Control.Monad (unless)
32−import Data.Maybe (isJust, fromJust)
32+import Data.Maybe (isJust, fromJust, fromMaybe)
3333
3434import Control.Failure
3535import Data.Typeable (Typeable)
@@ -37,6 +37,8 @@ import Data.Typeable (Typeable)
3737import Web.Encodings.StringLike (StringLike)
3838import qualified Web.Encodings.StringLike as SL
3939
40+import qualified Safe
41+
4042run :: Port -> Application -> IO ()
4143run port = withSocketsDo .
4244 bracket
@@ -97,12 +99,11 @@ data InvalidRequest =
9799instance Exception InvalidRequest
98100
99101-- | Parse a set of header lines and body into a 'Request'.
100−parseRequest :: (MonadFailure InvalidRequest m)
101− => Port
102− -> [BS.ByteString]
103− -> Handle
104− -> String
105− -> m Request
102+parseRequest :: Port
103+ -> [BS.ByteString]
104+ -> Handle
105+ -> String
106+ -> IO Request
106107parseRequest port lines' handle remoteHost' = do
107108 case lines' of
108109 (_:_:_) -> return ()
@@ -116,10 +117,11 @@ parseRequest port lines' handle remoteHost' = do
116117 let host' = lookup (SL.pack "Host") heads
117118 unless (isJust host') $ failure HostNotIncluded
118119 let host = fromJust host'
119− {- FIXME use length somewhere?
120− let len = maybe "0" SL.unpack
121− $ lookup (SL.pack "Content-Length") heads
122− -}
120+ let len = fromMaybe 0 $ do
121+ bs <- lookup (SL.pack "Content-Length") heads
122+ let str = SL.unpack bs
123+ Safe.readMay str
124+ mlen <- newMVar len
123125 let (serverName', _) = SL.breakChar ':' host
124126 return $ Request
125127 { requestMethod = method
@@ -129,18 +131,19 @@ parseRequest port lines' handle remoteHost' = do
129131 , serverPort = port
130132 , httpHeaders = heads
131133 , urlScheme = HTTP
132− , requestBody = RequestBody $ SSRequestBody handle
134+ , requestBody = requestBodyHandle handle mlen
133135 , errorHandler = System.IO.hPutStr System.IO.stderr
134136 , remoteHost = remoteHost'
135137 }
136138
137−newtype SSRequestBody = SSRequestBody Handle
138−instance RequestBodyClass SSRequestBody where
139− receiveByteString (SSRequestBody h) = do
140− bs <- BS.hGet h 1024 -- FIXME find a good chunk size
141− if BS.null bs
142− then return Nothing
143− else return $ Just bs
139+requestBodyHandle :: Handle -> MVar Int -> IO (Maybe BS.ByteString)
140+requestBodyHandle h mlen = modifyMVar mlen helper where
141+ helper :: Int -> IO (Int, Maybe BS.ByteString)
142+ helper 0 = return (0, Nothing)
143+ helper len = do
144+ bs <- BS.hGet h len
145+ let newLen = len - BS.length bs
146+ return (newLen, Just bs)
144147
145148parseFirst :: (StringLike s, MonadFailure InvalidRequest m) =>
146149 s