S3 Signed Download Tutorial

Would it be possible for someone to help walk me through (step by step) how to download a file from S3?

I have reviewed the following topics and can get the download to display in the browser, but not download as a file.

Thanks

Hi Scott, what are the file types: images, PDFs or both?

Could be images, PDFs, .mp3, .mp4, or .mov.

These are the steps for downloading an image from S3 without opening it in the browser. I open PDFs in the browser first and users can view or download it from the browser tab. I haven’t tried, but I think the same process as image download should work for the PDFs or other file types as well.

A. Set up Server Action to call in the Server Connect

  1. Create a Server Action -> Add a Get variable image_id
  2. Add a Single Query to get the saved URL and filename in the DB (filter $_GET.image_id).
  3. Add a condition to check whether a record is returned in Step 2.
  4. Add a Set Value step = {{image_file_name}} as returned from the Step 2. This value will be used in the download route.
  5. Add Get File step and fill in values

B. Set up Server Connect in the UI

  1. Create a Server Connect with No Auto Load true. Select the Server Action as created in Step 1 Section A.
  2. Add a dynamic on-success event -> browser.goto action -> Define URL in the Client-Side Binding Code as'/DownloadImage/'+sc_download_item_images.data.imageFilename
  3. DownloadImage is the Server Route we will setup to download image and sc_download_item_images.data.imageFilename is the filename fetched from the Server Action Set Value (Step 4 Section-A)
  4. Add a Button to download -> add dmx-on:click event -> load the Server Connect (Step 1 Section B) and assign image_id to the Get variable (Step 1 Section A).
<dmx-serverconnect id="sc_download_item_images" url="/api/1/0/AppPortal/Files/download_item_images" noload="true" dmx-on:success="browser1.goto('/DownloadImage/'+sc_download_item_images.data.imageFilename)"></dmx-serverconnect>
dmx-on:click="run({run:{action:`sc_download_item_images.load({item_image_id: dd_list_item_images.data.item_image_id})`,name:'sc_download_images',outputType:'text'}})"

C. Set up Download Server Route

  1. Add a new Server Action -> Add a Parameter variable imageFilename (same name as in Set Value and on-success event above)
  2. Add a new action: File Download and fill in value for the File Path. This file path will download file on the local instance of the project
  3. Open Routes -> Click on the lightening bolt` icon in the top status bar under Routes and select the Server Action as created in the Step 1.
  4. Click on the new Server Route and change the Path value to this /DownloadImage/:imageFilename This is the same path that has been defined earlier in Step 2 Section B.
  5. Make sure that the parameter name is the same as defined previously.

Server Action for Server Route

New Server Connect Route

Screenshot 2024-05-08 at 11.26.39 AM

Server Route Setup

Screenshot 2024-05-08 at 11.28.46 AM

3 Likes

Thanks @guptast! I appreciate the detail you put into this. I’ll give it a whirl and let you know the outcome!

1 Like

If you need to download S3 file directly from S3 server, you can use signed download

HI @guptast,

I have followed the directions and part of it appears to be working correctly. The file is retrieved from S3 and downloaded to the server. The part that I am having an issue with is the downloading to the users computer.

On the page, the server connect > browser > go to is:

Screenshot 2024-05-08 at 8.03.42 PM

The server route is:

Screenshot 2024-05-08 at 8.04.34 PM

The server action is:

Screenshot 2024-05-08 at 8.05.24 PM

The result is:

I can see that the file was downloaded to the server, so it is just a matter of connecting the server to the users computer and downloading it.

Screenshot 2024-05-08 at 8.09.15 PM

Hi Scott,

In the error 404, the path to download the file seems incorrect. The path should look like this /downloads/moviefile.mp4 where moviefile.mp4 is the filename retrieved from the Set Value step (Step 4 Section A).

Please check in the browsergoto code that only the Set Value step name has been added on the success event of the main Server Action. From the error message, it looks like a path to nested folders and filename.

Ok, that might present a problem, when the file is uploaded, I save the entire key in the database not just the file name because the S3 folder structure could change based upon what is being uploaded. For example:

folder1/folder2/folder3/file-name.mp4 or
folder23/folder46/folder102/file-name.mp4

In the above screenshots, I see the S3 file being retrieved from Amazon and downloaded to the server in the /public/assets/downloads/folder1/folder2/folder3/file-name.mp4.

The error is looking for a file in /public/assets/downloads/folder1/folder2/folder3/file-name.mp4. (which is there).

So, what it appears I need to do is strip the folder structure from the database entry and just have the file name by itself, correct?

Also, is /public/assets/downloads/ a proper place to store the download or would be better to have it as you did /public/downloads ?

That is correct. The File Path has already been defined in the File Download step under Server Action for the Server Route plus the filename that will be fetched from the parameter value.

I keep it separate from the assets folder. This way if I need to periodically remove files that can be sometimes left behind after downloading on the server, then I’m not accidently deleting any important files under the assets folder.

The route localhost:8100/downloads/moviefile.mp4 can be tested manually in the browser. Replace the filename with the file name that has been already downloaded on the server and see if it downloads it on the local PC.

@guptast,

Thank you so much for your guidance! The trick was in the download path. I was able to successfully make it work! :heart_eyes:

1 Like

You are welcome, Scott; I’m glad that the process is working for you! :slight_smile:

1 Like