6 module Network.HTTP.Lucu.ETag
17 import Control.Applicative
19 import Data.Ascii (Ascii, AsciiBuilder)
20 import qualified Data.Ascii as A
21 import Data.Attoparsec.Char8
22 import Data.Monoid.Unicode
23 import Network.HTTP.Lucu.Parser.Http hiding (token)
24 import Network.HTTP.Lucu.Utils
25 import Prelude.Unicode
27 -- |An entity tag consists of a weakness flag and an opaque string.
29 -- |The weakness flag. Weak tags looks like W\/\"blahblah\" and
30 -- strong tags are like \"blahblah\". See:
31 -- <http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.3.3>
33 -- |An opaque string. Only characters from 0x20 (sp) to 0x7e (~)
38 -- |Convert an 'ETag' to an 'AsciiBuilder'.
39 printETag ∷ ETag → AsciiBuilder
40 {-# INLINEABLE printETag #-}
42 = ( if etagIsWeak et then
48 quoteStr (etagToken et)
50 -- |Parse 'Etag' from an 'Ascii'. This functions throws an exception
52 parseETag ∷ Ascii → ETag
53 {-# INLINEABLE parseETag #-}
55 = case parseOnly p $ A.toByteString str of
57 Left err → error ("unparsable ETag: " ⧺ A.toString str ⧺ ": " ⧺ err)
65 -- |This is equivalent to @'ETag' 'False'@. If you want to generate an
66 -- ETag from a file, try using
67 -- 'Network.HTTP.Lucu.StaticFile.generateETagFromFile'.
68 strongETag ∷ Ascii → ETag
69 {-# INLINE strongETag #-}
70 strongETag = ETag False
72 -- |This is equivalent to @'ETag' 'True'@.
73 weakETag ∷ Ascii → ETag
74 {-# INLINE weakETag #-}
77 -- |'Parser' for an 'ETag'.
79 {-# INLINEABLE eTag #-}
80 eTag = do isWeak ← option False (string "W/" *> return True)
82 return $ ETag isWeak str
84 -- |'Parser' for a list of 'ETag's.
85 eTagList ∷ Parser [ETag]
86 {-# INLINEABLE eTagList #-}
87 eTagList = do xs ← listOf eTag
89 fail "empty list of ETags"