packages feed

tcp-streams 0.6.0.0 → 1.0.0.0

raw patch · 9 files changed

+498/−452 lines, 9 filesdep −QuickCheckdep −test-framework-quickcheck2PVP ok

version bump matches the API change (PVP)

Dependencies removed: QuickCheck, test-framework-quickcheck2

API changes (from Hackage documentation)

- System.IO.Streams.TCP: acceptWithBufferSize :: Socket -> Int -> IO (InputStream ByteString, OutputStream ByteString, Socket, SockAddr)
- System.IO.Streams.TCP: close :: Socket -> IO ()
- System.IO.Streams.TCP: connectWithBufferSize :: HostName -> PortNumber -> Int -> IO (InputStream ByteString, OutputStream ByteString, Socket)
- System.IO.Streams.TCP: socketToStreamsWithBufferSize :: Int -> Socket -> IO (InputStream ByteString, OutputStream ByteString)
- System.IO.Streams.TCP: withConnection :: HostName -> PortNumber -> (InputStream ByteString -> OutputStream ByteString -> Socket -> IO a) -> IO a
- System.IO.Streams.TLS: close :: Context -> IO ()
- System.IO.Streams.TLS: tlsToStreams :: Context -> IO (InputStream ByteString, OutputStream ByteString)
- System.IO.Streams.TLS: withConnection :: ClientParams -> Maybe HostName -> HostName -> PortNumber -> (InputStream ByteString -> OutputStream ByteString -> Context -> IO a) -> IO a
+ Data.Connection: Connection :: {-# UNPACK #-} !(InputStream ByteString) -> (ByteString -> IO ()) -> IO () -> a -> Connection a
+ Data.Connection: [close] :: Connection a -> IO ()
+ Data.Connection: [connExtraInfo] :: Connection a -> a
+ Data.Connection: [send] :: Connection a -> ByteString -> IO ()
+ Data.Connection: [source] :: Connection a -> {-# UNPACK #-} !(InputStream ByteString)
+ Data.Connection: data Connection a
+ System.IO.Streams.TCP: acceptWith :: ((Socket, SockAddr) -> IO TCPConnection) -> Socket -> IO TCPConnection
+ System.IO.Streams.TCP: bindAndListenWith :: (Socket -> IO ()) -> Int -> PortNumber -> IO Socket
+ System.IO.Streams.TCP: defaultChunkSize :: Int
+ System.IO.Streams.TCP: socketToConnection :: Int -> (Socket, SockAddr) -> IO TCPConnection
+ System.IO.Streams.TCP: type TCPConnection = Connection (Socket, SockAddr)
+ System.IO.Streams.TLS: connectTLS :: ClientParams -> Maybe String -> HostName -> PortNumber -> IO (Context, SockAddr)
+ System.IO.Streams.TLS: tLsToConnection :: (Context, SockAddr) -> IO TLSConnection
+ System.IO.Streams.TLS: type TLSConnection = Connection (Context, SockAddr)
+ System.IO.Streams.UnixSocket: bindAndListen :: Int -> String -> IO Socket
+ System.IO.Streams.UnixSocket: connect :: String -> IO TCPConnection
+ System.IO.Streams.UnixSocket: connectSocket :: String -> IO (Socket, SockAddr)
- System.IO.Streams.TCP: accept :: Socket -> IO (InputStream ByteString, OutputStream ByteString, Socket, SockAddr)
+ System.IO.Streams.TCP: accept :: Socket -> IO TCPConnection
- System.IO.Streams.TCP: bindAndListen :: PortNumber -> Int -> IO Socket
+ System.IO.Streams.TCP: bindAndListen :: Int -> PortNumber -> IO Socket
- System.IO.Streams.TCP: connect :: HostName -> PortNumber -> IO (InputStream ByteString, OutputStream ByteString, Socket)
+ System.IO.Streams.TCP: connect :: HostName -> PortNumber -> IO TCPConnection
- System.IO.Streams.TCP: connectSocket :: HostName -> PortNumber -> IO Socket
+ System.IO.Streams.TCP: connectSocket :: HostName -> PortNumber -> IO (Socket, SockAddr)
- System.IO.Streams.TLS: accept :: ServerParams -> Socket -> IO (InputStream ByteString, OutputStream ByteString, Context, SockAddr)
+ System.IO.Streams.TLS: accept :: ServerParams -> Socket -> IO TLSConnection
- System.IO.Streams.TLS: connect :: ClientParams -> Maybe String -> HostName -> PortNumber -> IO (InputStream ByteString, OutputStream ByteString, Context)
+ System.IO.Streams.TLS: connect :: ClientParams -> Maybe String -> HostName -> PortNumber -> IO TLSConnection

Files

ChangeLog.md view
@@ -1,5 +1,25 @@ # Revision history for tcp-streams +## 1.0.0.0++Major rewrite using new `Connection` interface.++* Introduce `Connection` in `Data.Connection` to leaverage vectorized IO.+* Now `connect`, `accept` return `Connection`, remove `withXXX` functions.+* Change exception behavior to work better with `bracket`.+* `bindAndListen` 's type changed from `PortNumber -> Int -> IO Socket` to `Int -> PortNumber -> IO Socket`.+* Add `bindAndListenWith` for custom socket options.+* Add unix domain socket support.+* Update built-in mozilla CA list(2017/01/18).++## 0.7.0.0++* Add built-in timeout support+* Change behavior using io-streams' convention: +    * reading `InputStream` will throw exception, and the socket won't be closed.+    * writing to `OutputStream` will not cause a write until flush.+    * writing empty `ByteString` to `OutputStream` will do a flush.+ ## 0.6.0.0  * Update built-in mozilla CA list(2016/11/02).
+ Data/Connection.hs view
@@ -0,0 +1,42 @@+module Data.Connection where++import qualified Data.ByteString           as B+import qualified Data.ByteString.Lazy.Internal as L+import qualified System.IO.Streams         as S++-- | A simple connection abstraction.+--+-- 'Connection' s from this package are supposed to have following properties:+--+--  * 'S.InputStream' is choosen to simplify streaming processing.+--  You can easily push back some data with 'S.unRead',+--  reading 'S.InputStream' will block until GHC IO manager find data is ready, for example:+--  @'S.readExactly' 1024@ will block until at least 1024 bytes are available.+--+--  * The type @'L.ByteString' -> 'IO' ()@ is choosen because it worked well with haskell's builder infrastructure.+--  <http://hackage.haskell.org/package/network-2.6.2.1/docs/Network-Socket-ByteString.html#g:2 vector-IO>+--  is used automatically when there's more than one chunk to send to save system call.+--+--  * 'connExtraInfo' field store extra data about the connection, 'N.SockAddr' for example.+--  You can also use this field as a type tag to distinguish different type of connection.+--+--  * 'close' should close connection resource, thus the 'Connection' shouldn't be used anymore+--  after 'close' is called.+--+--  * You should make sure there's no pending recv/send before you 'close' a 'Connection'.+--  That means either you call 'close' in the same thread you recv/send, or use async exception+--  to terminate recv/send thread before call 'close' in other thread(such as a reaper thread).+--  Otherwise you may run into+--  <https://mail.haskell.org/pipermail/haskell-cafe/2014-September/115823.html race-connections>.+--+--  * Exception or closed by other peer during recv/send will NOT close underline socket,+--  you should always use 'close' with 'E.bracket' to ensure safety.+--+--  @since 1.0+--+data Connection a = Connection+    { source        :: {-# UNPACK #-} !(S.InputStream B.ByteString)   -- ^ receive data as 'S.InputStream'+    , send          :: L.ByteString -> IO ()                          -- ^ send data with connection+    , close         :: IO ()                                          -- ^ close connection+    , connExtraInfo :: a                                              -- ^ extra info+    }
README.md view
@@ -2,7 +2,7 @@ ===========  [![Hackage](https://img.shields.io/hackage/v/tcp-streams.svg?style=flat)](http://hackage.haskell.org/package/tcp-streams)-[![Build Status](https://travis-ci.org/winterland1989/tcp-streams.svg)](https://travis-ci.org/winterland1989/tcp-streams)+[![Build Status](https://travis-ci.org/didi-FP/tcp-streams.svg)](https://travis-ci.org/didi-FP/tcp-streams)  One stop solution for tcp client and server with tls support! @@ -10,67 +10,62 @@  + use [tls](http://hackage.haskell.org/package/tls) for tls connection. -Built-in [mozilla CA list](https://curl.haxx.se/docs/caextract.html) date: 2016/11/02. +Built-in [mozilla CA list](https://curl.haxx.se/docs/caextract.html) date: 2017/01/18.   From v0.6 TLS using [HsOpenSSL](http://hackage.haskell.org/package/HsOpenSSL) is split into [tcp-streams-openssl](http://hackage.haskell.org/package/tcp-streams-openssl) due to the difficulties of setting up openssl on many platform. -Also take a look at [wire-stream](http://hackage.haskell.org/package/wire-streams-0.0.2.0), for serialize/deserialize data. Happy hacking!+Also take a look at [wire-stream](http://hackage.haskell.org/package/wire-streams), for serialize/deserialize data. Happy hacking!  Example -------  ```haskell-import qualified System.IO.Streams         as Stream+import           Data.Connection import qualified System.IO.Streams.TCP     as TCP import qualified Data.TLSSetting           as TLS import qualified System.IO.Streams.TLS     as TLS  --  TCP Client ...-(is, os, sock) <- TCP.connect "127.0.0.1" 8888-Stream.write os =<< ..  -- sending-Stream.read is >>=  ..  -- receiving-TCP.close sock   ..  -- closing+conn <- TCP.connect "127.0.0.1" 8888+send conn "Hello! World." ..  -- sending+res <- Stream.read (source conn) ..  -- receiving+close conn                ..  -- closing ...   -- TCP Server ...-sock <- TCP.bindAndListen 8888 1024-(is, os, csock, _) <- TCP.accept sock-Stream.write os =<< ..  -- sending-Stream.read is >>= ..   -- receiving+sock <- TCP.bindAndListen 1024 8888+conn <- TCP.accept sock+req <- Stream.read (source conn) ..   -- receiving+send conn "GoodBye!" ..  -- sending ...   --  TLS Client ... cp <- TLS.makeTLSClientParams (TLS.CustomCAStore "myCA.pem")-(is, os, ctx) <- TCP.connect cp (Just "myCAName") "127.0.0.1" 8888-Stream.write os =<< ..  -- sending-Stream.read is >>=  ..  -- receiving-TLS.close ctx    ..  -- closing+conn <- TLS.connect cp (Just "myCAName") "127.0.0.1" 8888 ...   --  TLS Server ... sp <- TLS.makeServerParams "server.crt" [] "server.key"-sock <- TCP.bindAndListen 8889 1024-(is, os, ctx, sockAddr) <- TLS.accept sp sock-Stream.write os =<< ..  -- sending-Stream.read is >>= ..   -- receiving+sock <- TCP.bindAndListen 1024 8889+conn <- TLS.accept sp sock ...   -- HTTPS Client ... cp <- TLS.makeClientParams TLS.MozillaCAStore-(is, os, ctx) <- TLS.connect cp Nothing "www.google.com" 443-Stream.write (Just "GET / HTTP/1.1\r\n") os-Stream.write (Just "Host: www.google.com\r\n") os-Stream.write (Just "\r\n") os-bs <- Stream.readExactly 1024 is+conn <- TLS.connect cp Nothing "www.google.com" 443+send conn "GET / HTTP/1.1\r\n"+send conn "Host: www.google.com\r\n"+send conn "\r\n"+bs <- Stream.readExactly 1024 (source conn) ... ``` 
System/IO/Streams/TCP.hs view
@@ -1,199 +1,167 @@ {-# LANGUAGE ScopedTypeVariables #-} --- | This module provides convenience functions for interfacing @io-streams@--- with raw tcp. the default receive buffer size is 4096. sending is unbuffered,--- anything write into 'OutputStream' will be immediately send to underlying socket.------ Reading 'InputStream' will block until GHC IO manager find data is ready,--- for example 'System.IO.Streams.ByteString.readExactly 1024' will block until 1024 bytes are available.------ When socket is closed, the 'InputStream' will be closed too(further reading will return 'Nothing'),--- no exception will be thrown. You still should handle 'IOError' when you write to  'OutputStream' for safety,--- but no exception doesn't essentially mean a successful write, especially under bad network--- environment(broken wire for example).+-- | This module provides convenience functions for interfacing raw tcp. ----- `TCP_NODELAY` are enabled by default. you can use 'N.setSocketOption' to adjust.+-- Please use 'E.bracket' or its friends to enusre exception safety. -- -- This module is intended to be imported @qualified@, e.g.: -- -- @+-- import           "Data.Connection" -- import qualified "System.IO.Streams.TCP" as TCP -- @ -- module System.IO.Streams.TCP-  ( -- * tcp client-    connectSocket+  ( TCPConnection+    -- * client   , connect-  , connectWithBufferSize-  , withConnection-    -- * tcp server+  , connectSocket+  , socketToConnection+  , defaultChunkSize+    -- * server   , bindAndListen+  , bindAndListenWith   , accept-  , acceptWithBufferSize-    -- * helpers-  , socketToStreamsWithBufferSize-  , N.close+  , acceptWith   ) where -import           Control.Concurrent.MVar   (withMVar) import qualified Control.Exception         as E-import           Control.Monad             (unless, void)-import           Data.ByteString           (ByteString)+import           Control.Monad+import           Data.Connection import qualified Data.ByteString           as B-import           Network.Socket            (HostName, PortNumber, Socket (..))+import qualified Data.ByteString.Lazy.Internal as L import qualified Network.Socket            as N import qualified Network.Socket.ByteString as NB-import           System.IO.Streams         (InputStream, OutputStream)-import qualified System.IO.Streams         as Stream+import qualified Network.Socket.ByteString.Lazy as NL+import qualified System.IO.Streams         as S+import           Foreign.Storable   (sizeOf) -bUFSIZ :: Int-bUFSIZ = 4096+-- | Type alias for tcp connection.+--+-- Normally you shouldn't use 'N.Socket' in 'connExtraInfo' directly, this field is+-- intend for used with 'N.setSocketOption' if you need to.+--+type TCPConnection = Connection (N.Socket, N.SockAddr) --- | Resolve a 'HostName'/'PortNumber' combination.+-- | The chunk size used for I\/O, less the memory management overhead. ----- This function throws an 'IOError' when resolve fail.+-- Currently set to 32k. ---resolveAddrInfo :: HostName -> PortNumber -> IO (N.Family, N.SocketType, N.ProtocolNumber, N.SockAddr)-resolveAddrInfo host port = do-    -- Partial function here OK, network will throw an exception rather than-    -- return the empty list here.-    (addrInfo:_) <- N.getAddrInfo (Just hints) (Just host) (Just $ show port)-    let family     = N.addrFamily addrInfo-    let socketType = N.addrSocketType addrInfo-    let protocol   = N.addrProtocol addrInfo-    let address    = N.addrAddress addrInfo-    return (family, socketType, protocol, address)+defaultChunkSize :: Int+defaultChunkSize = 32 * k - chunkOverhead   where-    hints = N.defaultHints {-            N.addrFlags      = [N.AI_ADDRCONFIG, N.AI_NUMERICSERV]-        ,   N.addrSocketType = N.Stream-        }-{-# INLINABLE resolveAddrInfo #-}+    k = 1024+    chunkOverhead = 2 * sizeOf (undefined :: Int) --- | Convenience function for initiating an raw TCP connection to the given--- @('HostName', 'PortNumber')@ combination.+-- | Initiating an raw TCP connection to the given @('HostName', 'PortNumber')@ combination. ----- Note that sending an end-of-file to the returned 'OutputStream' will not--- close the underlying Socket connection.+-- It use 'N.getAddrInfo' to resolve host/service name+-- with 'N.AI_ADDRCONFIG', 'N.AI_NUMERICSERV' hint set, so it should be able to+-- resolve both numeric IPv4/IPv6 hostname and domain name. ---connectSocket :: HostName             -- ^ hostname to connect to-              -> PortNumber           -- ^ port number to connect to-              -> IO Socket+-- `TCP_NODELAY` are enabled by default. you can use 'N.setSocketOption' to adjust.+--+connectSocket :: N.HostName             -- ^ hostname to connect to+              -> N.PortNumber           -- ^ port number to connect to+              -> IO (N.Socket, N.SockAddr) connectSocket host port = do-    (family, socketType, protocol, address) <- resolveAddrInfo host port+    (family, socketType, protocol, addr) <- resolveAddrInfo host port     E.bracketOnError (N.socket family socketType protocol)                      N.close-                     (\sock -> do N.connect sock address-                                  -- NoDelay causes an error for AF_UNIX.-                                  E.catch-                                    (N.setSocketOption sock N.NoDelay 1)-                                    (\ (E.SomeException _) -> return ())-                                  return sock+                     (\sock -> do N.connect sock addr+                                  N.setSocketOption sock N.NoDelay 1+                                  return (sock, addr)                      )-+  where+    resolveAddrInfo host port = do+        -- Partial function here OK, network will throw an exception rather than+        -- return the empty list here.+        (addrInfo:_) <- N.getAddrInfo (Just hints) (Just host) (Just $ show port)+        let family     = N.addrFamily addrInfo+        let socketType = N.addrSocketType addrInfo+        let protocol   = N.addrProtocol addrInfo+        let addr    = N.addrAddress addrInfo+        return (family, socketType, protocol, addr)+      where+        hints = N.defaultHints {+                N.addrFlags      = [N.AI_ADDRCONFIG, N.AI_NUMERICSERV]+            ,   N.addrSocketType = N.Stream+            }+    {-# INLINABLE resolveAddrInfo #-} --- | Connect to remote tcp server.------ You may need to use 'E.bracket' pattern to enusre 'N.Socket' 's safety.+-- | Make a 'Connection' from a 'Socket' with given buffer size. ---connect :: HostName             -- ^ hostname to connect to-        -> PortNumber           -- ^ port number to connect to-        -> IO (InputStream ByteString, OutputStream ByteString, Socket)-connect host port = connectWithBufferSize host port bUFSIZ+socketToConnection+    :: Int                      -- ^ receive buffer size+    -> (N.Socket, N.SockAddr)   -- ^ socket address pair+    -> IO TCPConnection+socketToConnection bufsiz (sock, addr) = do+    is <- S.makeInputStream $ do+        s <- NB.recv sock bufsiz+        return $! if B.null s then Nothing else Just s+    return (Connection is (send sock) (N.close sock) (sock, addr))+  where+    send _    (L.Empty) = return ()+    send sock (L.Chunk bs L.Empty) = unless (B.null bs) (NB.sendAll sock bs)+    send sock lbs = NL.sendAll sock lbs --- | Connect to remote tcp server with adjustable receive buffer size.+-- | Connect to server using 'defaultChunkSize'. ---connectWithBufferSize :: HostName             -- ^ hostname to connect to-                      -> PortNumber           -- ^ port number to connect to-                      -> Int                  -- ^ tcp read buffer size-                      -> IO (InputStream ByteString, OutputStream ByteString, Socket)-connectWithBufferSize host port bufsiz = do-    sock <- connectSocket host port-    (is, os) <- socketToStreamsWithBufferSize bufsiz sock-    return (is, os, sock)--+connect :: N.HostName             -- ^ hostname to connect to+        -> N.PortNumber           -- ^ port number to connect to+        -> IO TCPConnection+connect host port = connectSocket host port >>= socketToConnection defaultChunkSize --- | Convenience function for initiating an TCP connection to the given--- @('HostName', 'PortNumber')@ combination. The socket will be--- closed and deleted after the user handler runs.+-- | Bind and listen on port with a limit on connection count. ---withConnection :: HostName             -- ^ hostname to connect to-               -> PortNumber           -- ^ port number to connect to-               -> ( InputStream ByteString-                    -> OutputStream ByteString -> Socket -> IO a) -- ^ Action to run with the new connection-               -> IO a-withConnection host port action =-    E.bracket (connect host port) cleanup go--  where-    go (is, os, sock) = action is os sock--    cleanup (_, os, sock) = E.mask_ $-        eatException $! Stream.write Nothing os >> N.close sock--    eatException m = void m `E.catch` (\(_::E.SomeException) -> return ())+-- This function will set @SO_REUSEADDR@, @TCP_NODELAY@ before binding.+--+bindAndListen :: Int                 -- ^ connection limit+              -> N.PortNumber        -- ^ port number+              -> IO N.Socket+bindAndListen = bindAndListenWith $ \ sock -> do+    N.setSocketOption sock N.ReuseAddr 1+    N.setSocketOption sock N.NoDelay 1  -- | Bind and listen on port with a limit on connection count. ---bindAndListen :: PortNumber -> Int -> IO Socket-bindAndListen port maxc = do+-- Note: The following socket options are inherited by a connected TCP socket from the listening socket:+--+-- @+-- SO_DEBUG+-- SO_DONTROUTE+-- SO_KEEPALIVE+-- SO_LINGER+-- SO_OOBINLINE+-- SO_RCVBUF+-- SO_RCVLOWAT+-- SO_SNDBUF+-- SO_SNDLOWAT+-- TCP_MAXSEG+-- TCP_NODELAY+-- @+--+bindAndListenWith :: (N.Socket -> IO ()) -- ^ set socket options before binding+                  -> Int                 -- ^ connection limit+                  -> N.PortNumber        -- ^ port number+                  -> IO N.Socket+bindAndListenWith f maxc port = do     E.bracketOnError (N.socket N.AF_INET N.Stream 0)                      N.close-                     (\sock -> do-                                  -- NoDelay causes an error for AF_UNIX.-                                  E.catch-                                    (do-                                        N.setSocketOption sock N.ReuseAddr 1-                                        N.setSocketOption sock N.NoDelay 1)-                                    (\ (E.SomeException _) -> return ())+                     (\sock -> do f sock                                   N.bind sock (N.SockAddrInet port N.iNADDR_ANY)                                   N.listen sock maxc                                   return sock                      ) --- | Accept a new connection from remote client, return a 'InputStream' / 'OutputStream' pair,--- a new underlying 'Socket', and remote 'N.SockAddr',you should call 'bindAndListen' first.------ This function will block if there's no connection comming.----accept :: Socket -> IO (InputStream ByteString, OutputStream ByteString, N.Socket, N.SockAddr)-accept sock = acceptWithBufferSize sock bUFSIZ----- | accept a connection with adjustable receive buffer size.+-- | Accept a connection with 'defaultChunkSize'. ---acceptWithBufferSize :: Socket -> Int -> IO (InputStream ByteString, OutputStream ByteString, N.Socket, N.SockAddr)-acceptWithBufferSize sock bufsiz = do-    (sock', sockAddr) <- N.accept sock-    (is, os) <- socketToStreamsWithBufferSize bufsiz sock'-    return (is, os, sock', sockAddr)-+accept :: N.Socket -> IO TCPConnection+accept = acceptWith (socketToConnection defaultChunkSize) --- | Convert a 'Socket' into a streams pair, catch 'IOException's on receiving and close 'InputStream'.--- You still should handle 'IOError' when you write to  'OutputStream' for safety,--- but no exception doesn't essentially mean a successful write, especially under bad network--- environment(broken wire for example).------ During receiving, the status 'Control.Concurrent.MVar.MVar' is locked, so that a cleanup thread--- can't affect receiving until finish.+-- | Accept a connection with user customization. ---socketToStreamsWithBufferSize-    :: Int                      -- ^ how large the receive buffer should be-    -> Socket                   -- ^ network socket-    -> IO (InputStream ByteString, OutputStream ByteString)-socketToStreamsWithBufferSize bufsiz sock@(MkSocket _ _ _ _ statusMVar) = do-    is <- Stream.makeInputStream input-    os <- Stream.makeOutputStream output-    return (is, os)-  where-    input = withMVar statusMVar $ \ status ->-        case status of-            N.Connected -> ( do-                s <- NB.recv sock bufsiz-                return $! if B.null s then Nothing else Just s-                ) `E.catch` (\(_::E.IOException) -> return Nothing)-            _ -> return Nothing--    output Nothing  = return ()-    output (Just s) = unless (B.null s) (NB.sendAll sock s)+acceptWith :: ((N.Socket, N.SockAddr) -> IO TCPConnection) -- ^ set socket options, adjust receive buffer, etc.+           -> N.Socket+           -> IO TCPConnection+acceptWith f = f <=< N.accept
System/IO/Streams/TLS.hs view
@@ -1,131 +1,103 @@ {-# LANGUAGE ScopedTypeVariables #-} --- | This module provides convenience functions for interfacing @io-streams@--- with @tls@. the default receive buffer size is decided by @tls@.--- sending is unbuffered, anything write into 'OutputStream' will be--- immediately send to underlying socket.------ The same exceptions rule which applied to TCP apply here, with addtional--- 'TLS.TLSException' to be watched out.+-- | This module provides convenience functions for interfacing @tls@. -- -- This module is intended to be imported @qualified@, e.g.: -- -- @+-- import           "Data.Connection" -- import qualified "System.IO.Streams.TLS" as TLS -- @ -- module System.IO.Streams.TLS-  ( -- * client-    connect-  , withConnection+  ( TLSConnection+    -- * client+  , connect+  , connectTLS+  , tLsToConnection     -- * server   , accept-    -- * helpers-  , tlsToStreams-  , close-    -- * re-export helpers+    -- * re-export   , module Data.TLSSetting   ) where  import qualified Control.Exception     as E-import           Control.Monad         (void)-import           Data.ByteString       (ByteString)+import           Data.Connection import qualified Data.ByteString       as B import qualified Data.ByteString.Char8 as BC-import           Data.ByteString.Lazy  (fromStrict) import           Data.TLSSetting-import           Network.Socket        (HostName, PortNumber, Socket) import qualified Network.Socket        as N import           Network.TLS           (ClientParams, Context, ServerParams) import qualified Network.TLS           as TLS-import           System.IO.Streams     (InputStream, OutputStream) import qualified System.IO.Streams     as Stream import qualified System.IO.Streams.TCP as TCP  --- | Given an existing TLS 'Context' connection, produces an 'InputStream' \/--- 'OutputStream' pair.+-- | Type alias for tls connection. ---tlsToStreams :: Context             -- ^ TLS connection object-             -> IO (InputStream ByteString, OutputStream ByteString)-tlsToStreams ctx = do+-- Normally you shouldn't use 'TLS.Context' in 'connExtraInfo' directly.+--+type TLSConnection = Connection (TLS.Context, N.SockAddr)++-- | Make a 'Connection' from a 'Context'.+--+tLsToConnection :: (Context, N.SockAddr)    -- ^ TLS connection / socket address pair+                -> IO TLSConnection+tLsToConnection (ctx, addr) = do     is <- Stream.makeInputStream input-    os <- Stream.makeOutputStream output-    return (is, os)+    return (Connection is write (closeTLS ctx) (ctx, addr))   where-    input = ( do+    input = (do         s <- TLS.recvData ctx         return $! if B.null s then Nothing else Just s         ) `E.catch` (\(_::E.SomeException) -> return Nothing)--    output Nothing  = return ()-    output (Just s) = TLS.sendData ctx (fromStrict s)-{-# INLINABLE tlsToStreams #-}+    write s = TLS.sendData ctx s  -- | Close a TLS 'Context' and its underlying socket. ---close :: Context -> IO ()-close ctx = (TLS.bye ctx >> TLS.contextClose ctx) -- sometimes socket was closed before 'TLS.bye'+closeTLS :: Context -> IO ()+closeTLS ctx = (TLS.bye ctx >> TLS.contextClose ctx) -- sometimes socket was closed before 'TLS.bye'     `E.catch` (\(_::E.SomeException) -> return ())   -- so we catch the 'Broken pipe' error here  -- | Convenience function for initiating an TLS connection to the given -- @('HostName', 'PortNumber')@ combination. ----- Note that sending an end-of-file to the returned 'OutputStream' will not--- close the underlying TLS connection; to do that, call 'close'------ this operation will throw 'TLS.TLSException' on failure.+-- This operation may throw 'TLS.TLSException' on failure. ---connect :: ClientParams         -- ^ check "Data.TLSSetting".-        -> Maybe String         -- ^ Optional certificate subject name, if set to 'Nothing'-                                -- then we will try to verify 'HostName' as subject name.-        -> HostName             -- ^ hostname to connect to-        -> PortNumber           -- ^ port number to connect to-        -> IO (InputStream ByteString, OutputStream ByteString, Context)-connect prms subname host port = do+connectTLS :: ClientParams         -- ^ check "Data.TLSSetting"+           -> Maybe String         -- ^ Optional certificate subject name, if set to 'Nothing'+                                   -- then we will try to verify 'HostName' as subject name+           -> N.HostName           -- ^ hostname to connect to+           -> N.PortNumber         -- ^ port number to connect to+           -> IO (Context, N.SockAddr)+connectTLS prms subname host port = do     let subname' = maybe host id subname         prms' = prms { TLS.clientServerIdentification = (subname', BC.pack (show port)) }-    sock <- TCP.connectSocket host port-    E.bracketOnError (TLS.contextNew sock prms') close $ \ ctx -> do+    (sock, addr) <- TCP.connectSocket host port+    E.bracketOnError (TLS.contextNew sock prms') closeTLS $ \ ctx -> do         TLS.handshake ctx-        (is, os) <- tlsToStreams ctx-        return (is, os, ctx)-+        return (ctx, addr) --- | Convenience function for initiating an TLS connection to the given--- @('HostName', 'PortNumber')@ combination. The socket and TLS connection are--- closed and deleted after the user handler runs.+-- | Connect to server using TLS and return a 'Connection'. ---withConnection :: ClientParams-               -> Maybe HostName-               -> HostName-               -> PortNumber-               -> (InputStream ByteString -> OutputStream ByteString -> Context -> IO a)-                       -- ^ Action to run with the new connection-               -> IO a-withConnection prms subname host port action =-    E.bracket (connect prms subname host port) cleanup go--  where-    go (is, os, ctx) = action is os ctx--    cleanup (_, os, ctx) = E.mask_ $-        eatException $! Stream.write Nothing os >> close ctx--    eatException m = void m `E.catch` (\(_::E.SomeException) -> return ())-+connect :: ClientParams         -- ^ check "Data.TLSSetting"+        -> Maybe String         -- ^ Optional certificate subject name, if set to 'Nothing'+                                -- then we will try to verify 'HostName' as subject name+        -> N.HostName           -- ^ hostname to connect to+        -> N.PortNumber         -- ^ port number to connect to+        -> IO TLSConnection+connect prms subname host port = connectTLS prms subname host port >>= tLsToConnection --- | Accept a new connection from remote client, return a 'InputStream' / 'OutputStream'--- pair and remote 'N.SockAddr', you should call 'TCP.bindAndListen' first.+-- | Accept a new TLS connection from remote client with listening socket. ----- this operation will throw 'TLS.TLSException' on failure.+-- This operation may throw 'TLS.TLSException' on failure. ---accept :: ServerParams              -- ^ check "Data.TLSSetting".-       -> Socket                    -- ^ the listening 'Socket'.-       -> IO (InputStream ByteString, OutputStream ByteString, Context, N.SockAddr)+accept :: ServerParams              -- ^ check "Data.TLSSetting"+       -> N.Socket                  -- ^ the listening 'Socket'+       -> IO TLSConnection accept prms sock = do-    (sock', sockAddr) <- N.accept sock-    E.bracketOnError (TLS.contextNew sock' prms) close $ \ ctx -> do+    (sock', addr) <- N.accept sock+    E.bracketOnError (TLS.contextNew sock' prms) closeTLS $ \ ctx -> do         TLS.handshake ctx-        (is, os) <- tlsToStreams ctx-        return (is, os, ctx, sockAddr)+        conn <- tLsToConnection (ctx, addr)+        return conn
+ System/IO/Streams/UnixSocket.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE ScopedTypeVariables #-}++-- | This module provides convenience functions for interfacing unix-socket.+--+-- This module is only exported on platforms with+-- <https://en.wikipedia.org/wiki/Unix_domain_socket Unix domain socket> support.+--+-- This module is intended to be imported @qualified@, e.g.:+--+-- @+-- import           "Data.Connection"+-- import qualified "System.IO.Streams.UnixSocket" as UnixSocket+-- import qualified "System.IO.Streams.TCP"        as TCP+-- @+--+-- @since 1.0+--+module System.IO.Streams.UnixSocket+  ( -- * client+    connect+  , connectSocket+    -- * server+  , bindAndListen+  ) where++import qualified Control.Exception         as E+import qualified Network.Socket            as N+import qualified System.IO.Streams.TCP     as TCP++-- | Convenience function for initiating an raw TCP connection to the given+-- unix-socket file.+--+-- Note that sending an end-of-file to the returned 'OutputStream' will not+-- close the underlying Socket connection.+--+connectSocket :: String             -- ^ unix-socket to connect to+              -> IO (N.Socket, N.SockAddr)+connectSocket usock =+    E.bracketOnError (N.socket N.AF_UNIX N.Stream N.defaultProtocol)+                     N.close+                     (\sock -> do let addr = N.SockAddrUnix usock+                                  N.connect sock addr+                                  -- NoDelay causes an error for AF_UNIX, so we don't set+                                  -- default output buffer of unix socket is too small+                                  N.setSocketOption sock N.SendBuffer (TCP.defaultChunkSize * 16)+                                  return (sock, addr)+                     )++-- | Connect to unix-socket.+--+connect :: String             -- ^ unix-socket to connect to+        -> IO TCP.TCPConnection+connect usock = connectSocket usock >>= TCP.socketToConnection TCP.defaultChunkSize++-- | Bind and listen on a unix-socket with a limit on connection count.+--+-- Use 'TCP.accept' / 'TCP.acceptWith'  to accept new unix socket connections.+--+bindAndListen :: Int -> String -> IO N.Socket+bindAndListen maxc usock =+    E.bracketOnError+        (N.socket N.AF_UNIX N.Stream 0)+        N.close+        (\sock -> do N.setSocketOption sock N.SendBuffer (TCP.defaultChunkSize * 16)+                     N.bind sock (N.SockAddrUnix usock)+                     N.listen sock maxc+                     return sock+        )
mozillaCAStore.pem view
@@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ##-## Certificate data from Mozilla as of: Wed Nov  2 04:12:05 2016 GMT+## Certificate data from Mozilla as of: Wed Jan 18 04:12:05 2017 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates@@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.27.-## SHA256: 17e2a90c8a5cfd6a675b3475d3d467e1ab1fe0d5397e907b08206182389caa08+## SHA256: dffa79e6aa993f558e82884abf7bb54bf440ab66ee91d82a27a627f6f2a4ace4 ##  @@ -252,27 +252,6 @@ tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- -RSA Security 2048 v3-====================------BEGIN CERTIFICATE------MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6MRkwFwYDVQQK-ExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJpdHkgMjA0OCBWMzAeFw0wMTAy-MjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAXBgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAb-BgNVBAsTFFJTQSBTZWN1cml0eSAyMDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC-AQEAt49VcdKA3XtpeafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7-Jylg/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGlwSMiuLgb-WhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnhAMFRD0xS+ARaqn1y07iH-KrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP-+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpuAWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/-MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4E-FgQUB8NRMKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYcHnmY-v/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/Zb5gEydxiKRz44Rj-0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+f00/FGj1EVDVwfSQpQgdMWD/YIwj-VAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVOrSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395-nzIlQnQFgCi/vcEkllgVsRch6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kA-pKnXwiJPZ9d37CAFYd4=------END CERTIFICATE------ GeoTrust Global CA ================== -----BEGIN CERTIFICATE-----@@ -1285,30 +1264,6 @@ U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- -IGC/A-=====------BEGIN CERTIFICATE------MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYD-VQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVE-Q1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZy-MB4XDTAyMTIxMzE0MjkyM1oXDTIwMTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQI-EwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NT-STEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMIIB-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaIs9z4iPf930Pfeo2aSVz2-TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCW-So7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYy-HF2fYPepraX/z9E0+X1bF8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNd-frGoRpAxVs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGdPDPQ-tQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNVHSAEDjAMMAoGCCqB-egF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAxNjAfBgNVHSMEGDAWgBSjBS8YYFDC-iQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUFAAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RK-q89toB9RlPhJy3Q2FLwV3duJL92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3Q-MZsyK10XZZOYYLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg-Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2aNjSaTFR+FwNI-lQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R0982gaEbeC9xs/FZTEYYKKuF-0mBWWg==------END CERTIFICATE------ Security Communication EV RootCA1 ================================= -----BEGIN CERTIFICATE-----@@ -1518,58 +1473,6 @@ dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI= -----END CERTIFICATE----- -Buypass Class 2 CA 1-====================------BEGIN CERTIFICATE------MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU-QnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3MgQ2xhc3MgMiBDQSAxMB4XDTA2-MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBh-c3MgQVMtOTgzMTYzMzI3MR0wGwYDVQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZI-hvcNAQEBBQADggEPADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7M-cXA0ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLXl18xoS83-0r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVBHfCuuCkslFJgNJQ72uA4-0Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/R-uFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNC-MEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0P-AQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLPgcIV-1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+DKhQ7SLHrQVMdvvt-7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKuBctN518fV4bVIJwo+28TOPX2EZL2-fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHsh7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5w-wDX3OaJdZtB7WZ+oRxKaJyOkLY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho------END CERTIFICATE-------EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1-==========================================================================------BEGIN CERTIFICATE------MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNVBAMML0VCRyBF-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMTcwNQYDVQQKDC5FQkcg-QmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXptZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAe-Fw0wNjA4MTcwMDIxMDlaFw0xNjA4MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25p-ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2lt-IFRla25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIiMA0GCSqG-SIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h4fuXd7hxlugTlkaDT7by-X3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAktiHq6yOU/im/+4mRDGSaBUorzAzu8T2b-gmmkTPiab+ci2hC6X5L8GCcKqKpE+i4stPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfr-eYteIAbTdgtsApWjluTLdlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZ-TqNGFav4c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8UmTDGy-Y5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z+kI2sSXFCjEmN1Zn-uqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0OLna9XvNRiYuoP1Vzv9s6xiQFlpJI-qkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMWOeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vm-ExH8nYQKE3vwO9D8owrXieqWfo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0-Nokb+Clsi7n2l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB-/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgwFoAU587GT/wW-Z5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+8ygjdsZs93/mQJ7ANtyVDR2t-FcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgm-zJNSroIBk5DKd8pNSe/iWtkqvTDOTLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64k-XPBfrAowzIpAoHMEwfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqT-bCmYIai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJnxk1Gj7sU-RT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4QDgZxGhBM/nV+/x5XOULK-1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9qKd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt-2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11thie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQ-Y9iJSrSq3RZj9W6+YKH47ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9-AahH3eU7QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT------END CERTIFICATE------ certSIGN ROOT CA ================ -----BEGIN CERTIFICATE-----@@ -1819,34 +1722,6 @@ 66+KAQ== -----END CERTIFICATE----- -Juur-SK-=======------BEGIN CERTIFICATE------MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcNAQkBFglwa2lA-c2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMRAw-DgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMwMVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqG-SIb3DQEJARYJcGtpQHNrLmVlMQswCQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVy-aW1pc2tlc2t1czEQMA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC-ggEBAIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOBSvZiF3tf-TQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkzABpTpyHhOEvWgxutr2TC-+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvHLCu3GFH+4Hv2qEivbDtPL+/40UceJlfw-UR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMPPbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDa-Tpxt4brNj3pssAki14sL2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQF-MAMBAf8wggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwICMIHD-HoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDkAGwAagBhAHMAdABh-AHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0AHMAZQBlAHIAaQBtAGkAcwBrAGUA-cwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABzAGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABr-AGkAbgBuAGkAdABhAG0AaQBzAGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nw-cy8wKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE-FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcYP2/v6X2+MA4G-A1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOiCfP+JmeaUOTDBS8rNXiRTHyo-ERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+gkcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyL-abVAyJRld/JXIWY7zoVAtjNjGr95HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678-IIbsSt4beDI3poHSna9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkh-Mp6qqIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0ZTbvGRNs2-yyqcjg==------END CERTIFICATE------ Hongkong Post Root CA 1 ======================= -----BEGIN CERTIFICATE-----@@ -2310,41 +2185,6 @@ vgt2Fl43N+bYdJeimUV5 -----END CERTIFICATE----- -Root CA Generalitat Valenciana-==============================------BEGIN CERTIFICATE------MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJFUzEfMB0GA1UE-ChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290-IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcNMDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3-WjBoMQswCQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UE-CxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0G-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+WmmmO3I2-F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKjSgbwJ/BXufjpTjJ3Cj9B-ZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGlu6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQ-D0EbtFpKd71ng+CT516nDOeB0/RSrFOyA8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXte-JajCq+TA81yc477OMUxkHl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMB-AAGjggM7MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBraS5n-dmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIICIwYKKwYBBAG/VQIB-ADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBl-AHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIAYQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIA-YQBsAGkAdABhAHQAIABWAGEAbABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQBy-AGEAYwBpAPMAbgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA-aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMAaQBvAG4AYQBt-AGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQAZQAgAEEAdQB0AG8AcgBpAGQA-YQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBu-AHQAcgBhACAAZQBuACAAbABhACAAZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAA-OgAvAC8AdwB3AHcALgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0-dHA6Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+yeAT8MIGV-BgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQswCQYDVQQGEwJFUzEfMB0G-A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScwJQYDVQQDEx5S-b290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRh-TvW1yEICKrNcda3FbcrnlD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdz-Ckj+IHLtb8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg9J63-NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XFducTZnV+ZfsBn5OH-iJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmCIoaZM3Fa6hlXPZHNqcCjbgcTpsnt-+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=------END CERTIFICATE------ TWCA Root Certification Authority ================================= -----BEGIN CERTIFICATE-----@@ -4063,4 +3903,141 @@ YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ m+kXQ99b21/+jh5Xos1AnX5iItreGCc=+-----END CERTIFICATE-----++AC RAIZ FNMT-RCM+================+-----BEGIN CERTIFICATE-----+MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT+AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw+MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD+TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC+ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf+qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr+btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL+j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou+08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw+WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT+tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ+47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC+ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa+i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE+FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o+dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD+nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s+D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ+j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT+Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW++YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7+Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d+8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm+5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG+rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM=+-----END CERTIFICATE-----++Amazon Root CA 1+================+-----BEGIN CERTIFICATE-----+MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD+VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1+MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv+bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC+ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH+FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ+gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t+dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce+VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB+/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3+DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM+CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy+8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa+2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2+xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5+-----END CERTIFICATE-----++Amazon Root CA 2+================+-----BEGIN CERTIFICATE-----+MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD+VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1+MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv+bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC+ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4+kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp+N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9+AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd+fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx+kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS+btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0+Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN+c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf++3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw+DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA+A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE+YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW+xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ+gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW+aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV+Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3+KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi+JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=+-----END CERTIFICATE-----++Amazon Root CA 3+================+-----BEGIN CERTIFICATE-----+MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG+EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy+NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ+MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB+f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr+Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43+rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc+eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==+-----END CERTIFICATE-----++Amazon Root CA 4+================+-----BEGIN CERTIFICATE-----+MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG+EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy+NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ+MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN+/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri+83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV+HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA+MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1+AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==+-----END CERTIFICATE-----++LuxTrust Global Root 2+======================+-----BEGIN CERTIFICATE-----+MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG+A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh+bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW+MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm+Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2+xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC+wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm+1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm+FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF+wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/+a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U+ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ+MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB+/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5+Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ+FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN+H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW+7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu+ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA+VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR+TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt+/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc+7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I+iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr -----END CERTIFICATE-----
tcp-streams.cabal view
@@ -1,12 +1,12 @@ name:                tcp-streams-version:             0.6.0.0+version:             1.0.0.0 synopsis:            One stop solution for tcp client and server with tls support. description:         One stop solution for tcp client and server with tls support. license:             BSD3 license-file:        LICENSE author:              winterland1989 maintainer:          winterland1989@gmail.com-homepage:            https://github.com/winterland1989/tcp-streams+homepage:            https://github.com/didi-FP/tcp-streams copyright:           (c) Winterland 2016  category:            Network build-type:          Simple@@ -21,13 +21,17 @@  source-repository head   type:     git-  location: git://github.com/winterland1989/tcp-streams.git+  location: git://github.com/didi-FP/tcp-streams.git  library   exposed-modules:      Data.TLSSetting+                    ,   Data.Connection                     ,   System.IO.Streams.TCP                     ,   System.IO.Streams.TLS +  if !os(windows)+    exposed-modules:    System.IO.Streams.UnixSocket+   other-modules:    Paths_tcp_streams   -- other-extensions:       build-depends:        base           >=4.7  && < 5.0@@ -47,7 +51,7 @@  test-suite testsuite   type:              exitcode-stdio-1.0-  Hs-source-dirs:    src test+  Hs-source-dirs:    test   main-is:           Main.hs   default-language:  Haskell2010   ghc-options:    -Wall -threaded@@ -57,8 +61,6 @@                     ,   network                     ,   bytestring                     ,   HUnit                      >= 1.2      && <2-                    ,   QuickCheck                 >= 2.3.0.2  && <3                     ,   test-framework             >= 0.6      && <0.9                     ,   test-framework-hunit       >= 0.2.7    && <0.4-                    ,   test-framework-quickcheck2 >= 0.2.12.1 && <0.4                     ,   directory      == 1.*
test/Main.hs view
@@ -6,35 +6,36 @@ ------------------------------------------------------------------------------ import           Control.Concurrent             (forkIO, newEmptyMVar, putMVar,                                                  takeMVar)-import qualified Control.Exception              as E import qualified Network.Socket                 as N import           System.Timeout                 (timeout) import           Test.Framework import           Test.Framework.Providers.HUnit import           Test.HUnit                     hiding (Test) import qualified Data.ByteString                as B+import qualified Data.ByteString.Lazy           as L import           System.Directory               (removeFile) ------------------------------------------------------------------------------ import qualified Data.TLSSetting                as TLS+import           Data.Connection import qualified System.IO.Streams              as Stream-import qualified System.IO.Streams.TCP          as Raw+import qualified System.IO.Streams.TCP          as TCP import qualified System.IO.Streams.TLS          as TLS ------------------------------------------------------------------------------  main :: IO () main = defaultMain tests   where-    tests = [ testGroup "TCP" rawTests+    tests = [ testGroup "TCP" tcpTests             , testGroup "TLS"  tlsTests             ]  ------------------------------------------------------------------------------ -rawTests :: [Test]-rawTests = [ testRawSocket ]+tcpTests :: [Test]+tcpTests = [ testTCPSocket ] -testRawSocket :: Test-testRawSocket = testCase "network/socket" $+testTCPSocket :: Test+testTCPSocket = testCase "network/socket" $     N.withSocketsDo $ do     x <- timeout (10 * 10^(6::Int)) go     assertEqual "ok" (Just ()) x@@ -50,18 +51,18 @@      client mvar resultMVar = do         _ <- takeMVar mvar-        (is, os, sock) <- Raw.connect "127.0.0.1" 8888-        Stream.fromList ["", "ok"] >>= Stream.connectTo os-        N.shutdown sock N.ShutdownSend-        Stream.toList is >>= putMVar resultMVar-        N.close sock+        conn <- TCP.connect "127.0.0.1" 8888+        send conn "ok"+        Stream.toList (source conn) >>= putMVar resultMVar+        close conn      server mvar = do-        sock <- Raw.bindAndListen 8888 1024+        sock <- TCP.bindAndListen 1024 8888         putMVar mvar ()-        (is, os, csock, _) <- Raw.accept sock-        os' <- Stream.atEndOfOutput (N.close csock) os-        os' `Stream.connectTo` is+        conn <- TCP.accept sock+        req <- Stream.readExactly 2 (source conn)+        send conn (L.fromStrict req)+        close conn  ------------------------------------------------------------------------------ @@ -81,23 +82,24 @@         forkIO $ client portMVar resultMVar         server portMVar         l <- takeMVar resultMVar-        assertEqual "testSocket" l (Just "ok")+        assertEqual "testSocket" l ["ok"]      client mvar resultMVar = do         _ <- takeMVar mvar         cp <- TLS.makeClientParams (TLS.CustomCAStore "./test/cert/ca.pem")-        (is, os, ctx) <- TLS.connect cp (Just "Winter") "127.0.0.1" 8889-        Stream.fromList ["", "ok"] >>= Stream.connectTo os-        Stream.read is >>= putMVar resultMVar  -- There's no shutdown in tls, so we won't get a 'Nothing'-        TLS.close ctx+        conn <- TLS.connect cp (Just "Winter") "127.0.0.1" 8889+        send conn "ok"+        Stream.toList (source conn) >>= putMVar resultMVar+        close conn      server mvar = do         sp <- TLS.makeServerParams "./test/cert/server.crt" [] "./test/cert/server.key"-        sock <- Raw.bindAndListen 8889 1024+        sock <- TCP.bindAndListen 1024 8889         putMVar mvar ()-        (is, os, tls, _) <- TLS.accept sp sock-        os' <- Stream.atEndOfOutput (TLS.close tls) os-        os' `Stream.connectTo` is+        conn <- TLS.accept sp sock+        req <- Stream.readExactly 2 (source conn)+        send conn (L.fromStrict req)+        close conn  testHTTPS :: Test testHTTPS = testCase "network/https" $@@ -107,10 +109,10 @@   where     go = do         cp <- TLS.makeClientParams TLS.MozillaCAStore-        (is, os, ctx) <- TLS.connect cp Nothing "www.google.com" 443-        Stream.write (Just "GET / HTTP/1.1\r\n") os-        Stream.write (Just "Host: www.google.com\r\n") os-        Stream.write (Just "\r\n") os-        bs <- Stream.readExactly 1024 is-        TLS.close ctx+        conn <- TLS.connect cp Nothing "www.bing.com" 443+        send conn ("GET / HTTP/1.1\r\n")+        send conn ("Host: www.bing.com\r\n")+        send conn ("\r\n")+        bs <- Stream.readExactly 1024 (source conn)+        close conn         return (B.length bs)