URI.hs 1.2 KB

123456789101112131415161718192021222324252627282930313233343536
  1. {-# LANGUAGE OverloadedStrings #-}
  2. module Data.SMTP.Parser.URI (parseURI) where
  3. import Data.Attoparsec.ByteString.Char8
  4. import qualified Data.Attoparsec.ByteString.Char8 as A
  5. import qualified Network.URI as N
  6. import Data.SMTP.Types.URI
  7. import Data.SMTP.Account
  8. import Text.StringConvert
  9. import Data.List.Split
  10. import Control.Monad
  11. parseURI :: Parser URI
  12. parseURI = do
  13. stringCI "fCMTP://"
  14. remURI <- A.takeWhile N.isAllowedInURI
  15. let u' = do
  16. u <- N.parseURI $ "fCMTP://" ++ s remURI
  17. a <- N.uriAuthority u
  18. return (u, a)
  19. case u' of
  20. Nothing -> fail "Not a valid URI"
  21. Just (uri, auth) -> do
  22. let au = N.uriUserInfo $ auth
  23. ah = N.uriRegName auth
  24. ac <- case A.parseOnly parseAccount (s $ au++ah) of
  25. Left e -> fail e
  26. Right ac -> return ac
  27. let (p, r) = break (==':') . N.uriPath $ uri
  28. pp = splitOn "/" p
  29. qq = if null . N.uriQuery $ uri
  30. then []
  31. else map (\(x, y) -> (drop 1 x, drop 1 y)) . map (break (=='=')) . splitOn "&" . N.uriQuery $ uri
  32. unless (null . N.uriPort $ auth) $ fail "fCMTP URIs must not determine a port"
  33. return $ URI ac (Path pp) (Just . Revision . drop 1 $ r) (map (\(x, y) -> Parameter x y) qq)