Replace protolude with relude and build with GHC 9.0.2 (#168)

- relude is a better and more commonly used library

- Add compiler warnings and fixes

- Update stack lts to 18.24

- Add explicit deriving strategies
This commit is contained in:
Aditya Manthramurthy 2022-02-11 13:48:08 -08:00 committed by GitHub
parent c59b7066fc
commit bdac380c77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 259 additions and 211 deletions

View File

@ -29,7 +29,7 @@ jobs:
os: [ubuntu-latest, windows-latest] # Removed macos-latest due to cert issues. os: [ubuntu-latest, windows-latest] # Removed macos-latest due to cert issues.
cabal: ["3.6"] cabal: ["3.6"]
ghc: ghc:
# - "9.0.1" - "9.0.2"
- "8.10.7" - "8.10.7"
- "8.8.4" - "8.8.4"
- "8.6.5" - "8.6.5"
@ -122,13 +122,13 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
stack: ["2.3.1"] stack: ["2.7.3"]
ghc: ["8.8.4"] ghc: ["8.10.7"]
os: [ubuntu-latest] os: [ubuntu-latest]
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/main' if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
- uses: haskell/actions/setup@v1 - uses: haskell/actions/setup@v1
name: Setup Haskell Stack name: Setup Haskell Stack

View File

@ -19,7 +19,6 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-}
import Data.Monoid ((<>))
import Data.Text (pack) import Data.Text (pack)
import Network.Minio import Network.Minio
import Options.Applicative import Options.Applicative

View File

