Hello community,

here is the log from the commit of package ghc-wai-extra for openSUSE:Factory 
checked in at 2016-03-31 13:02:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ghc-wai-extra (Old)
 and      /work/SRC/openSUSE:Factory/.ghc-wai-extra.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ghc-wai-extra"

Changes:
--------
--- /work/SRC/openSUSE:Factory/ghc-wai-extra/ghc-wai-extra.changes      
2016-03-26 15:26:24.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.ghc-wai-extra.new/ghc-wai-extra.changes 
2016-03-31 13:02:45.000000000 +0200
@@ -1,0 +2,6 @@
+Wed Mar 23 08:24:05 UTC 2016 - mimi...@gmail.com
+
+- update to 3.0.15
+* add requestSizeCheck
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ ghc-wai-extra.spec ++++++
--- /var/tmp/diff_new_pack.CMbPSh/_old  2016-03-31 13:02:48.000000000 +0200
+++ /var/tmp/diff_new_pack.CMbPSh/_new  2016-03-31 13:02:48.000000000 +0200
@@ -21,7 +21,7 @@
 %bcond_with tests
 
 Name:           ghc-wai-extra
-Version:        3.0.14.3
+Version:        3.0.15
 Release:        0
 Summary:        Provides some basic WAI handlers and middleware
 License:        MIT

