check the string for being an IPv4 address
authorEugene Crosser <crosser@average.org>
Fri, 4 Apr 2014 14:15:55 +0000 (18:15 +0400)
committerEugene Crosser <crosser@average.org>
Fri, 4 Apr 2014 14:15:55 +0000 (18:15 +0400)
When we encounter a string where a json object representing a
domain is expected, check if this string looks like an IPv4
address, and return a domain object with this address.

NmcJson.hs

index 14a2f6322d39d913a20a67be222e955b0faad7e5..69e693ff000e7ea5aafb986e5c45f017a1c60d05 100644 (file)
@@ -8,6 +8,8 @@ module NmcJson  ( NmcRes(..)
 
 import Data.ByteString.Lazy (ByteString)
 import Data.Text as T (unpack)
+import Data.List.Split
+import Data.Char
 import Data.Map as M (Map, lookup)
 import Control.Applicative ((<$>), (<*>), empty)
 import Data.Aeson
@@ -66,9 +68,19 @@ data NmcDom = NmcDom    { domService     :: Maybe [[String]] -- [NmcRRService]
                         } deriving (Show, Eq)
 
 instance FromJSON NmcDom where
-        -- Some just put the IP address in the value, especially in the map.
-        -- As an ugly hack, try to interpret string as IP (v4) address.
-        parseJSON (String s) = return emptyNmcDom { domIp = Just [T.unpack s] }
+        -- Wherever we expect a domain object, there may be a string
+        -- containing IPv4 address. Interpret it as such.
+        -- Question: shall we try to recognize IPv6 addresses too?
+        parseJSON (String s) =
+                 return $ if isIPv4 s'
+                            then emptyNmcDom { domIp = Just [s'] }
+                            else emptyNmcDom
+                          where
+                            s' = T.unpack s
+                            isIPv4 x = all isNibble $ splitOn "." x
+                            isNibble x =
+                              if all isDigit x then (read x :: Int) < 256
+                              else False
         parseJSON (Object o) = NmcDom
                 <$> o .:? "service"
                 <*> o .:? "ip"