diff options
Diffstat (limited to 'dht/src/Network/SocketLike.hs')
-rw-r--r-- | dht/src/Network/SocketLike.hs | 98 |
1 files changed, 0 insertions, 98 deletions
diff --git a/dht/src/Network/SocketLike.hs b/dht/src/Network/SocketLike.hs deleted file mode 100644 index 37891cfd..00000000 --- a/dht/src/Network/SocketLike.hs +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} | ||
2 | {-# LANGUAGE TupleSections #-} | ||
3 | {-# LANGUAGE CPP #-} | ||
4 | -- | | ||
5 | -- | ||
6 | -- A socket could be used indirectly via a 'System.IO.Handle' or a conduit from | ||
7 | -- Michael Snoyman's conduit package. But doing so presents an encapsulation | ||
8 | -- problem. Do we allow access to the underlying socket and trust that it wont | ||
9 | -- be used in an unsafe way? Or do we protect it at the higher level and deny | ||
10 | -- access to various state information? | ||
11 | -- | ||
12 | -- The 'SocketLike' class enables the approach that provides a safe wrapper to | ||
13 | -- the underlying socket and gives access to various state information without | ||
14 | -- enabling direct reads or writes. | ||
15 | module Network.SocketLike | ||
16 | ( SocketLike(..) | ||
17 | , RestrictedSocket | ||
18 | , restrictSocket | ||
19 | , restrictHandleSocket | ||
20 | -- * Re-exports | ||
21 | -- | ||
22 | -- | To make the 'SocketLike' methods less awkward to use, the types | ||
23 | -- 'CUInt', 'SockAddr', and 'PortNumber' are re-exported. | ||
24 | , CUInt | ||
25 | , PortNumber | ||
26 | , SockAddr(..) | ||
27 | ) where | ||
28 | |||
29 | import Network.Socket | ||
30 | ( PortNumber | ||
31 | , SockAddr | ||
32 | ) | ||
33 | import Foreign.C.Types ( CUInt ) | ||
34 | |||
35 | import qualified Network.Socket as NS | ||
36 | import System.IO (Handle,hClose,hIsOpen) | ||
37 | import Control.Arrow | ||
38 | |||
39 | -- | A safe (mostly read-only) interface to a 'NS.Socket'. Note that despite | ||
40 | -- how this class is named, it provides no access to typical 'NS.Socket' uses | ||
41 | -- like sending or receiving network packets. | ||
42 | class SocketLike sock where | ||
43 | -- | See 'NS.getSocketName' | ||
44 | getSocketName :: sock -> IO SockAddr | ||
45 | -- | See 'NS.getPeerName' | ||
46 | getPeerName :: sock -> IO SockAddr | ||
47 | -- | See 'NS.getPeerCred' | ||
48 | -- getPeerCred :: sock -> IO (CUInt, CUInt, CUInt) | ||
49 | |||
50 | -- | Is the socket still valid? Connected | ||
51 | -- | ||
52 | -- In order to give the instance writer | ||
53 | -- the option to do book-keeping in a pure | ||
54 | -- type, a conceptually modified version of | ||
55 | -- the 'SocketLike' is returned. | ||
56 | -- | ||
57 | isValidSocket :: sock -> IO (sock,Bool) | ||
58 | |||
59 | |||
60 | instance SocketLike NS.Socket where | ||
61 | getSocketName = NS.getSocketName | ||
62 | getPeerName = NS.getPeerName | ||
63 | -- getPeerCred = NS.getPeerCred | ||
64 | #if MIN_VERSION_network(3,1,0) | ||
65 | isValidSocket s = (s,) <$> NS.withFdSocket s (return . (/= (-1))) | ||
66 | #else | ||
67 | #if MIN_VERSION_network(3,0,0) | ||
68 | isValidSocket s = (s,) . (/= (-1)) <$> NS.fdSocket s | ||
69 | #else | ||
70 | #if MIN_VERSION_network(2,4,0) | ||
71 | isValidSocket s = (s,) <$> NS.isConnected s -- warning: this is always False if the socket | ||
72 | -- was converted to a Handle | ||
73 | #else | ||
74 | isValidSocket s = (s,) <$> NS.sIsConnected s -- warning: this is always False if the socket | ||
75 | -- was converted to a Handle | ||
76 | #endif | ||
77 | #endif | ||
78 | #endif | ||
79 | |||
80 | -- | An encapsulated socket. Data reads and writes are not possible. | ||
81 | data RestrictedSocket = Restricted (Maybe Handle) NS.Socket deriving Show | ||
82 | |||
83 | instance SocketLike RestrictedSocket where | ||
84 | getSocketName (Restricted mb sock) = NS.getSocketName sock | ||
85 | getPeerName (Restricted mb sock) = NS.getPeerName sock | ||
86 | -- getPeerCred (Restricted mb sock) = NS.getPeerCred sock | ||
87 | isValidSocket rs@(Restricted mb sock) = maybe (first (Restricted mb) <$> isValidSocket sock) (((rs,) <$>) . hIsOpen) mb | ||
88 | |||
89 | -- | Create a 'RestrictedSocket' that explicitly disallows sending or | ||
90 | -- receiving data. | ||
91 | restrictSocket :: NS.Socket -> RestrictedSocket | ||
92 | restrictSocket socket = Restricted Nothing socket | ||
93 | |||
94 | -- | Build a 'RestrictedSocket' for which 'sClose' will close the given | ||
95 | -- 'Handle'. It is intended that this 'Handle' was obtained via | ||
96 | -- 'NS.socketToHandle'. | ||
97 | restrictHandleSocket :: Handle -> NS.Socket -> RestrictedSocket | ||
98 | restrictHandleSocket h socket = Restricted (Just h) socket | ||