Add the Network.DNS.RBL.Host module.
[dead/harbl.git] / src / Network / DNS / RBL / Host.hs
1 module Network.DNS.RBL.Host
2 where
3
4 import Data.ByteString.Char8 (
5 ByteString,
6 intercalate,
7 pack,
8 split )
9 import qualified Network.DNS as DNS ( Domain )
10
11 import Network.DNS.RBL.Domain ( UserDomain(..) )
12 import Network.DNS.RBL.Pretty ( Pretty(..) )
13
14
15 -- | A data type representing a host that we would like to look up on
16 -- a blacklist. This can be either an IP address (for normal
17 -- blacklists) or a domain name (for name-based blacklists).
18 --
19 -- Rather than make a distinction, we rely on the fact that we can
20 -- parse all-digit \"domain names\". That is, we'll happily accept
21 -- e.g. \"127.0.0.1\" as a name, and anything that isn't a valid IP
22 -- address will implicitly be treated as a name and not an address.
23 --
24 newtype Host = Host UserDomain
25
26 instance Pretty Host where pretty_show (Host d) = pretty_show d
27
28
29 -- | Reverse the labels of this host in preparation for making a
30 -- lookup (using the DNS library). We need to reverse the labels
31 -- (the stuff between the dots) whether we're looking up a host or a
32 -- name. The only tricky part here is that we need to turn an
33 -- absolute 'UserDomain' into a relative one.
34 --
35 -- ==== _Examples_
36 --
37 -- >>> import Text.Parsec ( parse )
38 -- >>> import Network.DNS.RBL.Domain ( user_domain )
39 --
40 -- >>> let (Right r) = parse user_domain "" "1.2.3.4"
41 -- >>> let h = Host r
42 -- >>> reverse_labels h
43 -- "4.3.2.1"
44 --
45 -- >>> let (Right r) = parse user_domain "" "www.example.com"
46 -- >>> let h = Host r
47 -- >>> reverse_labels h
48 -- "com.example.www"
49 --
50 -- Make sure absolute names are made relative:
51 --
52 -- >>> let (Right r) = parse user_domain "" "www.example.com."
53 -- >>> let h = Host r
54 -- >>> reverse_labels h
55 -- "com.example.www"
56 --
57 reverse_labels :: Host -> DNS.Domain
58 reverse_labels (Host h) = reversed
59 where
60 -- | It's possible that we are given an absolute domain name to
61 -- look up. This is legit; say I want to look up
62 -- \"www.example.com.\" That's fine, but before we make the
63 -- actual query we'll need to make it relative and then append
64 -- the DNSBL's suffix to it.
65 relative_host_string :: String
66 relative_host_string =
67 case h of
68 (UserDomainRelative _) -> pretty_show h
69 (UserDomainAbsolute d) -> pretty_show d
70
71 dot = pack "."
72 labels = split '.' (pack relative_host_string)
73 reversed = intercalate dot (reverse labels)