packages feed

pipes-network 0.6.3 → 0.6.4

raw patch · 6 files changed

+277/−138 lines, 6 filesdep ~network-simple

Dependency ranges changed: network-simple

Files

PEOPLE view
@@ -1,9 +1,11 @@ The following people have participated in creating this library, either-by directly contributing code or by providing thoughtful input in-discussions about the library design.+by directly contributing code, by providing thoughtful input in+discussions about the library design, or by doing anything else that+helps this library move forwards.  Renzo Carbonara Gabriel Gonzalez Paolo Capriotti Marius Ghita Kyle Van Berendonck+Nicolas Trangez
− changelog
@@ -1,94 +0,0 @@-# Version 0.6.3--* Bump `network-simple`, `transformers` and `pipes-safe` upper bounds.--* Remove `Base m ~ IO` constraints from `Pipes.Network.TCP.Safe`, as-  not all of them were removed in 0.6.1.---# Version 0.6.2--* Dependency bumps (upper bounds).---# Version 0.6.1--* Remove the `Base m ~ IO` constraint from `Pipes.Network.TCP.Safe`---# Version 0.6.0--* Significantly upgraded the API and renamed functions to play well with-  pipes-4.0.0, pipes-safe-2.0.0 and network-simple-0.3.0.--* Throw `IOError` in `IO` in order to report timeout errors. Delete-  the `Timeout` data-type.---# Version 0.5.1.0--* Re-export `Network.Socket.withSocketsDo`.--* Use TCP `send` and `recv` as eported by network-simple-0.2.1.0.---# Version 0.5.0.0--* Removed `Control.Proxy.TCP.Sync` and `Control.Proxy.TCP.Safe.Sync`.---# Version 0.4.0.1--* FIX: `acceptFork` now properly closes the connection socket, even in-  case of asynchronous exceptions.---# Version 0.4.0.0--* Do not handle “Broken Pipe” errors on the `*Write*D` proxies anymore.-  As as a result, those proxies run forever and have a polymorphic-  return value, which makes this release binary compatible with 0.2.0.0,-  but not with 0.3.0.0.---# Version 0.3.0.0--* Quietly stop writing or reading bytes from a TCP socket if a-  “Broken Pipe” error happens, indicating that the remote end-  already closed the connection. Previously, a `ResourceVanished`-  exception was thrown.--* All the `*Write*D` proxies now return `()` if the remote end-  closed the connection.---# Version 0.2.0.0--* Depend on network-simple 0.2--* In both modules `Control.Proxy.TCP` and `Control.Proxy.TCP.Safe`:-  `serveFork` was renamed to `serve` and the previous function named-  `serve` was removed.---# Version 0.1.1.0--* Split many of the non-pipes-related TCP utilities to the own-  `network-simple` package.-* Depend on `network-simple` and re-export its functions.---# Version 0.1.0.1--* Dependency bumps.---# Version 0.1.0--* New backwards incompatible API-* Based on pipes 3.1---# Up to version 0.0.2--* Based on pipes-core.
+ changelog.md view
@@ -0,0 +1,108 @@+# Version 0.6.4++* The various `fromServe` and `toServe*` pipes from+  `Pipes.Network.TCP.Safe` now close the listening socket immediately+  after accepting a first connection.++* Re-export `sendLazy`, `sendMany` and `closeSock`.++* Add `to{Socket,SocketTimeout,Serve,Connect}{Lazy,Many}`.++* Fix issue #29 where `fromSocketTimeout` and `fromSocketTimeoutN`+  would loop forever.+++# Version 0.6.3++* Bump `network-simple`, `transformers` and `pipes-safe` upper bounds.++* Remove `Base m ~ IO` constraints from `Pipes.Network.TCP.Safe`, as+  not all of them were removed in 0.6.1.+++# Version 0.6.2++* Dependency bumps (upper bounds).+++# Version 0.6.1++* Remove the `Base m ~ IO` constraint from `Pipes.Network.TCP.Safe`+++# Version 0.6.0++* Significantly upgraded the API and renamed functions to play well with+  pipes-4.0.0, pipes-safe-2.0.0 and network-simple-0.3.0.++* Throw `IOError` in `IO` in order to report timeout errors. Delete+  the `Timeout` data-type.+++# Version 0.5.1.0++* Re-export `Network.Socket.withSocketsDo`.++* Use TCP `send` and `recv` as eported by network-simple-0.2.1.0.+++# Version 0.5.0.0++* Removed `Control.Proxy.TCP.Sync` and `Control.Proxy.TCP.Safe.Sync`.+++# Version 0.4.0.1++* FIX: `acceptFork` now properly closes the connection socket, even in+  case of asynchronous exceptions.+++# Version 0.4.0.0++* Do not handle “Broken Pipe” errors on the `*Write*D` proxies anymore.+  As as a result, those proxies run forever and have a polymorphic+  return value, which makes this release binary compatible with 0.2.0.0,+  but not with 0.3.0.0.+++# Version 0.3.0.0++* Quietly stop writing or reading bytes from a TCP socket if a+  “Broken Pipe” error happens, indicating that the remote end+  already closed the connection. Previously, a `ResourceVanished`+  exception was thrown.++* All the `*Write*D` proxies now return `()` if the remote end+  closed the connection.+++# Version 0.2.0.0++* Depend on network-simple 0.2++* In both modules `Control.Proxy.TCP` and `Control.Proxy.TCP.Safe`:+  `serveFork` was renamed to `serve` and the previous function named+  `serve` was removed.+++# Version 0.1.1.0++* Split many of the non-pipes-related TCP utilities to the own+  `network-simple` package.+* Depend on `network-simple` and re-export its functions.+++# Version 0.1.0.1++* Dependency bumps.+++# Version 0.1.0++* New backwards incompatible API+* Based on pipes 3.1+++# Up to version 0.0.2++* Based on pipes-core.
pipes-network.cabal view
@@ -1,5 +1,5 @@ name:               pipes-network-version:            0.6.3+version:            0.6.4 license:            BSD3 license-file:       LICENSE copyright:          Copyright (c) Renzo Carbonara 2012-2014, Paolo Capriotti 2012-2012.@@ -13,7 +13,7 @@ build-type:         Simple synopsis:           Use network sockets together with the pipes library. cabal-version:      >=1.8-extra-source-files: README.md PEOPLE changelog+extra-source-files: README.md PEOPLE changelog.md description:   Use network sockets together with the @pipes@ library.   .@@ -41,7 +41,7 @@         base           (==4.*),         bytestring     (>=0.9.2.1),         network,-        network-simple (>=0.3 && <0.5),+        network-simple (>=0.4.0.1 && <0.5),         pipes          (>=4.0 && <4.2),         pipes-safe     (>=2.1 && <2.3),         transformers   (>=0.2 && <0.5)@@ -49,4 +49,3 @@         Pipes.Network.TCP         Pipes.Network.TCP.Safe     ghc-options: -Wall -O2-
src/Pipes/Network/TCP.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE RankNTypes #-}  -- | This minimal module exports facilities that ease the usage of TCP+ -- 'Socket's in the /Pipes ecosystem/. It is meant to be used together with -- the "Network.Simple.TCP" module from the @network-simple@ package, which is -- completely re-exported from this module.@@ -24,19 +25,25 @@   -- * Sending   -- $sending   , toSocket+  , toSocketLazy+  , toSocketMany   , toSocketTimeout+  , toSocketTimeoutLazy+  , toSocketTimeoutMany   -- * Exports   -- $exports   , module Network.Simple.TCP   ) where  import qualified Data.ByteString                as B+import qualified Data.ByteString.Lazy           as BL import           Foreign.C.Error                (errnoToIOError, eTIMEDOUT) import qualified Network.Socket.ByteString      as NSB import           Network.Simple.TCP                   (connect, serve, listen, accept, acceptFork,-                   bindSock, connectSock, recv, send, withSocketsDo,-                   HostName, HostPreference(HostAny, HostIPv4, HostIPv6, Host),+                   bindSock, connectSock, closeSock, recv, send, sendLazy,+                   sendMany, withSocketsDo, HostName,+                   HostPreference(HostAny, HostIPv4, HostIPv6, Host),                    ServiceName, SockAddr, Socket) import           Pipes import           Pipes.Core@@ -46,13 +53,13 @@  -- $receiving ----- The following pipes allow you to receive bytes from the remote end.+-- The following producers allow you to receive bytes from the remote end. ----- Besides the pipes below, you might want to use "Network.Simple.TCP"'s--- 'Network.Simple.TCP.recv', which happens to be an 'Effect'':+-- Besides the producers below, you might want to use "Network.Simple.TCP"'s+-- 'recv', which happens to be an 'Effect'': -- -- @--- 'Network.Simple.TCP.recv' :: 'MonadIO' m => 'Socket' -> 'Int' -> 'Effect'' m ('Maybe' 'B.ByteString')+-- 'recv' :: 'MonadIO' m => 'Socket' -> 'Int' -> 'Effect'' m ('Maybe' 'B.ByteString') -- @  --------------------------------------------------------------------------------@@ -91,7 +98,9 @@     loop = do        mbs <- liftIO (timeout wait (NSB.recv sock nbytes))        case mbs of-          Just bs -> yield bs >> loop+          Just bs+           | B.null bs -> return ()+           | otherwise -> yield bs >> loop           Nothing -> liftIO $ ioError $ errnoToIOError              "Pipes.Network.TCP.fromSocketTimeout" eTIMEDOUT Nothing Nothing {-# INLINABLE fromSocketTimeout #-}@@ -129,7 +138,9 @@     loop = \nbytes -> do        mbs <- liftIO (timeout wait (NSB.recv sock nbytes))        case mbs of-          Just bs -> respond bs >>= loop+          Just bs+           | B.null bs -> return ()+           | otherwise -> respond bs >>= loop           Nothing -> liftIO $ ioError $ errnoToIOError              "Pipes.Network.TCP.fromSocketTimeoutN" eTIMEDOUT Nothing Nothing {-# INLINABLE fromSocketTimeoutN #-}@@ -138,13 +149,15 @@  -- $sending ----- The following pipes allow you to send bytes to the remote end.+-- The following consumers allow you to send bytes to the remote end. ----- Besides the pipes below, you might want to use "Network.Simple.TCP"'s--- 'Network.Simple.TCP.send', which happens to be an 'Effect'':+-- Besides the consumers below, you might want to use "Network.Simple.TCP"'s+-- 'send', 'sendLazy' or 'sendMany' which happen to be 'Effect''s: -- -- @--- 'Network.Simple.TCP.send' :: 'MonadIO' m => 'Socket' -> 'B.ByteString' -> 'Effect'' m ()+-- 'send'     :: 'MonadIO' m => 'Socket' ->  'B.ByteString'  -> 'Effect'' m ()+-- 'sendLazy' :: 'MonadIO' m => 'Socket' ->  'BL.ByteString'  -> 'Effect'' m ()+-- 'sendMany' :: 'MonadIO' m => 'Socket' -> ['B.ByteString'] -> 'Effect'' m () -- @  -- | Sends to the remote end each 'B.ByteString' received from upstream.@@ -155,20 +168,64 @@ toSocket sock = for cat (\a -> send sock a) {-# INLINABLE toSocket #-} +-- | Like 'toSocket' but takes a lazy 'BL.ByteSring' and sends it in a more+-- efficient manner (compared to converting it to a strict 'B.ByteString' and+-- sending it).+toSocketLazy+  :: MonadIO m+  => Socket  -- ^Connected socket.+  -> Consumer' BL.ByteString m r+toSocketLazy sock = for cat (\a -> sendLazy sock a)+{-# INLINABLE toSocketLazy #-}++-- | Like 'toSocket' but takes a @['BL.ByteSring']@ and sends it in a more+-- efficient manner (compared to converting it to a strict 'B.ByteString' and+-- sending it).+toSocketMany+  :: MonadIO m+  => Socket  -- ^Connected socket.+  -> Consumer' [B.ByteString] m r+toSocketMany sock = for cat (\a -> sendMany sock a)+{-# INLINABLE toSocketMany #-}+ -- | Like 'toSocket', except with the first 'Int' argument you can specify -- the maximum time that each interaction with the remote end can take. If such -- time elapses before the interaction finishes, then an 'IOError' exception is -- thrown. The time is specified in microseconds (1 second = 1e6 microseconds).-toSocketTimeout+toSocketTimeout :: MonadIO m => Int -> Socket -> Consumer' B.ByteString m r+toSocketTimeout = _toSocketTimeout send "Pipes.Network.TCP.toSocketTimeout"+{-# INLINABLE toSocketTimeout #-}++-- | Like 'toSocketTimeout' but takes a lazy 'BL.ByteSring' and sends it in a+-- more efficient manner (compared to converting it to a strict 'B.ByteString'+-- and sending it).+toSocketTimeoutLazy :: MonadIO m => Int -> Socket -> Consumer' BL.ByteString m r+toSocketTimeoutLazy =+    _toSocketTimeout sendLazy "Pipes.Network.TCP.toSocketTimeoutLazy"+{-# INLINABLE toSocketTimeoutLazy #-}++-- | Like 'toSocketTimeout' but takes a @['BL.ByteSring']@ and sends it in a+-- more efficient manner (compared to converting it to a strict 'B.ByteString'+-- and sending it).+toSocketTimeoutMany+  :: MonadIO m => Int -> Socket -> Consumer' [B.ByteString] m r+toSocketTimeoutMany =+    _toSocketTimeout sendMany "Pipes.Network.TCP.toSocketTimeoutMany"+{-# INLINABLE toSocketTimeoutMany #-}++_toSocketTimeout   :: MonadIO m-  => Int -> Socket -> Consumer' B.ByteString m r-toSocketTimeout wait sock = for cat $ \a -> do-    mu <- liftIO (timeout wait (NSB.sendAll sock a))+  => (Socket -> a -> IO ())+  -> String+  -> Int+  -> Socket+  -> Consumer' a m r+_toSocketTimeout send' nm = \wait sock -> for cat $ \a -> do+    mu <- liftIO (timeout wait (send' sock a))     case mu of-       Just () -> return ()-       Nothing -> liftIO $ ioError $ errnoToIOError-          "Pipes.Network.TCP.toSocketTimeout" eTIMEDOUT Nothing Nothing-{-# INLINABLE toSocketTimeout #-}+      Just () -> return ()+      Nothing -> liftIO $ ioError $ errnoToIOError nm eTIMEDOUT Nothing Nothing+{-# INLINABLE _toSocketTimeout #-}  -------------------------------------------------------------------------------- @@ -180,10 +237,13 @@ --     'bindSock', --     'connect', --     'connectSock',+--     'closeSock', --     'HostPreference'('HostAny','HostIPv4','HostIPv6','Host'), --     'listen', --     'recv', --     'send',+--     'sendLazy',+--     'sendMany', --     'serve'. -- -- [From "Network.Socket"]
src/Pipes/Network/TCP/Safe.hs view
@@ -26,10 +26,14 @@   -- $client-streaming   , fromConnect   , toConnect+  , toConnectLazy+  , toConnectMany   -- ** Server side   -- $server-streaming   , fromServe   , toServe+  , toServeLazy+  , toServeMany   -- * Exports   -- $exports   , module Pipes.Network.TCP@@ -39,15 +43,18 @@  import           Control.Monad import qualified Data.ByteString        as B+import qualified Data.ByteString.Lazy   as BL import           Network.Simple.TCP-                  (acceptFork, bindSock, connectSock, recv, send, withSocketsDo,-                   HostName, HostPreference(HostAny, HostIPv4, HostIPv6, Host),+                  (acceptFork, bindSock, connectSock, closeSock, recv, send,+                   sendLazy, sendMany, withSocketsDo, HostName,+                   HostPreference(HostAny, HostIPv4, HostIPv6, Host),                    ServiceName, SockAddr, Socket) import qualified Network.Socket         as NS import           Pipes import           Pipes.Network.TCP                   (fromSocket, fromSocketTimeout, fromSocketN,-                   fromSocketTimeoutN, toSocket, toSocketTimeout)+                   fromSocketTimeoutN, toSocket, toSocketLazy, toSocketMany,+                   toSocketTimeout, toSocketTimeoutLazy, toSocketTimeoutMany) import qualified Pipes.Safe             as Ps import           Pipes.Safe             (runSafeT) @@ -128,9 +135,7 @@   -> HostName        -- ^Server host name.   -> ServiceName     -- ^Server service port.   -> Producer' B.ByteString m ()-fromConnect nbytes host port = do-   connect host port $ \(csock,_) -> do-      fromSocket csock nbytes+fromConnect nbytes = _connect (\csock -> fromSocket csock nbytes)  -- | Connects to a TCP server, sends to the remote end the bytes received from -- upstream.@@ -147,10 +152,37 @@   => HostName        -- ^Server host name.   -> ServiceName     -- ^Server service port.   -> Consumer' B.ByteString m r-toConnect hp port = do-   connect hp port $ \(csock,_) -> do-      toSocket csock+toConnect = _connect toSocket +-- | Like 'toConnect', but works more efficiently on lazy 'BL.ByteString's+-- (compared to converting them to a strict 'B.ByteString' and sending it)+toConnectLazy+  :: Ps.MonadSafe m+  => HostName        -- ^Server host name.+  -> ServiceName     -- ^Server service port.+  -> Consumer' BL.ByteString m r+toConnectLazy = _connect toSocketLazy++-- | Like 'toConnect', but works more efficiently on @['B.ByteString']@+-- (compared to converting them to a strict 'B.ByteString' and sending it)+toConnectMany+  :: Ps.MonadSafe m+  => HostName        -- ^Server host name.+  -> ServiceName     -- ^Server service port.+  -> Consumer' [B.ByteString] m r+toConnectMany = _connect toSocketMany++_connect+  :: Ps.MonadSafe m+  => (Socket -> m r) -- ^Action to perform on the connection socket.+  -> HostName        -- ^Server host name.+  -> ServiceName     -- ^Server service port.+  -> m r+_connect act hp port = do+    connect hp port $ \(csock,_) -> do+       act csock+{-# INLINABLE _connect #-}+ --------------------------------------------------------------------------------  -- $server-streaming@@ -189,10 +221,7 @@   -> HostPreference  -- ^Preferred host to bind.   -> ServiceName     -- ^Service port to bind.   -> Producer' B.ByteString m ()-fromServe nbytes hp port = do-   listen hp port $ \(lsock,_) -> do-      accept lsock $ \(csock,_) -> do-         fromSocket csock nbytes+fromServe nbytes = _serve (\csock -> fromSocket csock nbytes)  -- | Binds a listening socket, accepts a single connection, sends to the remote -- end the bytes received from upstream.@@ -210,10 +239,39 @@   => HostPreference  -- ^Preferred host to bind.   -> ServiceName     -- ^Service port to bind.   -> Consumer' B.ByteString m r-toServe hp port = do+toServe = _serve toSocket++-- | Like 'toServe', but works more efficiently on lazy 'BL.ByteString's+-- (compared to converting them to a strict 'B.ByteString' and sending it)+toServeLazy+  :: Ps.MonadSafe m+  => HostPreference  -- ^Preferred host to bind.+  -> ServiceName     -- ^Service port to bind.+  -> Consumer' BL.ByteString m r+toServeLazy = _serve toSocketLazy++-- | Like 'toServe', but works more efficiently on @['B.ByteString']@+-- (compared to converting them to a strict 'B.ByteString' and sending it)+toServeMany+  :: Ps.MonadSafe m+  => HostPreference  -- ^Preferred host to bind.+  -> ServiceName     -- ^Service port to bind.+  -> Consumer' [B.ByteString] m r+toServeMany = _serve toSocketMany++_serve+  :: Ps.MonadSafe m+  => (Socket -> m r) -- ^Action to perform on the connection socket.+  -> HostPreference  -- ^Preferred host to bind.+  -> ServiceName     -- ^Service port to bind.+  -> m r+_serve act hp port = do    listen hp port $ \(lsock,_) -> do       accept lsock $ \(csock,_) -> do-         toSocket csock+         closeSock lsock -- We prevent more connection attempts to happen+                         -- while we deal with `csock`.+         act csock+{-# INLINABLE _serve #-}  -------------------------------------------------------------------------------- @@ -225,15 +283,22 @@ --    'fromSocketTimeout', --    'fromSocketTimeoutN', --    'toSocket',---    'toSocketTimeout'.+--    'toSocketLazy',+--    'toSocketMany',+--    'toSocketTimeout',+--    'toSocketTimeoutLazy',+--    'toSocketTimeoutMany'. -- -- [From "Network.Simple.TCP"] --    'acceptFork', --    'bindSock', --    'connectSock',+--    'closeSock', --    'HostPreference'('HostAny','HostIPv4','HostIPv6','Host'), --    'recv',---    'send'.+--    'send',+--    'sendLazy',+--    'sendMany'. -- -- [From "Network.Socket"] --    'HostName',@@ -244,4 +309,3 @@ -- -- [From "Pipes.Safe"] --    'Ps.runSafeT'.-