diff --git a/lib/amazonka-core/src/Amazonka/Data/Time.hs b/lib/amazonka-core/src/Amazonka/Data/Time.hs index cad91729da4..626dd127f1d 100644 --- a/lib/amazonka-core/src/Amazonka/Data/Time.hs +++ b/lib/amazonka-core/src/Amazonka/Data/Time.hs @@ -107,7 +107,20 @@ parseFormattedTime = do ++ show s ) - parse (format (Proxy @RFC822)) + -- A more lenient format string for parsing RFC822, whose + -- grammar allows single-digit days. + -- + -- We still use `%d` over `%-d` in the `TimeFormat RFC822` + -- instance to always produce two-digit days, since that is what + -- most people expect to see. + -- + -- This allows us to parse responses from versions of + -- `rclone serve s3` circa 2024: + -- https://github.com/rclone/rclone/issues/8277 + rfc822 :: String + rfc822 = "%a, %-d %b %Y %H:%M:%S %Z" + + parse rfc822 <|> parse (format (Proxy @ISO8601)) <|> parse (format (Proxy @BasicTime)) <|> parse (format (Proxy @AWSTime)) @@ -138,7 +151,7 @@ instance ToText AWSTime where instance ToText POSIX where toText (Time t) = toText (truncate (utcTimeToPOSIXSeconds t) :: Integer) -renderFormattedTime :: forall a. TimeFormat (Time a) => Time a -> String +renderFormattedTime :: forall a. (TimeFormat (Time a)) => Time a -> String renderFormattedTime (Time t) = formatTime defaultTimeLocale diff --git a/lib/amazonka-core/test/Test/Amazonka/Data/Time.hs b/lib/amazonka-core/test/Test/Amazonka/Data/Time.hs index 49fb969d4e4..6d186b4fe74 100644 --- a/lib/amazonka-core/test/Test/Amazonka/Data/Time.hs +++ b/lib/amazonka-core/test/Test/Amazonka/Data/Time.hs @@ -29,6 +29,10 @@ tests = "rfc822 - GMT" "Fri, 07 Nov 2014 04:42:13 GMT" (time :: RFC822), + testFromText + "rfc822 - GMT - single-digit day" + "Fri, 7 Nov 2014 04:42:13 GMT" + (time :: RFC822), testFromText "rfc822 - PST" "Fri, 06 Nov 2014 20:42:13 PST" diff --git a/lib/amazonka-core/test/Test/Amazonka/Util.hs b/lib/amazonka-core/test/Test/Amazonka/Util.hs index 12aff836c7e..bca1866a29b 100644 --- a/lib/amazonka-core/test/Test/Amazonka/Util.hs +++ b/lib/amazonka-core/test/Test/Amazonka/Util.hs @@ -29,19 +29,19 @@ doc = newtype X a = X a deriving stock (Eq, Show) -instance ToQuery a => ToQuery (X a) where +instance (ToQuery a) => ToQuery (X a) where toQuery (X x) = "x" =: x -instance FromXML a => FromXML (X a) where +instance (FromXML a) => FromXML (X a) where parseXML = fmap X . parseXML -instance ToXML a => ToElement (X a) where +instance (ToXML a) => ToElement (X a) where toElement (X x) = mkElement "x" x -instance FromJSON a => FromJSON (X a) where +instance (FromJSON a) => FromJSON (X a) where parseJSON = withObject "X" (fmap X . (.: "x")) -instance ToJSON a => ToJSON (X a) where +instance (ToJSON a) => ToJSON (X a) where toJSON (X x) = object ["x" .= x] testFromText :: @@ -50,7 +50,7 @@ testFromText :: Text -> a -> TestTree -testFromText n t x = testCase n (Right x @?= fromText t) +testFromText n t x = testCase n (Right x @=? fromText t) testToText :: (ToText a, Show a, Eq a) => @@ -58,7 +58,7 @@ testToText :: Text -> a -> TestTree -testToText n t x = testCase n (t @?= toText x) +testToText n t x = testCase n (t @=? toText x) testToQuery :: (ToQuery a, Show a, Eq a) => @@ -76,7 +76,7 @@ testFromXML :: TestTree testFromXML n bs x = testCase n $ - Right (X x) @?= (decodeXML (wrapXML bs) >>= parseXML) + (decodeXML (wrapXML bs) >>= parseXML) @=? Right (X x) testToXML :: (ToXML a, Show a, Eq a) => @@ -84,7 +84,7 @@ testToXML :: ByteStringLazy -> a -> TestTree -testToXML n bs x = testCase n $ wrapXML bs @?= encodeXML (X x) +testToXML n bs x = testCase n $ wrapXML bs @=? encodeXML (X x) testFromJSON :: (FromJSON a, Show a, Eq a) => @@ -94,7 +94,7 @@ testFromJSON :: TestTree testFromJSON n bs x = testCase n $ - Right (X x) @?= eitherDecode' ("{\"x\":" <> bs <> "}") + eitherDecode' ("{\"x\":" <> bs <> "}") @=? Right (X x) testToJSON :: (ToJSON a, Show a, Eq a) => @@ -102,7 +102,7 @@ testToJSON :: ByteStringLazy -> a -> TestTree -testToJSON n bs x = testCase n (bs @?= Aeson.encode x) +testToJSON n bs x = testCase n (bs @=? Aeson.encode x) str :: ByteStringLazy -> ByteStringLazy str bs = "\"" <> bs <> "\"" @@ -117,5 +117,5 @@ maxInt = maxBound minInt :: Int minInt = minBound -toLazyBS :: ToByteString a => a -> ByteStringLazy +toLazyBS :: (ToByteString a) => a -> ByteStringLazy toLazyBS = LBS.fromStrict . toBS diff --git a/lib/amazonka/CHANGELOG.md b/lib/amazonka/CHANGELOG.md index b4eea49eb2b..942c5f71158 100644 --- a/lib/amazonka/CHANGELOG.md +++ b/lib/amazonka/CHANGELOG.md @@ -32,6 +32,8 @@ ### Fixed +- `amazonka-core`: Accept single-digit days when parsing RFC822 dates +[\#1032](https://github.com/brendanhay/amazonka/pull/1032) - `amazonka-core`: Fixed the sorting of query parameters during request canonicalisation. In rare cases, it could sort incorrectly, resulting in requests that failed signature verification. [\#1031](https://github.com/brendanhay/amazonka/pull/1031) - `amazonka`: Attempt to load credentials in the correct order. In particular, this means that the IMDS is queried last and is once again consistent with other SDKs.