diff options
Diffstat (limited to 'vendor/github.com/minio/minio-go/v7/api-get-object-file.go')
-rw-r--r-- | vendor/github.com/minio/minio-go/v7/api-get-object-file.go | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/vendor/github.com/minio/minio-go/v7/api-get-object-file.go b/vendor/github.com/minio/minio-go/v7/api-get-object-file.go new file mode 100644 index 0000000..2332dbf --- /dev/null +++ b/vendor/github.com/minio/minio-go/v7/api-get-object-file.go | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * MinIO Go Library for Amazon S3 Compatible Cloud Storage | ||
3 | * Copyright 2015-2017 MinIO, Inc. | ||
4 | * | ||
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | * you may not use this file except in compliance with the License. | ||
7 | * You may obtain a copy of the License at | ||
8 | * | ||
9 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | * | ||
11 | * Unless required by applicable law or agreed to in writing, software | ||
12 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | * See the License for the specific language governing permissions and | ||
15 | * limitations under the License. | ||
16 | */ | ||
17 | |||
18 | package minio | ||
19 | |||
20 | import ( | ||
21 | "context" | ||
22 | "io" | ||
23 | "os" | ||
24 | "path/filepath" | ||
25 | |||
26 | "github.com/minio/minio-go/v7/pkg/s3utils" | ||
27 | ) | ||
28 | |||
29 | // FGetObject - download contents of an object to a local file. | ||
30 | // The options can be used to specify the GET request further. | ||
31 | func (c *Client) FGetObject(ctx context.Context, bucketName, objectName, filePath string, opts GetObjectOptions) error { | ||
32 | // Input validation. | ||
33 | if err := s3utils.CheckValidBucketName(bucketName); err != nil { | ||
34 | return err | ||
35 | } | ||
36 | if err := s3utils.CheckValidObjectName(objectName); err != nil { | ||
37 | return err | ||
38 | } | ||
39 | |||
40 | // Verify if destination already exists. | ||
41 | st, err := os.Stat(filePath) | ||
42 | if err == nil { | ||
43 | // If the destination exists and is a directory. | ||
44 | if st.IsDir() { | ||
45 | return errInvalidArgument("fileName is a directory.") | ||
46 | } | ||
47 | } | ||
48 | |||
49 | // Proceed if file does not exist. return for all other errors. | ||
50 | if err != nil { | ||
51 | if !os.IsNotExist(err) { | ||
52 | return err | ||
53 | } | ||
54 | } | ||
55 | |||
56 | // Extract top level directory. | ||
57 | objectDir, _ := filepath.Split(filePath) | ||
58 | if objectDir != "" { | ||
59 | // Create any missing top level directories. | ||
60 | if err := os.MkdirAll(objectDir, 0o700); err != nil { | ||
61 | return err | ||
62 | } | ||
63 | } | ||
64 | |||
65 | // Gather md5sum. | ||
66 | objectStat, err := c.StatObject(ctx, bucketName, objectName, StatObjectOptions(opts)) | ||
67 | if err != nil { | ||
68 | return err | ||
69 | } | ||
70 | |||
71 | // Write to a temporary file "fileName.part.minio" before saving. | ||
72 | filePartPath := filePath + objectStat.ETag + ".part.minio" | ||
73 | |||
74 | // If exists, open in append mode. If not create it as a part file. | ||
75 | filePart, err := os.OpenFile(filePartPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o600) | ||
76 | if err != nil { | ||
77 | return err | ||
78 | } | ||
79 | |||
80 | // If we return early with an error, be sure to close and delete | ||
81 | // filePart. If we have an error along the way there is a chance | ||
82 | // that filePart is somehow damaged, and we should discard it. | ||
83 | closeAndRemove := true | ||
84 | defer func() { | ||
85 | if closeAndRemove { | ||
86 | _ = filePart.Close() | ||
87 | _ = os.Remove(filePartPath) | ||
88 | } | ||
89 | }() | ||
90 | |||
91 | // Issue Stat to get the current offset. | ||
92 | st, err = filePart.Stat() | ||
93 | if err != nil { | ||
94 | return err | ||
95 | } | ||
96 | |||
97 | // Initialize get object request headers to set the | ||
98 | // appropriate range offsets to read from. | ||
99 | if st.Size() > 0 { | ||
100 | opts.SetRange(st.Size(), 0) | ||
101 | } | ||
102 | |||
103 | // Seek to current position for incoming reader. | ||
104 | objectReader, objectStat, _, err := c.getObject(ctx, bucketName, objectName, opts) | ||
105 | if err != nil { | ||
106 | return err | ||
107 | } | ||
108 | |||
109 | // Write to the part file. | ||
110 | if _, err = io.CopyN(filePart, objectReader, objectStat.Size); err != nil { | ||
111 | return err | ||
112 | } | ||
113 | |||
114 | // Close the file before rename, this is specifically needed for Windows users. | ||
115 | closeAndRemove = false | ||
116 | if err = filePart.Close(); err != nil { | ||
117 | return err | ||
118 | } | ||
119 | |||
120 | // Safely completed. Now commit by renaming to actual filename. | ||
121 | if err = os.Rename(filePartPath, filePath); err != nil { | ||
122 | return err | ||
123 | } | ||
124 | |||
125 | // Return. | ||
126 | return nil | ||
127 | } | ||