Skip to content

Commit 30d163c

Browse files
committed
Merge pull request #49 from ian-ross/issue-14
Fix #14: connection pool tries to reuse closed connections
2 parents 9a8a49e + 69d57a3 commit 30d163c

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

Network/Browser.hs

+25-2
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,9 @@ import Data.List (isPrefixOf)
139139
import Data.Maybe (fromMaybe, listToMaybe, catMaybes )
140140
import Control.Applicative (Applicative (..), (<$>))
141141
#ifdef MTL1
142-
import Control.Monad (filterM, when, ap)
142+
import Control.Monad (filterM, forM_, when, ap)
143143
#else
144-
import Control.Monad (filterM, when)
144+
import Control.Monad (filterM, forM_, when)
145145
#endif
146146
import Control.Monad.State (StateT (..), MonadIO (..), modify, gets, withStateT, evalStateT, MonadState (..))
147147

@@ -820,6 +820,8 @@ request' nullVal rqState rq = do
820820
-- add new cookies to browser state
821821
handleCookies uri (uriAuthToString $ reqURIAuth rq)
822822
(retrieveHeaders HdrSetCookie rsp)
823+
-- Deal with "Connection: close" in response.
824+
handleConnectionClose (reqURIAuth rq) (retrieveHeaders HdrConnection rsp)
823825
mbMxAuths <- getMaxAuthAttempts
824826
case rspCode rsp of
825827
(4,0,1) -- Credentials not sent or refused.
@@ -1000,6 +1002,18 @@ updateConnectionPool c = do
10001002
defaultMaxPoolSize :: Int
10011003
defaultMaxPoolSize = 5
10021004

1005+
cleanConnectionPool :: HStream hTy
1006+
=> URIAuth -> BrowserAction (HandleStream hTy) ()
1007+
cleanConnectionPool uri = do
1008+
let ep = EndPoint (uriRegName uri) (uriAuthPort Nothing uri)
1009+
pool <- gets bsConnectionPool
1010+
bad <- liftIO $ mapM (\c -> c `isTCPConnectedTo` ep) pool
1011+
let tmp = zip bad pool
1012+
newpool = map snd $ filter (not . fst) tmp
1013+
toclose = map snd $ filter fst tmp
1014+
liftIO $ forM_ toclose close
1015+
modify (\b -> b { bsConnectionPool = newpool })
1016+
10031017
handleCookies :: URI -> String -> [Header] -> BrowserAction t ()
10041018
handleCookies _ _ [] = return () -- cut short the silliness.
10051019
handleCookies uri dom cookieHeaders = do
@@ -1015,6 +1029,15 @@ handleCookies uri dom cookieHeaders = do
10151029
where
10161030
(errs, newCookies) = processCookieHeaders dom cookieHeaders
10171031

1032+
handleConnectionClose :: HStream hTy
1033+
=> URIAuth -> [Header]
1034+
-> BrowserAction (HandleStream hTy) ()
1035+
handleConnectionClose _ [] = return ()
1036+
handleConnectionClose uri headers = do
1037+
let doClose = any (== "close") $ map headerToConnType headers
1038+
when doClose $ cleanConnectionPool uri
1039+
where headerToConnType (Header _ t) = map toLower t
1040+
10181041
------------------------------------------------------------------
10191042
----------------------- Miscellaneous ----------------------------
10201043
------------------------------------------------------------------

0 commit comments

Comments
 (0)