on master help sign in
sendfile support
65d3136Michael Snoyman
Network/Wai/Handler/Warp.hs+12−3
@@ -25,6 +25,8 @@ import qualified System.IO
25
25
26import Data.ByteString (ByteString)
26import Data.ByteString (ByteString)
27import qualified Data.ByteString.Char8 as B
27import qualified Data.ByteString.Char8 as B
28+import qualified Data.ByteString as S
29+import qualified Data.ByteString.Lazy as L
28import Network
30import Network
29 ( listenOn, accept, sClose, PortID(PortNumber), Socket
31 ( listenOn, accept, sClose, PortID(PortNumber), Socket
30 , withSocketsDo)
32 , withSocketsDo)
@@ -45,9 +47,10 @@ import Data.Enumerator.IO (iterHandle)
45import Blaze.ByteString.Builder.Enumerator (builderToByteString)
47import Blaze.ByteString.Builder.Enumerator (builderToByteString)
46import Blaze.ByteString.Builder.HTTP
48import Blaze.ByteString.Builder.HTTP
47 (chunkedTransferEncoding, chunkedTransferTerminator)
49 (chunkedTransferEncoding, chunkedTransferTerminator)
48−import Blaze.ByteString.Builder (fromByteString, Builder)
50+import Blaze.ByteString.Builder (fromByteString, Builder, toLazyByteString)
49import Blaze.ByteString.Builder.Char8 (fromChar, fromString)
51import Blaze.ByteString.Builder.Char8 (fromChar, fromString)
50import Data.Monoid (mconcat)
52import Data.Monoid (mconcat)
53+import Network.Socket.SendFile (unsafeSendFile)
51
54
52import Control.Monad.IO.Class (liftIO)
55import Control.Monad.IO.Class (liftIO)
53import Data.ByteString.Lazy.Internal (defaultChunkSize)
56import Data.ByteString.Lazy.Internal (defaultChunkSize)
@@ -195,8 +198,14 @@ isChunked :: HttpVersion -> Bool
195isChunked = (==) http11
198isChunked = (==) http11
196
199
197sendResponse :: HttpVersion -> Handle -> Response -> IO Bool
200sendResponse :: HttpVersion -> Handle -> Response -> IO Bool
198−sendResponse hv handle res =
201+sendResponse hv handle (ResponseFile s hs fp) = do
199− responseEnumerator res go
202+ mapM_ (S.hPut handle) $ L.toChunks $ toLazyByteString $ headers hv s hs False
203+ unsafeSendFile handle fp
204+ if lookup "content-length" hs == Nothing
205+ then return False
206+ else S.hPut handle "\r\n\r\n" >> return True
207+sendResponse hv handle (ResponseEnumerator res) =
208+ res go
200 where
209 where
201 go s hs =
210 go s hs =
202 chunk'
211 chunk'
warp.cabal+1
@@ -20,6 +20,7 @@ Library
20 , transformers >= 0.2 && < 0.3
20 , transformers >= 0.2 && < 0.3
21 , enumerator >= 0.4 && < 0.5
21 , enumerator >= 0.4 && < 0.5
22 , blaze-builder >= 0.2.1.3 && < 0.3
22 , blaze-builder >= 0.2.1.3 && < 0.3
23+ , sendfile >= 0.7.2 && < 0.8
23 Exposed-modules: Network.Wai.Handler.Warp
24 Exposed-modules: Network.Wai.Handler.Warp
24 ghc-options: -Wall
25 ghc-options: -Wall
25
26