1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- {-# LANGUAGE OverloadedStrings #-}
- module Data.SMTP.Parser.Mime where
- import Data.Attoparsec.ByteString.Char8.Extras
- import Data.SMTP.Types.Mime
- import Text.StringConvert
- import Data.Default.Class
- import Control.Applicative ((<|>))
- import Data.Attoparsec.ByteString.Char8
- import qualified Data.Attoparsec.ByteString.Char8 as A
- import qualified Data.Char as C
- parseContentType :: Parser (ContentType, ContentTypeParameters)
- parseContentType = do
- mime <- (
- stringCI "multipart/" *>
- parseMultipart
- ) <|> (
- stringCI "message/" *>
- parseMessage
- ) <|> (
- ContentMime . s <$> takeTill endType
- )
- A.takeWhile endType
- pars <- parseContentTypeParameters
- return (mime, pars)
- where
- endType c = C.isSpace c || c == ';'
- parseMultipart :: Parser ContentType
- parseMultipart = (
- stringCI "vnd.dFCMTP.Digest" *>
- (return . MultiPartMime $ FcmtpDigest)
- ) <|> (do
- tp <- takeTill endType
- return . MultiPartMime . OtherMultiPartType $ "multipart/" ++ s tp
- )
- parseMessage :: Parser ContentType
- parseMessage = (
- do
- stringCI "vnd.dFCMTP.Resource"
- return . MessageMime $ FcmtpResource
- ) <|> (
- do
- tp <- takeTill endType
- return . MessageMime . OtherMessageType $ "message/" ++ s tp
- )
- parseContentTypeParameters :: Parser ContentTypeParameters
- parseContentTypeParameters = parserFold parseContentTypeParameter def
- parseContentTypeParameter :: Parser (ContentTypeParameters -> ContentTypeParameters)
- parseContentTypeParameter = do
- A.takeWhile isSpace
- k' <- takeTill (\c -> C.isSpace c || c == '=')
- skipWhile isSpace
- let k = map C.toLower . s $ k'
- A.char '='
- A.skipWhile isSpace
- v' <- takeTill (\c -> C.isSpace c || c == ';')
- skipWhile isSpace
- let v = s v'
- case lookup k [
- ("boundary", \pp -> pp{boundary=Just v}),
- ("charset", \pp -> pp{charset=Just v})
- ] of
- Just f -> return f
- Nothing -> return (\pp -> pp{other = (k,v): other pp})
- parseTransferEncoding :: Parser TransferEncoding
- parseTransferEncoding = parseShowCI allEncodings
- where
- allEncodings = map IdentityEncoding [B7BitEncoding,
- B8BitEncoding,
- BBinaryEncoding] ++
- [
- QPEncodedBody,
- Base64EncodedBody
- ]
- parseBodyEncoding :: Parser BodyEncoding
- parseBodyEncoding = parseEnumCI
|