@@ -13,11 +13,7 @@ import Control.Reaper
1313import Data.ByteString (ByteString)
1414import qualified Data.ByteString as BS
1515import Data.ByteString.Internal (ByteString(..), memchr)
16−import Data.Map (Map)
17−import qualified Data.Map.Strict as M
1816import Data.Maybe (isNothing)
19−import Data.Set (Set)
20−import qualified Data.Set as S
2117import Data.Word (Word8)
2218import Data.Word8
2319import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
@@ -29,6 +25,8 @@ import Network.Wai.Handler.Warp
2925import Network.Wai.Internal (Response(..))
3026import System.IO.Unsafe (unsafePerformIO)
3127
28+import qualified Network.Wai.Middleware.Push.Referer.LimitMultiMap as M
29+
3230-- $setup
3331-- >>> :set -XOverloadedStrings
3432
@@ -47,10 +45,10 @@ type MakePushPromise = URLPath -- ^ path in referer
4745-- | Type for URL path.
4846type URLPath = ByteString
4947
50−type Cache = Map URLPath (Set PushPromise)
48+type Cache = M.LimitMultiMap URLPath PushPromise
5149
5250emptyCache :: Cache
53−emptyCache = M.empty
51+emptyCache = M.empty 20 20 -- FIXME hard-coding
5452
5553cacheReaper :: Reaper Cache (URLPath,PushPromise)
5654cacheReaper = unsafePerformIO $ mkReaper settings
@@ -59,18 +57,12 @@ cacheReaper = unsafePerformIO $ mkReaper settings
5957settings :: ReaperSettings Cache (URLPath,PushPromise)
6058settings = defaultReaperSettings {
6159 reaperAction = \_ -> return (\_ -> emptyCache)
62− , reaperCons = insert
63− , reaperNull = M.null
60+ , reaperCons = M.insert
61+ , reaperNull = M.isEmpty
6462 , reaperEmpty = emptyCache
6563-- , reaperDelay = 30000000 -- FIXME hard-coding
6664 }
6765
68−insert :: (URLPath,PushPromise) -> Cache -> Cache
69−insert (path,pp) m = M.alter ins path m
70− where
71− ins Nothing = Just $ S.singleton pp
72− ins (Just set) = Just $ S.insert pp set
73−
7466-- | The middleware to push files based on Referer:.
7567-- Learning strategy is implemented in the first argument.
7668-- Learning information is kept for 30 seconds.
@@ -81,7 +73,7 @@ pushOnReferer func app req sendResponse = app req push
8173 let !path = rawPathInfo req
8274 m <- reaperRead cacheReaper
8375 case M.lookup path m of
84− Nothing -> case requestHeaderReferer req of
76+ [] -> case requestHeaderReferer req of
8577 Nothing -> return ()
8678 Just referer -> do
8779 (mauth,refPath) <- parseUrl referer
@@ -92,9 +84,8 @@ pushOnReferer func app req sendResponse = app req push
9284 case mpp of
9385 Nothing -> return ()
9486 Just pp -> reaperAdd cacheReaper (refPath,pp)
95− Just pset -> do
96− let !ps = S.toList pset
97− !h2d = defaultHTTP2Data { http2dataPushPromise = ps}
87+ ps -> do
88+ let !h2d = defaultHTTP2Data { http2dataPushPromise = ps}
9889 setHTTP2Data req (Just h2d)
9990 sendResponse res
10091 push res = sendResponse res