hostaddress 0.1.0.0 → 0.2.0.0
raw patch · 4 files changed
+75/−13 lines, 4 filesdep ~QuickCheckdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: QuickCheck, base
API changes (from Hackage documentation)
+ Network.HostAddress: pattern HostIPv4 :: IPv4 -> Hostname
+ Network.HostAddress: pattern HostIPv6 :: IPv6 -> Hostname
+ Network.HostAddress: pattern HostName :: CI ByteString -> Hostname
+ Network.HostAddress: type IPv4 = (Word8, Word8, Word8, Word8)
+ Network.HostAddress: type IPv6 = [Maybe Word16]
Files
- CHANGELOG.md +4/−0
- README.md +1/−1
- hostaddress.cabal +6/−6
- src/Network/HostAddress.hs +64/−6
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for hostaddress +## 0.2.0.0 -- 2021-10-23++* Add pattern synonyms for Hostname.+ ## 0.1.0.0 -- 2020-02-12 * First version. Released on an unsuspecting world.
README.md view
@@ -13,7 +13,7 @@ # Build from Source ```sh-cabal v2-build+cabal build ``` The following optional build flags are available:
hostaddress.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: hostaddress-version: 0.1.0.0+version: 0.2.0.0 synopsis: Network Host Addresses description: Host addresses as described in RFC2396 section 3.2.2 with additional consideration of@@ -17,7 +17,7 @@ author: Lars Kuhtz maintainer: Lars Kuhtz <lakuhtz@gmail.com> copyright: Copyright (c) 2020, Lars Kuhtz <lakuhtz@gmail.com>-category: Data+category: Network tested-with: GHC==8.6.5 , GHC==8.8.2@@ -52,11 +52,11 @@ exposed-modules: Network.HostAddress build-depends:- base >=4.10 && <4.15+ base >=4.10 && <5 , bytestring >=0.10 , deepseq >=1.4 , text >=1.2- , hashable >=1.3+ , hashable >=1.2 , case-insensitive >=1.2 , microlens-th >=0.4 , exceptions >=0.10@@ -70,10 +70,10 @@ if flag(with-configuration-tools) build-depends: configuration-tools >=0.4- , optparse-applicative >=0.15+ , optparse-applicative >=0.14 , aeson >=1.4 if flag(with-quickcheck) build-depends:- QuickCheck >=2.13+ QuickCheck >=2.12
src/Network/HostAddress.hs view
@@ -6,10 +6,12 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ViewPatterns #-} #ifdef VERSION_aeson {-# LANGUAGE StandaloneDeriving #-}@@ -87,6 +89,13 @@ , hostnameFromText , unsafeHostnameFromText +-- ** Pattern Synonyms+, IPv4+, IPv6+, pattern HostName+, pattern HostIPv4+, pattern HostIPv6+ -- ** Special Host Names , localhost , localhostIPv4@@ -154,7 +163,8 @@ import qualified Data.ByteString.Char8 as B8 import qualified Data.CaseInsensitive as CI import Data.Hashable (Hashable(..))-import Data.IP+import Data.IP hiding (IPv4, IPv6)+import qualified Data.IP as IP (IPv4) #ifdef VERSION_QuickCheck import qualified Data.List as L #endif@@ -238,7 +248,9 @@ alphanumhyphen = satisfy (\c -> isAlpha_ascii c || isDigit c || c == '-') <?> "alphahumhypen" -ipV4Parser :: Parser (Word8, Word8, Word8, Word8)+type IPv4 = (Word8, Word8, Word8, Word8)++ipV4Parser :: Parser IPv4 ipV4Parser = (,,,) <$> (octet <* ".") <*> (octet <* ".") <*> (octet <* ".") <*> octet <?> "ipv4address"@@ -247,7 +259,9 @@ octet = (decimal >>= \(d :: Integer) -> int d <$ guard (d < 256)) <?> "octet" -ipV6Parser :: Parser [Maybe Word16]+type IPv6 = [Maybe Word16]++ipV6Parser :: Parser IPv6 ipV6Parser = p0 where p0 = l1 <$> elision <* endOfInput@@ -295,6 +309,14 @@ msg e = "Failed to parse " <> sshow b <> " as " <> name <> ": " <> T.pack e +parseIPv4 :: MonadThrow m => B8.ByteString -> m IPv4+parseIPv4 = parseBytes "IPv4" (ipV4Parser <* endOfInput)+{-# INLINE parseIPv4 #-}++parseIPv6 :: MonadThrow m => B8.ByteString -> m IPv6+parseIPv6 = parseBytes "IPv6" (ipV6Parser <* endOfInput)+{-# INLINE parseIPv6 #-}+ -- -------------------------------------------------------------------------- -- -- Port Numbers @@ -379,19 +401,27 @@ isReservedHostname (HostnameIPv4 ip) = isReservedIp (read $ B8.unpack $ CI.original ip) isReservedHostname h = isPrivateHostname h +ip2ip :: IPv4 -> IP.IPv4+ip2ip (i0, i1, i2, i3) = toIPv4 $ int <$> [i0, i1, i2, i3]+{-# INLINE ip2ip #-}+ isLocalIp :: IPv4 -> Bool-isLocalIp ip =+isLocalIp i = isMatchedTo ip $ makeAddrRange (toIPv4 [127,0,0,0]) 8+ where+ ip = ip2ip i isPrivateIp :: IPv4 -> Bool-isPrivateIp ip = or+isPrivateIp i = or [ isMatchedTo ip $ makeAddrRange (toIPv4 [10,0,0,0]) 8 , isMatchedTo ip $ makeAddrRange (toIPv4 [172,16,0,0]) 12 , isMatchedTo ip $ makeAddrRange (toIPv4 [192,168,0,0]) 16 ]+ where+ ip = ip2ip i isReservedIp :: IPv4 -> Bool-isReservedIp ip = isLocalIp ip || isPrivateIp ip || or+isReservedIp i = isLocalIp i || isPrivateIp i || or [ isMatchedTo ip $ makeAddrRange (toIPv4 [0,0,0,0]) 8 , isMatchedTo ip $ makeAddrRange (toIPv4 [100,64,0,0]) 10 , isMatchedTo ip $ makeAddrRange (toIPv4 [169,254,0,0]) 16@@ -405,6 +435,8 @@ , isMatchedTo ip $ makeAddrRange (toIPv4 [240,0,0,0]) 4 , isMatchedTo ip $ makeAddrRange (toIPv4 [255,255,255,255]) 32 ]+ where+ ip = ip2ip i hostnameBytes :: Hostname -> B8.ByteString hostnameBytes (HostnameName b) = CI.original b@@ -423,6 +455,32 @@ unsafeHostnameFromText :: HasCallStack => T.Text -> Hostname unsafeHostnameFromText = fromJuste . hostnameFromText {-# INLINE unsafeHostnameFromText #-}++-- -------------------------------------------------------------------------- --+-- Hostname Pattern Synonyms++pattern HostName :: CI.CI B8.ByteString -> Hostname+pattern HostName n <- HostnameName n++pattern HostIPv4 :: IPv4 -> Hostname+pattern HostIPv4 i <- (viewIPv4 -> Just i)+ where+ HostIPv4 i = HostnameIPv4 (CI.mk $ sshow i)++pattern HostIPv6 :: IPv6 -> Hostname+pattern HostIPv6 i <- (viewIPv6 -> Just i)+ where+ HostIPv6 i = HostnameIPv6 (CI.mk $ sshow i)++{-# COMPLETE HostIPv4, HostIPv6, HostName #-}++viewIPv4 :: Hostname -> Maybe IPv4+viewIPv4 (HostnameIPv4 bytes) = parseIPv4 $ CI.original bytes+viewIPv4 _ = Nothing++viewIPv6 :: Hostname -> Maybe IPv6+viewIPv6 (HostnameIPv6 bytes) = parseIPv6 $ CI.original bytes+viewIPv6 _ = Nothing -- -------------------------------------------------------------------------- -- -- Host Addresses