@@ -28,6 +28,8 @@ module Network.Minio.S3API
2828 , ListObjectsResult
2929 , listObjects'
3030
31+ -- * Retrieving buckets
32+ , headBucket
3133 -- * Retrieving objects
3234 -----------------------
3335 , getObject'
@@ -64,12 +66,14 @@ module Network.Minio.S3API
6466
6567 ) where
6668
69+import Control.Monad.Catch (catches, Handler(..))
6770import qualified Data.Conduit as C
6871import Data.Default (def)
6972import qualified Network.HTTP.Conduit as NC
7073import qualified Network.HTTP.Types as HT
74+import Network.HTTP.Types.Status (status404)
7175
72−import Lib.Prelude
76+import Lib.Prelude hiding (catches)
7377
7478import Network.Minio.API
7579import Network.Minio.Data
@@ -325,3 +329,30 @@ headObject bucket object = do
325329
326330 maybe (throwM MErrVInvalidObjectInfoResponse) return $
327331 ObjectInfo <$> Just object <*> modTime <*> etag <*> size
332+
333+
334+
335+-- | Query the object store if a given bucket exists.
336+headBucket :: Bucket -> Minio Bool
337+headBucket bucket = headBucketEx `catches`
338+ [ Handler handleNoSuchBucket
339+ , Handler handleStatus404
340+ ]
341+
342+ where
343+ handleNoSuchBucket :: ServiceErr -> Minio Bool
344+ handleNoSuchBucket e | e == NoSuchBucket = return False
345+ | otherwise = throwM e
346+
347+ handleStatus404 :: NC.HttpException -> Minio Bool
348+ handleStatus404 e@(NC.HttpExceptionRequest _ (NC.StatusCodeException res _)) =
349+ if NC.responseStatus res == status404
350+ then return False
351+ else throwM e
352+ handleStatus404 e = throwM e
353+
354+ headBucketEx = do
355+ resp <- executeRequest $ def { riMethod = HT.methodHead
356+ , riBucket = Just bucket
357+ }
358+ return $ (NC.responseStatus resp) == HT.ok200