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 - [email protected]
+
+- Update to version 0.3.4 with cabal2obs.
+
+-------------------------------------------------------------------
+Sun Feb 12 14:17:39 UTC 2017 - [email protected]
+
+- 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