How to Upload Images from The Browser to Amazon S3 Using Vapor and Leaf

How to display image using AWS S3 and Vapor 3 and Leaf

So I am going to assume that you have a perfectly good URL to the image.

Let's start by creating a route at GET /image:

routes.get("image", use: image)

func image(_ request: Request) -> EventLoopFuture<View> {

}

To properly render the Leaf view, we will need a context that contains the data for the Leaf variables. It will look something like this:

struct ImageContext: Encodable {
let title: String
let imageURL: String
}

We also need to edit your leaf file so it will use the properties in the context:

#set("content") {
<h1>#(title)</h1>
<img src="#(imageURL)">
}

#embed("base")

Now we can render the leaf file with out new context and return the resulting view from the route handler. Here is what the implementation of the image route handler will look like:

func image(_ request: Request) -> EventLoopFuture<View> {
let context = ImageContext(title: "Image", imageURL: preparePresignedImageUrl(request: request)
return try request.view().make("showImage", context)
}

Now you should be able to access localhost:8080/image from your browser and the image will be there!

How to retrieve files from S3 in Laravel Vapor

I got the solution to this problem. I contacted laravel vapor support and I was told to set the visibility property for my file to public when I copy it to the permanent location, as stated in Laravel's official documentation here.

So after you upload your file using the js vapor.store method you should copy it to a permanent directory, then set it's visibility to public.

Storage::copy($request->path, str_replace('tmp/', '', $request->path));
Storage::setVisibility(str_replace('tmp/', '', $request->path), 'public');

I also noticed that your can set the visibility of the file directly in the vapor.store method by passing a visibility attribute with the respective value.

vapor.store(file, { visibility: 'public-read' });

As a side note: just 'public' will return a 400 bad request, it must be set to 'public-read'.

Unable to view an image in S3 in browser

It looks like you are trying to view the image in browser.

For that, you need to

  1. Open the S3 object in your AWS.
  2. Go to properties of the S3 object.
  3. Go to Metadata section.
  4. There will be a property called Content-Type. It's initial value might be binary/stream. Change that to the type of image like image/jpeg, image/png
    or application/pdf (if you are dealing with pdf files) etc.

Now you should be able to view the image or file in the browser tab instead of downloading.

How to display s3 image in browser

It appears that you are wanting to have images served from Amazon S3 cached in browsers.

To do this, you can set cache-control metadata on the objects.

See:

  • Amazon S3 images cache-control not being applied
  • How to add cache control in AWS S3?

Upload Images as image/jpeg mime/type from Flutter to S3 Bucket

So I went with using Minio like this;

 await minio.fPutObject('mybucket', objectpath, croppedFile.path,
{
'x-amz-acl': 'public-read'
}
);

In order to do that I needed the following dependencies;

import 'package:minio/minio.dart';
import 'package:minio/io.dart';

Uploading an Image using AWS SDK for PHP 2

First, you are missing a s3 'filename' aka key:

'Key' => '/files/imgage/fuzzykitten.jpg'

Next, I have had far fewer complications with:

//use Aws\S3\S3Client;
use Aws\Common\Enum\Region;
//use Aws\Common\Aws;
use Aws\S3\Enum\CannedAcl;
use Aws\S3\Exception\S3Exception;
use Guzzle\Http\EntityBody;

$amazon = Aws\S3\S3Client::factory($config)

with being able to find the class files. Every time I try to include ./common/aws or ./s3/s3client, it start giving me "cannot find Aws\S3\Aws\S3Client" which leaves me at wt???

Architectural and design question about uploading photos from iPhone app and S3

I've discussed this issue on the AWS forums before. As I say there, the proper solution for accessing AWS from a mobile device is to use the AWS Identity and Access Management service to generate temporary, limited-privilege access keys for each user. The service is great, but it's still in beta for now and it's not part of the mobile SDK yet. I have a feeling once this thing is released for good, you'll see it out on the mobile SDK immediately afterwards.

Until then, generate presigned URLs for your users, or proxy through your own server like some others have suggested. The presigned URL will allow your users to temporarily GET or PUT to an S3 object in one of your buckets without actually having your credentials (they are hashed into the signature). You can read about the details here.

EDIT: I've implemented a proper solution for this problem, using the preview beta of IAM. It's available on GitHub, and you can read about it here.



Related Topics



Leave a reply



Submit