++++++ wai-extra-3.0.14.3.tar.gz -> wai-extra-3.0.15.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wai-extra-3.0.14.3/ChangeLog.md 
new/wai-extra-3.0.15/ChangeLog.md
--- old/wai-extra-3.0.14.3/ChangeLog.md 2016-03-16 13:47:43.000000000 +0100
+++ new/wai-extra-3.0.15/ChangeLog.md   2016-03-22 10:15:32.000000000 +0100
@@ -1,3 +1,7 @@
+## 3.0.15
+
+* add requestSizeCheck [#525](https://github.com/yesodweb/wai/pull/525)
+
 ## 3.0.14.3
 
 * Add missing `requestHeaderReferer` and `requestHeaderUserAgent` fields to 
CGI [yesod#1186](https://github.com/yesodweb/yesod/issues/1186)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wai-extra-3.0.14.3/Network/Wai/Request.hs 
new/wai-extra-3.0.15/Network/Wai/Request.hs
--- old/wai-extra-3.0.14.3/Network/Wai/Request.hs       2016-03-16 
13:47:43.000000000 +0100
+++ new/wai-extra-3.0.15/Network/Wai/Request.hs 2016-03-22 10:15:32.000000000 
+0100
@@ -1,17 +1,25 @@
+{-# LANGUAGE DeriveDataTypeable #-}
 -- | Some helpers for interrogating a WAI 'Request'.
 
 module Network.Wai.Request
     ( appearsSecure
     , guessApproot
+    , RequestSizeException(..)
+    , requestSizeCheck
     ) where
 
 import Data.ByteString (ByteString)
 import Data.Maybe (fromMaybe)
 import Network.HTTP.Types (HeaderName)
-import Network.Wai (Request, isSecure, requestHeaders, requestHeaderHost)
+import Network.Wai
 
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Char8 as C
+import Control.Exception (Exception, throwIO)
+import Data.Typeable (Typeable)
+import Data.Word (Word64)
+import Data.IORef (atomicModifyIORef', newIORef)
+
 
 -- | Does this request appear to have been made over an SSL connection?
 --
@@ -24,7 +32,7 @@
 -- force a non-SSL request to SSL by redirect. One can safely choose not to
 -- redirect when the request /appears/ secure, even if it's actually not.
 --
--- Since 3.0.7
+-- @since 3.0.7
 appearsSecure :: Request -> Bool
 appearsSecure request = isSecure request || any (uncurry matchHeader)
     [ ("HTTPS"                  , (== "on"))
@@ -44,8 +52,50 @@
 -- application. For more information and relevant caveats, please see
 -- "Network.Wai.Middleware.Approot".
 --
--- Since 3.0.7
+-- @since 3.0.7
 guessApproot :: Request -> ByteString
 guessApproot req =
     (if appearsSecure req then "https://"; else "http://";) `S.append`
     (fromMaybe "localhost" $ requestHeaderHost req)
+
+-- | see 'requestSizeCheck'
+--
+-- @since 3.0.15
+data RequestSizeException
+    = RequestSizeException Word64
+    deriving (Eq, Ord, Typeable)
+
+instance Exception RequestSizeException
+
+instance Show RequestSizeException where
+    showsPrec p (RequestSizeException limit) =
+        showString ("Request Body is larger than ") . showsPrec p limit . 
showString " bytes."
+
+-- | Check request body size to avoid server crash when request is too large.
+--
+-- This function first checks @'requestBodyLength'@, if content-length is known
+-- but larger than limit, or it's unknown but we have received too many chunks,
+-- a 'RequestSizeException' are thrown when user use @'requestBody'@ to extract
+-- request body inside IO.
+--
+-- @since 3.0.15
+requestSizeCheck :: Word64 -> Request -> IO Request
+requestSizeCheck maxSize req =
+    case requestBodyLength req of
+        KnownLength len  ->
+            if len > maxSize
+                then return $ req { requestBody = throwIO 
(RequestSizeException maxSize) }
+                else return req
+        ChunkedBody      -> do
+            currentSize <- newIORef 0
+            return $ req
+                { requestBody = do
+                    bs <- requestBody req
+                    total <-
+                        atomicModifyIORef' currentSize $ \sz ->
+                            let nextSize = sz + fromIntegral (S.length bs)
+                            in (nextSize, nextSize)
+                    if total > maxSize
+                    then throwIO (RequestSizeException maxSize)
+                    else return bs
+                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wai-extra-3.0.14.3/test/Network/Wai/RequestSpec.hs 
new/wai-extra-3.0.15/test/Network/Wai/RequestSpec.hs
--- old/wai-extra-3.0.14.3/test/Network/Wai/RequestSpec.hs      2016-03-16 
13:47:43.000000000 +0100
+++ new/wai-extra-3.0.15/test/Network/Wai/RequestSpec.hs        2016-03-22 
10:15:32.000000000 +0100
@@ -8,52 +8,82 @@
 
 import Data.ByteString (ByteString)
 import Network.HTTP.Types (HeaderName)
-import Network.Wai (Request(..), defaultRequest)
+import Network.Wai (Request(..), defaultRequest, RequestBodyLength(..))
 
 import Network.Wai.Request
+import Control.Exception (try)
+import Control.Monad (forever)
 
 main :: IO ()
 main = hspec spec
 
 spec :: Spec
-spec = describe "appearsSecure" $ do
-    let insecureRequest = defaultRequest
-            { isSecure = False
-            , requestHeaders =
-                [ ("HTTPS", "off")
-                , ("HTTP_X_FORWARDED_SSL", "off")
-                , ("HTTP_X_FORWARDED_SCHEME", "http")
-                , ("HTTP_X_FORWARDED_PROTO", "http,xyz")
-                ]
-            }
+spec = do
+    describe "requestSizeCheck" $ do
+        it "too large content length should throw RequestSizeException" $ do
+            let limit = 1024
+                largeRequest = defaultRequest
+                    { isSecure = False
+                    , requestBodyLength = KnownLength (limit + 1)
+                    , requestBody = return "repeat this chunk"
+                    }
+            checkedRequest <- requestSizeCheck limit largeRequest
+            body <- try (requestBody checkedRequest)
+            case body of
+                Left (RequestSizeException l) -> l `shouldBe` limit
+                Right _   -> expectationFailure "request size check failed"
+
+        it "too many chunks should throw RequestSizeException" $ do
+            let limit = 1024
+                largeRequest = defaultRequest
+                    { isSecure = False
+                    , requestBodyLength = ChunkedBody
+                    , requestBody = return "repeat this chunk"
+                    }
+            checkedRequest <- requestSizeCheck limit largeRequest
+            body <- try (forever $ requestBody checkedRequest)
+            case body of
+                Left (RequestSizeException l) -> l `shouldBe` limit
+                Right _   -> expectationFailure "request size check failed"
+
+    describe "appearsSecure" $ do
+        let insecureRequest = defaultRequest
+                { isSecure = False
+                , requestHeaders =
+                    [ ("HTTPS", "off")
+                    , ("HTTP_X_FORWARDED_SSL", "off")
+                    , ("HTTP_X_FORWARDED_SCHEME", "http")
+                    , ("HTTP_X_FORWARDED_PROTO", "http,xyz")
+                    ]
+                }
+
+        it "returns False for an insecure request" $
+            insecureRequest `shouldSatisfy` not . appearsSecure
+
+        it "checks if the Request is actually secure" $ do
+            let req = insecureRequest { isSecure = True }
+
+            req `shouldSatisfy` appearsSecure
+
+        it "checks for HTTP: on" $ do
+            let req = addHeader "HTTPS" "on" insecureRequest
+
+            req `shouldSatisfy` appearsSecure
+
+        it "checks for HTTP_X_FORWARDED_SSL: on" $ do
+            let req = addHeader "HTTP_X_FORWARDED_SSL" "on" insecureRequest
+
+            req `shouldSatisfy` appearsSecure
+
+        it "checks for HTTP_X_FORWARDED_SCHEME: https" $ do
+            let req = addHeader "HTTP_X_FORWARDED_SCHEME" "https" 
insecureRequest
 
-    it "returns False for an insecure request" $
-        insecureRequest `shouldSatisfy` not . appearsSecure
+            req `shouldSatisfy` appearsSecure
 
-    it "checks if the Request is actually secure" $ do
-        let req = insecureRequest { isSecure = True }
+        it "checks for HTTP_X_FORWARDED_PROTO: https,..." $ do
+            let req = addHeader "HTTP_X_FORWARDED_PROTO" "https,xyz" 
insecureRequest
 
-        req `shouldSatisfy` appearsSecure
-
-    it "checks for HTTP: on" $ do
-        let req = addHeader "HTTPS" "on" insecureRequest
-
-        req `shouldSatisfy` appearsSecure
-
-    it "checks for HTTP_X_FORWARDED_SSL: on" $ do
-        let req = addHeader "HTTP_X_FORWARDED_SSL" "on" insecureRequest
-
-        req `shouldSatisfy` appearsSecure
-
-    it "checks for HTTP_X_FORWARDED_SCHEME: https" $ do
-        let req = addHeader "HTTP_X_FORWARDED_SCHEME" "https" insecureRequest
-
-        req `shouldSatisfy` appearsSecure
-
-    it "checks for HTTP_X_FORWARDED_PROTO: https,..." $ do
-        let req = addHeader "HTTP_X_FORWARDED_PROTO" "https,xyz" 
insecureRequest
-
-        req `shouldSatisfy` appearsSecure
+            req `shouldSatisfy` appearsSecure
 
 addHeader :: HeaderName -> ByteString -> Request -> Request
 addHeader name value req = req
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/wai-extra-3.0.14.3/wai-extra.cabal 
new/wai-extra-3.0.15/wai-extra.cabal
--- old/wai-extra-3.0.14.3/wai-extra.cabal      2016-03-16 13:47:43.000000000 
+0100
+++ new/wai-extra-3.0.15/wai-extra.cabal        2016-03-22 10:15:32.000000000 
+0100
@@ -1,5 +1,5 @@
 Name:                wai-extra
-Version:             3.0.14.3
+Version:             3.0.15
 Synopsis:            Provides some basic WAI handlers and middleware.
 description:
   Provides basic WAI handler and middleware functionality:
@@ -71,7 +71,7 @@
 Homepage:            http://github.com/yesodweb/wai
 Category:            Web
 Build-Type:          Simple
-Cabal-Version:       >=1.8
+Cabal-Version:       >=1.10
 Stability:           Stable
 extra-source-files:
   test/requests/dalvik-request
@@ -119,7 +119,7 @@
   else
       build-depends: unix
 
-  extensions:        OverloadedStrings
+  default-extensions:        OverloadedStrings
 
   Exposed-modules:   Network.Wai.Handler.CGI
                      Network.Wai.Handler.SCGI
@@ -151,6 +151,7 @@
                      Network.Wai.EventSource
                      Network.Wai.EventSource.EventStream
   other-modules:     Network.Wai.Middleware.RequestLogger.Internal
+  default-language:          Haskell2010
   ghc-options:       -Wall
 
 test-suite spec
@@ -182,6 +183,7 @@
                    , time
                    , case-insensitive
     ghc-options:     -Wall
+    default-language:          Haskell2010
 
 source-repository head
   type:     git


Reply via email to