pipes-network 0.1.1.0 → 0.2.0.0
raw patch · 4 files changed
+109/−106 lines, 4 filesdep ~network-simplePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: network-simple
API changes (from Hackage documentation)
- Control.Proxy.TCP: serveFork :: HostPreference -> ServiceName -> ((Socket, SockAddr) -> IO ()) -> IO ()
- Control.Proxy.TCP.Safe: serveFork :: (Proxy p, Monad m) => (forall x. SafeIO x -> m x) -> HostPreference -> ServiceName -> ((Socket, SockAddr) -> IO ()) -> ExceptionP p a' a b' b m r
- Control.Proxy.TCP: serve :: HostPreference -> ServiceName -> ((Socket, SockAddr) -> IO r) -> IO r
+ Control.Proxy.TCP: serve :: HostPreference -> ServiceName -> ((Socket, SockAddr) -> IO ()) -> IO ()
- Control.Proxy.TCP.Safe: serve :: (Proxy p, Monad m) => (forall x. SafeIO x -> m x) -> HostPreference -> ServiceName -> ((Socket, SockAddr) -> ExceptionP p a' a b' b m r) -> ExceptionP p a' a b' b m r
+ Control.Proxy.TCP.Safe: serve :: (Proxy p, Monad m) => (forall x. SafeIO x -> m x) -> HostPreference -> ServiceName -> ((Socket, SockAddr) -> IO ()) -> ExceptionP p a' a b' b m r
Files
- NEWS +29/−0
- pipes-network.cabal +6/−3
- src/Control/Proxy/TCP.hs +15/−26
- src/Control/Proxy/TCP/Safe.hs +59/−77
+ NEWS view
@@ -0,0 +1,29 @@+# 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.1.1.0+version: 0.2.0.0 license: BSD3 license-file: LICENSE copyright: Copyright (c) Renzo Carbonara 2012-2013, 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+extra-source-files: README.md PEOPLE NEWS description: Use network sockets together with the @pipes@ library. .@@ -26,6 +26,9 @@ * "Control.Proxy.TCP.Safe" exports @pipes-safe@ proxies and functions to deal with TCP connections. Such proxies may safely acquire and release resources within a pipeline, using the facilities provided by the @pipes-safe@ package.+ .+ See the @NEWS@ file in the source distribution to learn about any+ important changes between version. source-repository head type: git@@ -37,7 +40,7 @@ base (==4.*), bytestring (>=0.9.2.1), network,- network-simple (>=0.1 && <0.2),+ network-simple (>=0.2 && <0.3), pipes (>=3.1 && <3.3), pipes-safe (>=1.0), transformers (>=0.2 && <0.4)
src/Control/Proxy/TCP.hs view
@@ -11,20 +11,19 @@ module Control.Proxy.TCP (+ -- * Client side+ -- $client-side+ S.connect+ -- * Server side -- $server-side- S.serve- , S.serveFork+ , S.serve -- ** Listening , S.listen -- ** Accepting , S.accept , S.acceptFork - -- * Client side- -- $client-side- , S.connect- -- * Socket streams -- $socket-streaming , socketReadS@@ -57,14 +56,11 @@ -- $client-side ----- The following functions allow you to obtain and use 'NS.Socket's useful to--- the client side of a TCP connection.--- -- Here's how you could run a TCP client: -- -- > connect "www.example.org" "80" $ \(connectionSocket, remoteAddr) -> do -- > putStrLn $ "Connection established to " ++ show remoteAddr--- > -- now you may use connectionSocket as you please within this scope,+-- > -- now you may use connectionSocket as you please within this scope. -- > -- possibly with any of the socketReadS, nsocketReadS or socketWriteD -- > -- proxies explained below. @@ -72,24 +68,17 @@ -- $server-side ----- The following functions allow you to obtain and use 'NS.Socket's useful to--- the server side of a TCP connection.------ Here's how you could run a TCP server that handles in different threads each--- incoming connection to port @8000@ at address @127.0.0.1@:+-- Here's how you can run a TCP server that handles in different threads each+-- incoming connection to port @8000@ at IPv4 address @127.0.0.1@: ----- > listen (Host "127.0.0.1") "8000" $ \(listeningSocket, listeningAddr) -> do--- > putStrLn $ "Listening for incoming connections at " ++ show listeningAddr--- > forever . acceptFork listeningSocket $ \(connectionSocket, remoteAddr) -> do--- > putStrLn $ "Connection established from " ++ show remoteAddr--- > -- now you may use connectionSocket as you please within this scope,--- > -- possibly with any of the socketReadS, nsocketReadS or socketWriteD--- > -- proxies explained below.+-- > serve (Host "127.0.0.1") "8000" $ \(connectionSocket, remoteAddr) -> do+-- > putStrLn $ "TCP connection established from " ++ show remoteAddr+-- > -- now you may use connectionSocket as you please within this scope.+-- > -- possibly with any of the socketReadS, nsocketReadS or socketWriteD+-- > -- proxies explained below. ----- If you keep reading you'll discover there are different ways to achieve--- the same, some ways more general than others. The above one was just an--- example using a pretty general approach, you are encouraged to use simpler--- approaches such as 'serve' if those suit your needs.+-- If you need more control on the way your server runs, then you can use more+-- advanced functions such as 'listen', 'accept' and 'acceptFork'. --------------------------------------------------------------------------------
src/Control/Proxy/TCP/Safe.hs view
@@ -10,10 +10,17 @@ -- "Control.Proxy.TCP". module Control.Proxy.TCP.Safe (+ -- * Client side+ -- $client-side+ connect,+ -- ** Streaming+ -- $client-streaming+ connectReadS,+ connectWriteD,+ -- * Server side -- $server-side serve,- serveFork, -- ** Listening listen, -- ** Accepting@@ -24,14 +31,6 @@ serveReadS, serveWriteD, - -- * Client side- -- $client-side- connect,- -- ** Streaming- -- $client-streaming- connectReadS,- connectWriteD,- -- * Socket streams -- $socket-streaming socketReadS,@@ -60,20 +59,19 @@ -- $client-side ----- The following functions allow you to obtain and use 'NS.Socket's useful to--- the client side of a TCP connection.--- -- Here's how you could run a TCP client: ----- > connect id "www.example.org" "80" $ \(connectionSocket, remoteAddr) -> do+-- > connect "www.example.org" "80" $ \(connectionSocket, remoteAddr) -> do -- > tryIO . putStrLn $ "Connection established to " ++ show remoteAddr--- > -- now you may use connectionSocket as you please within this scope,+-- > -- now you may use connectionSocket as you please within this scope. -- > -- possibly with any of the socketReadS, nsocketReadS or socketWriteD -- > -- proxies explained below. -- -- You might instead prefer the simpler but less general solutions offered by -- 'connectReadS' and 'connectWriteD', so check those too. +--------------------------------------------------------------------------------+ -- | Connect to a TCP server and use the connection. -- -- The connection socket is closed when done or in case of exceptions.@@ -101,6 +99,8 @@ -- immediately interact with it using streams, all at once, instead of -- having to perform the individual steps separately. +--------------------------------------------------------------------------------+ -- | Connect to a TCP server and send downstream the bytes received from the -- remote end. --@@ -156,25 +156,47 @@ -- $server-side ----- The following functions allow you to obtain and use 'NS.Socket's useful to--- the server side of a TCP connection.+-- Here's how you can run a TCP server that handles in different threads each+-- incoming connection to port @8000@ at IPv4 address @127.0.0.1@: ----- Here's how you could run a TCP server that handles in different threads each--- incoming connection to port @8000@ at address @127.0.0.1@:+-- > serve (Host "127.0.0.1") "8000" $ \(connectionSocket, remoteAddr) -> do+-- > tryIO . putStrLn $ "TCP connection established from " ++ show remoteAddr+-- > -- now you may use connectionSocket as you please within this scope.+-- > -- possibly with any of the socketReadS, nsocketReadS or socketWriteD+-- > -- proxies explained below. ----- > listen id (Host "127.0.0.1") "8000" $ \(listeningSocket, listeningAddr) -> do--- > tryIO . putStrLn $ "Listening for incoming connections at " ++ show listeningAddr--- > forever . acceptFork id listeningSocket $ \(connectionSocket, remoteAddr) -> do--- > putStrLn $ "Connection established from " ++ show remoteAddr--- > -- now you may use connectionSocket as you please within this scope,--- > -- possibly with any of the socketReadS, nsocketReadS or socketWriteD--- > -- proxies explained below.+-- You might instead prefer the simpler but less general solutions offered by+-- 'serveReadS' and 'serveWriteD', so check those too. On the other hand,+-- if you need more control on the way your server runs, then you can use more+-- advanced functions such as 'listen', 'accept' and 'acceptFork'.++--------------------------------------------------------------------------------++-- | Start a TCP server that accepts incoming connections and handles each of+-- them concurrently in different threads. ----- If you keep reading you'll discover there are different ways to achieve--- the same, some ways more general than others. The above one was just an--- example using a pretty general approach, you are encouraged to use simpler--- approaches such as 'serve' or 'serveReadS' if those suit your needs.+-- Any acquired network resources are properly closed and discarded when done or+-- in case of exceptions.+--+-- Note: This function performs 'listen' and 'acceptFork', so you don't need to+-- perform those manually.+serve+ :: (P.Proxy p, Monad m)+ => (forall x. P.SafeIO x -> m x) -- ^Monad morphism.+ -> S.HostPreference -- ^Preferred host to bind.+ -> NS.ServiceName -- ^Service port to bind.+ -> ((NS.Socket, NS.SockAddr) -> IO ())+ -- ^Computation to run in a different thread+ -- once an incoming connection is accepted.+ -- Takes the connection socket and remote end+ -- address.+ -> P.ExceptionP p a' a b' b m r+serve morph hp port k = do+ listen morph hp port $ \(lsock,_) -> do+ forever $ acceptFork morph lsock k +--------------------------------------------------------------------------------+ -- | Bind a TCP listening socket and use it. -- -- The listening socket is closed when done or in case of exceptions.@@ -201,49 +223,7 @@ NS.listen bsock $ max 2048 NS.maxListenQueue return x --- | Start a TCP server that sequentially accepts and uses each incoming--- connection.------ Both the listening and connection sockets are closed when done or in case of--- exceptions.------ Note: You don't need to use 'listen' nor 'accept' if you use this function.-serve- :: (P.Proxy p, Monad m)- => (forall x. P.SafeIO x -> m x) -- ^Monad morphism.- -> S.HostPreference -- ^Preferred host to bind.- -> NS.ServiceName -- ^Service port to bind.- -> ((NS.Socket, NS.SockAddr) -> P.ExceptionP p a' a b' b m r)- -- ^Computation to run once an incoming- -- connection is accepted. Takes the- -- connection socket and remote end address.- -> P.ExceptionP p a' a b' b m r-serve morph hp port k = do- listen morph hp port $ \(lsock,_) -> do- forever $ accept morph lsock k---- | Start a TCP server that accepts incoming connections and uses them--- concurrently in different threads.------ The listening and connection sockets are closed when done or in case of--- exceptions.------ Note: You don't need to use 'listen' nor 'acceptFork' if you use this--- function.-serveFork- :: (P.Proxy p, Monad m)- => (forall x. P.SafeIO x -> m x) -- ^Monad morphism.- -> S.HostPreference -- ^Preferred host to bind.- -> NS.ServiceName -- ^Service port to bind.- -> ((NS.Socket, NS.SockAddr) -> IO ())- -- ^Computation to run in a different thread- -- once an incoming connection is accepted.- -- Takes the connection socket and remote end- -- address.- -> P.ExceptionP p a' a b' b m r-serveFork morph hp port k = do- listen morph hp port $ \(lsock,_) -> do- forever $ acceptFork morph lsock k+-------------------------------------------------------------------------------- -- | Accept a single incoming connection and use it. --@@ -288,6 +268,8 @@ -- interact with incoming connections using streams, all at once, instead of -- having to perform the individual steps separately. +--------------------------------------------------------------------------------+ -- | Binds a listening socket, accepts a single connection and sends downstream -- any bytes received from the remote end. --@@ -355,6 +337,8 @@ -- Once you have a connected 'NS.Socket', you can use the following 'P.Proxy's -- to interact with the other connection end using streams. +--------------------------------------------------------------------------------+ -- | Receives bytes from the remote end and sends them downstream. -- -- If an optional timeout is given and receiveing data from the remote end takes@@ -380,7 +364,7 @@ case mbs of Nothing -> P.throw ex Just bs -> unless (B.null bs) $ P.respond bs >> loop- ex = Timeout $ "recv: " <> show wait <> " microseconds."+ ex = Timeout $ "socketReadS: " <> show wait <> " microseconds." {-# INLINABLE socketReadS #-} -- | Just like 'socketReadS', except each request from downstream specifies the@@ -400,7 +384,7 @@ case mbs of Nothing -> P.throw ex Just bs -> unless (B.null bs) $ P.respond bs >>= loop- ex = Timeout $ "recv: " <> show wait <> " microseconds."+ ex = Timeout $ "nsocketReadS: " <> show wait <> " microseconds." {-# INLINABLE nsocketReadS #-} -- | Sends to the remote end the bytes received from upstream, then forwards@@ -428,8 +412,6 @@ case m of Nothing -> P.throw ex Just () -> P.respond a >>= loop- ex = Timeout $ "sendAll: " <> show wait <> " microseconds."+ ex = Timeout $ "socketWriteD: " <> show wait <> " microseconds." {-# INLINABLE socketWriteD #-}--