@@ -339,13 +339,16 @@ serveConnection conn ii origAddr isSecure' settings app = do
339339 recvSendLoop addr istatus fromClient = do
340340 (req', mremainingRef, idxhdr) <- recvRequest settings conn ii addr fromClient
341341 let req = req' { isSecure = isSecure' }
342− processRequest addr istatus fromClient req mremainingRef idxhdr
343− `catch` \e -> do
342+ keepAlive <- processRequest istatus fromClient req mremainingRef idxhdr
343+ `E.catch` \e -> do
344344 -- Call the user-supplied exception handlers, passing the request.
345345 sendErrorResponse addr istatus e
346346 onE settings (Just req) e
347+ -- Don't throw the error again to prevent calling onE twice.
348+ return False
349+ when keepAlive $ recvSendLoop addr istatus fromClient
347350
348− processRequest addr istatus fromClient req mremainingRef idxhdr = do
351+ processRequest istatus fromClient req mremainingRef idxhdr = do
349352 -- Let the application run for as long as it wants
350353 T.pause th
351354
@@ -376,7 +379,9 @@ serveConnection conn ii origAddr isSecure' settings app = do
376379 -- the number of cores is small.
377380 Conc.yield
378381
379− when keepAlive $ do
382+ if not keepAlive then
383+ return False
384+ else do
380385 -- If there is an unknown or large amount of data to still be read
381386 -- from the request body, simple drop this connection instead of
382387 -- reading it all in to satisfy a keep-alive request.
@@ -384,18 +389,23 @@ serveConnection conn ii origAddr isSecure' settings app = do
384389 Nothing -> do
385390 flushEntireBody (requestBody req)
386391 T.resume th
387− recvSendLoop addr istatus fromClient
392+ return True
388393 Just maxToRead -> do
389394 let tryKeepAlive = do
390395 -- flush the rest of the request body
391396 isComplete <- flushBody (requestBody req) maxToRead
392− when isComplete $ do
397+ if isComplete then do
393398 T.resume th
394− recvSendLoop addr istatus fromClient
399+ return True
400+ else
401+ return False
395402 case mremainingRef of
396403 Just ref -> do
397404 remaining <- readIORef ref
398− when (remaining <= maxToRead) tryKeepAlive
405+ if remaining <= maxToRead then
406+ tryKeepAlive
407+ else
408+ return False
399409 Nothing -> tryKeepAlive
400410
401411flushEntireBody :: IO ByteString -> IO ()