Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ghc-wai-extra for openSUSE:Factory 
checked in at 2021-01-20 18:25:06
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-wai-extra (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-wai-extra.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-wai-extra"

Wed Jan 20 18:25:06 2021 rev:7 rq:862336 version:3.1.5

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-wai-extra/ghc-wai-extra.changes      
2020-12-22 11:50:20.586050428 +0100
+++ /work/SRC/openSUSE:Factory/.ghc-wai-extra.new.28504/ghc-wai-extra.changes   
2021-01-20 18:25:38.267415791 +0100
@@ -1,0 +2,8 @@
+Mon Jan  4 11:06:39 UTC 2021 - [email protected]
+
+- Update wai-extra to version 3.1.5.
+  ## 3.1.5
+
+  * `Network.Wai.Middleware.RealIp`: Add a new middleware to infer the remote 
IP address from headers [#834](https://github.com/yesodweb/wai/pull/834)
+
+-------------------------------------------------------------------

Old:
----
  wai-extra-3.1.4.1.tar.gz

New:
----
  wai-extra-3.1.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ghc-wai-extra.spec ++++++
--- /var/tmp/diff_new_pack.SHUW8e/_old  2021-01-20 18:25:40.163417597 +0100
+++ /var/tmp/diff_new_pack.SHUW8e/_new  2021-01-20 18:25:40.167417600 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package ghc-wai-extra
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %global pkg_name wai-extra
 %bcond_with tests
 Name:           ghc-%{pkg_name}
-Version:        3.1.4.1
+Version:        3.1.5
 Release:        0
 Summary:        Provides some basic WAI handlers and middleware
 License:        MIT

++++++ wai-extra-3.1.4.1.tar.gz -> wai-extra-3.1.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wai-extra-3.1.4.1/ChangeLog.md 
new/wai-extra-3.1.5/ChangeLog.md
--- old/wai-extra-3.1.4.1/ChangeLog.md  2020-12-13 16:48:41.000000000 +0100
+++ new/wai-extra-3.1.5/ChangeLog.md    2021-01-03 16:18:40.000000000 +0100
@@ -1,5 +1,9 @@
 # Changelog for wai-extra
 
+## 3.1.5
+
+* `Network.Wai.Middleware.RealIp`: Add a new middleware to infer the remote IP 
address from headers [#834](https://github.com/yesodweb/wai/pull/834)
+
 ## 3.1.4.1
 
 * `Network.Wai.Middleware.Gzip`: Add `Vary: Accept-Encoding` header to 
responses [#829](https://github.com/yesodweb/wai/pull/829)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wai-extra-3.1.4.1/Network/Wai/Middleware/RealIp.hs 
new/wai-extra-3.1.5/Network/Wai/Middleware/RealIp.hs
--- old/wai-extra-3.1.4.1/Network/Wai/Middleware/RealIp.hs      1970-01-01 
01:00:00.000000000 +0100
+++ new/wai-extra-3.1.5/Network/Wai/Middleware/RealIp.hs        2021-01-03 
16:18:40.000000000 +0100
@@ -0,0 +1,94 @@
+-- | Infer the remote IP address using headers
+module Network.Wai.Middleware.RealIp
+    ( realIp
+    , realIpHeader
+    , realIpTrusted
+    , defaultTrusted
+    , ipInRange
+    ) where
+
+import qualified Data.ByteString.Char8 as B8 (unpack, split)
+import qualified Data.IP as IP
+import Data.Maybe (fromMaybe, mapMaybe, listToMaybe)
+import Network.HTTP.Types (HeaderName, RequestHeaders)
+import Network.Wai
+import Text.Read (readMaybe)
+
+-- | Infer the remote IP address from the @X-Forwarded-For@ header,
+-- trusting requests from any private IP address. See 'realIpHeader' and
+-- 'realIpTrusted' for more information and options.
+--
+-- @since 3.1.5
+realIp :: Middleware
+realIp = realIpHeader "X-Forwarded-For"
+
+-- | Infer the remote IP address using the given header, trusting
+-- requests from any private IP address. See 'realIpTrusted' for more
+-- information and options.
+--
+-- @since 3.1.5
+realIpHeader :: HeaderName -> Middleware
+realIpHeader header =
+    realIpTrusted header $ \ip -> any (ipInRange ip) defaultTrusted
+
+-- | Infer the remote IP address using the given header, but only if the
+-- request came from an IP that is trusted by the provided predicate.
+--
+-- The last non-trusted address is used to replace the 'remoteHost' in
+-- the 'Request', unless all present IP addresses are trusted, in which
+-- case the first address is used. Invalid IP addresses are ignored, and
+-- the remoteHost value remains unaltered if no valid IP addresses are
+-- found.
+--
+-- Examples:
+--
+-- @ realIpTrusted "X-Forwarded-For" $ flip ipInRange "10.0.0.0/8" @
+--
+-- @ realIpTrusted "X-Real-Ip" $ \\ip -> any (ipInRange ip) defaultTrusted @
+--
+-- @since 3.1.5
+realIpTrusted :: HeaderName -> (IP.IP -> Bool) -> Middleware
+realIpTrusted header isTrusted app req respond = app req' respond
+  where
+    req' = fromMaybe req $ do
+             (ip, port) <- IP.fromSockAddr (remoteHost req)
+             ip' <- if isTrusted ip
+                      then findRealIp (requestHeaders req) header isTrusted
+                      else Nothing
+             Just $ req { remoteHost = IP.toSockAddr (ip', port) }
+
+-- | Standard private IP ranges.
+--
+-- @since 3.1.5
+defaultTrusted :: [IP.IPRange]
+defaultTrusted = [ "127.0.0.0/8"
+                 , "10.0.0.0/8"
+                 , "172.16.0.0/12"
+                 , "192.168.0.0/16"
+                 , "::1/128"
+                 , "fc00::/7"
+                 ]
+
+-- | Check if the given IP address is in the given range.
+--
+-- IPv4 addresses can be checked against IPv6 ranges, but testing an
+-- IPv6 address against an IPv4 range is always 'False'.
+--
+-- @since 3.1.5
+ipInRange :: IP.IP -> IP.IPRange -> Bool
+ipInRange (IP.IPv4 ip) (IP.IPv4Range r) = ip `IP.isMatchedTo` r
+ipInRange (IP.IPv6 ip) (IP.IPv6Range r) = ip `IP.isMatchedTo` r
+ipInRange (IP.IPv4 ip) (IP.IPv6Range r) = IP.ipv4ToIPv6 ip `IP.isMatchedTo` r
+ipInRange _ _ = False
+
+
+findRealIp :: RequestHeaders -> HeaderName -> (IP.IP -> Bool) -> Maybe IP.IP
+findRealIp reqHeaders header isTrusted =
+    case (nonTrusted, ips) of
+      ([], xs) -> listToMaybe xs
+      (xs, _)  -> listToMaybe $ reverse xs
+  where
+    -- account for repeated headers
+    headerVals = [ v | (k, v) <- reqHeaders, k == header ]
+    ips = mapMaybe (readMaybe . B8.unpack) $ concatMap (B8.split ',') 
headerVals
+    nonTrusted = filter (not . isTrusted) ips
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/wai-extra-3.1.4.1/test/Network/Wai/Middleware/RealIpSpec.hs 
new/wai-extra-3.1.5/test/Network/Wai/Middleware/RealIpSpec.hs
--- old/wai-extra-3.1.4.1/test/Network/Wai/Middleware/RealIpSpec.hs     
1970-01-01 01:00:00.000000000 +0100
+++ new/wai-extra-3.1.5/test/Network/Wai/Middleware/RealIpSpec.hs       
2021-01-03 16:18:40.000000000 +0100
@@ -0,0 +1,91 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Network.Wai.Middleware.RealIpSpec
+    ( spec
+    ) where
+
+import Test.Hspec
+
+import qualified Data.ByteString.Lazy.Char8 as B8
+import qualified Data.IP as IP
+import Network.HTTP.Types (status200, RequestHeaders)
+import Network.Wai
+import Network.Wai.Middleware.RealIp
+import Network.Wai.Test
+
+spec :: Spec
+spec = do
+    describe "realIp" $ do
+        it "does nothing when header is missing" $ do
+            resp <- runApp "127.0.0.1" [] realIp
+            simpleBody resp `shouldBe` "127.0.0.1"
+
+        it "uses X-Forwarded-For when present" $ do
+            let headers = [("X-Forwarded-For", "1.1.1.1")]
+            resp <- runApp "127.0.0.1" headers realIp
+            simpleBody resp `shouldBe` "1.1.1.1"
+
+        it "ignores X-Forwarded-For from non-trusted ip" $ do
+            let headers = [("X-Forwarded-For", "1.1.1.1")]
+            resp <- runApp "1.2.3.4" headers realIp
+            simpleBody resp `shouldBe` "1.2.3.4"
+
+        it "ignores trusted ip addresses in X-Forwarded-For" $ do
+            let headers = [("X-Forwarded-For", "1.1.1.1, 10.0.0.1")]
+            resp <- runApp "127.0.0.1" headers realIp
+            simpleBody resp `shouldBe` "1.1.1.1"
+
+        it "ignores invalid ip addresses" $ do
+            let headers1 = [("X-Forwarded-For", "1.1.1")]
+            resp1 <- runApp "127.0.0.1" headers1 realIp
+            let headers2 = [("X-Forwarded-For", "1.1.1.1,foo")]
+            resp2 <- runApp "127.0.0.1" headers2 realIp
+
+            simpleBody resp1 `shouldBe` "127.0.0.1"
+            simpleBody resp2 `shouldBe` "1.1.1.1"
+
+        it "takes the last non-trusted address" $ do
+            let headers = [("X-Forwarded-For", "1.1.1.1, 2.2.2.2, 10.0.0.1")]
+            resp <- runApp "127.0.0.1" headers realIp
+            simpleBody resp `shouldBe` "2.2.2.2"
+
+        it "takes the first address when all are trusted" $ do
+            let headers = [("X-Forwarded-For", "192.168.0.1, 10.0.0.2, 
10.0.0.1")]
+            resp <- runApp "127.0.0.1" headers realIp
+            simpleBody resp `shouldBe` "192.168.0.1"
+
+        it "handles repeated headers" $ do
+            let headers = [("X-Forwarded-For", "1.1.1.1"), ("X-Forwarded-For", 
"2.2.2.2")]
+            resp <- runApp "127.0.0.1" headers realIp
+            simpleBody resp `shouldBe` "2.2.2.2"
+
+        it "handles ipv6 addresses" $ do
+            let headers = [("X-Forwarded-For", 
"2001:db8::ff00:42:8329,10.0.0.1")]
+            resp <- runApp "::1" headers realIp
+            simpleBody resp `shouldBe` "2001:db8::ff00:42:8329"
+
+    describe "realIpHeader" $ do
+        it "uses specified header" $ do
+            let headers = [("X-Forwarded-For", "1.1.1.1"), ("X-Real-Ip", 
"2.2.2.2")]
+            resp <- runApp "127.0.0.1" headers $ realIpHeader "X-Real-Ip"
+            simpleBody resp `shouldBe` "2.2.2.2"
+
+    describe "realIpTrusted" $ do
+        it "uses provided trusted predicate" $ do
+            let headers = [("X-Forwarded-For", "10.0.0.1, 1.1.1.1")]
+                isTrusted1 ip = any (ipInRange ip) ["127.0.0.1/32", 
"1.1.1.1/32"]
+                isTrusted2 = flip ipInRange "1.1.1.1/32"
+
+            resp1 <- runApp "127.0.0.1" headers $ realIpTrusted 
"X-Forwarded-For" isTrusted1
+            resp2 <- runApp "10.0.0.2" headers $ realIpTrusted 
"X-Forwarded-For" isTrusted2
+
+            simpleBody resp1 `shouldBe` "10.0.0.1"
+            simpleBody resp2 `shouldBe` "10.0.0.2"
+
+
+runApp :: IP.IP -> RequestHeaders -> Middleware -> IO SResponse
+runApp ip hs mw = runSession
+    (request defaultRequest { remoteHost = IP.toSockAddr (ip, 80), 
requestHeaders = hs }) $ mw app
+  where
+    app req respond = respond $ responseLBS status200 [] $ renderIp req
+    renderIp = B8.pack . maybe "" (show . fst) . IP.fromSockAddr . remoteHost
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wai-extra-3.1.4.1/wai-extra.cabal 
new/wai-extra-3.1.5/wai-extra.cabal
--- old/wai-extra-3.1.4.1/wai-extra.cabal       2020-12-13 16:48:41.000000000 
+0100
+++ new/wai-extra-3.1.5/wai-extra.cabal 2021-01-03 16:18:40.000000000 +0100
@@ -1,5 +1,5 @@
 Name:                wai-extra
-Version:             3.1.4.1
+Version:             3.1.5
 Synopsis:            Provides some basic WAI handlers and middleware.
 description:
   Provides basic WAI handler and middleware functionality:
@@ -114,7 +114,7 @@
                    , vault
                    , zlib
                    , aeson
-                   , iproute
+                   , iproute                   >= 1.7.8
                    , http2
                    , HUnit
                    , call-stack
@@ -150,6 +150,7 @@
                      Network.Wai.Middleware.ForceSSL
                      Network.Wai.Middleware.Routed
                      Network.Wai.Middleware.Timeout
+                     Network.Wai.Middleware.RealIp
                      Network.Wai.Parse
                      Network.Wai.Request
                      Network.Wai.UrlMap
@@ -191,6 +192,7 @@
                      Network.Wai.Middleware.RoutedSpec
                      Network.Wai.Middleware.StripHeadersSpec
                      Network.Wai.Middleware.TimeoutSpec
+                     Network.Wai.Middleware.RealIpSpec
                      WaiExtraSpec
     build-depends:   base                      >= 4        && < 5
                    , wai-extra
@@ -209,6 +211,7 @@
                    , case-insensitive
                    , http2
                    , aeson
+                   , iproute
     ghc-options:     -Wall
     default-language:          Haskell2010
 

Reply via email to