Skip to content

Commit 58f6e36

Browse files
brennanMKEroyjit
authored andcommitted
chore(storage): validates parts before completing multipart upload (#98)
1 parent 7b0c51f commit 58f6e36

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

AmplifyPlugins/Storage/AWSS3StoragePlugin/Support/Internal/StorageMultipartUpload.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Amplify
1111
enum StorageMultipartUpload {
1212
enum Failure: Error {
1313
case invalidStateTransition(reason: String)
14+
case invalidateParts(reason: String)
1415
}
1516

1617
case none
@@ -152,6 +153,34 @@ enum StorageMultipartUpload {
152153
return part
153154
}
154155

156+
func validateForCompletion() throws {
157+
guard case .parts(let uploadId, let uploadFile, let partSize, let parts) = self else {
158+
throw Failure.invalidateParts(reason: "not prepared to complete")
159+
}
160+
161+
if uploadId.isEmpty {
162+
throw Failure.invalidateParts(reason: "uploadId is not valid")
163+
}
164+
165+
if partSize.size < Bytes.megabytes(5).bytes {
166+
throw Failure.invalidateParts(reason: "parts size is below minimim size")
167+
}
168+
169+
for part in parts {
170+
if part.eTag == nil || part.eTag?.isEmpty ?? false {
171+
throw Failure.invalidateParts(reason: "Part has invalid eTag")
172+
}
173+
}
174+
175+
let totalBytes = parts.reduce(into: 0) { result, part in
176+
result += part.bytes
177+
}
178+
179+
if uploadFile.size != totalBytes {
180+
throw Failure.invalidateParts(reason: "Total bytes uploaded does not match file size")
181+
}
182+
}
183+
155184
// swiftlint:disable cyclomatic_complexity
156185
mutating func transition(multipartUploadEvent: StorageMultipartUploadEvent, logger: Logger = storageLogger) throws {
157186
switch multipartUploadEvent {

AmplifyPlugins/Storage/AWSS3StoragePlugin/Support/Internal/StorageMultipartUploadSession.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@ class StorageMultipartUploadSession {
251251
fatalError("Invalid state")
252252
}
253253
} else if partsCompleted {
254+
do {
255+
try multipartUpload.validateForCompletion()
256+
} catch {
257+
fail(error: error)
258+
return
259+
}
260+
254261
if let uploadId = multipartUpload.uploadId {
255262
try client.completeMultipartUpload(uploadId: uploadId)
256263
} else {

0 commit comments

Comments
 (0)