X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=Lucu.git;a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FHeaders.hs;fp=Network%2FHTTP%2FLucu%2FHeaders.hs;h=f0e6ad8958bf056c30f41767263469c51a65922f;hp=242d19194d0a30f7f0d68bc375bc1914f0942505;hb=5f2ef377345fc47aabc63c1325df82c1cd9da9ed;hpb=313924e79d4ed48d3efb9f2530a48305fdd68c4b diff --git a/Network/HTTP/Lucu/Headers.hs b/Network/HTTP/Lucu/Headers.hs index 242d191..f0e6ad8 100644 --- a/Network/HTTP/Lucu/Headers.hs +++ b/Network/HTTP/Lucu/Headers.hs @@ -12,9 +12,7 @@ module Network.HTTP.Lucu.Headers ( Headers , HasHeaders(..) - , headers - , printHeaders ) where import Control.Applicative hiding (empty) @@ -22,8 +20,11 @@ import Control.Applicative.Unicode hiding ((∅)) import Control.Monad import Data.Ascii (Ascii, AsciiBuilder, CIAscii) import qualified Data.Ascii as A -import Data.Attoparsec.Char8 as P +import Data.Attoparsec.Char8 import qualified Data.Collections.Newtype.TH as C +import Data.Convertible.Base +import Data.Convertible.Instances.Ascii () +import Data.Convertible.Utils import Data.List (intersperse) import qualified Data.Map as M (Map) import Data.Collections @@ -56,7 +57,7 @@ class HasHeaders a where getCIHeader ∷ CIAscii → a → Maybe CIAscii {-# INLINE getCIHeader #-} - getCIHeader = ((A.toCIAscii <$>) ∘) ∘ getHeader + getCIHeader = ((cs <$>) ∘) ∘ getHeader deleteHeader ∷ CIAscii → a → a {-# INLINE deleteHeader #-} @@ -105,6 +106,27 @@ merge a b {-# INLINE nullA #-} nullA = null ∘ A.toByteString +instance ConvertSuccess Headers Ascii where + {-# INLINE convertSuccess #-} + convertSuccess = convertSuccessVia ((⊥) ∷ AsciiBuilder) + +instance ConvertSuccess Headers AsciiBuilder where + {-# INLINEABLE convertSuccess #-} + convertSuccess (Headers m) + = mconcat (header <$> fromFoldable m) ⊕ cs ("\x0D\x0A" ∷ Ascii) + where + header ∷ (CIAscii, Ascii) → AsciiBuilder + {-# INLINE header #-} + header (name, value) + = cs name ⊕ + cs (": " ∷ Ascii) ⊕ + cs value ⊕ + cs ("\x0D\x0A" ∷ Ascii) + +deriveAttempts [ ([t| Headers |], [t| Ascii |]) + , ([t| Headers |], [t| AsciiBuilder |]) + ] + {- message-header = field-name ":" [ field-value ] field-name = token @@ -118,12 +140,12 @@ merge a b -} headers ∷ Parser Headers {-# INLINEABLE headers #-} -headers = do xs ← P.many header +headers = do xs ← many header crlf return $ fromFoldable xs where header ∷ Parser (CIAscii, Ascii) - header = do name ← A.toCIAscii <$> token + header = do name ← cs <$> token void $ char ':' skipMany lws values ← content `sepBy` try lws @@ -139,19 +161,7 @@ headers = do xs ← P.many header joinValues ∷ [Ascii] → Ascii {-# INLINE joinValues #-} - joinValues = A.fromAsciiBuilder + joinValues = cs ∘ mconcat - ∘ intersperse (A.toAsciiBuilder "\x20") - ∘ (A.toAsciiBuilder <$>) - -printHeaders ∷ Headers → AsciiBuilder -printHeaders (Headers m) - = mconcat (printHeader <$> fromFoldable m) ⊕ - A.toAsciiBuilder "\x0D\x0A" - where - printHeader ∷ (CIAscii, Ascii) → AsciiBuilder - printHeader (name, value) - = A.toAsciiBuilder (A.fromCIAscii name) ⊕ - A.toAsciiBuilder ": " ⊕ - A.toAsciiBuilder value ⊕ - A.toAsciiBuilder "\x0D\x0A" + ∘ intersperse (cs ("\x20" ∷ Ascii) ∷ AsciiBuilder) + ∘ (cs <$>)