module Aws.S3.Commands.HeadObject
where

import           Aws.Core
import           Aws.S3.Core
import           Control.Applicative
import           Data.ByteString.Char8 ({- IsString -})
import qualified Data.ByteString.Char8 as B8
import           Data.Maybe
import qualified Data.Text             as T
import qualified Data.Text.Encoding    as T
import           Prelude
import qualified Network.HTTP.Conduit  as HTTP
import qualified Network.HTTP.Types    as HTTP

data HeadObject
    = HeadObject {
        HeadObject -> Bucket
hoBucket :: Bucket
      , HeadObject -> Bucket
hoObjectName :: Object
      , HeadObject -> Maybe Bucket
hoVersionId :: Maybe T.Text
      , HeadObject -> Maybe Bucket
hoIfMatch :: Maybe T.Text
      -- ^ Return the object only if its entity tag (ETag, which is an md5sum of the content) is the same as the one specified; otherwise, catch a 'StatusCodeException' with a status of 412 precondition failed.
      , HeadObject -> Maybe Bucket
hoIfNoneMatch :: Maybe T.Text
      -- ^ Return the object only if its entity tag (ETag, which is an md5sum of the content) is different from the one specified; otherwise, catch a 'StatusCodeException' with a status of 304 not modified.
      }
  deriving (Int -> HeadObject -> ShowS
[HeadObject] -> ShowS
HeadObject -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HeadObject] -> ShowS
$cshowList :: [HeadObject] -> ShowS
show :: HeadObject -> String
$cshow :: HeadObject -> String
showsPrec :: Int -> HeadObject -> ShowS
$cshowsPrec :: Int -> HeadObject -> ShowS
Show)

headObject :: Bucket -> T.Text -> HeadObject
headObject :: Bucket -> Bucket -> HeadObject
headObject Bucket
b Bucket
o = Bucket
-> Bucket
-> Maybe Bucket
-> Maybe Bucket
-> Maybe Bucket
-> HeadObject
HeadObject Bucket
b Bucket
o forall a. Maybe a
Nothing forall a. Maybe a
Nothing forall a. Maybe a
Nothing

data HeadObjectResponse
    = HeadObjectResponse {
        HeadObjectResponse -> Maybe ObjectMetadata
horMetadata :: Maybe ObjectMetadata
      } deriving (Int -> HeadObjectResponse -> ShowS
[HeadObjectResponse] -> ShowS
HeadObjectResponse -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HeadObjectResponse] -> ShowS
$cshowList :: [HeadObjectResponse] -> ShowS
show :: HeadObjectResponse -> String
$cshow :: HeadObjectResponse -> String
showsPrec :: Int -> HeadObjectResponse -> ShowS
$cshowsPrec :: Int -> HeadObjectResponse -> ShowS
Show)

data HeadObjectMemoryResponse
    = HeadObjectMemoryResponse (Maybe ObjectMetadata)
    deriving (Int -> HeadObjectMemoryResponse -> ShowS
[HeadObjectMemoryResponse] -> ShowS
HeadObjectMemoryResponse -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [HeadObjectMemoryResponse] -> ShowS
$cshowList :: [HeadObjectMemoryResponse] -> ShowS
show :: HeadObjectMemoryResponse -> String
$cshow :: HeadObjectMemoryResponse -> String
showsPrec :: Int -> HeadObjectMemoryResponse -> ShowS
$cshowsPrec :: Int -> HeadObjectMemoryResponse -> ShowS
Show)

-- | ServiceConfiguration: 'S3Configuration'
instance SignQuery HeadObject where
    type ServiceConfiguration HeadObject = S3Configuration
    signQuery :: forall queryType.
