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
- Open the
S3
object in yourAWS
. - Go to properties of the
S3
object. - Go to
Metadata
section. - There will be a property called
Content-Type
. It's initial value might bebinary/stream
. Change that to the type of image likeimage/jpeg
,image/png
orapplication/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
Swift Xcode 7 Beta 5 Type Cannot Refer to Itself as a Requirement
Swift Video to Document Directory
Filtering an Array Inside a Dictionary - Swift
Do Protocols Have an Effect on The Retain Count
Swiftsupport Folder Not Included in The IPA When Generating Build from Script
Anchor Constraints Not Honored in Xcode 10/iOS 12
Comma Automatically Being Added to Textfield in Swift
Spritekit and Swiftui, Change Scene a Better Way
Add New Card Is Not Being Called in Stripe Paymentoptionviewcontroller
How Does Swift Disambiguate Type Arguments in Expression Contexts
Swiftui Remove Transition of Fullscreen Cover
What Is The Advantage of Closure Stored Property Initialisation
Swift Initialization Rule Confusion
Uitableviewcell Subclass Wrong Image in Cell or Old Image Bug
Does Realm Support Computed Property in Swift
Cannot Convert Value of Type 'Nsmutablearray' to Expected Argument Type '[Skaction]'