warp 0.3.2.2 → 0.3.2.3
raw patch · 2 files changed
+28/−39 lines, 2 files
Files
- Network/Wai/Handler/Warp.hs +27/−38
- warp.cabal +1/−1
Network/Wai/Handler/Warp.hs view
@@ -64,6 +64,7 @@ , fromException ) import Control.Concurrent (forkIO, threadWaitWrite)+import qualified Data.Char as C import Data.Maybe (fromMaybe) import Data.Typeable (Typeable)@@ -206,19 +207,18 @@ parseRequest' _ [] _ = E.throwError $ NotEnoughLines [] parseRequest' port (firstLine:otherLines) remoteHost' = do (method, rpath', gets, httpversion) <- parseFirst firstLine- let rpath =+ let (host',rpath) = if S.null rpath'- then "/"- else rpath'+ then ("","/")+ else if "http://" `S.isPrefixOf` rpath'+ then S.breakByte 47 $ S.drop 7 rpath' -- '/'+ else ("", rpath') let heads = map parseHeaderNoAttr otherLines- let host = fromMaybe "" $ lookup "host" heads+ let host = fromMaybe host' $ lookup "host" heads let len = case lookup "content-length" heads of Nothing -> 0- Just bs ->- case reads $ B.unpack bs of -- FIXME could probably be optimized- (x, _):_ -> x- [] -> 0+ Just bs -> fromIntegral $ B.foldl' (\i c -> i * 10 + C.digitToInt c) 0 $ B.takeWhile C.isDigit bs let serverName' = takeUntil 58 host -- ':' -- FIXME isolate takes an Integer instead of Int or Int64. If this is a -- performance penalty, we may need our own version.@@ -245,18 +245,15 @@ parseFirst :: ByteString -> E.Iteratee S.ByteString IO (ByteString, ByteString, ByteString, HttpVersion)-parseFirst s = do- let pieces = S.split 32 s -- ' '- (method, query, http') <-- case pieces of- [x, y, z] -> return (x, y, z)- _ -> E.throwError $ BadFirstLine $ B.unpack s- let (hfirst, hsecond) = B.splitAt 5 http'- if (hfirst == "HTTP/")- then- let (rpath, qstring) = B.break (== '?') query- in return (method, rpath, qstring, hsecond)- else E.throwError NonHttp+parseFirst s = + case S.split 32 s of -- ' '+ [method, query, http'] -> do+ let (hfirst, hsecond) = B.splitAt 5 http'+ if hfirst == "HTTP/"+ then let (rpath, qstring) = S.breakByte 63 query -- '?'+ in return (method, rpath, qstring, hsecond)+ else E.throwError NonHttp+ _ -> E.throwError $ BadFirstLine $ B.unpack s {-# INLINE parseFirst #-} -- FIXME is this inline necessary? the function is only called from one place and not exported httpBuilder, spaceBuilder, newlineBuilder, transferEncodingBuilder@@ -329,8 +326,7 @@ return True where headers' = headers hv s hs isChunked'- b' =- if isChunked'+ b' = if isChunked' then headers' `mappend` chunkedTransferEncoding b `mappend` chunkedTransferTerminator@@ -342,14 +338,12 @@ res go where -- FIXME perhaps alloca a buffer per thread and reuse that in all functiosn below. Should lessen greatly the GC burden (I hope)- go s hs- | not (hasBody s req) = do+ go s hs | not (hasBody s req) = do liftIO $ Sock.sendMany socket $ L.toChunks $ toLazyByteString $ headers hv s hs False return True- go s hs =- chunk'+ go s hs = chunk' $ E.enumList 1 [headers hv s hs isChunked'] $$ E.joinI $ builderToByteString -- FIXME unsafeBuilderToByteString $$ (iterSocket th socket >> return isKeepAlive)@@ -357,10 +351,9 @@ hasLength = lookup "content-length" hs /= Nothing isChunked' = isChunked hv && not hasLength isKeepAlive = isChunked' || hasLength- chunk' i =- if isChunked'- then E.joinI $ chunk $$ i- else i+ chunk' i = if isChunked'+ then E.joinI $ chunk $$ i+ else i chunk :: E.Enumeratee Builder Builder IO Bool chunk = E.checkDone $ E.continue . step step k E.EOF = k (E.Chunks [chunkedTransferTerminator]) >>== return@@ -374,8 +367,8 @@ restLen = S.length rest -- FIXME check for colon without following space? rest' = if restLen > 1 && SU.unsafeTake 2 rest == ": "- then SU.unsafeDrop 2 rest- else rest+ then SU.unsafeDrop 2 rest+ else rest in (mkCIByteString k, rest') enumSocket :: T.Handle -> Int -> Socket -> E.Enumerator ByteString IO a@@ -386,13 +379,9 @@ bs <- liftIO $ Sock.recv socket len liftIO $ T.tickle th if S.null bs- then E.throwError SocketTimeout- else go k bs+ then E.continue k+ else k (E.Chunks [bs]) >>== inner inner step = E.returnI step- go k bs- | S.length bs == 0 = E.continue k- | otherwise = k (E.Chunks [bs]) >>== enumSocket th len socket- ------ The functions below are not warp-specific and could be split out into a --separate package.
warp.cabal view
@@ -1,5 +1,5 @@ Name: warp-Version: 0.3.2.2+Version: 0.3.2.3 Synopsis: A fast, light-weight web server for WAI applications. License: BSD3 License-file: LICENSE