on master help sign in
passing IndexHeader to sendResponse.
commit7fbe13d4acd9026909d88ed836360d560ab1eb29 authorKazu Yamamoto <kazu@iij.ad.jp> dateTue 29 Oct 2013, 20:45 (13 years ago) parentbfe178e
5 files changed+41−30
warp/Network/Wai/Handler/Warp.hs+5−1 warp/Network/Wai/Handler/Warp/Header.hs+3 warp/Network/Wai/Handler/Warp/Request.hs+2−1 warp/Network/Wai/Handler/Warp/Response.hs+26−24 warp/Network/Wai/Handler/Warp/Run.hs+5−4
warp/Network/Wai/Handler/Warp.hs+5−1
@@ -52,6 +52,9 @@ module Network.Wai.Handler.Warp (
5252 -- ** Data types
5353 , InternalInfo
5454 -- ** Request and response
55+ , HeaderValue
56+ , IndexedHeader
57+ , defaultIndexRequestHeader
5558 , recvRequest
5659 , sendResponse
5760#if TEST
@@ -70,4 +73,5 @@ import Network.Wai.Handler.Warp.Response
7073import Network.Wai.Handler.Warp.Run
7174import Network.Wai.Handler.Warp.Settings
7275import Network.Wai.Handler.Warp.Timeout
73−import Network.Wai.Handler.Warp.Types
76+import Network.Wai.Handler.Warp.Types
77+import Network.Wai.Handler.Warp.Header
warp/Network/Wai/Handler/Warp/Header.hs+3
@@ -28,6 +28,9 @@ idxHost = 5
2828requestMaxIndex :: Int
2929requestMaxIndex = 5
3030
31+defaultIndexRequestHeader :: IndexedHeader
32+defaultIndexRequestHeader = array (0,requestMaxIndex) [(i,Nothing)|i<-[0..requestMaxIndex]]
33+
3134----------------------------------------------------------------
3235
3336traverseHeader :: [Header] -> Int -> IndexedHeader
warp/Network/Wai/Handler/Warp/Request.hs+2−1
@@ -43,6 +43,7 @@ recvRequest :: Connection
4343 -> SockAddr
4444 -> Source IO ByteString
4545 -> IO (Request
46+ ,IndexedHeader
4647 ,IO (ResumableSource IO ByteString))
4748recvRequest conn timeoutHandle addr src0 = do
4849 (src, hdrlines) <- src0 $$+ headerLines
@@ -67,7 +68,7 @@ recvRequest conn timeoutHandle addr src0 = do
6768 , vault = mempty
6869 , requestBodyLength = bodyLength
6970 }
70− return (req, getSource)
71+ return (req, idxhdr, getSource)
7172
7273----------------------------------------------------------------
7374
warp/Network/Wai/Handler/Warp/Response.hs+26−24
@@ -12,6 +12,7 @@ import Blaze.ByteString.Builder.HTTP (chunkedTransferEncoding, chunkedTransferTe
1212import Control.Applicative
1313import Control.Exception
1414import Control.Monad.IO.Class (liftIO)
15+import Data.Array ((!))
1516import Data.ByteString (ByteString)
1617import qualified Data.ByteString.Char8 as B (pack)
1718import qualified Data.CaseInsensitive as CI
@@ -20,17 +21,18 @@ import Data.Conduit.Blaze (builderToByteString)
2021import qualified Data.Conduit.List as CL
2122import Data.Maybe (isJust, listToMaybe)
2223import Data.Monoid (mappend)
24+import Network.HTTP.Attoparsec (parseByteRanges)
2325import qualified Network.HTTP.Types as H
2426import Network.Wai
25−import Network.Wai.Internal
27+import Network.Wai.Handler.Warp.Header
2628import Network.Wai.Handler.Warp.ReadInt
27−import Network.Wai.Handler.Warp.Settings
2829import qualified Network.Wai.Handler.Warp.ResponseHeader as RH
30+import Network.Wai.Handler.Warp.Settings
2931import qualified Network.Wai.Handler.Warp.Timeout as T
3032import Network.Wai.Handler.Warp.Types
31−import qualified System.PosixCompat.Files as P
32−import Network.HTTP.Attoparsec (parseByteRanges)
33+import Network.Wai.Internal
3334import Numeric (showInt)
35+import qualified System.PosixCompat.Files as P
3436
3537----------------------------------------------------------------
3638----------------------------------------------------------------
@@ -38,12 +40,13 @@ import Numeric (showInt)
3840sendResponse :: Settings
3941 -> InternalInfo -> Request -> Connection
4042 -> (forall a. IO a -> IO a) -- ^ restore masking state
43+ -> IndexedHeader
4144 -> Response
4245 -> IO Bool
4346
4447----------------------------------------------------------------
4548
46−sendResponse settings ii req conn restore (ResponseFile s0 hs0 path mpart0) =
49+sendResponse settings ii req conn restore reqidxhdr (ResponseFile s0 hs0 path mpart0) =
4750 restore $ headerAndLength >>= sendResponse'
4851 where
4952 hs = addAccept hs0
@@ -60,14 +63,13 @@ sendResponse settings ii req conn restore (ResponseFile s0 hs0 path mpart0) =
6063 let (s, addRange, beg, end) =
6164 case mpart0 of
6265 Just part -> (s0, id, filePartOffset part, filePartByteCount part)
63− Nothing ->
64− case lookup H.hRange (requestHeaders req) >>= parseByteRanges >>= listToMaybe of
65− Just range | s0 == H.status200 ->
66− case range of
67− H.ByteRangeFrom from -> rangeRes cl from (cl - 1)
68− H.ByteRangeFromTo from to -> rangeRes cl from to
69− H.ByteRangeSuffix count -> rangeRes cl (cl - count) (cl - 1)
70− _ -> (s0, id, 0, cl)
66+ Nothing -> case reqidxhdr ! idxRange >>= parseByteRanges >>= listToMaybe of
67+ Just range | s0 == H.status200 ->
68+ case range of
69+ H.ByteRangeFrom from -> rangeRes cl from (cl - 1)
70+ H.ByteRangeFromTo from to -> rangeRes cl from to
71+ H.ByteRangeSuffix count -> rangeRes cl (cl - count) (cl - 1)
72+ _ -> (s0, id, 0, cl)
7173 hs'
7274 | hadLength = hs
7375 | otherwise = addLength end hs
@@ -95,16 +97,16 @@ sendResponse settings ii req conn restore (ResponseFile s0 hs0 path mpart0) =
9597 return isPersist -- FIXME isKeepAlive?
9698 where
9799 version = httpVersion req
98− (isPersist,_) = infoFromRequest req
100+ (isPersist,_) = infoFromRequest req reqidxhdr
99101
100102 sendResponse' (Left (_ :: SomeException)) =
101− sendResponse settings ii req conn restore notFound
103+ sendResponse settings ii req conn restore reqidxhdr notFound
102104 where
103105 notFound = responseLBS H.status404 [(H.hContentType, "text/plain")] "File not found"
104106
105107----------------------------------------------------------------
106108
107−sendResponse settings ii req conn restore (ResponseBuilder s hs b)
109+sendResponse settings ii req conn restore reqidxhdr (ResponseBuilder s hs b)
108110 | hasBody s req = restore $ do
109111 header <- composeHeaderBuilder settings version s hs needsChunked
110112 let body
@@ -122,12 +124,12 @@ sendResponse settings ii req conn restore (ResponseBuilder s hs b)
122124 where
123125 th = threadHandle ii
124126 version = httpVersion req
125− reqinfo@(isPersist,_) = infoFromRequest req
127+ reqinfo@(isPersist,_) = infoFromRequest req reqidxhdr
126128 (isKeepAlive, needsChunked) = infoFromResponse hs reqinfo
127129
128130----------------------------------------------------------------
129131
130−sendResponse settings ii req conn restore (ResponseSource s hs withBodyFlush)
132+sendResponse settings ii req conn restore reqidxhdr (ResponseSource s hs withBodyFlush)
131133 | hasBody s req = withBodyFlush $ \bodyFlush -> restore $ do
132134 header <- liftIO $ composeHeaderBuilder settings version s hs needsChunked
133135 let src = CL.sourceList [header] `mappend` cbody bodyFlush
@@ -152,7 +154,7 @@ sendResponse settings ii req conn restore (ResponseSource s hs withBodyFlush)
152154 chunk :: Conduit Builder IO Builder
153155 chunk = await >>= maybe (yield chunkedTransferTerminator) (\x -> yield (chunkedTransferEncoding x) >> chunk)
154156 version = httpVersion req
155− reqinfo@(isPersist,_) = infoFromRequest req
157+ reqinfo@(isPersist,_) = infoFromRequest req reqidxhdr
156158 (isKeepAlive, needsChunked) = infoFromResponse hs reqinfo
157159
158160----------------------------------------------------------------
@@ -177,16 +179,16 @@ connSink Connection { connSendAll = send } th =
177179
178180----------------------------------------------------------------
179181
180−infoFromRequest :: Request -> (Bool,Bool)
181−infoFromRequest req = (checkPersist req, checkChunk req)
182+infoFromRequest :: Request -> IndexedHeader -> (Bool,Bool)
183+infoFromRequest req reqidxhdr = (checkPersist req reqidxhdr, checkChunk req)
182184
183−checkPersist :: Request -> Bool
184−checkPersist req
185+checkPersist :: Request -> IndexedHeader -> Bool
186+checkPersist req reqidxhdr
185187 | ver == H.http11 = checkPersist11 conn
186188 | otherwise = checkPersist10 conn
187189 where
188190 ver = httpVersion req
189− conn = lookup H.hConnection $ requestHeaders req
191+ conn = reqidxhdr ! idxConnection
190192 checkPersist11 (Just x)
191193 | CI.foldCase x == "close" = False
192194 checkPersist11 _ = True
warp/Network/Wai/Handler/Warp/Run.hs+5−4
@@ -21,13 +21,14 @@ import Network.Socket (accept, SockAddr)
2121import qualified Network.Socket.ByteString as Sock
2222import Network.Wai
2323import qualified Network.Wai.Handler.Warp.FdCache as F
24+import Network.Wai.Handler.Warp.Header
2425import Network.Wai.Handler.Warp.Recv
2526import Network.Wai.Handler.Warp.Request
2627import Network.Wai.Handler.Warp.Response
28+import Network.Wai.Handler.Warp.SendFile
2729import Network.Wai.Handler.Warp.Settings
2830import qualified Network.Wai.Handler.Warp.Timeout as T
2931import Network.Wai.Handler.Warp.Types
30−import Network.Wai.Handler.Warp.SendFile
3132
3233#if WINDOWS
3334import qualified Control.Concurrent.MVar as MV
@@ -217,14 +218,14 @@ serveConnection timeoutHandle settings ii app conn remoteHost' =
217218 th = threadHandle ii
218219
219220 send500 = void $ mask $ \restore ->
220− sendResponse settings ii dummyreq conn restore internalError
221+ sendResponse settings ii dummyreq conn restore defaultIndexRequestHeader internalError
221222
222223 dummyreq = defaultRequest { remoteHost = remoteHost' }
223224
224225 internalError = responseLBS H.internalServerError500 [(H.hContentType, "text/plain")] "Something went wrong"
225226
226227 serveConnection'' fromClient = do
227− (env, getSource) <- recvRequest conn timeoutHandle remoteHost' fromClient
228+ (env, idxhdr, getSource) <- recvRequest conn timeoutHandle remoteHost' fromClient
228229 case settingsIntercept settings env of
229230 Nothing -> do
230231 -- Let the application run for as long as it wants
@@ -236,7 +237,7 @@ serveConnection timeoutHandle settings ii app conn remoteHost' =
236237 keepAlive <- mask $ \restore -> do
237238 res <- restore $ app env
238239 liftIO $ T.resume th
239− sendResponse settings ii env conn restore res
240+ sendResponse settings ii env conn restore idxhdr res
240241
241242 -- We just send a Response and it takes a time to
242243 -- receive a Request again. If we immediately call recv,