@ -21,22 +21,52 @@ extra-source-files:
examples/*.hs examples/*.hs
README.md README.md
stack.yaml stack.yaml
tested-with: GHC == 8.8.4
, GHC == 8.10.7
, GHC == 9.0.2
source-repository head
type: git
location: https://github.com/minio/minio-hs.git
common base-settings common base-settings
ghc-options: -Wall ghc-options: -Wall
-Wcompat
-Widentities
-Wincomplete-uni-patterns
-Wincomplete-record-updates
-haddock
if impl(ghc >= 8.0)
ghc-options: -Wredundant-constraints
if impl(ghc >= 8.2)
ghc-options: -fhide-source-paths
-- Add this when we have time. Fixing partial-fields requires major version
-- bump at this time.
-- if impl(ghc >= 8.4)
-- ghc-options: -Wpartial-fields
-- -Wmissing-export-lists
if impl(ghc >= 8.8)
ghc-options: -Wmissing-deriving-strategies
-Werror=missing-deriving-strategies
default-language: Haskell2010 default-language: Haskell2010
default-extensions: BangPatterns default-extensions: BangPatterns
, DerivingStrategies
, FlexibleContexts , FlexibleContexts
, FlexibleInstances , FlexibleInstances
, MultiParamTypeClasses , MultiParamTypeClasses
, MultiWayIf , MultiWayIf
, NoImplicitPrelude
, OverloadedStrings , OverloadedStrings
, RankNTypes , RankNTypes
, ScopedTypeVariables , ScopedTypeVariables
, TypeFamilies
, TupleSections , TupleSections
, TypeFamilies
other-modules: Lib.Prelude other-modules: Lib.Prelude
, Network.Minio.API , Network.Minio.API
, Network.Minio.APICommon , Network.Minio.APICommon
@ -55,8 +85,13 @@ common base-settings
, Network.Minio.XmlGenerator , Network.Minio.XmlGenerator
, Network.Minio.XmlParser , Network.Minio.XmlParser
, Network.Minio.JsonParser , Network.Minio.JsonParser
mixins: base hiding (Prelude)
, relude (Relude as Prelude)
, relude
build-depends: base >= 4.7 && < 5 build-depends: base >= 4.7 && < 5
, protolude >= 0.3 && < 0.4 , relude >= 0.7 && < 2
, aeson >= 1.2 && < 2 , aeson >= 1.2 && < 2
, base64-bytestring >= 1.0 , base64-bytestring >= 1.0
, binary >= 0.8.5.0 , binary >= 0.8.5.0
@ -292,7 +327,3 @@ executable SetConfig
import: examples-settings import: examples-settings
scope: private scope: private
main-is: SetConfig.hs main-is: SetConfig.hs
source-repository head
type: git
location: https://github.com/minio/minio-hs

View File

@ -20,6 +20,7 @@ module Lib.Prelude
showBS, showBS,
toStrictBS, toStrictBS,
fromStrictBS, fromStrictBS,
lastMay,
) )
where where
@ -29,14 +30,6 @@ import Data.Time as Exports
( UTCTime (..), ( UTCTime (..),
diffUTCTime, diffUTCTime,
) )
import Protolude as Exports hiding
( Handler,
catch,
catches,
throwIO,
try,
yield,
)
import UnliftIO as Exports import UnliftIO as Exports
( Handler, ( Handler,
catch, catch,
@ -50,10 +43,13 @@ both :: (a -> b) -> (a, a) -> (b, b)
both f (a, b) = (f a, f b) both f (a, b) = (f a, f b)
showBS :: Show a => a -> ByteString showBS :: Show a => a -> ByteString
showBS a = toUtf8 (show a :: Text) showBS a = encodeUtf8 (show a :: Text)
toStrictBS :: LByteString -> ByteString toStrictBS :: LByteString -> ByteString
toStrictBS = LB.toStrict toStrictBS = LB.toStrict
fromStrictBS :: ByteString -> LByteString fromStrictBS :: ByteString -> LByteString
fromStrictBS = LB.fromStrict fromStrictBS = LB.fromStrict
lastMay :: [a] -> Maybe a
lastMay a = last <$> nonEmpty a

View File

@ -225,7 +225,6 @@ This module exports the high-level MinIO API for object storage.
import qualified Data.Conduit as C import qualified Data.Conduit as C
import qualified Data.Conduit.Binary as CB import qualified Data.Conduit.Binary as CB
import qualified Data.Conduit.Combinators as CC import qualified Data.Conduit.Combinators as CC
import Lib.Prelude
import Network.Minio.CopyObject import Network.Minio.CopyObject
import Network.Minio.Data import Network.Minio.Data
import Network.Minio.Errors import Network.Minio.Errors

View File

@ -46,7 +46,7 @@ getPayloadSHA256Hash (PayloadC _ _) = throwIO MErrVUnexpectedPayload
getRequestBody :: Payload -> NC.RequestBody getRequestBody :: Payload -> NC.RequestBody
getRequestBody (PayloadBS bs) = NC.RequestBodyBS bs getRequestBody (PayloadBS bs) = NC.RequestBodyBS bs
getRequestBody (PayloadH h off size) = getRequestBody (PayloadH h off size) =
NC.requestBodySource (fromIntegral size) $ NC.requestBodySource size $
sourceHandleRange sourceHandleRange
h h
(return . fromIntegral $ off) (return . fromIntegral $ off)

View File

@ -90,7 +90,7 @@ data DriveInfo = DriveInfo
diEndpoint :: Text, diEndpoint :: Text,
diState :: Text diState :: Text
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON DriveInfo where instance FromJSON DriveInfo where
parseJSON = withObject "DriveInfo" $ \v -> parseJSON = withObject "DriveInfo" $ \v ->
@ -103,7 +103,7 @@ data StorageClass = StorageClass
{ scParity :: Int, { scParity :: Int,
scData :: Int scData :: Int
} }
deriving (Eq, Show) deriving stock (Show, Eq)
data ErasureInfo = ErasureInfo data ErasureInfo = ErasureInfo
{ eiOnlineDisks :: Int, { eiOnlineDisks :: Int,
@ -112,7 +112,7 @@ data ErasureInfo = ErasureInfo
eiReducedRedundancy :: StorageClass, eiReducedRedundancy :: StorageClass,
eiSets :: [[DriveInfo]] eiSets :: [[DriveInfo]]
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON ErasureInfo where instance FromJSON ErasureInfo where
parseJSON = withObject "ErasureInfo" $ \v -> do parseJSON = withObject "ErasureInfo" $ \v -> do
@ -132,7 +132,7 @@ instance FromJSON ErasureInfo where
data Backend data Backend
= BackendFS = BackendFS
| BackendErasure ErasureInfo | BackendErasure ErasureInfo
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON Backend where instance FromJSON Backend where
parseJSON = withObject "Backend" $ \v -> do parseJSON = withObject "Backend" $ \v -> do
@ -146,7 +146,7 @@ data ConnStats = ConnStats
{ csTransferred :: Int64, { csTransferred :: Int64,
csReceived :: Int64 csReceived :: Int64
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON ConnStats where instance FromJSON ConnStats where
parseJSON = withObject "ConnStats" $ \v -> parseJSON = withObject "ConnStats" $ \v ->
@ -161,7 +161,7 @@ data ServerProps = ServerProps
spRegion :: Text, spRegion :: Text,
spSqsArns :: [Text] spSqsArns :: [Text]
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON ServerProps where instance FromJSON ServerProps where
parseJSON = withObject "SIServer" $ \v -> do parseJSON = withObject "SIServer" $ \v -> do
@ -177,7 +177,7 @@ data StorageInfo = StorageInfo
{ siUsed :: Int64, { siUsed :: Int64,
siBackend :: Backend siBackend :: Backend
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON StorageInfo where instance FromJSON StorageInfo where
parseJSON = withObject "StorageInfo" $ \v -> parseJSON = withObject "StorageInfo" $ \v ->
@ -189,7 +189,7 @@ data CountNAvgTime = CountNAvgTime
{ caCount :: Int64, { caCount :: Int64,
caAvgDuration :: Text caAvgDuration :: Text
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON CountNAvgTime where instance FromJSON CountNAvgTime where
parseJSON = withObject "CountNAvgTime" $ \v -> parseJSON = withObject "CountNAvgTime" $ \v ->
@ -209,7 +209,7 @@ data HttpStats = HttpStats
hsTotalDeletes :: CountNAvgTime, hsTotalDeletes :: CountNAvgTime,
hsSuccessDeletes :: CountNAvgTime hsSuccessDeletes :: CountNAvgTime
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON HttpStats where instance FromJSON HttpStats where
parseJSON = withObject "HttpStats" $ \v -> parseJSON = withObject "HttpStats" $ \v ->
@ -231,7 +231,7 @@ data SIData = SIData
sdHttpStats :: HttpStats, sdHttpStats :: HttpStats,
sdProps :: ServerProps sdProps :: ServerProps
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON SIData where instance FromJSON SIData where
parseJSON = withObject "SIData" $ \v -> parseJSON = withObject "SIData" $ \v ->
@ -246,7 +246,7 @@ data ServerInfo = ServerInfo
siAddr :: Text, siAddr :: Text,
siData :: SIData siData :: SIData
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON ServerInfo where instance FromJSON ServerInfo where
parseJSON = withObject "ServerInfo" $ \v -> parseJSON = withObject "ServerInfo" $ \v ->
@ -259,7 +259,7 @@ data ServerVersion = ServerVersion
{ svVersion :: Text, { svVersion :: Text,
svCommitId :: Text svCommitId :: Text
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON ServerVersion where instance FromJSON ServerVersion where
parseJSON = withObject "ServerVersion" $ \v -> parseJSON = withObject "ServerVersion" $ \v ->
@ -271,7 +271,7 @@ data ServiceStatus = ServiceStatus
{ ssVersion :: ServerVersion, { ssVersion :: ServerVersion,
ssUptime :: NominalDiffTime ssUptime :: NominalDiffTime
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON ServiceStatus where instance FromJSON ServiceStatus where
parseJSON = withObject "ServiceStatus" $ \v -> do parseJSON = withObject "ServiceStatus" $ \v -> do
@ -283,7 +283,7 @@ instance FromJSON ServiceStatus where
data ServiceAction data ServiceAction
= ServiceActionRestart = ServiceActionRestart
| ServiceActionStop | ServiceActionStop
deriving (Eq, Show) deriving stock (Show, Eq)
instance ToJSON ServiceAction where instance ToJSON ServiceAction where
toJSON a = object ["action" .= serviceActionToText a] toJSON a = object ["action" .= serviceActionToText a]
@ -301,7 +301,7 @@ data HealStartResp = HealStartResp
hsrClientAddr :: Text, hsrClientAddr :: Text,
hsrStartTime :: UTCTime hsrStartTime :: UTCTime
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON HealStartResp where instance FromJSON HealStartResp where
parseJSON = withObject "HealStartResp" $ \v -> parseJSON = withObject "HealStartResp" $ \v ->
@ -314,7 +314,7 @@ data HealOpts = HealOpts
{ hoRecursive :: Bool, { hoRecursive :: Bool,
hoDryRun :: Bool hoDryRun :: Bool
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance ToJSON HealOpts where instance ToJSON HealOpts where
toJSON (HealOpts r d) = toJSON (HealOpts r d) =
@ -333,7 +333,7 @@ data HealItemType
| HealItemBucket | HealItemBucket
| HealItemBucketMetadata | HealItemBucketMetadata
| HealItemObject | HealItemObject
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON HealItemType where instance FromJSON HealItemType where
parseJSON = withText "HealItemType" $ \v -> case v of parseJSON = withText "HealItemType" $ \v -> case v of
@ -348,7 +348,7 @@ data NodeSummary = NodeSummary
nsErrSet :: Bool, nsErrSet :: Bool,
nsErrMessage :: Text nsErrMessage :: Text
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON NodeSummary where instance FromJSON NodeSummary where
parseJSON = withObject "NodeSummary" $ \v -> parseJSON = withObject "NodeSummary" $ \v ->
@ -361,7 +361,7 @@ data SetConfigResult = SetConfigResult
{ scrStatus :: Bool, { scrStatus :: Bool,
scrNodeSummary :: [NodeSummary] scrNodeSummary :: [NodeSummary]
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON SetConfigResult where instance FromJSON SetConfigResult where
parseJSON = withObject "SetConfigResult" $ \v -> parseJSON = withObject "SetConfigResult" $ \v ->
@ -383,7 +383,7 @@ data HealResultItem = HealResultItem
hriBefore :: [DriveInfo], hriBefore :: [DriveInfo],
hriAfter :: [DriveInfo] hriAfter :: [DriveInfo]
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON HealResultItem where instance FromJSON HealResultItem where
parseJSON = withObject "HealResultItem" $ \v -> parseJSON = withObject "HealResultItem" $ \v ->
@ -415,7 +415,7 @@ data HealStatus = HealStatus
hsFailureDetail :: Maybe Text, hsFailureDetail :: Maybe Text,
hsItems :: Maybe [HealResultItem] hsItems :: Maybe [HealResultItem]
} }
deriving (Eq, Show) deriving stock (Show, Eq)
instance FromJSON HealStatus where instance FromJSON HealStatus where
parseJSON = withObject "HealStatus" $ \v -> parseJSON = withObject "HealStatus" $ \v ->
@ -434,7 +434,7 @@ healPath bucket prefix = do
encodeUtf8 $ encodeUtf8 $
"v1/heal/" <> fromMaybe "" bucket <> "/" "v1/heal/" <> fromMaybe "" bucket <> "/"
<> fromMaybe "" prefix <> fromMaybe "" prefix
else encodeUtf8 $ "v1/heal/" else encodeUtf8 ("v1/heal/" :: Text)
-- | Get server version and uptime. -- | Get server version and uptime.
serviceStatus :: Minio ServiceStatus serviceStatus :: Minio ServiceStatus

View File

@ -45,11 +45,10 @@ copyObjectInternal b' o srcInfo = do
when when
( isJust rangeMay ( isJust rangeMay
&& or && ( (startOffset < 0)
[ startOffset < 0, || (endOffset < startOffset)
endOffset < startOffset, || (endOffset >= srcSize)
endOffset >= fromIntegral srcSize )
]
) )
$ throwIO $ $ throwIO $
MErrVInvalidSrcObjByteRange range MErrVInvalidSrcObjByteRange range
@ -70,8 +69,7 @@ copyObjectInternal b' o srcInfo = do
selectCopyRanges :: (Int64, Int64) -> [(PartNumber, (Int64, Int64))] selectCopyRanges :: (Int64, Int64) -> [(PartNumber, (Int64, Int64))]
selectCopyRanges (st, end) = selectCopyRanges (st, end) =
zip pns $ zip pns $
map (\(x, y) -> (st + x, st + x + y - 1)) $ zipWith (\x y -> (st + x, st + x + y - 1)) startOffsets partSizes
zip startOffsets partSizes
where where
size = end - st + 1 size = end - st + 1
(pns, startOffsets, partSizes) = List.unzip3 $ selectPartSizes size (pns, startOffsets, partSizes) = List.unzip3 $ selectPartSizes size
@ -88,7 +86,7 @@ multiPartCopyObject ::
multiPartCopyObject b o cps srcSize = do multiPartCopyObject b o cps srcSize = do
uid <- newMultipartUpload b o [] uid <- newMultipartUpload b o []
let byteRange = maybe (0, fromIntegral $ srcSize - 1) identity $ srcRange cps let byteRange = maybe (0, srcSize - 1) identity $ srcRange cps
partRanges = selectCopyRanges byteRange partRanges = selectCopyRanges byteRange
partSources = partSources =
map map

View File

@ -22,7 +22,14 @@ module Network.Minio.Data where
import qualified Conduit as C import qualified Conduit as C
import qualified Control.Concurrent.MVar as M import qualified Control.Concurrent.MVar as M
import Control.Monad.Trans.Except (throwE)
import Control.Monad.Trans.Resource import Control.Monad.Trans.Resource
( MonadResource,
MonadThrow (..),
MonadUnliftIO,
ResourceT,
runResourceT,
)
import qualified Data.Aeson as A import qualified Data.Aeson as A
import qualified Data.ByteArray as BA import qualified Data.ByteArray as BA
import qualified Data.ByteString as B import qualified Data.ByteString as B
@ -30,12 +37,10 @@ import qualified Data.ByteString.Lazy as LB
import Data.CaseInsensitive (mk) import Data.CaseInsensitive (mk)
import qualified Data.HashMap.Strict as H import qualified Data.HashMap.Strict as H
import qualified Data.Ini as Ini import qualified Data.Ini as Ini
import Data.String (IsString (..))
import qualified Data.Text as T import qualified Data.Text as T
import qualified Data.Text.Encoding as TE import qualified Data.Text.Encoding as TE
import Data.Time (defaultTimeLocale, formatTime) import Data.Time (defaultTimeLocale, formatTime)
import GHC.Show (Show (show)) import Lib.Prelude (UTCTime, throwIO)
import Lib.Prelude
import qualified Network.Connection as Conn import qualified Network.Connection as Conn
import Network.HTTP.Client (defaultManagerSettings) import Network.HTTP.Client (defaultManagerSettings)
import qualified Network.HTTP.Client.TLS as TLS import qualified Network.HTTP.Client.TLS as TLS
@ -49,12 +54,18 @@ import Network.HTTP.Types
) )
import qualified Network.HTTP.Types as HT import qualified Network.HTTP.Types as HT
import Network.Minio.Data.Crypto import Network.Minio.Data.Crypto
import Network.Minio.Data.Time ( encodeToBase64,
hashMD5ToBase64,
)
import Network.Minio.Data.Time (UrlExpiry)
import Network.Minio.Errors import Network.Minio.Errors
( MErrV (MErrVInvalidEncryptionKeyLength, MErrVMissingCredentials),
MinioErr (..),
)
import System.Directory (doesFileExist, getHomeDirectory) import System.Directory (doesFileExist, getHomeDirectory)
import qualified System.Environment as Env import qualified System.Environment as Env
import System.FilePath.Posix (combine) import System.FilePath.Posix (combine)
import Text.XML import Text.XML (Name (Name))
import qualified UnliftIO as U import qualified UnliftIO as U
-- | max obj size is 5TiB -- | max obj size is 5TiB
@ -111,7 +122,7 @@ data ConnectInfo = ConnectInfo
connectAutoDiscoverRegion :: Bool, connectAutoDiscoverRegion :: Bool,
connectDisableTLSCertValidation :: Bool connectDisableTLSCertValidation :: Bool
} }
deriving (Eq, Show) deriving stock (Eq, Show)
instance IsString ConnectInfo where instance IsString ConnectInfo where
fromString str = fromString str =
@ -132,7 +143,7 @@ data Credentials = Credentials
{ cAccessKey :: Text, { cAccessKey :: Text,
cSecretKey :: Text cSecretKey :: Text
} }
deriving (Eq, Show) deriving stock (Eq, Show)
-- | A Provider is an action that may return Credentials. Providers -- | A Provider is an action that may return Credentials. Providers
-- may be chained together using 'findFirst'. -- may be chained together using 'findFirst'.
@ -164,7 +175,7 @@ fromAWSConfigFile = do
return $ return $
Ini.lookupValue "default" "aws_secret_access_key" ini Ini.lookupValue "default" "aws_secret_access_key" ini
return $ Credentials akey skey return $ Credentials akey skey
return $ hush credsE return $ either (const Nothing) Just credsE
-- | This Provider loads `Credentials` from @AWS_ACCESS_KEY_ID@ and -- | This Provider loads `Credentials` from @AWS_ACCESS_KEY_ID@ and
-- @AWS_SECRET_ACCESS_KEY@ environment variables. -- @AWS_SECRET_ACCESS_KEY@ environment variables.
@ -224,10 +235,10 @@ disableTLSCertValidation c = c {connectDisableTLSCertValidation = True}
getHostAddr :: ConnectInfo -> ByteString getHostAddr :: ConnectInfo -> ByteString
getHostAddr ci = getHostAddr ci =
if if
| port == 80 || port == 443 -> toUtf8 host | port == 80 || port == 443 -> encodeUtf8 host
| otherwise -> | otherwise ->
toUtf8 $ encodeUtf8 $
T.concat [host, ":", Lib.Prelude.show port] T.concat [host, ":", show port]
where where
port = connectPort ci port = connectPort ci
host = connectHost ci host = connectHost ci
@ -276,7 +287,7 @@ type ETag = Text
-- | Data type to represent an object encryption key. Create one using -- | Data type to represent an object encryption key. Create one using
-- the `mkSSECKey` function. -- the `mkSSECKey` function.
newtype SSECKey = SSECKey BA.ScrubbedBytes newtype SSECKey = SSECKey BA.ScrubbedBytes
deriving (Eq, Show) deriving stock (Eq, Show)
-- | Validates that the given ByteString is 32 bytes long and creates -- | Validates that the given ByteString is 32 bytes long and creates
-- an encryption key. -- an encryption key.
@ -407,7 +418,7 @@ data BucketInfo = BucketInfo
{ biName :: Bucket, { biName :: Bucket,
biCreationDate :: UTCTime biCreationDate :: UTCTime
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | A type alias to represent a part-number for multipart upload -- | A type alias to represent a part-number for multipart upload
type PartNumber = Int16 type PartNumber = Int16
@ -425,7 +436,7 @@ data ListPartsResult = ListPartsResult
lprNextPart :: Maybe Int, lprNextPart :: Maybe Int,
lprParts :: [ObjectPartInfo] lprParts :: [ObjectPartInfo]
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Represents information about an object part in an ongoing -- | Represents information about an object part in an ongoing
-- multipart upload. -- multipart upload.
@ -435,7 +446,7 @@ data ObjectPartInfo = ObjectPartInfo
opiSize :: Int64, opiSize :: Int64,
opiModTime :: UTCTime opiModTime :: UTCTime
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Represents result from a listing of incomplete uploads to a -- | Represents result from a listing of incomplete uploads to a
-- bucket. -- bucket.
@ -446,7 +457,7 @@ data ListUploadsResult = ListUploadsResult
lurUploads :: [(Object, UploadId, UTCTime)], lurUploads :: [(Object, UploadId, UTCTime)],
lurCPrefixes :: [Text] lurCPrefixes :: [Text]
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Represents information about a multipart upload. -- | Represents information about a multipart upload.
data UploadInfo = UploadInfo data UploadInfo = UploadInfo
@ -455,7 +466,7 @@ data UploadInfo = UploadInfo
uiInitTime :: UTCTime, uiInitTime :: UTCTime,
uiSize :: Int64 uiSize :: Int64
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Represents result from a listing of objects in a bucket. -- | Represents result from a listing of objects in a bucket.
data ListObjectsResult = ListObjectsResult data ListObjectsResult = ListObjectsResult
@ -464,7 +475,7 @@ data ListObjectsResult = ListObjectsResult
lorObjects :: [ObjectInfo], lorObjects :: [ObjectInfo],
lorCPrefixes :: [Text] lorCPrefixes :: [Text]
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Represents result from a listing of objects version 1 in a bucket. -- | Represents result from a listing of objects version 1 in a bucket.
data ListObjectsV1Result = ListObjectsV1Result data ListObjectsV1Result = ListObjectsV1Result
@ -473,7 +484,7 @@ data ListObjectsV1Result = ListObjectsV1Result
lorObjects' :: [ObjectInfo], lorObjects' :: [ObjectInfo],
lorCPrefixes' :: [Text] lorCPrefixes' :: [Text]
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Represents information about an object. -- | Represents information about an object.
data ObjectInfo = ObjectInfo data ObjectInfo = ObjectInfo
@ -497,7 +508,7 @@ data ObjectInfo = ObjectInfo
-- user-metadata pairs) -- user-metadata pairs)
oiMetadata :: H.HashMap Text Text oiMetadata :: H.HashMap Text Text
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Represents source object in server-side copy object -- | Represents source object in server-side copy object
data SourceInfo = SourceInfo data SourceInfo = SourceInfo
@ -529,7 +540,7 @@ data SourceInfo = SourceInfo
-- given time. -- given time.
srcIfUnmodifiedSince :: Maybe UTCTime srcIfUnmodifiedSince :: Maybe UTCTime
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Provide a default for `SourceInfo` -- | Provide a default for `SourceInfo`
defaultSourceInfo :: SourceInfo defaultSourceInfo :: SourceInfo
@ -542,7 +553,7 @@ data DestinationInfo = DestinationInfo
-- | Destination object key -- | Destination object key
dstObject :: Text dstObject :: Text
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Provide a default for `DestinationInfo` -- | Provide a default for `DestinationInfo`
defaultDestinationInfo :: DestinationInfo defaultDestinationInfo :: DestinationInfo
@ -619,18 +630,18 @@ data Event
| ObjectRemovedDelete | ObjectRemovedDelete
| ObjectRemovedDeleteMarkerCreated | ObjectRemovedDeleteMarkerCreated
| ReducedRedundancyLostObject | ReducedRedundancyLostObject
deriving (Eq) deriving stock (Eq, Show)
instance Show Event where instance ToText Event where
show ObjectCreated = "s3:ObjectCreated:*" toText ObjectCreated = "s3:ObjectCreated:*"
show ObjectCreatedPut = "s3:ObjectCreated:Put" toText ObjectCreatedPut = "s3:ObjectCreated:Put"
show ObjectCreatedPost = "s3:ObjectCreated:Post" toText ObjectCreatedPost = "s3:ObjectCreated:Post"
show ObjectCreatedCopy = "s3:ObjectCreated:Copy" toText ObjectCreatedCopy = "s3:ObjectCreated:Copy"
show ObjectCreatedMultipartUpload = "s3:ObjectCreated:MultipartUpload" toText ObjectCreatedMultipartUpload = "s3:ObjectCreated:MultipartUpload"
show ObjectRemoved = "s3:ObjectRemoved:*" toText ObjectRemoved = "s3:ObjectRemoved:*"
show ObjectRemovedDelete = "s3:ObjectRemoved:Delete" toText ObjectRemovedDelete = "s3:ObjectRemoved:Delete"
show ObjectRemovedDeleteMarkerCreated = "s3:ObjectRemoved:DeleteMarkerCreated" toText ObjectRemovedDeleteMarkerCreated = "s3:ObjectRemoved:DeleteMarkerCreated"
show ReducedRedundancyLostObject = "s3:ReducedRedundancyLostObject" toText ReducedRedundancyLostObject = "s3:ReducedRedundancyLostObject"
textToEvent :: Text -> Maybe Event textToEvent :: Text -> Maybe Event
textToEvent t = case t of textToEvent t = case t of
@ -649,7 +660,7 @@ textToEvent t = case t of
data Filter = Filter data Filter = Filter
{ fFilter :: FilterKey { fFilter :: FilterKey
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | defaultFilter is empty, used to create a notification -- | defaultFilter is empty, used to create a notification
-- configuration. -- configuration.
@ -660,7 +671,7 @@ defaultFilter = Filter defaultFilterKey
data FilterKey = FilterKey data FilterKey = FilterKey
{ fkKey :: FilterRules { fkKey :: FilterRules
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | defaultFilterKey is empty, used to create notification -- | defaultFilterKey is empty, used to create notification
-- configuration. -- configuration.
@ -671,7 +682,7 @@ defaultFilterKey = FilterKey defaultFilterRules
data FilterRules = FilterRules data FilterRules = FilterRules
{ frFilterRules :: [FilterRule] { frFilterRules :: [FilterRule]
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | defaultFilterRules is empty, used to create notification -- | defaultFilterRules is empty, used to create notification
-- configuration. -- configuration.
@ -691,7 +702,7 @@ data FilterRule = FilterRule
{ frName :: Text, { frName :: Text,
frValue :: Text frValue :: Text
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | Arn is an alias of Text -- | Arn is an alias of Text
type Arn = Text type Arn = Text
@ -705,7 +716,7 @@ data NotificationConfig = NotificationConfig
ncEvents :: [Event], ncEvents :: [Event],
ncFilter :: Filter ncFilter :: Filter
} }
deriving (Show, Eq) deriving stock (Show, Eq)
-- | A data-type to represent bucket notification configuration. It is -- | A data-type to represent bucket notification configuration. It is
-- a collection of queue, topic or lambda function configurations. The -- a collection of queue, topic or lambda function configurations. The
@ -717,7 +728,7 @@ data Notification = Notification
nTopicConfigurations :: [NotificationConfig], nTopicConfigurations :: [NotificationConfig],
nCloudFunctionConfigurations :: [NotificationConfig] nCloudFunctionConfigurations :: [NotificationConfig]
} }
deriving (Eq, Show) deriving stock (Show, Eq)
-- | The default notification configuration is empty. -- | The default notification configuration is empty.
defaultNotification :: Notification defaultNotification :: Notification
@ -736,10 +747,10 @@ data SelectRequest = SelectRequest
srOutputSerialization :: OutputSerialization, srOutputSerialization :: OutputSerialization,
srRequestProgressEnabled :: Maybe Bool srRequestProgressEnabled :: Maybe Bool
} }
deriving (Eq, Show) deriving stock (Show, Eq)
data ExpressionType = SQL data ExpressionType = SQL
deriving (Eq, Show) deriving stock (Show, Eq)
-- | InputSerialization represents format information of the input -- | InputSerialization represents format information of the input
-- object being queried. Use one of the smart constructors such as -- object being queried. Use one of the smart constructors such as
@ -749,7 +760,7 @@ data InputSerialization = InputSerialization
{ isCompressionType :: Maybe CompressionType, { isCompressionType :: Maybe CompressionType,
isFormatInfo :: InputFormatInfo isFormatInfo :: InputFormatInfo
} }
deriving (Eq, Show) deriving stock (Show, Eq)
-- | Data type representing the compression setting in a Select -- | Data type representing the compression setting in a Select
-- request. -- request.
@ -757,7 +768,7 @@ data CompressionType
= CompressionTypeNone = CompressionTypeNone
| CompressionTypeGzip | CompressionTypeGzip
| CompressionTypeBzip2 | CompressionTypeBzip2
deriving (Eq, Show) deriving stock (Show, Eq)
-- | Data type representing input object format information in a -- | Data type representing input object format information in a
-- Select request. -- Select request.
@ -765,7 +776,7 @@ data InputFormatInfo
= InputFormatCSV CSVInputProp = InputFormatCSV CSVInputProp
| InputFormatJSON JSONInputProp | InputFormatJSON JSONInputProp
| InputFormatParquet | InputFormatParquet
deriving (Eq, Show) deriving stock (Show, Eq)
-- | defaultCsvInput returns InputSerialization with default CSV -- | defaultCsvInput returns InputSerialization with default CSV
-- format, and without any compression setting. -- format, and without any compression setting.
@ -845,7 +856,7 @@ type CSVInputProp = CSVProp
-- | CSVProp represents CSV format properties. It is built up using -- | CSVProp represents CSV format properties. It is built up using
-- the Monoid instance. -- the Monoid instance.
data CSVProp = CSVProp (H.HashMap Text Text) data CSVProp = CSVProp (H.HashMap Text Text)
deriving (Eq, Show) deriving stock (Show, Eq)
#if (__GLASGOW_HASKELL__ >= 804) #if (__GLASGOW_HASKELL__ >= 804)
instance Semigroup CSVProp where instance Semigroup CSVProp where
@ -890,15 +901,15 @@ data FileHeaderInfo
FileHeaderUse FileHeaderUse
| -- | Header are present, but should be ignored | -- | Header are present, but should be ignored
FileHeaderIgnore FileHeaderIgnore
deriving (Eq, Show) deriving stock (Show, Eq)
-- | Specify the CSV file header info property. -- | Specify the CSV file header info property.
fileHeaderInfo :: FileHeaderInfo -> CSVProp fileHeaderInfo :: FileHeaderInfo -> CSVProp
fileHeaderInfo = CSVProp . H.singleton "FileHeaderInfo" . toString fileHeaderInfo = CSVProp . H.singleton "FileHeaderInfo" . toStr
where where
toString FileHeaderNone = "NONE" toStr FileHeaderNone = "NONE"
toString FileHeaderUse = "USE" toStr FileHeaderUse = "USE"
toString FileHeaderIgnore = "IGNORE" toStr FileHeaderIgnore = "IGNORE"
-- | Specify the CSV comment character property. Lines starting with -- | Specify the CSV comment character property. Lines starting with
-- this character are ignored by the server. -- this character are ignored by the server.
@ -918,10 +929,10 @@ outputCSVFromProps :: CSVProp -> OutputSerialization
outputCSVFromProps p = OutputSerializationCSV p outputCSVFromProps p = OutputSerializationCSV p
data JSONInputProp = JSONInputProp {jsonipType :: JSONType} data JSONInputProp = JSONInputProp {jsonipType :: JSONType}
deriving (Eq, Show) deriving stock (Show, Eq)
data JSONType = JSONTypeDocument | JSONTypeLines data JSONType = JSONTypeDocument | JSONTypeLines
deriving (Eq, Show) deriving stock (Show, Eq)
-- | OutputSerialization represents output serialization settings for -- | OutputSerialization represents output serialization settings for
-- the SelectRequest. Use `defaultCsvOutput` or `defaultJsonOutput` as -- the SelectRequest. Use `defaultCsvOutput` or `defaultJsonOutput` as
@ -929,7 +940,7 @@ data JSONType = JSONTypeDocument | JSONTypeLines
data OutputSerialization data OutputSerialization
= OutputSerializationJSON JSONOutputProp = OutputSerializationJSON JSONOutputProp
| OutputSerializationCSV CSVOutputProp | OutputSerializationCSV CSVOutputProp
deriving (Eq, Show) deriving stock (Show, Eq)
type CSVOutputProp = CSVProp type CSVOutputProp = CSVProp
@ -943,10 +954,10 @@ quoteFields q = CSVProp $
-- | Represent the QuoteField setting. -- | Represent the QuoteField setting.
data QuoteFields = QuoteFieldsAsNeeded | QuoteFieldsAlways data QuoteFields = QuoteFieldsAsNeeded | QuoteFieldsAlways
deriving (Eq, Show) deriving stock (Show, Eq)
data JSONOutputProp = JSONOutputProp {jsonopRecordDelimiter :: Maybe Text} data JSONOutputProp = JSONOutputProp {jsonopRecordDelimiter :: Maybe Text}
deriving (Eq, Show) deriving stock (Show, Eq)
-- | Set the output record delimiter for JSON format -- | Set the output record delimiter for JSON format
outputJSONFromRecordDelimiter :: Text -> OutputSerialization outputJSONFromRecordDelimiter :: Text -> OutputSerialization
@ -964,7 +975,7 @@ data EventMessage
emErrorMessage :: Text emErrorMessage :: Text
} }
| RecordPayloadEventMessage {emPayloadBytes :: ByteString} | RecordPayloadEventMessage {emPayloadBytes :: ByteString}
deriving (Eq, Show) deriving stock (Show, Eq)
data MsgHeaderName data MsgHeaderName
= MessageType = MessageType
@ -972,7 +983,7 @@ data MsgHeaderName
| ContentType | ContentType
| ErrorCode | ErrorCode
| ErrorMessage | ErrorMessage
deriving (Eq, Show) deriving stock (Show, Eq)
msgHeaderValueType :: Word8 msgHeaderValueType :: Word8
msgHeaderValueType = 7 msgHeaderValueType = 7
@ -985,7 +996,7 @@ data Progress = Progress
pBytesProcessed :: Int64, pBytesProcessed :: Int64,
pBytesReturned :: Int64 pBytesReturned :: Int64
} }
deriving (Eq, Show) deriving stock (Show, Eq)
-- | Represent the stats event returned at the end of the Select -- | Represent the stats event returned at the end of the Select
-- response. -- response.
@ -1043,7 +1054,7 @@ defaultS3ReqInfo =
getS3Path :: Maybe Bucket -> Maybe Object -> ByteString getS3Path :: Maybe Bucket -> Maybe Object -> ByteString
getS3Path b o = getS3Path b o =
let segments = map toUtf8 $ catMaybes $ b : bool [] [o] (isJust b) let segments = map encodeUtf8 $ catMaybes $ b : bool [] [o] (isJust b)
in B.concat ["/", B.intercalate "/" segments] in B.concat ["/", B.intercalate "/" segments]
type RegionMap = H.HashMap Bucket Region type RegionMap = H.HashMap Bucket Region
@ -1053,7 +1064,7 @@ type RegionMap = H.HashMap Bucket Region
newtype Minio a = Minio newtype Minio a = Minio
{ unMinio :: ReaderT MinioConn (ResourceT IO) a { unMinio :: ReaderT MinioConn (ResourceT IO) a
} }
deriving deriving newtype
( Functor, ( Functor,
Applicative, Applicative,
Monad, Monad,

View File

@ -25,9 +25,8 @@ import qualified Data.ByteString as B
import qualified Data.ByteString.Builder as BB import qualified Data.ByteString.Builder as BB
import qualified Data.ByteString.Char8 as BC8 import qualified Data.ByteString.Char8 as BC8
import qualified Data.ByteString.Lazy as LB import qualified Data.ByteString.Lazy as LB
import Data.Char (isAsciiLower, isAsciiUpper) import Data.Char (isAsciiLower, isAsciiUpper, isDigit, isSpace, toUpper)
import qualified Data.Text as T import qualified Data.Text as T
import Lib.Prelude
import Numeric (showHex) import Numeric (showHex)
stripBS :: ByteString -> ByteString stripBS :: ByteString -> ByteString
@ -73,4 +72,4 @@ uriEncodeChar ch _
f n = BB.char7 '%' <> BB.string7 hexStr f n = BB.char7 '%' <> BB.string7 hexStr
where where
hexStr = map toUpper $ showHex q $ showHex r "" hexStr = map toUpper $ showHex q $ showHex r ""
(q, r) = divMod (fromIntegral n) (16 :: Word8) (q, r) = divMod n (16 :: Word8)

View File

@ -39,7 +39,6 @@ import Crypto.MAC.HMAC (HMAC, hmac)
import Data.ByteArray (ByteArrayAccess, convert) import Data.ByteArray (ByteArrayAccess, convert)
import Data.ByteArray.Encoding (Base (Base16, Base64), convertToBase) import Data.ByteArray.Encoding (Base (Base16, Base64), convertToBase)
import qualified Data.Conduit as C import qualified Data.Conduit as C
import Lib.Prelude
hashSHA256 :: ByteString -> ByteString hashSHA256 :: ByteString -> ByteString
hashSHA256 = digestToBase16 . hashWith SHA256 hashSHA256 = digestToBase16 . hashWith SHA256

View File

@ -14,10 +14,15 @@
-- limitations under the License. -- limitations under the License.
-- --
module Network.Minio.Errors where module Network.Minio.Errors
( MErrV (..),
ServiceErr (..),
MinioErr (..),
toServiceErr,
)
where
import Control.Exception import Control.Exception (IOException)
import Lib.Prelude
import qualified Network.HTTP.Conduit as NC import qualified Network.HTTP.Conduit as NC
--------------------------------- ---------------------------------
@ -44,7 +49,7 @@ data MErrV
| MErrVInvalidEncryptionKeyLength | MErrVInvalidEncryptionKeyLength
| MErrVStreamingBodyUnexpectedEOF | MErrVStreamingBodyUnexpectedEOF
| MErrVUnexpectedPayload | MErrVUnexpectedPayload
deriving (Show, Eq) deriving stock (Show, Eq)
instance Exception MErrV instance Exception MErrV
@ -57,7 +62,7 @@ data ServiceErr
| NoSuchKey | NoSuchKey
| SelectErr Text Text | SelectErr Text Text
| ServiceErr Text Text | ServiceErr Text Text
deriving (Show, Eq) deriving stock (Show, Eq)
instance Exception ServiceErr instance Exception ServiceErr
@ -75,7 +80,7 @@ data MinioErr
| MErrIO IOException | MErrIO IOException
| MErrService ServiceErr | MErrService ServiceErr
| MErrValidation MErrV | MErrValidation MErrV
deriving (Show) deriving stock (Show)
instance Eq MinioErr where instance Eq MinioErr where
MErrHTTP _ == MErrHTTP _ = True MErrHTTP _ == MErrHTTP _ = True

View File

@ -34,7 +34,7 @@ data AdminErrJSON = AdminErrJSON
{ aeCode :: Text, { aeCode :: Text,
aeMessage :: Text aeMessage :: Text
} }
deriving (Eq, Show) deriving stock (Eq, Show)
instance FromJSON AdminErrJSON where instance FromJSON AdminErrJSON where
parseJSON = withObject "AdminErrJSON" $ \v -> parseJSON = withObject "AdminErrJSON" $ \v ->

View File

@ -19,16 +19,47 @@ module Network.Minio.ListOps where
import qualified Data.Conduit as C import qualified Data.Conduit as C
import qualified Data.Conduit.Combinators as CC import qualified Data.Conduit.Combinators as CC
import qualified Data.Conduit.List as CL import qualified Data.Conduit.List as CL
import Lib.Prelude
import Network.Minio.Data import Network.Minio.Data
( Bucket,
ListObjectsResult
( lorCPrefixes,
lorHasMore,
lorNextToken,
lorObjects
),
ListObjectsV1Result
( lorCPrefixes',
lorHasMore',
lorNextMarker,
lorObjects'
),
ListPartsResult (lprHasMore, lprNextPart, lprParts),
ListUploadsResult
( lurHasMore,
lurNextKey,
lurNextUpload,
lurUploads
),
Minio,
Object,
ObjectInfo,
ObjectPartInfo (opiSize),
UploadId,
UploadInfo (UploadInfo),
)
import Network.Minio.S3API import Network.Minio.S3API
( listIncompleteParts',
listIncompleteUploads',
listObjects',
listObjectsV1',
)
-- | Represents a list output item - either an object or an object -- | Represents a list output item - either an object or an object
-- prefix (i.e. a directory). -- prefix (i.e. a directory).
data ListItem data ListItem
= ListItemObject ObjectInfo = ListItemObject ObjectInfo
| ListItemPrefix Text | ListItemPrefix Text
deriving (Show, Eq) deriving stock (Show, Eq)
-- | @'listObjects' bucket prefix recurse@ lists objects in a bucket -- | @'listObjects' bucket prefix recurse@ lists objects in a bucket
-- similar to a file system tree traversal. -- similar to a file system tree traversal.
@ -110,7 +141,7 @@ listIncompleteUploads bucket prefix recurse = loop Nothing Nothing
C.runConduit $ C.runConduit $
listIncompleteParts bucket uKey uId listIncompleteParts bucket uKey uId
C..| CC.sinkList C..| CC.sinkList
return $ foldl (\sizeSofar p -> opiSize p + sizeSofar) 0 partInfos return $ foldl' (\sizeSofar p -> opiSize p + sizeSofar) 0 partInfos
CL.sourceList $ CL.sourceList $
map map

View File

@ -88,7 +88,7 @@ makePresignedUrl expiry method bucket object region extraQuery extraHeaders = do
let uri = NClient.getUri req let uri = NClient.getUri req
uriString = uriToString identity uri "" uriString = uriToString identity uri ""
return $ toUtf8 uriString return $ encodeUtf8 uriString
-- | Generate a URL with authentication signature to PUT (upload) an -- | Generate a URL with authentication signature to PUT (upload) an
-- object. Any extra headers if passed, are signed, and so they are -- object. Any extra headers if passed, are signed, and so they are
@ -170,7 +170,7 @@ data PostPolicyCondition
= PPCStartsWith Text Text = PPCStartsWith Text Text
| PPCEquals Text Text | PPCEquals Text Text
| PPCRange Text Int64 Int64 | PPCRange Text Int64 Int64
deriving (Show, Eq) deriving stock (Show, Eq)
instance Json.ToJSON PostPolicyCondition where instance Json.ToJSON PostPolicyCondition where
toJSON (PPCStartsWith k v) = Json.toJSON ["starts-with", k, v] toJSON (PPCStartsWith k v) = Json.toJSON ["starts-with", k, v]
@ -188,7 +188,7 @@ data PostPolicy = PostPolicy
{ expiration :: UTCTime, { expiration :: UTCTime,
conditions :: [PostPolicyCondition] conditions :: [PostPolicyCondition]
} }
deriving (Show, Eq) deriving stock (Show, Eq)
instance Json.ToJSON PostPolicy where instance Json.ToJSON PostPolicy where
toJSON (PostPolicy e c) = toJSON (PostPolicy e c) =
@ -205,7 +205,7 @@ data PostPolicyError
| PPEBucketNotSpecified | PPEBucketNotSpecified
| PPEConditionKeyEmpty | PPEConditionKeyEmpty
| PPERangeInvalid | PPERangeInvalid
deriving (Eq, Show) deriving stock (Show, Eq)
-- | Set the bucket name that the upload should use. -- | Set the bucket name that the upload should use.
ppCondBucket :: Bucket -> PostPolicyCondition ppCondBucket :: Bucket -> PostPolicyCondition
@ -283,7 +283,7 @@ presignedPostPolicy p = do
signTime <- liftIO $ Time.getCurrentTime signTime <- liftIO $ Time.getCurrentTime
let extraConditions = let extraConditions =
[ PPCEquals "x-amz-date" (toS $ awsTimeFormat signTime), [ PPCEquals "x-amz-date" (toText $ awsTimeFormat signTime),
PPCEquals "x-amz-algorithm" "AWS4-HMAC-SHA256", PPCEquals "x-amz-algorithm" "AWS4-HMAC-SHA256",
PPCEquals PPCEquals
"x-amz-credential" "x-amz-credential"
@ -312,7 +312,7 @@ presignedPostPolicy p = do
mkPair (PPCEquals k v) = Just (k, v) mkPair (PPCEquals k v) = Just (k, v)
mkPair _ = Nothing mkPair _ = Nothing
formFromPolicy = formFromPolicy =
H.map toUtf8 $ H.map encodeUtf8 $
H.fromList $ H.fromList $
catMaybes $ catMaybes $
mkPair <$> conditions ppWithCreds mkPair <$> conditions ppWithCreds

View File

@ -77,7 +77,7 @@ putObjectInternal b o opts (ODStream src sizeMay) = do
| otherwise -> sequentialMultipartUpload b o opts (Just size) src | otherwise -> sequentialMultipartUpload b o opts (Just size) src
putObjectInternal b o opts (ODFile fp sizeMay) = do putObjectInternal b o opts (ODFile fp sizeMay) = do
hResE <- withNewHandle fp $ \h -> hResE <- withNewHandle fp $ \h ->
liftM2 (,) (isHandleSeekable h) (getFileSize h) liftA2 (,) (isHandleSeekable h) (getFileSize h)
(isSeekable, handleSizeMay) <- (isSeekable, handleSizeMay) <-
either either

View File

@ -380,7 +380,7 @@ putObjectPart bucket object uploadId partNumber headers payload = do
srcInfoToHeaders :: SourceInfo -> [HT.Header] srcInfoToHeaders :: SourceInfo -> [HT.Header]
srcInfoToHeaders srcInfo = srcInfoToHeaders srcInfo =
( "x-amz-copy-source", ( "x-amz-copy-source",
toUtf8 $ encodeUtf8 $
T.concat T.concat
[ "/", [ "/",
srcBucket srcInfo, srcBucket srcInfo,

View File

@ -111,7 +111,7 @@ data EventStreamException
| ESEInvalidHeaderType | ESEInvalidHeaderType
| ESEInvalidHeaderValueType | ESEInvalidHeaderValueType
| ESEInvalidMessageType | ESEInvalidMessageType
deriving (Eq, Show) deriving stock (Eq, Show)
instance Exception EventStreamException instance Exception EventStreamException
@ -219,7 +219,7 @@ handleMessage = do
hs <- parseHeaders hdrLen hs <- parseHeaders hdrLen
let payloadLen = msgLen - hdrLen - 16 let payloadLen = msgLen - hdrLen - 16
getHdrVal h = fmap snd . headMay . filter ((h ==) . fst) getHdrVal h = fmap snd . find ((h ==) . fst)
eventHdrValue = getHdrVal EventType hs eventHdrValue = getHdrVal EventType hs
msgHdrValue = getHdrVal MessageType hs msgHdrValue = getHdrVal MessageType hs
errCode = getHdrVal ErrorCode hs errCode = getHdrVal ErrorCode hs

View File

@ -58,7 +58,7 @@ data SignV4Data = SignV4Data
sv4StringToSign :: ByteString, sv4StringToSign :: ByteString,
sv4SigningKey :: ByteString sv4SigningKey :: ByteString
} }
deriving (Show) deriving stock (Show)
data SignParams = SignParams data SignParams = SignParams
{ spAccessKey :: Text, { spAccessKey :: Text,
@ -68,7 +68,7 @@ data SignParams = SignParams
spExpirySecs :: Maybe UrlExpiry, spExpirySecs :: Maybe UrlExpiry,
spPayloadHash :: Maybe ByteString spPayloadHash :: Maybe ByteString
} }
deriving (Show) deriving stock (Show)
debugPrintSignV4Data :: SignV4Data -> IO () debugPrintSignV4Data :: SignV4Data -> IO ()
debugPrintSignV4Data (SignV4Data t s cr h2s o sts sk) = do debugPrintSignV4Data (SignV4Data t s cr h2s o sts sk) = do
@ -92,7 +92,7 @@ mkAuthHeader accessKey scope signedHeaderKeys sign =
let authValue = let authValue =
B.concat B.concat
[ "AWS4-HMAC-SHA256 Credential=", [ "AWS4-HMAC-SHA256 Credential=",
toUtf8 accessKey, encodeUtf8 accessKey,
"/", "/",
scope, scope,
", SignedHeaders=", ", SignedHeaders=",
@ -119,8 +119,8 @@ signV4 !sp !req =
let region = fromMaybe "" $ spRegion sp let region = fromMaybe "" $ spRegion sp
ts = spTimeStamp sp ts = spTimeStamp sp
scope = mkScope ts region scope = mkScope ts region
accessKey = toUtf8 $ spAccessKey sp accessKey = encodeUtf8 $ spAccessKey sp
secretKey = toUtf8 $ spSecretKey sp secretKey = encodeUtf8 $ spSecretKey sp
expiry = spExpirySecs sp expiry = spExpirySecs sp
sha256Hdr = sha256Hdr =
( "x-amz-content-sha256", ( "x-amz-content-sha256",
@ -179,8 +179,8 @@ mkScope :: UTCTime -> Text -> ByteString
mkScope ts region = mkScope ts region =
B.intercalate B.intercalate
"/" "/"
[ toUtf8 $ Time.formatTime Time.defaultTimeLocale "%Y%m%d" ts, [ encodeUtf8 $ Time.formatTime Time.defaultTimeLocale "%Y%m%d" ts,
toUtf8 region, encodeUtf8 region,
"s3", "s3",
"aws4_request" "aws4_request"
] ]
@ -239,7 +239,7 @@ mkSigningKey :: UTCTime -> Text -> ByteString -> ByteString
mkSigningKey ts region !secretKey = mkSigningKey ts region !secretKey =
hmacSHA256RawBS "aws4_request" hmacSHA256RawBS "aws4_request"
. hmacSHA256RawBS "s3" . hmacSHA256RawBS "s3"
. hmacSHA256RawBS (toUtf8 region) . hmacSHA256RawBS (encodeUtf8 region)
. hmacSHA256RawBS (awsDateFormatBS ts) . hmacSHA256RawBS (awsDateFormatBS ts)
$ B.concat ["AWS4", secretKey] $ B.concat ["AWS4", secretKey]
@ -256,7 +256,7 @@ signV4PostPolicy ::
signV4PostPolicy !postPolicyJSON !sp = signV4PostPolicy !postPolicyJSON !sp =
let stringToSign = Base64.encode postPolicyJSON let stringToSign = Base64.encode postPolicyJSON
region = fromMaybe "" $ spRegion sp region = fromMaybe "" $ spRegion sp
signingKey = mkSigningKey (spTimeStamp sp) region $ toUtf8 $ spSecretKey sp signingKey = mkSigningKey (spTimeStamp sp) region $ encodeUtf8 $ spSecretKey sp
signature = computeSignature stringToSign signingKey signature = computeSignature stringToSign signingKey
in Map.fromList in Map.fromList
[ ("x-amz-signature", signature), [ ("x-amz-signature", signature),
@ -294,7 +294,7 @@ signV4Stream ::
signV4Stream !payloadLength !sp !req = signV4Stream !payloadLength !sp !req =
let ts = spTimeStamp sp let ts = spTimeStamp sp
addContentEncoding hs = addContentEncoding hs =
let ceMay = headMay $ filter (\(x, _) -> x == "content-encoding") hs let ceMay = find (\(x, _) -> x == "content-encoding") hs
in case ceMay of in case ceMay of
Nothing -> ("content-encoding", "aws-chunked") : hs Nothing -> ("content-encoding", "aws-chunked") : hs
Just (_, ce) -> Just (_, ce) ->
@ -332,7 +332,7 @@ signV4Stream !payloadLength !sp !req =
stringToSign = mkStringToSign ts scope canonicalReq stringToSign = mkStringToSign ts scope canonicalReq
-- 1.3 Compute signature -- 1.3 Compute signature
-- 1.3.1 compute signing key -- 1.3.1 compute signing key
signingKey = mkSigningKey ts region $ toUtf8 secretKey signingKey = mkSigningKey ts region $ encodeUtf8 secretKey
-- 1.3.2 Compute signature -- 1.3.2 Compute signature
seedSignature = computeSignature stringToSign signingKey seedSignature = computeSignature stringToSign signingKey
-- 1.3.3 Compute Auth Header -- 1.3.3 Compute Auth Header

View File

@ -52,7 +52,7 @@ allocateReadFile ::
m (R.ReleaseKey, Handle) m (R.ReleaseKey, Handle)
allocateReadFile fp = do allocateReadFile fp = do
(rk, hdlE) <- R.allocate (openReadFile fp) cleanup (rk, hdlE) <- R.allocate (openReadFile fp) cleanup
either (\(e :: IOException) -> throwIO e) (return . (rk,)) hdlE either (\(e :: U.IOException) -> throwIO e) (return . (rk,)) hdlE
where where
openReadFile f = U.try $ IO.openBinaryFile f IO.ReadMode openReadFile f = U.try $ IO.openBinaryFile f IO.ReadMode
cleanup = either (const $ return ()) IO.hClose cleanup = either (const $ return ()) IO.hClose
@ -60,25 +60,25 @@ allocateReadFile fp = do
-- | Queries the file size from the handle. Catches any file operation -- | Queries the file size from the handle. Catches any file operation
-- exceptions and returns Nothing instead. -- exceptions and returns Nothing instead.
getFileSize :: getFileSize ::
(MonadUnliftIO m, R.MonadResource m) => (MonadUnliftIO m) =>
Handle -> Handle ->
m (Maybe Int64) m (Maybe Int64)
getFileSize h = do getFileSize h = do
resE <- liftIO $ try $ fromIntegral <$> IO.hFileSize h resE <- liftIO $ try $ fromIntegral <$> IO.hFileSize h
case resE of case resE of
Left (_ :: IOException) -> return Nothing Left (_ :: U.IOException) -> return Nothing
Right s -> return $ Just s Right s -> return $ Just s
-- | Queries if handle is seekable. Catches any file operation -- | Queries if handle is seekable. Catches any file operation
-- exceptions and return False instead. -- exceptions and return False instead.
isHandleSeekable :: isHandleSeekable ::
(R.MonadResource m, MonadUnliftIO m) => (R.MonadResource m) =>
Handle -> Handle ->
m Bool m Bool
isHandleSeekable h = do isHandleSeekable h = do
resE <- liftIO $ try $ IO.hIsSeekable h resE <- liftIO $ try $ IO.hIsSeekable h
case resE of case resE of
Left (_ :: IOException) -> return False Left (_ :: U.IOException) -> return False
Right v -> return v Right v -> return v
-- | Helper function that opens a handle to the filepath and performs -- | Helper function that opens a handle to the filepath and performs
@ -89,7 +89,7 @@ withNewHandle ::
(MonadUnliftIO m, R.MonadResource m) => (MonadUnliftIO m, R.MonadResource m) =>
FilePath -> FilePath ->
(Handle -> m a) -> (Handle -> m a) ->
m (Either IOException a) m (Either U.IOException a)
withNewHandle fp fileAction = do withNewHandle fp fileAction = do
-- opening a handle can throw MError exception. -- opening a handle can throw MError exception.
handleE <- try $ allocateReadFile fp handleE <- try $ allocateReadFile fp
@ -106,7 +106,7 @@ mkHeaderFromPairs :: [(ByteString, ByteString)] -> [HT.Header]
mkHeaderFromPairs = map ((\(x, y) -> (mk x, y))) mkHeaderFromPairs = map ((\(x, y) -> (mk x, y)))
lookupHeader :: HT.HeaderName -> [HT.Header] -> Maybe ByteString lookupHeader :: HT.HeaderName -> [HT.Header] -> Maybe ByteString
lookupHeader hdr = headMay . map snd . filter (\(h, _) -> h == hdr) lookupHeader hdr = listToMaybe . map snd . filter (\(h, _) -> h == hdr)
getETagHeader :: [HT.Header] -> Maybe Text getETagHeader :: [HT.Header] -> Maybe Text
getETagHeader hs = decodeUtf8Lenient <$> lookupHeader Hdr.hETag hs getETagHeader hs = decodeUtf8Lenient <$> lookupHeader Hdr.hETag hs
@ -143,7 +143,7 @@ getLastModifiedHeader hs = do
getContentLength :: [HT.Header] -> Maybe Int64 getContentLength :: [HT.Header] -> Maybe Int64
getContentLength hs = do getContentLength hs = do
nbs <- decodeUtf8Lenient <$> lookupHeader Hdr.hContentLength hs nbs <- decodeUtf8Lenient <$> lookupHeader Hdr.hContentLength hs
fst <$> hush (decimal nbs) fst <$> either (const Nothing) Just (decimal nbs)
decodeUtf8Lenient :: ByteString -> Text decodeUtf8Lenient :: ByteString -> Text
decodeUtf8Lenient = decodeUtf8With lenientDecode decodeUtf8Lenient = decodeUtf8With lenientDecode
@ -280,7 +280,7 @@ selectPartSizes size =
fromIntegral size fromIntegral size
/ fromIntegral maxMultipartParts / fromIntegral maxMultipartParts
) )
m = fromIntegral partSize m = partSize
loop st sz loop st sz
| st > sz = [] | st > sz = []
| st + m >= sz = [(st, sz - st)] | st + m >= sz = [(st, sz - st)]

View File

@ -24,7 +24,6 @@ where
import qualified Data.ByteString.Lazy as LBS import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text as T import qualified Data.Text as T
import Lib.Prelude
import Network.Minio.Data import Network.Minio.Data
import Text.XML import Text.XML
@ -72,7 +71,7 @@ mkCompleteMultipartUploadRequest partInfo =
data XNode data XNode
= XNode Text [XNode] = XNode Text [XNode]
| XLeaf Text Text | XLeaf Text Text
deriving (Eq, Show) deriving stock (Eq, Show)
toXML :: Text -> XNode -> ByteString toXML :: Text -> XNode -> ByteString
toXML ns node = toXML ns node =
@ -94,7 +93,7 @@ class ToXNode a where
toXNode :: a -> XNode toXNode :: a -> XNode
instance ToXNode Event where instance ToXNode Event where
toXNode = XLeaf "Event" . show toXNode = XLeaf "Event" . toText
instance ToXNode Notification where instance ToXNode Notification where
toXNode (Notification qc tc lc) = toXNode (Notification qc tc lc) =
@ -104,9 +103,9 @@ instance ToXNode Notification where
++ map (toXNodesWithArnName "CloudFunctionConfiguration" "CloudFunction") lc ++ map (toXNodesWithArnName "CloudFunctionConfiguration" "CloudFunction") lc
toXNodesWithArnName :: Text -> Text -> NotificationConfig -> XNode toXNodesWithArnName :: Text -> Text -> NotificationConfig -> XNode
toXNodesWithArnName eltName arnName (NotificationConfig id arn events fRule) = toXNodesWithArnName eltName arnName (NotificationConfig itemId arn events fRule) =
XNode eltName $ XNode eltName $
[XLeaf "Id" id, XLeaf arnName arn] ++ map toXNode events [XLeaf "Id" itemId, XLeaf arnName arn] ++ map toXNode events
++ [toXNode fRule] ++ [toXNode fRule]
instance ToXNode Filter where instance ToXNode Filter where

View File

@ -32,7 +32,7 @@ where
import qualified Data.ByteString.Lazy as LB import qualified Data.ByteString.Lazy as LB
import qualified Data.HashMap.Strict as H import qualified Data.HashMap.Strict as H
import Data.List (zip3, zip4, zip6) import Data.List (zip4, zip6)
import qualified Data.Text as T import qualified Data.Text as T
import Data.Text.Read (decimal) import Data.Text.Read (decimal)
import Data.Time import Data.Time
@ -132,7 +132,7 @@ parseListObjectsV1Response xmldata = do
ns <- asks getSvcNamespace ns <- asks getSvcNamespace
let s3Elem' = s3Elem ns let s3Elem' = s3Elem ns
hasMore = ["true"] == (r $/ s3Elem' "IsTruncated" &/ content) hasMore = ["true"] == (r $/ s3Elem' "IsTruncated" &/ content)
nextMarker = headMay $ r $/ s3Elem' "NextMarker" &/ content nextMarker = listToMaybe $ r $/ s3Elem' "NextMarker" &/ content
prefixes = r $/ s3Elem' "CommonPrefixes" &/ s3Elem' "Prefix" &/ content prefixes = r $/ s3Elem' "CommonPrefixes" &/ s3Elem' "Prefix" &/ content
keys = r $/ s3Elem' "Contents" &/ s3Elem' "Key" &/ content keys = r $/ s3Elem' "Contents" &/ s3Elem' "Key" &/ content
modTimeStr = r $/ s3Elem' "Contents" &/ s3Elem' "LastModified" &/ content modTimeStr = r $/ s3Elem' "Contents" &/ s3Elem' "LastModified" &/ content
@ -158,7 +158,7 @@ parseListObjectsResponse xmldata = do
ns <- asks getSvcNamespace ns <- asks getSvcNamespace
let s3Elem' = s3Elem ns let s3Elem' = s3Elem ns
hasMore = ["true"] == (r $/ s3Elem' "IsTruncated" &/ content) hasMore = ["true"] == (r $/ s3Elem' "IsTruncated" &/ content)
nextToken = headMay $ r $/ s3Elem' "NextContinuationToken" &/ content nextToken = listToMaybe $ r $/ s3Elem' "NextContinuationToken" &/ content
prefixes = r $/ s3Elem' "CommonPrefixes" &/ s3Elem' "Prefix" &/ content prefixes = r $/ s3Elem' "CommonPrefixes" &/ s3Elem' "Prefix" &/ content
keys = r $/ s3Elem' "Contents" &/ s3Elem' "Key" &/ content keys = r $/ s3Elem' "Contents" &/ s3Elem' "Key" &/ content
modTimeStr = r $/ s3Elem' "Contents" &/ s3Elem' "LastModified" &/ content modTimeStr = r $/ s3Elem' "Contents" &/ s3Elem' "LastModified" &/ content
@ -185,8 +185,8 @@ parseListUploadsResponse xmldata = do
let s3Elem' = s3Elem ns let s3Elem' = s3Elem ns
hasMore = ["true"] == (r $/ s3Elem' "IsTruncated" &/ content) hasMore = ["true"] == (r $/ s3Elem' "IsTruncated" &/ content)
prefixes = r $/ s3Elem' "CommonPrefixes" &/ s3Elem' "Prefix" &/ content prefixes = r $/ s3Elem' "CommonPrefixes" &/ s3Elem' "Prefix" &/ content
nextKey = headMay $ r $/ s3Elem' "NextKeyMarker" &/ content nextKey = listToMaybe $ r $/ s3Elem' "NextKeyMarker" &/ content
nextUpload = headMay $ r $/ s3Elem' "NextUploadIdMarker" &/ content nextUpload = listToMaybe $ r $/ s3Elem' "NextUploadIdMarker" &/ content
uploadKeys = r $/ s3Elem' "Upload" &/ s3Elem' "Key" &/ content uploadKeys = r $/ s3Elem' "Upload" &/ s3Elem' "Key" &/ content
uploadIds = r $/ s3Elem' "Upload" &/ s3Elem' "UploadId" &/ content uploadIds = r $/ s3Elem' "Upload" &/ s3Elem' "UploadId" &/ content
uploadInitTimeStr = r $/ s3Elem' "Upload" &/ s3Elem' "Initiated" &/ content uploadInitTimeStr = r $/ s3Elem' "Upload" &/ s3Elem' "Initiated" &/ content
@ -203,7 +203,7 @@ parseListPartsResponse xmldata = do
ns <- asks getSvcNamespace ns <- asks getSvcNamespace
let s3Elem' = s3Elem ns let s3Elem' = s3Elem ns
hasMore = ["true"] == (r $/ s3Elem' "IsTruncated" &/ content) hasMore = ["true"] == (r $/ s3Elem' "IsTruncated" &/ content)
nextPartNumStr = headMay $ r $/ s3Elem' "NextPartNumberMarker" &/ content nextPartNumStr = listToMaybe $ r $/ s3Elem' "NextPartNumberMarker" &/ content
partNumberStr = r $/ s3Elem' "Part" &/ s3Elem' "PartNumber" &/ content partNumberStr = r $/ s3Elem' "Part" &/ s3Elem' "PartNumber" &/ content
partModTimeStr = r $/ s3Elem' "Part" &/ s3Elem' "LastModified" &/ content partModTimeStr = r $/ s3Elem' "Part" &/ s3Elem' "LastModified" &/ content
partETags = r $/ s3Elem' "Part" &/ s3Elem' "ETag" &/ content partETags = r $/ s3Elem' "Part" &/ s3Elem' "ETag" &/ content
@ -245,7 +245,7 @@ parseNotification xmldata = do
in FilterRule name value in FilterRule name value
parseNode ns arnName nodeData = do parseNode ns arnName nodeData = do
let c = fromNode nodeData let c = fromNode nodeData
id = T.concat $ c $/ s3Elem ns "Id" &/ content itemId = T.concat $ c $/ s3Elem ns "Id" &/ content
arn = T.concat $ c $/ s3Elem ns arnName &/ content arn = T.concat $ c $/ s3Elem ns arnName &/ content
events = catMaybes $ map textToEvent $ c $/ s3Elem ns "Event" &/ content events = catMaybes $ map textToEvent $ c $/ s3Elem ns "Event" &/ content
rules = rules =
@ -253,7 +253,7 @@ parseNotification xmldata = do
&/ s3Elem ns "FilterRule" &| getFilterRule ns &/ s3Elem ns "FilterRule" &| getFilterRule ns
return $ return $
NotificationConfig NotificationConfig
id itemId
arn arn
events events
(Filter $ FilterKey $ FilterRules rules) (Filter $ FilterKey $ FilterRules rules)

View File

@ -15,7 +15,7 @@
# resolver: # resolver:
# name: custom-snapshot # name: custom-snapshot
# location: "./custom-snapshot.yaml" # location: "./custom-snapshot.yaml"
resolver: lts-16.0 resolver: lts-18.24
# User packages to be built. # User packages to be built.
# Various formats can be used as shown in the example below. # Various formats can be used as shown in the example below.
@ -39,9 +39,7 @@ packages:
- '.' - '.'
# Dependency packages to be pulled from upstream that are not in the resolver # Dependency packages to be pulled from upstream that are not in the resolver
# (e.g., acme-missiles-0.3) # (e.g., acme-missiles-0.3)
extra-deps: extra-deps: []
- unliftio-core-0.2.0.1
- protolude-0.3.0
# Override default flag values for local packages and extra-deps # Override default flag values for local packages and extra-deps
flags: {} flags: {}

View File

@ -3,24 +3,10 @@
# For more information, please see the documentation at: # For more information, please see the documentation at:
# https://docs.haskellstack.org/en/stable/lock_files # https://docs.haskellstack.org/en/stable/lock_files
packages: packages: []
- completed:
hackage: unliftio-core-0.2.0.1@sha256:9b3e44ea9aacacbfc35b3b54015af450091916ac3618a41868ebf6546977659a,1082
pantry-tree:
size: 328
sha256: e81c5a1e82ec2cd68cbbbec9cd60567363abe02257fa1370a906f6754b6818b8
original:
hackage: unliftio-core-0.2.0.1
- completed:
hackage: protolude-0.3.0@sha256:8361b811b420585b122a7ba715aa5923834db6e8c36309bf267df2dbf66b95ef,2693
pantry-tree:
size: 1644
sha256: babf32b414f25f790b7a4ce6bae5c960bc51a11a289e7c47335b222e6762560c
original:
hackage: protolude-0.3.0
snapshots: snapshots:
- completed: - completed:
size: 531237 size: 587821
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/16/0.yaml url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/18/24.yaml
sha256: 210e15b7043e2783115afe16b0d54914b1611cdaa73f3ca3ca7f8e0847ff54e5 sha256: 06d844ba51e49907bd29cb58b4a5f86ee7587a4cd7e6cf395eeec16cba619ce8
original: lts-16.0 original: lts-18.24

View File

@ -37,7 +37,7 @@ import Network.Minio.Data.Crypto
import Network.Minio.S3API import Network.Minio.S3API
import Network.Minio.Utils import Network.Minio.Utils
import System.Directory (getTemporaryDirectory) import System.Directory (getTemporaryDirectory)
import System.Environment (lookupEnv) import qualified System.Environment as Env
import qualified Test.QuickCheck as Q import qualified Test.QuickCheck as Q
import Test.Tasty import Test.Tasty
import Test.Tasty.HUnit import Test.Tasty.HUnit
@ -79,8 +79,8 @@ funTestBucketPrefix = "miniohstest-"
loadTestServer :: IO ConnectInfo loadTestServer :: IO ConnectInfo
loadTestServer = do loadTestServer = do
val <- lookupEnv "MINIO_LOCAL" val <- Env.lookupEnv "MINIO_LOCAL"
isSecure <- lookupEnv "MINIO_SECURE" isSecure <- Env.lookupEnv "MINIO_SECURE"
return $ case (val, isSecure) of return $ case (val, isSecure) of
(Just _, Just _) -> setCreds (Credentials "minio" "minio123") "https://localhost:9000" (Just _, Just _) -> setCreds (Credentials "minio" "minio123") "https://localhost:9000"
(Just _, Nothing) -> setCreds (Credentials "minio" "minio123") "http://localhost:9000" (Just _, Nothing) -> setCreds (Credentials "minio" "minio123") "http://localhost:9000"
@ -616,7 +616,7 @@ presignedUrlFunTest = funTestWithBucket "presigned Url tests" $
headUrl <- presignedHeadObjectUrl bucket obj2 3600 [] headUrl <- presignedHeadObjectUrl bucket obj2 3600 []
headResp <- do headResp <- do
let req = NC.parseRequest_ $ toS $ decodeUtf8 headUrl let req = NC.parseRequest_ $ decodeUtf8 headUrl
NC.httpLbs (req {NC.method = HT.methodHead}) mgr NC.httpLbs (req {NC.method = HT.methodHead}) mgr
liftIO $ liftIO $
(NC.responseStatus headResp == HT.status200) (NC.responseStatus headResp == HT.status200)
@ -644,7 +644,7 @@ presignedUrlFunTest = funTestWithBucket "presigned Url tests" $
mapM_ (removeObject bucket) [obj, obj2] mapM_ (removeObject bucket) [obj, obj2]
where where
putR size filePath mgr url = do putR size filePath mgr url = do
let req = NC.parseRequest_ $ toS $ decodeUtf8 url let req = NC.parseRequest_ $ decodeUtf8 url
let req' = let req' =
req req
{ NC.method = HT.methodPut, { NC.method = HT.methodPut,
@ -654,7 +654,7 @@ presignedUrlFunTest = funTestWithBucket "presigned Url tests" $
} }
NC.httpLbs req' mgr NC.httpLbs req' mgr
getR mgr url = do getR mgr url = do
let req = NC.parseRequest_ $ toS $ decodeUtf8 url let req = NC.parseRequest_ $ decodeUtf8 url
NC.httpLbs req mgr NC.httpLbs req mgr
presignedPostPolicyFunTest :: TestTree presignedPostPolicyFunTest :: TestTree
@ -690,7 +690,7 @@ presignedPostPolicyFunTest = funTestWithBucket "Presigned Post Policy tests" $
mapM_ (removeObject bucket) [key] mapM_ (removeObject bucket) [key]
where where
postForm url formData inputFile = do postForm url formData inputFile = do
req <- NC.parseRequest $ toS $ decodeUtf8 url req <- NC.parseRequest $ decodeUtf8 url
let parts = let parts =
map (\(x, y) -> Form.partBS x y) $ map (\(x, y) -> Form.partBS x y) $
H.toList formData H.toList formData
@ -739,13 +739,13 @@ bucketPolicyFunTest = funTestWithBucket "Bucket Policy tests" $
[ proto, [ proto,
getHostAddr connInfo, getHostAddr connInfo,
"/", "/",
toUtf8 bucket, encodeUtf8 bucket,
"/", "/",
toUtf8 obj encodeUtf8 obj
] ]
respE <- respE <-
liftIO $ liftIO $
(fmap (Right . toStrictBS) $ NC.simpleHttp $ toS $ decodeUtf8 url) fmap (Right . toStrictBS) (NC.simpleHttp $ decodeUtf8 url)
`catch` (\(e :: NC.HttpException) -> return $ Left (show e :: Text)) `catch` (\(e :: NC.HttpException) -> return $ Left (show e :: Text))
case respE of case respE of
Left err -> liftIO $ assertFailure $ show err Left err -> liftIO $ assertFailure $ show err

View File

@ -24,7 +24,6 @@ module Network.Minio.API.Test
where where
import Data.Aeson (eitherDecode) import Data.Aeson (eitherDecode)
import Lib.Prelude
import Network.Minio.API import Network.Minio.API
import Network.Minio.AdminAPI import Network.Minio.AdminAPI
import Test.Tasty import Test.Tasty

View File

@ -19,7 +19,6 @@ module Network.Minio.TestHelpers
) )
where where
import Lib.Prelude
import Network.Minio.Data import Network.Minio.Data
newtype TestNS = TestNS {testNamespace :: Text} newtype TestNS = TestNS {testNamespace :: Text}

View File

@ -19,7 +19,6 @@ module Network.Minio.Utils.Test
) )
where where
import Lib.Prelude
import Network.Minio.Utils import Network.Minio.Utils
import Test.Tasty import Test.Tasty
import Test.Tasty.HUnit import Test.Tasty.HUnit

View File

@ -73,10 +73,10 @@ qcProps =
if if
| nparts > 1 -> -- last part can be smaller but > 0 | nparts > 1 -> -- last part can be smaller but > 0
all (>= minPartSize) (take (nparts - 1) sizes) all (>= minPartSize) (take (nparts - 1) sizes)
&& all (\s -> s > 0) (drop (nparts - 1) sizes) && all (> 0) (drop (nparts - 1) sizes)
| nparts == 1 -> -- size may be 0 here. | nparts == 1 -> -- size may be 0 here.
maybe True (\x -> x >= 0 && x <= minPartSize) $ maybe True (\x -> x >= 0 && x <= minPartSize) $
headMay sizes listToMaybe sizes
| otherwise -> False | otherwise -> False
in n < 0 in n < 0
|| ( isPNumsAscendingFrom1 && isOffsetsAsc && isSumSizeOk || ( isPNumsAscendingFrom1 && isOffsetsAsc && isSumSizeOk
@ -89,16 +89,16 @@ qcProps =
-- is last part's snd offset end? -- is last part's snd offset end?
isLastPartOk = maybe False ((end ==) . snd) $ lastMay pairs isLastPartOk = maybe False ((end ==) . snd) $ lastMay pairs
-- is first part's fst offset start -- is first part's fst offset start
isFirstPartOk = maybe False ((start ==) . fst) $ headMay pairs isFirstPartOk = maybe False ((start ==) . fst) $ listToMaybe pairs
-- each pair is >=64MiB except last, and all those parts -- each pair is >=64MiB except last, and all those parts
-- have same size. -- have same size.
initSizes = maybe [] (map (\(a, b) -> b - a + 1)) $ initMay pairs initSizes = maybe [] (map (\(a, b) -> b - a + 1)) $ init <$> nonEmpty pairs
isPartSizesOk = isPartSizesOk =
all (>= minPartSize) initSizes all (>= minPartSize) initSizes
&& maybe && maybe
True True
(\k -> all (== k) initSizes) (\k -> all (== k) initSizes)
(headMay initSizes) (listToMaybe initSizes)
-- returned offsets are contiguous. -- returned offsets are contiguous.
fsts = drop 1 $ map fst pairs fsts = drop 1 $ map fst pairs
snds = take (length pairs - 1) $ map snd pairs snds = take (length pairs - 1) $ map snd pairs