X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FParser%2FHttp.hs;h=cb21d299418671fccfe308d13a6befe3f75ed9be;hb=8e78bc83bfe67a376293c346ae0b30f1a684c787;hp=021ced85d9856cef8d48d7ffb3bcef4575854ffa;hpb=9961a721f98b101825ef154a2122c1fc2fa6d1ac;p=Lucu.git diff --git a/Network/HTTP/Lucu/Parser/Http.hs b/Network/HTTP/Lucu/Parser/Http.hs index 021ced8..cb21d29 100644 --- a/Network/HTTP/Lucu/Parser/Http.hs +++ b/Network/HTTP/Lucu/Parser/Http.hs @@ -1,25 +1,107 @@ +-- |This is an auxiliary parser utilities for parsing things related +-- on HTTP protocol. +-- +-- In general you don't have to use this module directly. module Network.HTTP.Lucu.Parser.Http - ( isCtl -- Char -> Bool - , isSeparator -- Char -> Bool - , token -- Parser Char + ( isCtl + , isSeparator + , isChar + , isToken + , listOf + , token + , lws + , text + , separator + , quotedStr ) where -import qualified Data.ByteString.Lazy.Char8 as B -import Data.ByteString.Lazy.Char8 (ByteString) import Data.List import Network.HTTP.Lucu.Parser +-- |@'isCtl' c@ is True iff @0x20 <= @c@ < 0x7F@. isCtl :: Char -> Bool isCtl c | c < '\x1f' = True - | c == '\x7f' = True - | otherwise = False - + | c >= '\x7f' = True + | otherwise = False +-- |@'isSeparator' c@ is True iff c is one of HTTP separators. isSeparator :: Char -> Bool -isSeparator c = elem c "()<>@,;:\\\"/[]?={} \t" +isSeparator '(' = True +isSeparator ')' = True +isSeparator '<' = True +isSeparator '>' = True +isSeparator '@' = True +isSeparator ',' = True +isSeparator ';' = True +isSeparator ':' = True +isSeparator '\\' = True +isSeparator '"' = True +isSeparator '/' = True +isSeparator '[' = True +isSeparator ']' = True +isSeparator '?' = True +isSeparator '=' = True +isSeparator '{' = True +isSeparator '}' = True +isSeparator ' ' = True +isSeparator '\t' = True +isSeparator _ = False + +-- |@'isChar' c@ is True iff @c <= 0x7f@. +isChar :: Char -> Bool +isChar c + | c <= '\x7f' = True + | otherwise = False + +-- |@'isToken' c@ is equivalent to @not ('isCtl' c || 'isSeparator' +-- c)@ +isToken :: Char -> Bool +isToken c = c `seq` + not (isCtl c || isSeparator c) + +-- |@'listOf' p@ is similar to @'Network.HTTP.Lucu.Parser.sepBy' p +-- ('Network.HTTP.Lucu.Parser.char' \',\')@ but it allows any +-- occurrences of LWS before and after each tokens. +listOf :: Parser a -> Parser [a] +listOf p = p `seq` + do many lws + sepBy p $! do many lws + char ',' + many lws + +-- |'token' is equivalent to @'Network.HTTP.Lucu.Parser.many1' $ +-- 'Network.HTTP.Lucu.Parser.satisfy' 'isToken'@ +token :: Parser String +token = many1 $! satisfy isToken +-- |'lws' is an HTTP LWS: @'Network.HTTP.Lucu.Parser.crlf'? +-- ('Network.HTTP.Lucu.Parser.sp' | 'Network.HTTP.Lucu.Parser.ht')+@ +lws :: Parser String +lws = do s <- option "" crlf + xs <- many1 (sp <|> ht) + return (s ++ xs) + +-- |'text' accepts one character which doesn't satisfy 'isCtl'. +text :: Parser Char +text = satisfy (\ c -> not (isCtl c)) + +-- |'separator' accepts one character which satisfies 'isSeparator'. +separator :: Parser Char +separator = satisfy isSeparator + +-- |'quotedStr' accepts a string surrounded by double quotation +-- marks. Quotes can be escaped by backslashes. +quotedStr :: Parser String +quotedStr = do char '"' + xs <- many (qdtext <|> quotedPair) + char '"' + return $ foldr (++) "" xs + where + qdtext = do c <- satisfy (/= '"') + return [c] -token :: Parser Char -token = satisfy (\ c -> not (isCtl c || isSeparator c)) + quotedPair = do q <- char '\\' + c <- satisfy isChar + return [c]