@@ -9,7 +9,6 @@ module Network.Wai.Handler.Warp.Request (
9 , headerLines
9 , headerLines
10 , pauseTimeoutKey
10 , pauseTimeoutKey
11 , getFileInfoKey
11 , getFileInfoKey
12− , getClientCertificateKey
13 , NoKeepAliveRequest (..)
12 , NoKeepAliveRequest (..)
@@ -22,7 +21,6 @@ import qualified Data.CaseInsensitive as CI
22import qualified Data.IORef as I
21import qualified Data.IORef as I
23import Data.Typeable (Typeable)
22import Data.Typeable (Typeable)
24import qualified Data.Vault.Lazy as Vault
23import qualified Data.Vault.Lazy as Vault
26import qualified Network.HTTP.Types as H
24import qualified Network.HTTP.Types as H
27import Network.Socket (SockAddr)
25import Network.Socket (SockAddr)
28import Network.Wai
26import Network.Wai
@@ -38,7 +36,13 @@ import Network.Wai.Handler.Warp.Header
38import Network.Wai.Handler.Warp.Imports hiding (readInt, lines)
36import Network.Wai.Handler.Warp.Imports hiding (readInt, lines)
39import Network.Wai.Handler.Warp.ReadInt
37import Network.Wai.Handler.Warp.ReadInt
40import Network.Wai.Handler.Warp.RequestHeader
38import Network.Wai.Handler.Warp.RequestHeader
41−import Network.Wai.Handler.Warp.Settings (Settings, settingsNoParsePath, settingsMaxTotalHeaderLength)
39+import Network.Wai.Handler.Warp.Settings (Settings, settingsNoParsePath)
41+----------------------------------------------------------------
43+-- FIXME come up with good values here
44+maxTotalHeaderLength :: Int
45+maxTotalHeaderLength = 50 * 1024
43----------------------------------------------------------------
47----------------------------------------------------------------
@@ -51,7 +55,6 @@ recvRequest :: Bool -- ^ first request on this connection?
51 -> Timeout.Handle
55 -> Timeout.Handle
52 -> SockAddr -- ^ Peer's address.
56 -> SockAddr -- ^ Peer's address.
53 -> Source -- ^ Where HTTP request comes from.
57 -> Source -- ^ Where HTTP request comes from.
55 -> IO (Request
58 -> IO (Request
56 ,Maybe (I.IORef Int)
59 ,Maybe (I.IORef Int)
57 ,IndexedHeader
60 ,IndexedHeader
@@ -61,8 +64,8 @@ recvRequest :: Bool -- ^ first request on this connection?
61 -- 'IndexedHeader' of HTTP request for internal use,
64 -- 'IndexedHeader' of HTTP request for internal use,
62 -- Body producing action used for flushing the request body
65 -- Body producing action used for flushing the request body
64−recvRequest firstRequest settings conn ii th addr src transport = do
67+recvRequest firstRequest settings conn ii th addr src = do
65− hdrlines <- headerLines (settingsMaxTotalHeaderLength settings) firstRequest src
68+ hdrlines <- headerLines firstRequest src
66 (method, unparsedPath, path, query, httpversion, hdr) <- parseHeaderLines hdrlines
69 (method, unparsedPath, path, query, httpversion, hdr) <- parseHeaderLines hdrlines
67 let idxhdr = indexRequestHeader hdr
70 let idxhdr = indexRequestHeader hdr
68 expect = idxhdr ! fromEnum ReqExpect
71 expect = idxhdr ! fromEnum ReqExpect
@@ -72,7 +75,6 @@ recvRequest firstRequest settings conn ii th addr src transport = do
72 rawPath = if settingsNoParsePath settings then unparsedPath else path
75 rawPath = if settingsNoParsePath settings then unparsedPath else path
73 vaultValue = Vault.insert pauseTimeoutKey (Timeout.pause th)
76 vaultValue = Vault.insert pauseTimeoutKey (Timeout.pause th)
74 $ Vault.insert getFileInfoKey (getFileInfo ii)
77 $ Vault.insert getFileInfoKey (getFileInfo ii)
75− $ Vault.insert getClientCertificateKey (tlsClientCertificate transport)
76 Vault.empty
78 Vault.empty
77 (rbody, remainingRef, bodyLength) <- bodyAndSource src cl te
79 (rbody, remainingRef, bodyLength) <- bodyAndSource src cl te
78 -- body producing function which will produce '100-continue', if needed
80 -- body producing function which will produce '100-continue', if needed
@@ -87,7 +89,7 @@ recvRequest firstRequest settings conn ii th addr src transport = do
87 , rawQueryString = query
89 , rawQueryString = query
88 , queryString = H.parseQuery query
90 , queryString = H.parseQuery query
89 , requestHeaders = hdr
91 , requestHeaders = hdr
90− , isSecure = isTransportSecure transport
92+ , isSecure = False
91 , remoteHost = addr
93 , remoteHost = addr
92 , requestBody = rbody'
94 , requestBody = rbody'
93 , vault = vaultValue
95 , vault = vaultValue
@@ -101,8 +103,8 @@ recvRequest firstRequest settings conn ii th addr src transport = do
102----------------------------------------------------------------
104----------------------------------------------------------------
104−headerLines :: Int -> Bool -> Source -> IO [ByteString]
106+headerLines :: Bool -> Source -> IO [ByteString]
105−headerLines maxTotalHeaderLength firstRequest src = do
107+headerLines firstRequest src = do
106 bs <- readSource src
108 bs <- readSource src
107 if S.null bs
109 if S.null bs
108 -- When we're working on a keep-alive connection and trying to
110 -- When we're working on a keep-alive connection and trying to
@@ -110,7 +112,7 @@ headerLines maxTotalHeaderLength firstRequest src = do
110 -- lack of data as a real exception. See the http1 function in
112 -- lack of data as a real exception. See the http1 function in
111 -- the Run module for more details.
113 -- the Run module for more details.
112 then if firstRequest then throwIO ConnectionClosedByPeer else throwIO NoKeepAliveRequest
114 then if firstRequest then throwIO ConnectionClosedByPeer else throwIO NoKeepAliveRequest
113− else push maxTotalHeaderLength src (THStatus 0 id id) bs
115+ else push src (THStatus 0 id id) bs
115data NoKeepAliveRequest = NoKeepAliveRequest
117data NoKeepAliveRequest = NoKeepAliveRequest
116 deriving (Show, Typeable)
118 deriving (Show, Typeable)
@@ -220,8 +222,8 @@ close :: Sink ByteString IO a
220close = throwIO IncompleteHeaders
222close = throwIO IncompleteHeaders
223−push :: Int -> Source -> THStatus -> ByteString -> IO [ByteString]
225+push :: Source -> THStatus -> ByteString -> IO [ByteString]
224−push maxTotalHeaderLength src (THStatus len lines prepend) bs'
226+push src (THStatus len lines prepend) bs'
225 -- Too many bytes
227 -- Too many bytes
226 | len > maxTotalHeaderLength = throwIO OverLargeHeader
228 | len > maxTotalHeaderLength = throwIO OverLargeHeader
227 | otherwise = push' mnl
229 | otherwise = push' mnl
@@ -249,13 +251,13 @@ push maxTotalHeaderLength src (THStatus len lines prepend) bs'
249 push' Nothing = do
251 push' Nothing = do
250 bst <- readSource' src
252 bst <- readSource' src
251 when (S.null bst) $ throwIO IncompleteHeaders
253 when (S.null bst) $ throwIO IncompleteHeaders
252− push maxTotalHeaderLength src status bst
254+ push src status bst
254 len' = len + bsLen
256 len' = len + bsLen
255 prepend' = S.append bs
257 prepend' = S.append bs
256 status = THStatus len' lines prepend'
258 status = THStatus len' lines prepend'
257 -- Found a newline, but next line continues as a multiline header
259 -- Found a newline, but next line continues as a multiline header
258− push' (Just (end, True)) = push maxTotalHeaderLength src status rest
260+ push' (Just (end, True)) = push src status rest
260 rest = S.drop (end + 1) bs
262 rest = S.drop (end + 1) bs
261 prepend' = S.append (SU.unsafeTake (checkCR bs end) bs)
263 prepend' = S.append (SU.unsafeTake (checkCR bs end) bs)
@@ -274,12 +276,12 @@ push maxTotalHeaderLength src (THStatus len lines prepend) bs'
274 in if start < bsLen then
276 in if start < bsLen then
275 -- more bytes in this chunk, push again
277 -- more bytes in this chunk, push again
276 let bs'' = SU.unsafeDrop start bs
278 let bs'' = SU.unsafeDrop start bs
277− in push maxTotalHeaderLength src status bs''
279+ in push src status bs''
279 -- no more bytes in this chunk, ask for more
281 -- no more bytes in this chunk, ask for more
280 bst <- readSource' src
282 bst <- readSource' src
281 when (S.null bs) $ throwIO IncompleteHeaders
283 when (S.null bs) $ throwIO IncompleteHeaders
282− push maxTotalHeaderLength src status bst
284+ push src status bst
284 start = end + 1 -- start of next chunk
286 start = end + 1 -- start of next chunk
285 line = SU.unsafeTake (checkCR bs end) bs
287 line = SU.unsafeTake (checkCR bs end) bs
@@ -297,7 +299,3 @@ pauseTimeoutKey = unsafePerformIO Vault.newKey
297getFileInfoKey :: Vault.Key (FilePath -> IO FileInfo)
299getFileInfoKey :: Vault.Key (FilePath -> IO FileInfo)
298getFileInfoKey = unsafePerformIO Vault.newKey
300getFileInfoKey = unsafePerformIO Vault.newKey
299{-# NOINLINE getFileInfoKey #-}
301{-# NOINLINE getFileInfoKey #-}
301−getClientCertificateKey :: Vault.Key (Maybe CertificateChain)
302−getClientCertificateKey = unsafePerformIO Vault.newKey
303−{-# NOINLINE getClientCertificateKey #-}