@@ -13,11 +13,7 @@ import Control.Reaper
13import Data.ByteString (ByteString)
13import Data.ByteString (ByteString)
14import qualified Data.ByteString as BS
14import qualified Data.ByteString as BS
15import Data.ByteString.Internal (ByteString(..), memchr)
15import Data.ByteString.Internal (ByteString(..), memchr)
17−import qualified Data.Map.Strict as M
18import Data.Maybe (isNothing)
16import Data.Maybe (isNothing)
20−import qualified Data.Set as S
21import Data.Word (Word8)
17import Data.Word (Word8)
22import Data.Word8
18import Data.Word8
23import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
19import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)
@@ -29,6 +25,8 @@ import Network.Wai.Handler.Warp
29import Network.Wai.Internal (Response(..))
25import Network.Wai.Internal (Response(..))
30import System.IO.Unsafe (unsafePerformIO)
26import System.IO.Unsafe (unsafePerformIO)
28+import qualified Network.Wai.Middleware.Push.Referer.LimitMultiMap as M
33-- >>> :set -XOverloadedStrings
31-- >>> :set -XOverloadedStrings
@@ -47,10 +45,10 @@ type MakePushPromise = URLPath -- ^ path in referer
47-- | Type for URL path.
45-- | Type for URL path.
48type URLPath = ByteString
46type URLPath = ByteString
50−type Cache = Map URLPath (Set PushPromise)
48+type Cache = M.LimitMultiMap URLPath PushPromise
52emptyCache :: Cache
50emptyCache :: Cache
53−emptyCache = M.empty
51+emptyCache = M.empty 20 20 -- FIXME hard-coding
55cacheReaper :: Reaper Cache (URLPath,PushPromise)
53cacheReaper :: Reaper Cache (URLPath,PushPromise)
56cacheReaper = unsafePerformIO $ mkReaper settings
54cacheReaper = unsafePerformIO $ mkReaper settings
@@ -59,18 +57,12 @@ cacheReaper = unsafePerformIO $ mkReaper settings
59settings :: ReaperSettings Cache (URLPath,PushPromise)
57settings :: ReaperSettings Cache (URLPath,PushPromise)
60settings = defaultReaperSettings {
58settings = defaultReaperSettings {
61 reaperAction = \_ -> return (\_ -> emptyCache)
59 reaperAction = \_ -> return (\_ -> emptyCache)
62− , reaperCons = insert
60+ , reaperCons = M.insert
63− , reaperNull = M.null
61+ , reaperNull = M.isEmpty
64 , reaperEmpty = emptyCache
62 , reaperEmpty = emptyCache
65-- , reaperDelay = 30000000 -- FIXME hard-coding
63-- , reaperDelay = 30000000 -- FIXME hard-coding
68−insert :: (URLPath,PushPromise) -> Cache -> Cache
69−insert (path,pp) m = M.alter ins path m
71− ins Nothing = Just $ S.singleton pp
72− ins (Just set) = Just $ S.insert pp set
74-- | The middleware to push files based on Referer:.
66-- | The middleware to push files based on Referer:.
75-- Learning strategy is implemented in the first argument.
67-- Learning strategy is implemented in the first argument.
76-- Learning information is kept for 30 seconds.
68-- Learning information is kept for 30 seconds.
@@ -81,7 +73,7 @@ pushOnReferer func app req sendResponse = app req push
81 let !path = rawPathInfo req
73 let !path = rawPathInfo req
82 m <- reaperRead cacheReaper
74 m <- reaperRead cacheReaper
83 case M.lookup path m of
75 case M.lookup path m of
84− Nothing -> case requestHeaderReferer req of
76+ [] -> case requestHeaderReferer req of
85 Nothing -> return ()
77 Nothing -> return ()
86 Just referer -> do
78 Just referer -> do
87 (mauth,refPath) <- parseUrl referer
79 (mauth,refPath) <- parseUrl referer
@@ -92,9 +84,8 @@ pushOnReferer func app req sendResponse = app req push
92 case mpp of
84 case mpp of
93 Nothing -> return ()
85 Nothing -> return ()
94 Just pp -> reaperAdd cacheReaper (refPath,pp)
86 Just pp -> reaperAdd cacheReaper (refPath,pp)
95− Just pset -> do
87+ ps -> do
96− let !ps = S.toList pset
97− !h2d = defaultHTTP2Data { http2dataPushPromise = ps}
88+ let !h2d = defaultHTTP2Data { http2dataPushPromise = ps}
98 setHTTP2Data req (Just h2d)
89 setHTTP2Data req (Just h2d)
99 sendResponse res
90 sendResponse res
100 push res = sendResponse res
91 push res = sendResponse res