@@ -139,9 +139,9 @@ import Data.List (isPrefixOf)
139
139
import Data.Maybe (fromMaybe , listToMaybe , catMaybes )
140
140
import Control.Applicative (Applicative (.. ), (<$>) )
141
141
#ifdef MTL1
142
- import Control.Monad (filterM , when , ap )
142
+ import Control.Monad (filterM , forM_ , when , ap )
143
143
#else
144
- import Control.Monad (filterM , when )
144
+ import Control.Monad (filterM , forM_ , when )
145
145
#endif
146
146
import Control.Monad.State (StateT (.. ), MonadIO (.. ), modify , gets , withStateT , evalStateT , MonadState (.. ))
147
147
@@ -820,6 +820,8 @@ request' nullVal rqState rq = do
820
820
-- add new cookies to browser state
821
821
handleCookies uri (uriAuthToString $ reqURIAuth rq)
822
822
(retrieveHeaders HdrSetCookie rsp)
823
+ -- Deal with "Connection: close" in response.
824
+ handleConnectionClose (reqURIAuth rq) (retrieveHeaders HdrConnection rsp)
823
825
mbMxAuths <- getMaxAuthAttempts
824
826
case rspCode rsp of
825
827
(4 ,0 ,1 ) -- Credentials not sent or refused.
@@ -1000,6 +1002,18 @@ updateConnectionPool c = do
1000
1002
defaultMaxPoolSize :: Int
1001
1003
defaultMaxPoolSize = 5
1002
1004
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
+
1003
1017
handleCookies :: URI -> String -> [Header ] -> BrowserAction t ()
1004
1018
handleCookies _ _ [] = return () -- cut short the silliness.
1005
1019
handleCookies uri dom cookieHeaders = do
@@ -1015,6 +1029,15 @@ handleCookies uri dom cookieHeaders = do
1015
1029
where
1016
1030
(errs, newCookies) = processCookieHeaders dom cookieHeaders
1017
1031
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
+
1018
1041
------------------------------------------------------------------
1019
1042
----------------------- Miscellaneous ----------------------------
1020
1043
------------------------------------------------------------------
0 commit comments