X-Git-Url: http://git.cielonegro.org/gitweb.cgi?p=time-http.git;a=blobdiff_plain;f=Data%2FTime%2FFormat%2FHTTP.hs;fp=Data%2FTime%2FFormat%2FHTTP.hs;h=1d2ceac68382fd08e3378258fe974f28cb385b5e;hp=2c44147295cbe03ce0d0668600a3b13fce0f6492;hb=e8f778a92c4aa7c7606bb1b17dada43639543509;hpb=9e1f758b33355286df79648ffcf1f73cb414b5d9 diff --git a/Data/Time/Format/HTTP.hs b/Data/Time/Format/HTTP.hs index 2c44147..1d2ceac 100644 --- a/Data/Time/Format/HTTP.hs +++ b/Data/Time/Format/HTTP.hs @@ -3,6 +3,7 @@ , MultiParamTypeClasses , OverloadedStrings , TemplateHaskell + , TypeSynonymInstances , UnicodeSyntax #-} -- |This module provides functions to parse and format HTTP\/1.1 date @@ -46,8 +47,6 @@ -- > | "Sep" | "Oct" | "Nov" | "Dec" module Data.Time.Format.HTTP ( HTTP - , http - , httpDateAndTime ) where import Control.Applicative @@ -55,7 +54,7 @@ import Data.Ascii (Ascii, AsciiBuilder) import qualified Data.Ascii as A import Data.Attoparsec.Char8 import Data.Convertible.Base -import Data.Proxy +import Data.Default import Data.Tagged import Data.Time import Data.Time.Format.C @@ -68,47 +67,42 @@ import Prelude.Unicode -- |The phantom type for conversions between HTTP/1.1 date and time -- strings and 'UTCTime'. -- --- >>> convertSuccess (UTCTime (ModifiedJulianDay 49662) 31777) --- Tagged "Sun, 06 Nov 1994 08:49:37 GMT" +-- >>> convertSuccess (Tagged (UTCTime (ModifiedJulianDay 49662) 31777) :: Tagged HTTP UTCTime) +-- "Sun, 06 Nov 1994 08:49:37 GMT" data HTTP --- |The proxy for conversions between ANSI HTTP/1.1 date and time --- strings and 'UTCTime'. -http ∷ Proxy HTTP -{-# INLINE CONLIKE http #-} -http = Proxy - -instance ConvertSuccess UTCTime (Tagged HTTP Ascii) where +instance ConvertSuccess (Tagged HTTP UTCTime) Ascii where {-# INLINE convertSuccess #-} - convertSuccess = (A.fromAsciiBuilder <$>) ∘ cs + convertSuccess = A.fromAsciiBuilder ∘ cs -instance ConvertSuccess UTCTime (Tagged HTTP AsciiBuilder) where +instance ConvertSuccess (Tagged HTTP UTCTime) AsciiBuilder where {-# INLINE convertSuccess #-} - convertSuccess = Tagged ∘ toAsciiBuilder + convertSuccess = toAsciiBuilder -instance ConvertAttempt (Tagged HTTP Ascii) UTCTime where +instance ConvertAttempt Ascii (Tagged HTTP UTCTime) where {-# INLINE convertAttempt #-} - convertAttempt = parseAttempt' httpDateAndTime ∘ untag + convertAttempt = parseAttempt' def -- |Parse a date and time string in any of RFC 822, RFC 1123, RFC 850 -- and ANSI C's asctime() formats. -- --- This function is even more permissive than what HTTP\/1.1 (RFC --- 2616) specifies. That is, it accepts 2-digit years in RFC 822, --- omitted separator symbols in RFC 850, omitted sec fields, and --- non-GMT time zones. I believe this behavior will not cause a --- problem though. -httpDateAndTime ∷ Parser UTCTime -httpDateAndTime - = choice [ zonedTimeToUTC <$> try rfc1123DateAndTime - , zonedTimeToUTC <$> try rfc733DateAndTime - , zonedTimeToUTC <$> try rfc822DateAndTime - , localTimeToUTC utc <$> cDateAndTime - ] +-- This parser is even more permissive than what HTTP\/1.1 (RFC 2616) +-- specifies. That is, it accepts 2-digit years in RFC 822, omitted +-- separator symbols in RFC 850, omitted sec fields, and non-GMT time +-- zones. I believe this behavior will not cause a problem though. +instance Default (Parser (Tagged HTTP UTCTime)) where + {-# INLINEABLE def #-} + def = Tagged + <$> + choice [ (zonedTimeToUTC ∘ untag) <$> try (def ∷ Parser (Tagged RFC1123 ZonedTime)) + , (zonedTimeToUTC ∘ untag) <$> try (def ∷ Parser (Tagged RFC733 ZonedTime)) + , (zonedTimeToUTC ∘ untag) <$> try (def ∷ Parser (Tagged RFC822 ZonedTime)) + , (localTimeToUTC utc ∘ untag) <$> (def ∷ Parser (Tagged C LocalTime)) + ] -toAsciiBuilder ∷ UTCTime → AsciiBuilder -{-# INLINE toAsciiBuilder #-} -toAsciiBuilder = flip proxy rfc1123 ∘ cs ∘ ut2zt +toAsciiBuilder ∷ Tagged HTTP UTCTime → AsciiBuilder +{-# INLINEABLE toAsciiBuilder #-} +toAsciiBuilder = cs ∘ (ut2zt <$>) ∘ retag' where ut2zt ∷ UTCTime → ZonedTime {-# INLINE ut2zt #-} @@ -118,6 +112,10 @@ toAsciiBuilder = flip proxy rfc1123 ∘ cs ∘ ut2zt {-# INLINE CONLIKE gmt #-} gmt = TimeZone 0 False "GMT" -deriveAttempts [ ([t| UTCTime |], [t| Tagged HTTP Ascii |]) - , ([t| UTCTime |], [t| Tagged HTTP AsciiBuilder |]) + retag' ∷ Tagged τ α → Tagged RFC1123 α + {-# INLINE retag' #-} + retag' = retag + +deriveAttempts [ ([t| Tagged HTTP UTCTime |], [t| Ascii |]) + , ([t| Tagged HTTP UTCTime |], [t| AsciiBuilder |]) ]