--
-- <https://tools.ietf.org/html/rfc1035#section-2.3.1>
--
-module Domain
+-- We basically work with strings and characters everywhere, even
+-- though this isn't really correct. The length specifications in
+-- the RFCs are all in terms of octets, so really a ByteString.Char8
+-- would be more appropriate. With strings, for example, we could
+-- have a unicode mumbo jumbo character that takes up two bytes
+-- (octets).
+--
+module Domain (
+ UserDomain,
+ user_domain )
where
import Data.Char ( toLower )
import qualified Text.Parsec as Parsec ( digit, letter)
import Text.Parsec.String ( Parser )
-import Pretty
+import Pretty ( Pretty(..) )
-- * Digits
-- >>> parseTest domain "."
-- DomainRoot
--
+-- Anything over 255 characters is an error, so the root will be
+-- parsed:
+--
+-- >>> let big_label = replicate 63 'x'
+-- >>> let big_subdomain = concat $ replicate 5 (big_label ++ ".")
+-- >>> parseTest domain big_subdomain
+-- DomainRoot
+--
+-- But exactly 255 is allowed:
+--
+-- >>> import Data.List ( intercalate )
+-- >>> let big_label = replicate 63 'x'
+-- >>> let big_subdomain = intercalate "." (replicate 4 big_label)
+-- >>> let (Right r) = parse domain "" big_subdomain
+-- >>> length (pretty_show r)
+-- 255
+--
domain :: Parser Domain
domain = try parse_subdomain <|> parse_empty
where
- parse_subdomain = fmap DomainName subdomain
+ parse_subdomain :: Parser Domain
+ parse_subdomain = do
+ s <- subdomain
+ if (length $ pretty_show s) <= 255
+ then return $ DomainName s
+ else fail "subdomains can be at most 255 characters"
+
+ parse_empty :: Parser Domain
parse_empty = string "" >> return DomainRoot