packages feed

wai-http2-extra 0.0.1 → 0.0.2

raw patch · 3 files changed

+72/−33 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Network.Wai.Middleware.Push.Referer: type MakePushPromise = URLPath path in referer -> URLPath path to be pushed -> FilePath file to be pushed -> IO (Maybe PushPromise)
+ Network.Wai.Middleware.Push.Referer: type MakePushPromise = URLPath path in referer (key: /index.html) -> URLPath path to be pushed (value: /style.css) -> FilePath file to be pushed (file_path/style.css) -> IO (Maybe PushPromise)

Files

Network/Wai/Middleware/Push/Referer.hs view
@@ -13,11 +13,7 @@ import Data.ByteString (ByteString) import qualified Data.ByteString as BS import Data.ByteString.Internal (ByteString(..), memchr)-import Data.Map (Map)-import qualified Data.Map.Strict as M import Data.Maybe (isNothing)-import Data.Set (Set)-import qualified Data.Set as S import Data.Word (Word8) import Data.Word8 import Foreign.ForeignPtr (withForeignPtr, ForeignPtr)@@ -29,6 +25,8 @@ import Network.Wai.Internal (Response(..)) import System.IO.Unsafe (unsafePerformIO) +import qualified Network.Wai.Middleware.Push.Referer.LimitMultiMap as M+ -- $setup -- >>> :set -XOverloadedStrings @@ -39,18 +37,18 @@ --   this function should return 'Just'. --   If 'Nothing' is returned, --   the middleware learns nothing.-type MakePushPromise = URLPath  -- ^ path in referer-                    -> URLPath  -- ^ path to be pushed-                    -> FilePath -- ^ file to be pushed+type MakePushPromise = URLPath  -- ^ path in referer  (key: /index.html)+                    -> URLPath  -- ^ path to be pushed (value: /style.css)+                    -> FilePath -- ^ file to be pushed (file_path/style.css)                     -> IO (Maybe PushPromise)  -- | Type for URL path. type URLPath = ByteString -type Cache = Map URLPath (Set PushPromise)+type Cache = M.LimitMultiMap URLPath PushPromise  emptyCache :: Cache-emptyCache = M.empty+emptyCache = M.empty 20 20 -- FIXME hard-coding  cacheReaper :: Reaper Cache (URLPath,PushPromise) cacheReaper = unsafePerformIO $ mkReaper settings@@ -59,30 +57,30 @@ settings :: ReaperSettings Cache (URLPath,PushPromise) settings = defaultReaperSettings {       reaperAction = \_ -> return (\_ -> emptyCache)-    , reaperCons   = insert-    , reaperNull   = M.null+    , reaperCons   = M.insert+    , reaperNull   = M.isEmpty     , reaperEmpty  = emptyCache --  , reaperDelay  = 30000000 -- FIXME hard-coding     } -insert :: (URLPath,PushPromise) -> Cache -> Cache-insert (path,pp) m = M.alter ins path m-  where-    ins Nothing    = Just $ S.singleton pp-    ins (Just set) = Just $ S.insert pp set- -- | The middleware to push files based on Referer:. --   Learning strategy is implemented in the first argument.---   Learning information is kept for 30 seconds.+--+--   Cache of learning information is kept for 30 seconds+--   and cleared completely.+--   Max number of keys (e.g. index.html) is 20.+--   Max number of values (e.g. style.css) for each key is 20.+--   These numbers are hard-coded at this moment. pushOnReferer :: MakePushPromise -> Middleware-pushOnReferer func app req sendResponse = app req $ \res -> do-    let !path = rawPathInfo req-    m <- reaperRead cacheReaper-    case M.lookup path m of-        Nothing -> case requestHeaderReferer req of-            Nothing      -> return ()-            Just referer -> case res of-                ResponseFile (Status 200 "OK") _ file Nothing -> do+pushOnReferer func app req sendResponse = app req push+  where+    push res@(ResponseFile (Status 200 "OK") _ file Nothing) = do+        let !path = rawPathInfo req+        m <- reaperRead cacheReaper+        case M.lookup path m of+            [] -> case requestHeaderReferer req of+                Nothing      -> return ()+                Just referer -> do                     (mauth,refPath) <- parseUrl referer                     when (isNothing mauth                        || requestHeaderHost req == mauth) $ do@@ -91,12 +89,12 @@                             case mpp of                                 Nothing -> return ()                                 Just pp -> reaperAdd cacheReaper (refPath,pp)-                _ -> return ()-        Just pset -> do-            let !ps = S.toList pset-                !h2d = defaultHTTP2Data { http2dataPushPromise = ps}-            setHTTP2Data req (Just h2d)-    sendResponse res+            ps -> do+                let !h2d = defaultHTTP2Data { http2dataPushPromise = ps}+                setHTTP2Data req (Just h2d)+        sendResponse res+    push res = sendResponse res+  -- | Learn if the file to be pushed is CSS (.css) or JavaScript (.js) file --   AND the Referer: ends with \"/\" or \".html\" or \".htm\".
+ Network/Wai/Middleware/Push/Referer/LimitMultiMap.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE BangPatterns #-}++module Network.Wai.Middleware.Push.Referer.LimitMultiMap where++import Data.Map (Map)+import qualified Data.Map.Strict as M+import Data.Set (Set)+import qualified Data.Set as S++data LimitMultiMap k v = LimitMultiMap {+      limitKey :: !Int+    , limitVal :: !Int+    , multiMap :: !(Map k (Set v))+    } deriving (Eq, Show)++isEmpty :: LimitMultiMap k t -> Bool+isEmpty (LimitMultiMap _ _ m) = M.null m++empty :: Int -> Int -> LimitMultiMap k v+empty lk lv = LimitMultiMap lk lv M.empty++insert :: (Ord k, Ord v) => (k,v) -> LimitMultiMap k v -> LimitMultiMap k v+insert (k,v) (LimitMultiMap lk lv m)+  | siz <  lk = let !m' = M.alter  alt k m in LimitMultiMap lk lv m'+  | siz == lk = let !m' = M.adjust adj k m in LimitMultiMap lk lv m'+  | otherwise = error "insert"+  where+    siz = M.size m+    alt Nothing          = Just $ S.singleton v+    alt s@(Just set)+      | S.size set == lv = s+      | otherwise        = Just $ S.insert v set+    adj set+      | S.size set == lv = set+      | otherwise        = S.insert v set++lookup :: Ord k => k -> LimitMultiMap k v -> [v]+lookup k (LimitMultiMap _ _ m) = case M.lookup k m of+  Nothing  -> []+  Just set -> S.toList set
wai-http2-extra.cabal view
@@ -1,5 +1,5 @@ Name:                wai-http2-extra-Version:             0.0.1+Version:             0.0.2 Synopsis:            WAI utilities for HTTP/2 License:             MIT License-file:        LICENSE@@ -22,6 +22,7 @@                    , warp                    , word8   Exposed-modules:   Network.Wai.Middleware.Push.Referer+  Other-modules:     Network.Wai.Middleware.Push.Referer.LimitMultiMap   Ghc-Options:       -Wall  Test-Suite doctest