Skip to content

Downloading file with data returns a 403. Downloading to a local url works, generating a url works too. #3860

@ipodishima

Description

@ipodishima

Describe the bug

Hey

I noticed something really weird which took me a while to figure out (I didn't required to save the data to a file, so I was looking for other issues like misconfiguration).

After uploading a file, if you download it as data, you get a 403.

▿ StorageError: Received HTTP Response status code 403 Forbidden
Recovery suggestion: Make sure the user has access to the key before trying to download/upload it.
  ▿ accessDenied : 3 elements
    - .0 : "Received HTTP Response status code 403 Forbidden"
    - .1 : "Make sure the user has access to the key before trying to download/upload it."
    - .2 : nil

If I download the same file, same key, to a local url or if I generate a presigned url and download it, it works perfectly.

Steps To Reproduce

1.

Define storage like


import { defineStorage } from "@aws-amplify/backend";

export const projectsStorage = defineStorage({
  name: "project-files",
  access: (allow) => ({
    'projectData/*': [
      allow.authenticated.to(['read', 'write', 'delete']),
    ],
  })
});
  1. Upload a file
let dataString = "My Data"
let data = Data(dataString.utf8)
let uploadTask = Amplify.Storage.uploadData(
    path: .fromString("projectData/myFile.data"),
    data: data
)
  1. Download the file
let downloadTask = Amplify.Storage.downloadData(path: .fromString("projectData/myFile.data"))
let data = try await downloadTask.value
print("Completed: \(data)")

You'll get

▿ StorageError: Received HTTP Response status code 403 Forbidden
Recovery suggestion: Make sure the user has access to the key before trying to download/upload it.
  ▿ accessDenied : 3 elements
    - .0 : "Received HTTP Response status code 403 Forbidden"
    - .1 : "Make sure the user has access to the key before trying to download/upload it."
    - .2 : nil
  1. Use file
let downloadToFileName = FileManager.default.urls(
    for: .documentDirectory,
    in: .userDomainMask
)[0].appendingPathComponent("myFile.txt")

let downloadTask = Amplify.Storage.downloadFile(
    path: .fromString("projectData/myFile.data"),
    local: downloadToFileName,
    options: nil
)
try await downloadTask.value
print("Completed")

And it work perfectly.

NB: My workaround for now is

func downloadData(for key: String,
                  downloadProgressHandler: @escaping (Progress) -> Void) async throws -> Data {
    Logger.amplify.debug("Downloading data at \(key)")
    // For some reasons, this return a 403
    // let downloadTask = Amplify.Storage.downloadData(key: key)
    let destinationURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(UUID().uuidString)
    let downloadTask = Amplify.Storage.downloadFile(path: .fromString(key),
                                                    local: destinationURL)

    for await progress in await downloadTask.progress {
        Logger.amplify.trace("Download progress for \(key): \(progress)")
        downloadProgressHandler(progress)
    }
    try await downloadTask.value
    let data = try Data(contentsOf: destinationURL)
    Logger.amplify.trace("Download completed for \(key)")
    return data
}


### Expected behavior

Downloading data should not return a 403 when the resource is accessible

### Amplify Framework Version

2.39.0

### Amplify Categories

Storage

### Dependency manager

Swift PM

### Swift version

5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)

### CLI version

npx ampx --version 1.2.5

### Xcode version

Xcode 15.4 Build version 15F31d

### Relevant log output

```shell
<details>
<summary>Log Messages</summary>


INSERT LOG MESSAGES HERE
```

Is this a regression?

No

Regression additional context

I don't know, first time using it.

Platforms

iOS

OS Version

17.2

Device

Simulator

Specific to simulators

No

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionGeneral questionstorageIssues related to the Storage category

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions