@@ -20,15 +20,15 @@ awsCI { connectAccesskey = "your-access-key"
2020
2121```
2222
23−|Bucket operations|Object Operations|
24−|:---|:---|
25−|[`listBuckets`](#listBuckets) |[`getObject`](#getObject)|
26−|[`makeBucket`](#makeBucket)|[`putObject`](#putObject)|
27−|[`removeBucket`](#removeBucket)|[`fGetObject`](#fGetObject)|
28−|[`listObjects`](#listObjects)|[`fPutObject`](#fPutObject)|
29−|[`listObjectsV1`](#listObjectsV1)|[`copyObject`](#copyObject)|
30−|[`listIncompleteUploads`](#listIncompleteUploads)|[`removeObject`](#removeObject)|
31−|[`bucketExists`](#bucketExists)||
23+|Bucket operations|Object Operations|Presigned Operations|
24+|:---|:---|:---|
25+|[`listBuckets`](#listBuckets) |[`getObject`](#getObject)|[`presignedGetObjectUrl`](#presignedGetObjectUrl)|
26+|[`makeBucket`](#makeBucket)|[`putObject`](#putObject)|[`presignedPutObjectUrl`](#presignedPutObjectUrl)|
27+|[`removeBucket`](#removeBucket)|[`fGetObject`](#fGetObject)|[`presignedPostPolicy`](#presignedPostPolicy)|
28+|[`listObjects`](#listObjects)|[`fPutObject`](#fPutObject)||
29+|[`listObjectsV1`](#listObjectsV1)|[`copyObject`](#copyObject)||
30+|[`listIncompleteUploads`](#listIncompleteUploads)|[`removeObject`](#removeObject)||
31+|[`bucketExists`](#bucketExists)|||
3232
3333## 1. Connecting and running operations on the storage service
3434
@@ -685,9 +685,216 @@ In the expression `bucketExists bucketName` the parameters are:
685685| `bucketName` | _Bucket_ (alias for `Text`) | Name of the bucket |
686686
687687
688−<!-- ## 4. Presigned operations -->
688+## 4. Presigned operations
689689
690−<!-- TODO -->
690+<a name="presignedGetObjectUrl"></a>
691+### presignedGetObjectUrl :: Bucket -> Object -> UrlExpiry -> Query -> RequestHeaders -> Minio ByteString
692+
693+Generate a URL with authentication signature to GET (download) an
694+object. All extra query parameters and headers passed here will be
695+signed and are required when the generated URL is used. Query
696+parameters could be used to change the response headers sent by the
697+server. Headers can be used to set Etag match conditions among others.
698+
699+For a list of possible request parameters and headers, please refer
700+to the GET object REST API AWS S3 documentation.
701+
702+__Parameters__
703+
704+In the expression `presignedGetObjectUrl bucketName objectName expiry queryParams headers`
705+the parameters are:
706+
707+|Param |Type |Description |
708+|:---|:---| :---|
709+| `bucketName` | _Bucket_ (alias for `Text`) | Name of the bucket |
710+| `objectName` | _Object_ (alias for `Text`) | Name of the object |
711+| `expiry` | _UrlExpiry_ (alias for `Int`) | Url expiry time in seconds |
712+| `queryParams` | _Query_ (from package `http-types:Network.HTTP.Types`) | Query parameters to add to the URL |
713+| `headers` | _RequestHeaders_ (from package `http-types:Network.HTTP.Types` | Request headers that would be used with the URL |
714+
715+__Return Value__
716+
717+Returns the generated URL - it will include authentication
718+information.
719+
720+|Return type |Description |
721+|:---|:---|
722+| _ByteString_ | Generated presigned URL |
723+
724+__Example__
725+
726+```haskell
727+{-# Language OverloadedStrings #-}
728+
729+import Network.Minio
730+import qualified Data.ByteString.Char8 as B
731+
732+main :: IO ()
733+main = do
734+ let
735+ bucket = "mybucket"
736+ object = "myobject"
737+
738+ res <- runMinio minioPlayCI $ do
739+ -- Set a 7 day expiry for the URL
740+ presignedGetObjectUrl bucket object (7*24*3600) [] []
741+
742+ -- Print the URL on success.
743+ putStrLn $ either
744+ (("Failed to generate URL: " ++) . show)
745+ B.unpack
746+ res
747+```
748+
749+<a name="presignedPutObjectUrl"></a>
750+### presignedPutObjectUrl :: Bucket -> Object -> UrlExpiry -> RequestHeaders -> Minio ByteString
751+
752+Generate a URL with authentication signature to PUT (upload) an
753+object. Any extra headers if passed, are signed, and so they are
754+required when the URL is used to upload data. This could be used, for
755+example, to set user-metadata on the object.
756+
757+For a list of possible headers to pass, please refer to the PUT object
758+REST API AWS S3 documentation.
759+
760+__Parameters__
761+
762+In the expression `presignedPutObjectUrl bucketName objectName expiry headers`
763+the parameters are:
764+
765+|Param |Type |Description |
766+|:---|:---| :---|
767+| `bucketName` | _Bucket_ (alias for `Text`) | Name of the bucket |
768+| `objectName` | _Object_ (alias for `Text`) | Name of the object |
769+| `expiry` | _UrlExpiry_ (alias for `Int`) | Url expiry time in seconds |
770+| `headers` | _RequestHeaders_ (from package `http-types:Network.HTTP.Types` | Request headers that would be used with the URL |
771+
772+__Return Value__
773+
774+Returns the generated URL - it will include authentication
775+information.
776+
777+|Return type |Description |
778+|:---|:---|
779+| _ByteString_ | Generated presigned URL |
780+
781+__Example__
782+
783+```haskell
784+{-# Language OverloadedStrings #-}
785+
786+import Network.Minio
787+import qualified Data.ByteString.Char8 as B
788+
789+main :: IO ()
790+main = do
791+ let
792+ bucket = "mybucket"
793+ object = "myobject"
794+
795+ res <- runMinio minioPlayCI $ do
796+ -- Set a 7 day expiry for the URL
797+ presignedPutObjectUrl bucket object (7*24*3600) [] []
798+
799+ -- Print the URL on success.
800+ putStrLn $ either
801+ (("Failed to generate URL: " ++) . show)
802+ B.unpack
803+ res
804+```
805+
806+<a name="presignedPostPolicy"></a>
807+### presignedPostPolicy :: PostPolicy -> Minio (ByteString, Map.Map Text ByteString)
808+
809+Generate a presigned URL and POST policy to upload files via a POST
810+request. This is intended for browser uploads and generates form data
811+that should be submitted in the request.
812+
813+The `PostPolicy` argument is created using the `newPostPolicy` function:
814+
815+#### newPostPolicy :: UTCTime -> [PostPolicyCondition] -> Either PostPolicyError PostPolicy
816+
817+In the expression `newPostPolicy expirationTime conditions` the parameters are:
818+
819+|Param | Type| Description |
820+|:---|:---|:---|
821+| `expirationTime` | _UTCTime_ (from package `time:Data.Time.UTCTime`) | The expiration time for the policy |
822+| `conditions` | _[PostPolicyConditions]_ | List of conditions to be added to the policy |
823+
824+The policy conditions are created using various helper functions -
825+please refer to the Haddocks for details.
826+
827+Since conditions are validated by `newPostPolicy` it returns an
828+`Either` value.
829+
830+__Return Value__
831+
832+`presignedPostPolicy` returns a 2-tuple - the generated URL and a map
833+containing the form-data that should be submitted with the request.
834+
835+__Example__
836+
837+```haskell
838+{-# Language OverloadedStrings #-}
839+
840+import Network.Minio
841+
842+import qualified Data.ByteString as B
843+import qualified Data.ByteString.Char8 as Char8
844+import qualified Data.Map.Strict as Map
845+import qualified Data.Text.Encoding as Enc
846+import qualified Data.Time as Time
847+
848+main :: IO ()
849+main = do
850+ now <- Time.getCurrentTime
851+ let
852+ bucket = "mybucket"
853+ object = "myobject"
854+
855+ -- set an expiration time of 10 days
856+ expireTime = Time.addUTCTime (3600 * 24 * 10) now
857+
858+ -- create a policy with expiration time and conditions - since the
859+ -- conditions are validated, newPostPolicy returns an Either value
860+ policyE = newPostPolicy expireTime
861+ [ -- set the object name condition
862+ ppCondKey "photos/my-object"
863+ -- set the bucket name condition
864+ , ppCondBucket "my-bucket"
865+ -- set the size range of object as 1B to 10MiB
866+ , ppCondContentLengthRange 1 (10*1024*1024)
867+ -- set content type as jpg image
868+ , ppCondContentType "image/jpeg"
869+ -- on success set the server response code to 200
870+ , ppCondSuccessActionStatus 200
871+ ]
872+
873+ case policyE of
874+ Left err -> putStrLn $ show err
875+ Right policy -> do
876+ res <- runMinio minioPlayCI $ do
877+ (url, formData) <- presignedPostPolicy policy
878+
879+ -- a curl command is output to demonstrate using the generated
880+ -- URL and form-data
881+ let
882+ formFn (k, v) = B.concat ["-F ", Enc.encodeUtf8 k, "=",
883+ "'", v, "'"]
884+ formOptions = B.intercalate " " $ map formFn $ Map.toList formData
885+
886+
887+ return $ B.intercalate " " $
888+ ["curl", formOptions, "-F file=@/tmp/photo.jpg", url]
889+
890+ case res of
891+ Left e -> putStrLn $ "post-policy error: " ++ (show e)
892+ Right cmd -> do
893+ putStrLn $ "Put a photo at /tmp/photo.jpg and run command:\n"
894+
895+ -- print the generated curl command
896+ Char8.putStrLn cmd
897+```
691898
692899<!-- ## 5. Bucket policy/notification operations -->
693900