Hello community, here is the log from the commit of package ghc-http-client for openSUSE:Factory checked in at 2015-12-23 08:50:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-http-client (Old) and /work/SRC/openSUSE:Factory/.ghc-http-client.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-http-client" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-http-client/ghc-http-client.changes 2015-10-06 13:24:23.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-http-client.new/ghc-http-client.changes 2015-12-23 08:50:13.000000000 +0100 @@ -1,0 +2,12 @@ +Thu Dec 17 10:40:19 UTC 2015 - [email protected] + +- update to 0.4.26.1 +* Make sure we never read from or write to closed socket + +------------------------------------------------------------------- +Sun Dec 13 16:44:45 UTC 2015 - [email protected] + +- update to 0.4.25 +* Don't error out when response body flushing fails + +------------------------------------------------------------------- Old: ---- http-client-0.4.24.tar.gz New: ---- http-client-0.4.26.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-http-client.spec ++++++ --- /var/tmp/diff_new_pack.bWlTsn/_old 2015-12-23 08:50:14.000000000 +0100 +++ /var/tmp/diff_new_pack.bWlTsn/_new 2015-12-23 08:50:14.000000000 +0100 @@ -21,7 +21,7 @@ %bcond_with tests Name: ghc-http-client -Version: 0.4.24 +Version: 0.4.26.1 Release: 0 Summary: HTTP client engine, intended as a base layer License: MIT ++++++ http-client-0.4.24.tar.gz -> http-client-0.4.26.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-0.4.24/ChangeLog.md new/http-client-0.4.26.1/ChangeLog.md --- old/http-client-0.4.24/ChangeLog.md 2015-09-24 08:54:33.000000000 +0200 +++ new/http-client-0.4.26.1/ChangeLog.md 2015-12-15 06:31:42.000000000 +0100 @@ -1,3 +1,15 @@ +## 0.4.26.1 + +* Fix compilation for GHC < 7.10 + +## 0.4.26 + +* Make sure we never read from or write to closed socket [#170](https://github.com/snoyberg/http-client/pull/170) + +## 0.4.25 + +* Don't error out when response body flushing fails [#169](https://github.com/snoyberg/http-client/issues/169) + ## 0.4.24 * Use a new `TlsExceptionHostPort` exception to indicate the host and port of the server we were trying to connect to when a TLS exception occurred. See [commercialhaskell/stack#1010](https://github.com/commercialhaskell/stack/issues/1010) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-0.4.24/Network/HTTP/Client/Connection.hs new/http-client-0.4.26.1/Network/HTTP/Client/Connection.hs --- old/http-client-0.4.24/Network/HTTP/Client/Connection.hs 2015-09-24 08:54:33.000000000 +0200 +++ new/http-client-0.4.26.1/Network/HTTP/Client/Connection.hs 2015-12-15 06:31:42.000000000 +0100 @@ -85,15 +85,39 @@ -> IO Connection makeConnection r w c = do istack <- newIORef [] + + -- it is necessary to make sure we never read from or write to + -- already closed connection. + closedVar <- newIORef False + _ <- mkWeakIORef istack c return $! Connection - { connectionRead = join $ atomicModifyIORef istack $ \stack -> - case stack of - x:xs -> (xs, return x) - [] -> ([], r) - , connectionUnread = \x -> atomicModifyIORef istack $ \stack -> (x:stack, ()) - , connectionWrite = w - , connectionClose = c + { connectionRead = do + closed <- readIORef closedVar + when closed $ + throwIO ConnectionClosed + join $ atomicModifyIORef istack $ \stack -> + case stack of + x:xs -> (xs, return x) + [] -> ([], r) + + , connectionUnread = \x -> do + closed <- readIORef closedVar + when closed $ + throwIO ConnectionClosed + atomicModifyIORef istack $ \stack -> (x:stack, ()) + + , connectionWrite = \x -> do + closed <- readIORef closedVar + when closed $ + throwIO ConnectionClosed + w x + + , connectionClose = do + closed <- readIORef closedVar + unless closed $ + c + writeIORef closedVar True } socketConnection :: Socket -> Int -> IO Connection diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-0.4.24/Network/HTTP/Client/Core.hs new/http-client-0.4.26.1/Network/HTTP/Client/Core.hs --- old/http-client-0.4.24/Network/HTTP/Client/Core.hs 2015-09-24 08:54:33.000000000 +0200 +++ new/http-client-0.4.26.1/Network/HTTP/Client/Core.hs 2015-12-15 06:31:42.000000000 +0100 @@ -190,6 +190,9 @@ responseClose res return (Just exc') where +#ifndef MIN_VERSION_bytestring +#define MIN_VERSION_bytestring(x,y,z) 1 +#endif #if MIN_VERSION_bytestring(0,10,0) toStrict' = L.toStrict #else @@ -215,6 +218,10 @@ -- instead just close the connection. let maxFlush = 1024 lbs <- brReadSome (responseBody res) maxFlush + -- The connection may already be closed, e.g. + -- when using withResponseHistory. See + -- https://github.com/snoyberg/http-client/issues/169 + `catch` \(_ :: ConnectionClosed) -> return L.empty responseClose res -- And now perform the actual redirect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-0.4.24/Network/HTTP/Client/Manager.hs new/http-client-0.4.26.1/Network/HTTP/Client/Manager.hs --- old/http-client-0.4.24/Network/HTTP/Client/Manager.hs 2015-09-24 08:54:33.000000000 +0200 +++ new/http-client-0.4.26.1/Network/HTTP/Client/Manager.hs 2015-12-15 06:31:42.000000000 +0100 @@ -22,6 +22,9 @@ , dropProxyAuthSecure ) where +#ifndef MIN_VERSION_base +#define MIN_VERSION_base(x,y,z) 1 +#endif #if !MIN_VERSION_base(4,6,0) import Prelude hiding (catch) #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-0.4.24/Network/HTTP/Client/Request.hs new/http-client-0.4.26.1/Network/HTTP/Client/Request.hs --- old/http-client-0.4.24/Network/HTTP/Client/Request.hs 2015-09-24 08:54:33.000000000 +0200 +++ new/http-client-0.4.26.1/Network/HTTP/Client/Request.hs 2015-12-15 06:31:42.000000000 +0100 @@ -87,6 +87,9 @@ -- it as per 'setUri'; if it is relative, merge it with the existing request. setUriRelative :: MonadThrow m => Request -> URI -> m Request setUriRelative req uri = +#ifndef MIN_VERSION_network +#define MIN_VERSION_network(x,y,z) 1 +#endif #if MIN_VERSION_network(2,4,0) setUri req $ uri `relativeTo` getUri req #else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-0.4.24/Network/HTTP/Client/Types.hs new/http-client-0.4.26.1/Network/HTTP/Client/Types.hs --- old/http-client-0.4.24/Network/HTTP/Client/Types.hs 2015-09-24 08:54:33.000000000 +0200 +++ new/http-client-0.4.26.1/Network/HTTP/Client/Types.hs 2015-12-15 06:31:42.000000000 +0100 @@ -7,6 +7,7 @@ ( BodyReader , Connection (..) , StatusHeaders (..) + , ConnectionClosed (..) , HttpException (..) , Cookie (..) , CookieJar (..) @@ -75,12 +76,20 @@ , connectionWrite :: S.ByteString -> IO () -- ^ Send data to server , connectionClose :: IO () + -- ^ Close connection. Any successive operation on the connection + -- (exept closing) should fail with `ConnectionClosed` exception. + -- It is allowed to close connection multiple times. } deriving T.Typeable data StatusHeaders = StatusHeaders Status HttpVersion RequestHeaders deriving (Show, Eq, Ord, T.Typeable) +data ConnectionClosed = ConnectionClosed + deriving (Eq, Show, T.Typeable) + +instance Exception ConnectionClosed + data HttpException = StatusCodeException Status ResponseHeaders CookieJar | InvalidUrlException String String | TooManyRedirects [Response L.ByteString] -- ^ List of encountered responses containing redirects in reverse chronological order; including last redirect, which triggered the exception and was not followed. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-0.4.24/Network/HTTP/Client/Util.hs new/http-client-0.4.26.1/Network/HTTP/Client/Util.hs --- old/http-client-0.4.24/Network/HTTP/Client/Util.hs 2015-09-24 08:54:33.000000000 +0200 +++ new/http-client-0.4.26.1/Network/HTTP/Client/Util.hs 2015-12-15 06:31:42.000000000 +0100 @@ -16,6 +16,11 @@ import Data.Monoid (Monoid, mappend) import qualified Data.ByteString.Char8 as S8 + +#ifndef MIN_VERSION_bytestring +#define MIN_VERSION_bytestring(x,y,z) 1 +#endif + #if MIN_VERSION_bytestring(0,10,0) import Data.ByteString.Lazy (fromStrict) #else @@ -35,6 +40,9 @@ import Data.Function (fix) import Data.Typeable (Typeable) +#ifndef MIN_VERSION_base +#define MIN_VERSION_base(x,y,z) 1 +#endif #if MIN_VERSION_base(4,3,0) import Data.ByteString (hGetSome) #else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-0.4.24/http-client.cabal new/http-client-0.4.26.1/http-client.cabal --- old/http-client-0.4.24/http-client.cabal 2015-09-24 08:54:33.000000000 +0200 +++ new/http-client-0.4.26.1/http-client.cabal 2015-12-15 06:31:42.000000000 +0100 @@ -1,5 +1,5 @@ name: http-client -version: 0.4.24 +version: 0.4.26.1 synopsis: An HTTP client engine, intended as a base layer for more user-friendly packages. description: Hackage documentation generation is not reliable. For up to date documentation, please see: <http://www.stackage.org/package/http-client>. homepage: https://github.com/snoyberg/http-client diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-0.4.24/test-nonet/Network/HTTP/ClientSpec.hs new/http-client-0.4.26.1/test-nonet/Network/HTTP/ClientSpec.hs --- old/http-client-0.4.24/test-nonet/Network/HTTP/ClientSpec.hs 2015-09-24 08:54:33.000000000 +0200 +++ new/http-client-0.4.26.1/test-nonet/Network/HTTP/ClientSpec.hs 2015-12-15 06:31:42.000000000 +0100 @@ -1,9 +1,11 @@ {-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} module Network.HTTP.ClientSpec where import Control.Concurrent (forkIO, threadDelay) import Control.Concurrent.Async (withAsync) -import Control.Exception (bracket) +import qualified Control.Concurrent.Async as Async +import Control.Exception (bracket, catch, IOException) import Control.Monad (forever, replicateM_, void) import Network.HTTP.Client import Network.HTTP.Types (status413) @@ -33,6 +35,20 @@ N.appWrite ad "hello\r\n" threadDelay 10000 +redirectCloseServer :: (Int -> IO a) -> IO a +redirectCloseServer inner = bracket + (N.bindRandomPortTCP "*4") + (sClose . snd) + $ \(port, lsocket) -> withAsync + (N.runTCPServer (N.serverSettingsTCPSocket lsocket) app) + (const $ inner port) + where + app ad = do + Async.race_ + (forever (N.appRead ad)) + (N.appWrite ad "HTTP/1.1 301 Redirect\r\nLocation: /\r\nConnection: close\r\n\r\nhello") + N.appCloseConnection ad + bad100Server :: Bool -- ^ include extra headers? -> (Int -> IO a) -> IO a bad100Server extraHeaders inner = bracket @@ -175,3 +191,14 @@ withManager defaultManagerSettings $ \man -> do res <- getChunkedResponse port' man responseBody res `shouldBe` "Wikipedia in\r\n\r\nchunks." + + it "withResponseHistory and redirect" $ redirectCloseServer $ \port -> do + -- see https://github.com/snoyberg/http-client/issues/169 + req' <- parseUrl $ "http://127.0.0.1:" ++ show port + let req = req' {redirectCount = 1} + withManager defaultManagerSettings $ \man -> do + withResponseHistory req man (const $ return ()) + `shouldThrow` \e -> + case e of + TooManyRedirects _ -> True + _ -> False
