on master help sign in
Fixed rpath and chunked enum
1354eb4Michael Snoyman
Network/Wai/Handler/Warp.hs+4−6
@@ -59,7 +59,7 @@ import Blaze.ByteString.Builder.HTTP
59import Blaze.ByteString.Builder
59import Blaze.ByteString.Builder
60 (copyByteString, Builder, toLazyByteString, toByteStringIO)
60 (copyByteString, Builder, toLazyByteString, toByteStringIO)
61import Blaze.ByteString.Builder.Char8 (fromChar, fromShow)
61import Blaze.ByteString.Builder.Char8 (fromChar, fromShow)
62−import Data.Monoid (mappend)
62+import Data.Monoid (mappend, mconcat)
63import Network.Socket.SendFile (sendFile)
63import Network.Socket.SendFile (sendFile)
64import Network.Socket.Enumerator (iterSocket)
64import Network.Socket.Enumerator (iterSocket)
65
65
@@ -133,9 +133,7 @@ parseRequest' port (firstLine:otherLines) remoteHost' = do
133 let rpath =
133 let rpath =
134 if S.null rpath'
134 if S.null rpath'
135 then "/"
135 then "/"
136− else if '/' == B.head rpath'
137− then "/"
138− else B.cons '/' rpath'
136+ else rpath'
139 let heads = map parseHeaderNoAttr otherLines
137 let heads = map parseHeaderNoAttr otherLines
140 let host = fromMaybe "" $ lookup "host" heads
138 let host = fromMaybe "" $ lookup "host" heads
141 let len =
139 let len =
@@ -276,8 +274,8 @@ sendResponse req hv socket (ResponseEnumerator res) =
276 chunk = E.checkDone $ E.continue . step
274 chunk = E.checkDone $ E.continue . step
277 step k E.EOF = k (E.Chunks [chunkedTransferTerminator]) >>== return
275 step k E.EOF = k (E.Chunks [chunkedTransferTerminator]) >>== return
278 step k (E.Chunks []) = E.continue $ step k
276 step k (E.Chunks []) = E.continue $ step k
279− -- FIXME ensure that the mconcat on the concents here is unnecessary
277+ step k (E.Chunks [x]) = k (E.Chunks [chunkedTransferEncoding x]) >>== chunk
280− step k x = k x >>== chunk
278+ step k (E.Chunks xs) = k (E.Chunks [chunkedTransferEncoding $ mconcat xs]) >>== chunk
281
279
282parseHeaderNoAttr :: ByteString -> (CIByteString, ByteString)
280parseHeaderNoAttr :: ByteString -> (CIByteString, ByteString)
283parseHeaderNoAttr s =
281parseHeaderNoAttr s =
pong.hs+59−3
@@ -1,11 +1,67 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2import Network.Wai
2import Network.Wai
3import Network.Wai.Handler.Warp
3import Network.Wai.Handler.Warp
4−import Blaze.ByteString.Builder (fromByteString)
4+import Blaze.ByteString.Builder (copyByteString)
5+import Data.Monoid
6+import Data.Enumerator (run_, enumList, ($$))
5
7
8+main = run 3000 app
9+
10+app req = return $
11+ case pathInfo req of
12+ "/builder/withlen" -> builderWithLen
13+ "/builder/nolen" -> builderNoLen
14+ "/enum/withlen" -> enumWithLen
15+ "/enum/nolen" -> enumNoLen
16+ "/file/withlen" -> fileWithLen
17+ "/file/nolen" -> fileNoLen
18+ _ -> index $ pathInfo req
19+
6−main = run 3000 $ const $ return $ ResponseBuilder
20+builderWithLen = ResponseBuilder
7 status200
21 status200
8 [ ("Content-Type", "text/plain")
22 [ ("Content-Type", "text/plain")
9 , ("Content-Length", "4")
23 , ("Content-Length", "4")
10 ]
24 ]
11− $ fromByteString "PONG"
25+ $ copyByteString "PONG"
26+
27+builderNoLen = ResponseBuilder
28+ status200
29+ [ ("Content-Type", "text/plain")
30+ ]
31+ $ copyByteString "PONG"
32+
33+fileWithLen = ResponseFile
34+ status200
35+ [ ("Content-Type", "text/plain")
36+ , ("Content-Length", "4")
37+ ]
38+ "pong.txt"
39+
40+fileNoLen = ResponseFile
41+ status200
42+ [ ("Content-Type", "text/plain")
43+ ]
44+ "pong.txt"
45+
46+enumWithLen = ResponseEnumerator $ \f ->
47+ run_ $ (enumList 1 $ map copyByteString ["P", "O", "NG"]) $$ f
48+ status200
49+ [ ("Content-Type", "text/plain")
50+ , ("Content-Length", "4")
51+ ]
52+
53+enumNoLen = ResponseEnumerator $ \f ->
54+ run_ $ (enumList 1 $ map copyByteString ["P", "O", "NG"]) $$ f
55+ status200
56+ [ ("Content-Type", "text/plain")
57+ ]
58+
59+index p = ResponseBuilder status200 [("Content-Type", "text/html")] $ mconcat $ map copyByteString
60+ [ "<p><a href='/builder/withlen'>builder withlen</a></p>\n"
61+ , "<p><a href='/builder/nolen'>builder nolen</a></p>\n"
62+ , "<p><a href='/enum/withlen'>enum withlen</a></p>\n"
63+ , "<p><a href='/enum/nolen'>enum nolen</a></p>\n"
64+ , "<p><a href='/file/withlen'>file withlen</a></p>\n"
65+ , "<p><a href='/file/nolen'>file nolen</a></p>\n"
66+ , p
67+ ]