HeadObject
-> ServiceConfiguration HeadObject queryType
-> SignatureData
-> SignedQuery
signQuery HeadObject {Maybe Bucket
Bucket
hoIfNoneMatch :: Maybe Bucket
hoIfMatch :: Maybe Bucket
hoVersionId :: Maybe Bucket
hoObjectName :: Bucket
hoBucket :: Bucket
hoIfNoneMatch :: HeadObject -> Maybe Bucket
hoIfMatch :: HeadObject -> Maybe Bucket
hoVersionId :: HeadObject -> Maybe Bucket
hoObjectName :: HeadObject -> Bucket
hoBucket :: HeadObject -> Bucket
..} = forall qt.
S3Query -> S3Configuration qt -> SignatureData -> SignedQuery
s3SignQuery S3Query {
                                   s3QMethod :: Method
s3QMethod = Method
Head
                                 , s3QBucket :: Maybe ByteString
s3QBucket = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Bucket -> ByteString
T.encodeUtf8 Bucket
hoBucket
                                 , s3QObject :: Maybe ByteString
s3QObject = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Bucket -> ByteString
T.encodeUtf8 Bucket
hoObjectName
                                 , s3QSubresources :: Query
s3QSubresources = forall a. QueryLike a => a -> Query
HTTP.toQuery [
                                                       (ByteString
"versionId" :: B8.ByteString,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Bucket
hoVersionId
                                                     ]
                                 , s3QQuery :: Query
s3QQuery = []
                                 , s3QContentType :: Maybe ByteString
s3QContentType = forall a. Maybe a
Nothing
                                 , s3QContentMd5 :: Maybe (Digest MD5)
s3QContentMd5 = forall a. Maybe a
Nothing
                                 , s3QAmzHeaders :: RequestHeaders
s3QAmzHeaders = []
                                 , s3QOtherHeaders :: RequestHeaders
s3QOtherHeaders = forall a. [Maybe a] -> [a]
catMaybes [
                                                       (HeaderName
"if-match",) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bucket -> ByteString
T.encodeUtf8 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Bucket
hoIfMatch
                                                     , (HeaderName
"if-none-match",) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bucket -> ByteString
T.encodeUtf8 forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Bucket
hoIfNoneMatch
                                                     ]
                                 , s3QRequestBody :: Maybe RequestBody
s3QRequestBody = forall a. Maybe a
Nothing
                                 }

instance ResponseConsumer HeadObject HeadObjectResponse where
    type ResponseMetadata HeadObjectResponse = S3Metadata
    responseConsumer :: Request
-> HeadObject
-> IORef (ResponseMetadata HeadObjectResponse)
-> HTTPResponseConsumer HeadObjectResponse
responseConsumer Request
httpReq HeadObject{} IORef (ResponseMetadata HeadObjectResponse)
_ Response (ConduitM () ByteString (ResourceT IO) ())
resp
        | Status
status forall a. Eq a => a -> a -> Bool
== Status
HTTP.status200 = Maybe ObjectMetadata -> HeadObjectResponse
HeadObjectResponse forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *).
MonadThrow m =>
RequestHeaders -> m ObjectMetadata
parseObjectMetadata RequestHeaders
headers
        | Status
status forall a. Eq a => a -> a -> Bool
== Status
HTTP.status404 = forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ Maybe ObjectMetadata -> HeadObjectResponse
HeadObjectResponse forall a. Maybe a
Nothing
        | Bool
otherwise = forall (m :: * -> *) a.
MonadThrow m =>
Request -> Response (ConduitM () ByteString m ()) -> m a
throwStatusCodeException Request
httpReq Response (ConduitM () ByteString (ResourceT IO) ())
resp
      where
        status :: Status
status  = forall body. Response body -> Status
HTTP.responseStatus    Response (ConduitM () ByteString (ResourceT IO) ())
resp
        headers :: RequestHeaders
headers = forall body. Response body -> RequestHeaders
HTTP.responseHeaders   Response (ConduitM () ByteString (ResourceT IO) ())
resp

instance Transaction HeadObject HeadObjectResponse

instance AsMemoryResponse HeadObjectResponse where
    type MemoryResponse HeadObjectResponse = HeadObjectMemoryResponse
    loadToMemory :: HeadObjectResponse
-> ResourceT IO (MemoryResponse HeadObjectResponse)
loadToMemory (HeadObjectResponse Maybe ObjectMetadata
om) = forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ObjectMetadata -> HeadObjectMemoryResponse
HeadObjectMemoryResponse Maybe ObjectMetadata
om)