tcp-streams 0.2.3.0 → 0.3.0.0
raw patch · 7 files changed
+60/−37 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- System.IO.Streams.OpenSSL: closeSSL :: SSL -> IO ()
- System.IO.Streams.TLS: closeTLS :: Context -> IO ()
+ System.IO.Streams.OpenSSL: close :: SSL -> IO ()
+ System.IO.Streams.TLS: close :: Context -> IO ()
Files
- ChangeLog.md +5/−0
- README.md +3/−3
- System/IO/Streams/OpenSSL.hs +13/−6
- System/IO/Streams/TCP.hs +9/−3
- System/IO/Streams/TLS.hs +17/−9
- tcp-streams.cabal +1/−1
- test/Main.hs +12/−15
ChangeLog.md view
@@ -1,5 +1,10 @@ # Revision history for tcp-simple +## 0.3.0.0++* Add qualified notes, rename `closeTLS/closeSSL` to `close`.+* fix `Bad pipe` error in tls's `close`+ ## 0.2.3.0 * Add `acceptWithBufferSize`, `socketToStreamsWithBufferSize`, fix recv exception handler.
README.md view
@@ -28,15 +28,15 @@ ```haskell import qualified System.IO.Streams as Stream import qualified System.IO.Streams.TCP as TCP+import qualified Data.TLSSetting as TLS import qualified System.IO.Streams.TLS as TLS-import qualified NetWork.Socket as Socket -- TCP Client ... (is, os, sock) <- TCP.connect "127.0.0.1" 8888 Stream.write os =<< .. -- sending Stream.read is >>= .. -- receiving-Socket.close sock .. -- closing+TCP.close sock .. -- closing ... @@ -55,7 +55,7 @@ (is, os, ctx) <- TCP.connect cp (Just "myCAName") "127.0.0.1" 8888 Stream.write os =<< .. -- sending Stream.read is >>= .. -- receiving-TLS.closeTLS ctx .. -- closing+TLS.close ctx .. -- closing ...
System/IO/Streams/OpenSSL.hs view
@@ -9,6 +9,13 @@ -- The same exceptions rule which applied to TCP apply here, with addtional -- 'SSL.SomeSSLException` to be watched out. --+-- This module is intended to be imported @qualified@, e.g.:+--+-- @+-- import qualified "Data.SSLSetting" as SSL+-- import qualified "System.IO.Streams.OpenSSL" as SSL+-- @+-- -- Be sure to use 'withOpenSSL' wrap your operation before using any functions here. -- otherwise a segmentation fault will happen. --@@ -21,7 +28,7 @@ -- * helpers , withOpenSSL , sslToStreams- , closeSSL+ , close ) where import qualified Control.Exception as E@@ -61,8 +68,8 @@ output (Just s) = SSL.write ssl s {-# INLINABLE sslToStreams #-} -closeSSL :: SSL.SSL -> IO ()-closeSSL ssl = do+close :: SSL.SSL -> IO ()+close ssl = do SSL.shutdown ssl SSL.Unidirectional maybe (return ()) N.close (SSL.sslSocket ssl) @@ -82,7 +89,7 @@ -> IO (InputStream ByteString, OutputStream ByteString, SSL) connect ctx subname host port = do sock <- TCP.connectSocket host port- E.bracketOnError (SSL.connection ctx sock) closeSSL $ \ ssl -> do+ E.bracketOnError (SSL.connection ctx sock) close $ \ ssl -> do SSL.connect ssl trusted <- SSL.getVerifyResult ssl cert <- SSL.getPeerCertificate ssl@@ -128,7 +135,7 @@ go (is, os, ssl) = action is os ssl cleanup (_, os, ssl) = E.mask_ $- eatException $! Streams.write Nothing os >> closeSSL ssl+ eatException $! Streams.write Nothing os >> close ssl eatException m = void m `E.catch` (\(_::E.SomeException) -> return ()) @@ -143,7 +150,7 @@ -> IO (InputStream ByteString, OutputStream ByteString, SSL.SSL, N.SockAddr) accept ctx sock = do (sock', sockAddr) <- N.accept sock- E.bracketOnError (SSL.connection ctx sock') closeSSL $ \ ssl -> do+ E.bracketOnError (SSL.connection ctx sock') close $ \ ssl -> do SSL.accept ssl trusted <- SSL.getVerifyResult ssl unless trusted (E.throwIO $ SSL.ProtocolError "fail to verify certificate")
System/IO/Streams/TCP.hs view
@@ -13,9 +13,15 @@ -- environment(broken wire for example). -- -- `TCP_NODELAY` are enabled by default. you can use 'N.setSocketOption' to adjust.--module System.IO.Streams.TCP (- -- * tcp client+--+-- This module is intended to be imported @qualified@, e.g.:+--+-- @+-- import qualified "System.IO.Streams.TCP" as TCP+-- @+--+module System.IO.Streams.TCP+ ( -- * tcp client connectSocket , connect , connectWithBufferSize
System/IO/Streams/TLS.hs view
@@ -8,15 +8,22 @@ -- The same exceptions rule which applied to TCP apply here, with addtional -- 'TLS.TLSException' to be watched out. ---module System.IO.Streams.TLS (- -- * client+-- This module is intended to be imported @qualified@, e.g.:+--+-- @+-- import qualified "Data.TLSSetting" as TLS+-- import qualified "System.IO.Streams.TLS" as TLS+-- @+--+module System.IO.Streams.TLS+ ( -- * client connect , withConnection -- * server , accept -- * helpers , tlsToStreams- , closeTLS+ , close ) where import qualified Control.Exception as E@@ -55,14 +62,15 @@ -- | Close a TLS 'Context' and its underlying socket. ---closeTLS :: Context -> IO ()-closeTLS ctx = TLS.bye ctx >> TLS.contextClose ctx+close :: Context -> IO ()+close 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 'closeTLS'+-- close the underlying TLS connection; to do that, call 'close' -- -- this operation will throw 'TLS.TLSException' on failure. --@@ -76,7 +84,7 @@ 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') closeTLS $ \ ctx -> do+ E.bracketOnError (TLS.contextNew sock prms') close $ \ ctx -> do TLS.handshake ctx (is, os) <- tlsToStreams ctx return (is, os, ctx)@@ -100,7 +108,7 @@ go (is, os, ctx) = action is os ctx cleanup (_, os, ctx) = E.mask_ $- eatException $! Stream.write Nothing os >> closeTLS ctx+ eatException $! Stream.write Nothing os >> close ctx eatException m = void m `E.catch` (\(_::E.SomeException) -> return ()) @@ -115,7 +123,7 @@ -> IO (InputStream ByteString, OutputStream ByteString, Context, N.SockAddr) accept prms sock = do (sock', sockAddr) <- N.accept sock- E.bracketOnError (TLS.contextNew sock' prms) closeTLS $ \ ctx -> do+ E.bracketOnError (TLS.contextNew sock' prms) close $ \ ctx -> do TLS.handshake ctx (is, os) <- tlsToStreams ctx return (is, os, ctx, sockAddr)
tcp-streams.cabal view
@@ -1,5 +1,5 @@ name: tcp-streams-version: 0.2.3.0+version: 0.3.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
test/Main.hs view
@@ -61,9 +61,8 @@ sock <- Raw.bindAndListen 8888 1024 putMVar mvar () (is, os, csock, _) <- Raw.accept sock- is' <- Stream.atEndOfInput (N.close csock) is- os `Stream.connectTo` is'- N.sClose sock+ os' <- Stream.atEndOfOutput (N.close csock) os+ os' `Stream.connectTo` is ------------------------------------------------------------------------------ @@ -91,19 +90,18 @@ (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.closeTLS ctx+ TLS.close ctx server mvar = do sp <- TLS.makeServerParams "./test/cert/server.crt" [] "./test/cert/server.key" sock <- Raw.bindAndListen 8889 1024 putMVar mvar () (is, os, tls, _) <- TLS.accept sp sock- is' <- Stream.atEndOfInput (Stream.write Nothing os >> TLS.closeTLS tls) is- os `Stream.connectTo` is'- N.sClose sock+ os' <- Stream.atEndOfOutput (TLS.close tls) os+ os' `Stream.connectTo` is testHTTPS :: Test-testHTTPS = testCase "network/socket" $+testHTTPS = testCase "network/https" $ N.withSocketsDo $ do x <- timeout (10 * 10^(6::Int)) go assertEqual "ok" (Just 1024) x@@ -115,7 +113,7 @@ Stream.write (Just "Host: www.google.com\r\n") os Stream.write (Just "\r\n") os bs <- Stream.readExactly 1024 is- TLS.closeTLS ctx+ TLS.close ctx return (B.length bs) ------------------------------------------------------------------------------@@ -144,19 +142,18 @@ (is, os, ctx) <- SSL.connect cp (Just "Winter") "127.0.0.1" 8890 Stream.fromList ["", "ok"] >>= Stream.connectTo os Stream.read is >>= putMVar resultMVar -- There's no shutdown in tls, so we won't get a 'Nothing'- SSL.closeSSL ctx+ SSL.close ctx server mvar = do sp <- SSL.makeServerSSLContext "./test/cert/server.crt" [] "./test/cert/server.key" sock <- Raw.bindAndListen 8890 1024 putMVar mvar () (is, os, ssl, _) <- SSL.accept sp sock- is' <- Stream.atEndOfInput (Stream.write Nothing os >> SSL.closeSSL ssl) is- os `Stream.connectTo` is'- N.close sock+ os' <- Stream.atEndOfOutput (SSL.close ssl) os+ os' `Stream.connectTo` is testHTTPS' :: Test-testHTTPS' = testCase "network/socket" $+testHTTPS' = testCase "network/https" $ N.withSocketsDo . SSL.withOpenSSL $ do x <- timeout (10 * 10^(6::Int)) go assertEqual "ok" (Just 1024) x@@ -168,7 +165,7 @@ Stream.write (Just "Host: www.google.com\r\n") os Stream.write (Just "\r\n") os bs <- Stream.readExactly 1024 is- SSL.closeSSL ctx+ SSL.close ctx return (B.length bs)