{-# LANGUAGE CPP #-}
module Aws.S3.Commands.PutObject
where
import Aws.Core
import Aws.S3.Core
import Control.Applicative
import Control.Arrow (second)
import qualified Crypto.Hash as CH
import Data.ByteString.Char8 ()
import Data.Maybe
import qualified Data.ByteString.Char8 as B
import qualified Data.CaseInsensitive as CI
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Prelude
import qualified Network.HTTP.Conduit as HTTP
data PutObject = PutObject {
PutObject -> Text
poObjectName :: T.Text,
PutObject -> Text
poBucket :: Bucket,
PutObject -> Maybe ByteString
poContentType :: Maybe B.ByteString,
PutObject -> Maybe Text
poCacheControl :: Maybe T.Text,
PutObject -> Maybe Text
poContentDisposition :: Maybe T.Text,
PutObject -> Maybe Text
poContentEncoding :: Maybe T.Text,
PutObject -> Maybe (Digest MD5)
poContentMD5 :: Maybe (CH.Digest CH.MD5),
PutObject -> Maybe Int
poExpires :: Maybe Int,
PutObject -> Maybe CannedAcl
poAcl :: Maybe CannedAcl,
PutObject -> Maybe StorageClass
poStorageClass :: Maybe StorageClass,
PutObject -> Maybe Text
poWebsiteRedirectLocation :: Maybe T.Text,
PutObject -> Maybe ServerSideEncryption
poServerSideEncryption :: Maybe ServerSideEncryption,
PutObject -> RequestBody
poRequestBody :: HTTP.RequestBody,
PutObject -> [(Text, Text)]
poMetadata :: [(T.Text,T.Text)],
PutObject -> Bool
poAutoMakeBucket :: Bool,
PutObject -> Bool
poExpect100Continue :: Bool
}
putObject :: Bucket -> T.Text -> HTTP.RequestBody -> PutObject
putObject :: Text -> Text -> RequestBody -> PutObject
putObject Text
bucket Text
obj RequestBody
body = Text
-> Text
-> Maybe ByteString
-> Maybe Text
-> Maybe Text
-> Maybe Text
-> Maybe (Digest MD5)
-> Maybe Int
-> Maybe CannedAcl
-> Maybe StorageClass
-> Maybe Text
-> Maybe ServerSideEncryption
-> RequestBody
-> [(Text, Text)]
-> Bool
-> Bool
-> PutObject
PutObject Text
obj Text
bucket Maybe ByteString
forall a. Maybe a
Nothing Maybe Text
forall a. Maybe a
Nothing Maybe Text
forall a. Maybe a
Nothing Maybe Text
forall a. Maybe a
Nothing Maybe (Digest MD5)
forall a. Maybe a
Nothing Maybe Int
forall a. Maybe a
Nothing Maybe CannedAcl
forall a. Maybe a
Nothing Maybe StorageClass
forall a. Maybe a
Nothing Maybe Text
forall a. Maybe a
Nothing Maybe ServerSideEncryption
forall a. Maybe a
Nothing RequestBody
body [] Bool
False Bool
False
data PutObjectResponse
= PutObjectResponse
{ PutObjectResponse -> Maybe Text
porVersionId :: Maybe T.Text
, PutObjectResponse -> Text
porETag :: T.Text
}
deriving (Int -> PutObjectResponse -> ShowS
[PutObjectResponse] -> ShowS
PutObjectResponse -> String
(Int -> PutObjectResponse -> ShowS)
-> (PutObjectResponse -> String)
-> ([PutObjectResponse] -> ShowS)
-> Show PutObjectResponse
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PutObjectResponse -> ShowS
showsPrec :: Int -> PutObjectResponse -> ShowS
$cshow :: PutObjectResponse -> String
show :: PutObjectResponse -> String
$cshowList :: [PutObjectResponse] -> ShowS
showList :: [PutObjectResponse] -> ShowS
Show)
instance SignQuery PutObject where
type ServiceConfiguration PutObject = S3Configuration
signQuery :: forall queryType.
PutObject
-> ServiceConfiguration PutObject queryType
-> SignatureData
-> SignedQuery
signQuery PutObject {Bool
[(Text, Text)]
Maybe Int
Maybe Text
Maybe ByteString
Maybe (Digest MD5)
Maybe ServerSideEncryption
Maybe StorageClass
Maybe CannedAcl
Text
RequestBody
poObjectName :: PutObject -> Text
poBucket :: PutObject -> Text
poContentType :: PutObject -> Maybe ByteString
poCacheControl :: PutObject -> Maybe Text
poContentDisposition :: PutObject -> Maybe Text
poContentEncoding :: PutObject -> Maybe Text
poContentMD5 :: PutObject -> Maybe (Digest MD5)
poExpires :: PutObject -> Maybe Int
poAcl :: PutObject -> Maybe CannedAcl
poStorageClass :: PutObject -> Maybe StorageClass
poWebsiteRedirectLocation :: PutObject -> Maybe Text
poServerSideEncryption :: PutObject -> Maybe ServerSideEncryption
poRequestBody :: PutObject -> RequestBody
poMetadata :: PutObject -> [(Text, Text)]
poAutoMakeBucket :: PutObject -> Bool
poExpect100Continue :: PutObject -> Bool
poObjectName :: Text
poBucket :: Text
poContentType :: Maybe ByteString
poCacheControl :: Maybe Text
poContentDisposition :: Maybe Text
poContentEncoding :: Maybe Text
poContentMD5 :: Maybe (Digest MD5)
poExpires :: Maybe Int
poAcl :: Maybe CannedAcl
poStorageClass :: Maybe StorageClass
poWebsiteRedirectLocation :: Maybe Text
poServerSideEncryption :: Maybe ServerSideEncryption
poRequestBody :: RequestBody
poMetadata :: [(Text, Text)]
poAutoMakeBucket :: Bool
poExpect100Continue :: Bool
..} = S3Query
-> S3Configuration queryType -> SignatureData -> SignedQuery
forall qt.
S3Query -> S3Configuration qt -> SignatureData -> SignedQuery
s3SignQuery S3Query {
s3QMethod :: Method
s3QMethod = Method
Put
, s3QBucket :: Maybe ByteString
s3QBucket = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
T.encodeUtf8 Text
poBucket
, s3QSubresources :: Query
s3QSubresources = []
, s3QQuery :: Query
s3QQuery = []
, s3QContentType :: Maybe ByteString
s3QContentType = Maybe ByteString
poContentType
, s3QContentMd5 :: Maybe (Digest MD5)
s3QContentMd5 = Maybe (Digest MD5)
poContentMD5
, s3QAmzHeaders :: RequestHeaders
s3QAmzHeaders = ((CI ByteString, Text) -> Header)
-> [(CI ByteString, Text)] -> RequestHeaders
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> ByteString) -> (CI ByteString, Text) -> Header
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Text -> ByteString
T.encodeUtf8) ([(CI ByteString, Text)] -> RequestHeaders)
-> [(CI ByteString, Text)] -> RequestHeaders
forall a b. (a -> b) -> a -> b
$ [Maybe (CI ByteString, Text)] -> [(CI ByteString, Text)]
forall a. [Maybe a] -> [a]
catMaybes [
(CI ByteString
"x-amz-acl",) (Text -> (CI ByteString, Text))
-> (CannedAcl -> Text) -> CannedAcl -> (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CannedAcl -> Text
writeCannedAcl (CannedAcl -> (CI ByteString, Text))
-> Maybe CannedAcl -> Maybe (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe CannedAcl
poAcl
, (CI ByteString
"x-amz-storage-class",) (Text -> (CI ByteString, Text))
-> (StorageClass -> Text) -> StorageClass -> (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StorageClass -> Text
writeStorageClass (StorageClass -> (CI ByteString, Text))
-> Maybe StorageClass -> Maybe (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe StorageClass
poStorageClass
, (CI ByteString
"x-amz-website-redirect-location",) (Text -> (CI ByteString, Text))
-> Maybe Text -> Maybe (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
poWebsiteRedirectLocation
, (CI ByteString
"x-amz-server-side-encryption",) (Text -> (CI ByteString, Text))
-> (ServerSideEncryption -> Text)
-> ServerSideEncryption
-> (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ServerSideEncryption -> Text
writeServerSideEncryption (ServerSideEncryption -> (CI ByteString, Text))
-> Maybe ServerSideEncryption -> Maybe (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ServerSideEncryption
poServerSideEncryption
, if Bool
poAutoMakeBucket then (CI ByteString, Text) -> Maybe (CI ByteString, Text)
forall a. a -> Maybe a
Just (CI ByteString
"x-amz-auto-make-bucket", Text
"1") else Maybe (CI ByteString, Text)
forall a. Maybe a
Nothing
] [(CI ByteString, Text)]
-> [(CI ByteString, Text)] -> [(CI ByteString, Text)]
forall a. [a] -> [a] -> [a]
++ ((Text, Text) -> (CI ByteString, Text))
-> [(Text, Text)] -> [(CI ByteString, Text)]
forall a b. (a -> b) -> [a] -> [b]
map( \(Text, Text)
x -> (ByteString -> CI ByteString
forall s. FoldCase s => s -> CI s
CI.mk (ByteString -> CI ByteString)
-> (Text -> ByteString) -> Text -> CI ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8 (Text -> CI ByteString) -> Text -> CI ByteString
forall a b. (a -> b) -> a -> b
$ [Text] -> Text
T.concat [Text
"x-amz-meta-", (Text, Text) -> Text
forall a b. (a, b) -> a
fst (Text, Text)
x], (Text, Text) -> Text
forall a b. (a, b) -> b
snd (Text, Text)
x)) [(Text, Text)]
poMetadata
, s3QOtherHeaders :: RequestHeaders
s3QOtherHeaders = ((CI ByteString, Text) -> Header)
-> [(CI ByteString, Text)] -> RequestHeaders
forall a b. (a -> b) -> [a] -> [b]
map ((Text -> ByteString) -> (CI ByteString, Text) -> Header
forall b c d. (b -> c) -> (d, b) -> (d, c)
forall (a :: * -> * -> *) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second Text -> ByteString
T.encodeUtf8) ([(CI ByteString, Text)] -> RequestHeaders)
-> [(CI ByteString, Text)] -> RequestHeaders
forall a b. (a -> b) -> a -> b
$ [Maybe (CI ByteString, Text)] -> [(CI ByteString, Text)]
forall a. [Maybe a] -> [a]
catMaybes [
(CI ByteString
"Expires",) (Text -> (CI ByteString, Text))
-> (Int -> Text) -> Int -> (CI ByteString, Text)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack (String -> Text) -> (Int -> String) -> Int -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String
forall a. Show a => a -> String
show (Int -> (CI ByteString, Text))
-> Maybe Int -> Maybe (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Int
poExpires
, (CI ByteString
"Cache-Control",) (Text -> (CI ByteString, Text))
-> Maybe Text -> Maybe (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
poCacheControl
, (CI ByteString
"Content-Disposition",) (Text -> (CI ByteString, Text))
-> Maybe Text -> Maybe (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
poContentDisposition
, (CI ByteString
"Content-Encoding",) (Text -> (CI ByteString, Text))
-> Maybe Text -> Maybe (CI ByteString, Text)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Text
poContentEncoding
, if Bool
poExpect100Continue
then (CI ByteString, Text) -> Maybe (CI ByteString, Text)
forall a. a -> Maybe a
Just (CI ByteString
"Expect", Text
"100-continue")
else Maybe (CI ByteString, Text)
forall a. Maybe a
Nothing
]
, s3QRequestBody :: Maybe RequestBody
s3QRequestBody = RequestBody -> Maybe RequestBody
forall a. a -> Maybe a
Just RequestBody
poRequestBody
, s3QObject :: Maybe ByteString
s3QObject = ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just (ByteString -> Maybe ByteString) -> ByteString -> Maybe ByteString
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
T.encodeUtf8 Text
poObjectName
}
instance ResponseConsumer PutObject PutObjectResponse where
type ResponseMetadata PutObjectResponse = S3Metadata
responseConsumer :: Request
-> PutObject
-> IORef (ResponseMetadata PutObjectResponse)
-> HTTPResponseConsumer PutObjectResponse
responseConsumer Request
_ PutObject
_ = HTTPResponseConsumer PutObjectResponse
-> IORef S3Metadata -> HTTPResponseConsumer PutObjectResponse
forall a.
HTTPResponseConsumer a
-> IORef S3Metadata -> HTTPResponseConsumer a
s3ResponseConsumer (HTTPResponseConsumer PutObjectResponse
-> IORef S3Metadata -> HTTPResponseConsumer PutObjectResponse)
-> HTTPResponseConsumer PutObjectResponse
-> IORef S3Metadata
-> HTTPResponseConsumer PutObjectResponse
forall a b. (a -> b) -> a -> b
$ \Response (ConduitM () ByteString (ResourceT IO) ())
resp -> do
let vid :: Maybe Text
vid = ByteString -> Text
T.decodeUtf8 (ByteString -> Text) -> Maybe ByteString -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` CI ByteString -> RequestHeaders -> Maybe ByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup CI ByteString
"x-amz-version-id" (Response (ConduitM () ByteString (ResourceT IO) ())
-> RequestHeaders
forall body. Response body -> RequestHeaders
HTTP.responseHeaders Response (ConduitM () ByteString (ResourceT IO) ())
resp)
let etag :: Text
etag = Text -> Maybe Text -> Text
forall a. a -> Maybe a -> a
fromMaybe Text
"" (Maybe Text -> Text) -> Maybe Text -> Text
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
T.decodeUtf8 (ByteString -> Text) -> Maybe ByteString -> Maybe Text
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` CI ByteString -> RequestHeaders -> Maybe ByteString
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup CI ByteString
"ETag" (Response (ConduitM () ByteString (ResourceT IO) ())
-> RequestHeaders
forall body. Response body -> RequestHeaders
HTTP.responseHeaders Response (ConduitM () ByteString (ResourceT IO) ())
resp)
PutObjectResponse -> ResourceT IO PutObjectResponse
forall a. a -> ResourceT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PutObjectResponse -> ResourceT IO PutObjectResponse)
-> PutObjectResponse -> ResourceT IO PutObjectResponse
forall a b. (a -> b) -> a -> b
$ Maybe Text -> Text -> PutObjectResponse
PutObjectResponse Maybe Text
vid Text
etag
instance Transaction PutObject PutObjectResponse
instance AsMemoryResponse PutObjectResponse where
type MemoryResponse PutObjectResponse = PutObjectResponse
loadToMemory :: PutObjectResponse
-> ResourceT IO (MemoryResponse PutObjectResponse)
loadToMemory = PutObjectResponse
-> ResourceT IO (MemoryResponse PutObjectResponse)
PutObjectResponse -> ResourceT IO PutObjectResponse
forall a. a -> ResourceT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return