Hello community, here is the log from the commit of package ghc-http-client-tls for openSUSE:Factory checked in at 2017-03-20 17:07:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-http-client-tls (Old) and /work/SRC/openSUSE:Factory/.ghc-http-client-tls.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-http-client-tls" Mon Mar 20 17:07:22 2017 rev:6 rq:477452 version:0.3.4 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-http-client-tls/ghc-http-client-tls.changes 2016-10-18 10:41:01.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-http-client-tls.new/ghc-http-client-tls.changes 2017-03-20 17:07:23.292293318 +0100 @@ -1,0 +2,10 @@ +Mon Feb 27 10:12:07 UTC 2017 - psim...@suse.com + +- Update to version 0.3.4 with cabal2obs. + +------------------------------------------------------------------- +Sun Feb 12 14:17:39 UTC 2017 - psim...@suse.com + +- Update to version 0.3.3.1 with cabal2obs. + +------------------------------------------------------------------- Old: ---- http-client-tls-0.2.4.1.tar.gz http-client-tls.cabal New: ---- http-client-tls-0.3.4.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-http-client-tls.spec ++++++ --- /var/tmp/diff_new_pack.VUTKU0/_old 2017-03-20 17:07:23.880210304 +0100 +++ /var/tmp/diff_new_pack.VUTKU0/_new 2017-03-20 17:07:23.884209739 +0100 @@ -1,7 +1,7 @@ # # spec file for package ghc-http-client-tls # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,26 +19,33 @@ %global pkg_name http-client-tls %bcond_with tests Name: ghc-%{pkg_name} -Version: 0.2.4.1 +Version: 0.3.4 Release: 0 Summary: Http-client backend using the connection package and tls library License: MIT Group: Development/Languages/Other Url: https://hackage.haskell.org/package/%{pkg_name} Source0: https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz -Source1: https://hackage.haskell.org/package/%{pkg_name}-%{version}/revision/1.cabal#/%{pkg_name}.cabal BuildRequires: ghc-Cabal-devel BuildRequires: ghc-bytestring-devel +BuildRequires: ghc-case-insensitive-devel BuildRequires: ghc-connection-devel +BuildRequires: ghc-containers-devel +BuildRequires: ghc-cryptonite-devel BuildRequires: ghc-data-default-class-devel +BuildRequires: ghc-exceptions-devel BuildRequires: ghc-http-client-devel +BuildRequires: ghc-http-types-devel +BuildRequires: ghc-memory-devel BuildRequires: ghc-network-devel +BuildRequires: ghc-network-uri-devel BuildRequires: ghc-rpm-macros +BuildRequires: ghc-text-devel BuildRequires: ghc-tls-devel +BuildRequires: ghc-transformers-devel BuildRoot: %{_tmppath}/%{name}-%{version}-build %if %{with tests} BuildRequires: ghc-hspec-devel -BuildRequires: ghc-http-types-devel %endif %description @@ -59,7 +66,6 @@ %prep %setup -q -n %{pkg_name}-%{version} -cp -p %{SOURCE1} %{pkg_name}.cabal %build %ghc_lib_build @@ -82,5 +88,6 @@ %files devel -f %{name}-devel.files %defattr(-,root,root,-) +%doc ChangeLog.md README.md %changelog ++++++ http-client-tls-0.2.4.1.tar.gz -> http-client-tls-0.3.4.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-tls-0.2.4.1/ChangeLog.md new/http-client-tls-0.3.4/ChangeLog.md --- old/http-client-tls-0.2.4.1/ChangeLog.md 2016-06-16 14:07:25.000000000 +0200 +++ new/http-client-tls-0.3.4/ChangeLog.md 2017-02-26 15:39:37.000000000 +0100 @@ -1,3 +1,39 @@ +## 0.3.4 + +* Add 'newTlsManager' + [#263](https://github.com/snoyberg/http-client/issues/263), which adds + support for respecting `socks5://` and `socks5h://` `http_proxy` and + `https_proxy` environment variables. + +## 0.3.3.2 + +* Better handling of internal exceptions + +## 0.3.3.1 + +* Better exception safety via `bracketOnError` + +## 0.3.3 + +* Add `DigestAuthException` and generalize `applyDigestAuth` +* Global manager uses a shared TLS context (faster init) + +## 0.3.2 + +* Add `mkManagerSettingsContext` [#228](https://github.com/snoyberg/http-client/issues/228) + +## 0.3.1.1 + +* Minor doc updates + +## 0.3.1 + +* Add `applyDigestAuth` + +## 0.3.0 + +* Support http-client 0.5 + ## 0.2.4.1 * Cabal description fix diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-tls-0.2.4.1/Network/HTTP/Client/TLS.hs new/http-client-tls-0.3.4/Network/HTTP/Client/TLS.hs --- old/http-client-tls-0.2.4.1/Network/HTTP/Client/TLS.hs 2016-06-16 14:07:25.000000000 +0200 +++ new/http-client-tls-0.3.4/Network/HTTP/Client/TLS.hs 2017-02-26 15:38:40.000000000 +0100 @@ -1,22 +1,33 @@ +{-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE DeriveDataTypeable #-} -- | Support for making connections via the connection package and, in turn, -- the tls package suite. -- --- Recommended reading: <https://github.com/commercialhaskell/jump/blob/master/doc/http-client.md> +-- Recommended reading: <https://haskell-lang.org/library/http-client> module Network.HTTP.Client.TLS ( -- * Settings tlsManagerSettings , mkManagerSettings + , mkManagerSettingsContext + , newTlsManager + -- * Digest authentication + , applyDigestAuth + , DigestAuthException (..) + , DigestAuthExceptionDetails (..) + , displayDigestAuthException -- * Global manager , getGlobalManager , setGlobalManager - -- * Internal - , getTlsConnection ) where +import Control.Applicative ((<|>)) +import Control.Arrow (first) +import System.Environment (getEnvironment) import Data.Default.Class -import Network.HTTP.Client -import Network.HTTP.Client.Internal +import Network.HTTP.Client hiding (host, port) +import Network.HTTP.Client.Internal hiding (host, port) import Control.Exception import qualified Network.Connection as NC import Network.Socket (HostAddress) @@ -24,44 +35,74 @@ import qualified Data.ByteString as S import Data.IORef (IORef, newIORef, readIORef, writeIORef) import System.IO.Unsafe (unsafePerformIO) +import Control.Monad.IO.Class (MonadIO, liftIO) +import Control.Monad (guard, unless) +import qualified Data.CaseInsensitive as CI +import Data.Maybe (fromMaybe, isJust) +import Network.HTTP.Types (status401) +import Crypto.Hash (hash, Digest, MD5) +import Control.Arrow ((***)) +import Data.ByteArray.Encoding (convertToBase, Base (Base16)) +import Data.Typeable (Typeable) +import Control.Monad.Catch (MonadThrow, throwM) +import qualified Data.Map as Map +import qualified Data.Text as T +import Data.Text.Read (decimal) +import qualified Network.URI as U -- | Create a TLS-enabled 'ManagerSettings' with the given 'NC.TLSSettings' and -- 'NC.SockSettings' mkManagerSettings :: NC.TLSSettings -> Maybe NC.SockSettings -> ManagerSettings -mkManagerSettings tls sock = defaultManagerSettings - { managerTlsConnection = getTlsConnection (Just tls) sock - , managerTlsProxyConnection = getTlsProxyConnection tls sock +mkManagerSettings = mkManagerSettingsContext Nothing + +-- | Same as 'mkManagerSettings', but also takes an optional +-- 'NC.ConnectionContext'. Providing this externally can be an +-- optimization, though that may change in the future. For more +-- information, see: +-- +-- <https://github.com/snoyberg/http-client/pull/227> +-- +-- @since 0.3.2 +mkManagerSettingsContext + :: Maybe NC.ConnectionContext + -> NC.TLSSettings + -> Maybe NC.SockSettings + -> ManagerSettings +mkManagerSettingsContext mcontext tls sock = mkManagerSettingsContext' mcontext tls sock sock + +-- | Internal, allow different SockSettings for HTTP and HTTPS +mkManagerSettingsContext' + :: Maybe NC.ConnectionContext + -> NC.TLSSettings + -> Maybe NC.SockSettings -- ^ insecure + -> Maybe NC.SockSettings -- ^ secure + -> ManagerSettings +mkManagerSettingsContext' mcontext tls sockHTTP sockHTTPS = defaultManagerSettings + { managerTlsConnection = getTlsConnection mcontext (Just tls) sockHTTPS + , managerTlsProxyConnection = getTlsProxyConnection mcontext tls sockHTTPS , managerRawConnection = - case sock of + case sockHTTP of Nothing -> managerRawConnection defaultManagerSettings - Just _ -> getTlsConnection Nothing sock + Just _ -> getTlsConnection mcontext Nothing sockHTTP , managerRetryableException = \e -> case () of () | ((fromException e)::(Maybe TLS.TLSError))==Just TLS.Error_EOF -> True - | otherwise -> case fromException e of - Just (_ :: IOException) -> True - _ -> - case fromException e of - -- Note: Some servers will timeout connections by accepting - -- the incoming packets for the new request, but closing - -- the connection as soon as we try to read. To make sure - -- we open a new connection under these circumstances, we - -- check for the NoResponseDataReceived exception. - Just NoResponseDataReceived -> True - Just IncompleteHeaders -> True - _ -> False - , managerWrapIOException = - let wrapper se = - case fromException se of - Just e -> toException $ InternalIOException e - Nothing -> case fromException se of - Just TLS.Terminated{} -> toException $ TlsException se - Just TLS.HandshakeFailed{} -> toException $ TlsException se - Just TLS.ConnectionNotEstablished -> toException $ TlsException se - _ -> se + | otherwise -> managerRetryableException defaultManagerSettings e + , managerWrapException = \req -> + let wrapper se + | Just (_ :: IOException) <- fromException se = se' + | Just (_ :: TLS.TLSException) <- fromException se = se' + | Just (_ :: NC.LineTooLong) <- fromException se = se' +#if MIN_VERSION_connection(0,2,7) + | Just (_ :: NC.HostNotResolved) <- fromException se = se' + | Just (_ :: NC.HostCannotConnect) <- fromException se = se' +#endif + | otherwise = se + where + se' = toException $ HttpExceptionRequest req $ InternalException se in handle $ throwIO . wrapper } @@ -69,11 +110,12 @@ tlsManagerSettings :: ManagerSettings tlsManagerSettings = mkManagerSettings def Nothing -getTlsConnection :: Maybe NC.TLSSettings +getTlsConnection :: Maybe NC.ConnectionContext + -> Maybe NC.TLSSettings -> Maybe NC.SockSettings -> IO (Maybe HostAddress -> String -> Int -> IO Connection) -getTlsConnection tls sock = do - context <- NC.initConnectionContext +getTlsConnection mcontext tls sock = do + context <- maybe NC.initConnectionContext return mcontext return $ \_ha host port -> do conn <- NC.connectTo context NC.ConnectionParams { NC.connectionHostname = host @@ -84,14 +126,14 @@ convertConnection conn getTlsProxyConnection - :: NC.TLSSettings + :: Maybe NC.ConnectionContext + -> NC.TLSSettings -> Maybe NC.SockSettings -> IO (S.ByteString -> (Connection -> IO ()) -> String -> Maybe HostAddress -> String -> Int -> IO Connection) -getTlsProxyConnection tls sock = do - context <- NC.initConnectionContext - return $ \connstr checkConn serverName _ha host port -> do - --error $ show (connstr, host, port) - conn <- NC.connectTo context NC.ConnectionParams +getTlsProxyConnection mcontext tls sock = do + context <- maybe NC.initConnectionContext return mcontext + return $ \connstr checkConn serverName _ha host port -> bracketOnError + (NC.connectTo context NC.ConnectionParams { NC.connectionHostname = serverName , NC.connectionPort = fromIntegral port , NC.connectionUseSecure = Nothing @@ -99,16 +141,17 @@ case sock of Just _ -> error "Cannot use SOCKS and TLS proxying together" Nothing -> Just $ NC.OtherProxy host $ fromIntegral port - } - - NC.connectionPut conn connstr - conn' <- convertConnection conn + }) + NC.connectionClose + $ \conn -> do + NC.connectionPut conn connstr + conn' <- convertConnection conn - checkConn conn' + checkConn conn' - NC.connectionSetSecure context conn tls + NC.connectionSetSecure context conn tls - return conn' + return conn' convertConnection :: NC.Connection -> IO Connection convertConnection conn = makeConnection @@ -119,9 +162,60 @@ -- already closed, and we get a @ResourceVanished@. (NC.connectionClose conn `Control.Exception.catch` \(_ :: IOException) -> return ()) +-- We may decide in the future to just have a global +-- ConnectionContext and use it directly in tlsManagerSettings, at +-- which point this can again be a simple (newManager +-- tlsManagerSettings >>= newIORef). See: +-- https://github.com/snoyberg/http-client/pull/227. +globalConnectionContext :: NC.ConnectionContext +globalConnectionContext = unsafePerformIO NC.initConnectionContext +{-# NOINLINE globalConnectionContext #-} + +-- | Load up a new TLS manager with default settings, respecting proxy +-- environment variables. +-- +-- @since 0.3.4 +newTlsManager :: MonadIO m => m Manager +newTlsManager = liftIO $ do + env <- getEnvironment + let lenv = Map.fromList $ map (first $ T.toLower . T.pack) env + msocksHTTP = parseSocksSettings env lenv "http_proxy" + msocksHTTPS = parseSocksSettings env lenv "https_proxy" + settings = mkManagerSettingsContext' (Just globalConnectionContext) def msocksHTTP msocksHTTPS + settings' = maybe id (const $ managerSetInsecureProxy proxyFromRequest) msocksHTTP + $ maybe id (const $ managerSetSecureProxy proxyFromRequest) msocksHTTPS + settings + newManager settings' + +parseSocksSettings :: [(String, String)] -- ^ original environment + -> Map.Map T.Text String -- ^ lower-cased keys + -> T.Text -- ^ env name + -> Maybe NC.SockSettings +parseSocksSettings env lenv n = do + str <- lookup (T.unpack n) env <|> Map.lookup n lenv + let allowedScheme x = x == "socks5:" || x == "socks5h:" + uri <- U.parseURI str + + guard $ allowedScheme $ U.uriScheme uri + guard $ null (U.uriPath uri) || U.uriPath uri == "/" + guard $ null $ U.uriQuery uri + guard $ null $ U.uriFragment uri + + auth <- U.uriAuthority uri + port' <- + case U.uriPort auth of + "" -> Nothing -- should we use some default? + ':':rest -> + case decimal $ T.pack rest of + Right (p, "") -> Just p + _ -> Nothing + _ -> Nothing + + Just $ NC.SockSettingsSimple (U.uriRegName auth) port' + -- | Evil global manager, to make life easier for the common use case globalManager :: IORef Manager -globalManager = unsafePerformIO (newManager tlsManagerSettings >>= newIORef) +globalManager = unsafePerformIO $ newTlsManager >>= newIORef {-# NOINLINE globalManager #-} -- | Get the current global 'Manager' @@ -136,3 +230,170 @@ -- @since 0.2.4 setGlobalManager :: Manager -> IO () setGlobalManager = writeIORef globalManager + +-- | Generated by 'applyDigestAuth' when it is unable to apply the +-- digest credentials to the request. +-- +-- @since 0.3.3 +data DigestAuthException + = DigestAuthException Request (Response ()) DigestAuthExceptionDetails + deriving (Show, Typeable) +instance Exception DigestAuthException where +#if MIN_VERSION_base(4, 8, 0) + displayException = displayDigestAuthException +#endif + +-- | User friendly display of a 'DigestAuthException' +-- +-- @since 0.3.3 +displayDigestAuthException :: DigestAuthException -> String +displayDigestAuthException (DigestAuthException req res det) = concat + [ "Unable to submit digest credentials due to: " + , details + , ".\n\nRequest: " + , show req + , ".\n\nResponse: " + , show res + ] + where + details = + case det of + UnexpectedStatusCode -> "received unexpected status code" + MissingWWWAuthenticateHeader -> + "missing WWW-Authenticate response header" + WWWAuthenticateIsNotDigest -> + "WWW-Authenticate response header does not indicate Digest" + MissingRealm -> + "WWW-Authenticate response header does include realm" + MissingNonce -> + "WWW-Authenticate response header does include nonce" + +-- | Detailed explanation for failure for 'DigestAuthException' +-- +-- @since 0.3.3 +data DigestAuthExceptionDetails + = UnexpectedStatusCode + | MissingWWWAuthenticateHeader + | WWWAuthenticateIsNotDigest + | MissingRealm + | MissingNonce + deriving (Show, Read, Typeable, Eq, Ord) + +-- | Apply digest authentication to this request. +-- +-- Note that this function will need to make an HTTP request to the +-- server in order to get the nonce, thus the need for a @Manager@ and +-- to live in @IO@. This also means that the request body will be sent +-- to the server. If the request body in the supplied @Request@ can +-- only be read once, you should replace it with a dummy value. +-- +-- In the event of successfully generating a digest, this will return +-- a @Just@ value. If there is any problem with generating the digest, +-- it will return @Nothing@. +-- +-- @since 0.3.1 +applyDigestAuth :: (MonadIO m, MonadThrow n) + => S.ByteString -- ^ username + -> S.ByteString -- ^ password + -> Request + -> Manager + -> m (n Request) +applyDigestAuth user pass req man = liftIO $ do + res <- httpNoBody req man + let throw' = throwM . DigestAuthException req res + return $ do + unless (responseStatus res == status401) + $ throw' UnexpectedStatusCode + h1 <- maybe (throw' MissingWWWAuthenticateHeader) return + $ lookup "WWW-Authenticate" $ responseHeaders res + h2 <- maybe (throw' WWWAuthenticateIsNotDigest) return + $ stripCI "Digest " h1 + let pieces = map (strip *** strip) (toPairs h2) + realm <- maybe (throw' MissingRealm) return + $ lookup "realm" pieces + nonce <- maybe (throw' MissingNonce) return + $ lookup "nonce" pieces + let qop = isJust $ lookup "qop" pieces + digest + | qop = md5 $ S.concat + [ ha1 + , ":" + , nonce + , ":00000001:deadbeef:auth:" + , ha2 + ] + | otherwise = md5 $ S.concat [ha1, ":", nonce, ":", ha2] + where + ha1 = md5 $ S.concat [user, ":", realm, ":", pass] + + -- we always use no qop or qop=auth + ha2 = md5 $ S.concat [method req, ":", path req] + + md5 bs = convertToBase Base16 (hash bs :: Digest MD5) + key = "Authorization" + val = S.concat + [ "Digest username=\"" + , user + , "\", realm=\"" + , realm + , "\", nonce=\"" + , nonce + , "\", uri=\"" + , path req + , "\", response=\"" + , digest + , "\"" + -- FIXME algorithm? + , case lookup "opaque" pieces of + Nothing -> "" + Just o -> S.concat [", opaque=\"", o, "\""] + , if qop + then ", qop=auth, nc=00000001, cnonce=\"deadbeef\"" + else "" + ] + return req + { requestHeaders = (key, val) + : filter + (\(x, _) -> x /= key) + (requestHeaders req) + , cookieJar = Just $ responseCookieJar res + } + where + stripCI x y + | CI.mk x == CI.mk (S.take len y) = Just $ S.drop len y + | otherwise = Nothing + where + len = S.length x + + _comma = 44 + _equal = 61 + _dquot = 34 + _space = 32 + + strip = fst . S.spanEnd (== _space) . S.dropWhile (== _space) + + toPairs bs0 + | S.null bs0 = [] + | otherwise = + let bs1 = S.dropWhile (== _space) bs0 + (key, bs2) = S.break (\w -> w == _equal || w == _comma) bs1 + in case () of + () + | S.null bs2 -> [(key, "")] + | S.head bs2 == _equal -> + let (val, rest) = parseVal $ S.tail bs2 + in (key, val) : toPairs rest + | otherwise -> + assert (S.head bs2 == _comma) $ + (key, "") : toPairs (S.tail bs2) + + parseVal bs0 = fromMaybe (parseUnquoted bs0) $ do + guard $ not $ S.null bs0 + guard $ S.head bs0 == _dquot + let (x, y) = S.break (== _dquot) $ S.tail bs0 + guard $ not $ S.null y + Just (x, S.drop 1 $ S.dropWhile (/= _comma) y) + + parseUnquoted bs = + let (x, y) = S.break (== _comma) bs + in (x, S.drop 1 y) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-tls-0.2.4.1/README.md new/http-client-tls-0.3.4/README.md --- old/http-client-tls-0.2.4.1/README.md 2016-06-16 14:07:25.000000000 +0200 +++ new/http-client-tls-0.3.4/README.md 2016-12-19 16:29:45.000000000 +0100 @@ -1,7 +1,7 @@ ## http-client-tls Full tutorial docs are available at: -https://github.com/commercialhaskell/jump/blob/master/doc/http-client.md +https://haskell-lang.org/library/http-client Use the http-client package with the pure-Haskell tls package for secure connections. For the most part, you'll just want to replace diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-tls-0.2.4.1/bench/Bench.hs new/http-client-tls-0.3.4/bench/Bench.hs --- old/http-client-tls-0.2.4.1/bench/Bench.hs 1970-01-01 01:00:00.000000000 +0100 +++ new/http-client-tls-0.3.4/bench/Bench.hs 2016-12-19 16:29:45.000000000 +0100 @@ -0,0 +1,15 @@ +module Main where + +import Criterion.Main +import Network.HTTP.Client +import Network.HTTP.Client.TLS + +main :: IO () +main = defaultMain [ + bgroup "newManager" [ + bench "defaultManagerSettings" $ + whnfIO (newManager defaultManagerSettings) + , bench "tlsManagerSettings" $ + whnfIO (newManager tlsManagerSettings) + ] + ] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-tls-0.2.4.1/http-client-tls.cabal new/http-client-tls-0.3.4/http-client-tls.cabal --- old/http-client-tls-0.2.4.1/http-client-tls.cabal 2016-06-16 14:07:25.000000000 +0200 +++ new/http-client-tls-0.3.4/http-client-tls.cabal 2017-02-26 15:38:40.000000000 +0100 @@ -1,5 +1,5 @@ name: http-client-tls -version: 0.2.4.1 +version: 0.3.4 synopsis: http-client backend using the connection package and tls library description: Hackage documentation generation is not reliable. For up to date documentation, please see: <https://www.stackage.org/package/http-client-tls>. homepage: https://github.com/snoyberg/http-client @@ -18,12 +18,22 @@ other-extensions: ScopedTypeVariables build-depends: base >= 4 && < 5 , data-default-class - , http-client >= 0.3.5 - , connection >= 0.2.2 + , http-client >= 0.5.0 + , connection >= 0.2.5 , network , tls >= 1.2 , bytestring + , case-insensitive + , transformers + , http-types + , cryptonite + , memory + , exceptions + , containers + , text + , network-uri default-language: Haskell2010 + ghc-options: -Wall test-suite spec main-is: Spec.hs @@ -35,3 +45,13 @@ , http-client , http-client-tls , http-types + +benchmark benchmark + main-is: Bench.hs + type: exitcode-stdio-1.0 + hs-source-dirs: bench + default-language: Haskell2010 + build-depends: base + , criterion + , http-client + , http-client-tls diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/http-client-tls-0.2.4.1/test/Spec.hs new/http-client-tls-0.3.4/test/Spec.hs --- old/http-client-tls-0.2.4.1/test/Spec.hs 2016-06-16 14:07:25.000000000 +0200 +++ new/http-client-tls-0.3.4/test/Spec.hs 2016-12-19 16:29:45.000000000 +0100 @@ -2,14 +2,28 @@ import Test.Hspec import Network.HTTP.Client import Network.HTTP.Client.TLS -import Network.HTTP.Client.Internal import Network.HTTP.Types +import Control.Monad (join) main :: IO () main = hspec $ do it "make a TLS connection" $ do manager <- newManager tlsManagerSettings - withResponse "https://httpbin.org/status/418" - { checkStatus = \_ _ _ -> Nothing - } manager $ \res -> do + withResponse "https://httpbin.org/status/418" manager $ \res -> responseStatus res `shouldBe` status418 + + it "digest authentication" $ do + man <- newManager defaultManagerSettings + req <- join $ applyDigestAuth + "user" + "passwd" + "http://httpbin.org/digest-auth/qop/user/passwd" + man + response <- httpNoBody req man + responseStatus response `shouldBe` status200 + + it "incorrect digest authentication" $ do + man <- newManager defaultManagerSettings + join (applyDigestAuth "user" "passwd" "http://httpbin.org/" man) + `shouldThrow` \(DigestAuthException _ _ det) -> + det == UnexpectedStatusCode