Search code examples
amazon-web-servicesflutterdartamazon-s3mime-types

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


I'm using Flutters' aws_s3_upload plugin which I found on Github. I am able to upload images to my AWS s3 bucket. However, the images are missing the "image/jpeg" mime/type required so that I may view them in a browser window as images.

At the moment when clicking on the URL the image downloads instead of appearing in my browser. Can I update this code so that it is uploaded to my S3 bucket as an image?

 library aws_s3_upload;  

 import 'dart:io';    
 import 'package:amazon_cognito_identity_dart_2/sig_v4.dart';
 import 'package:http/http.dart' as http;
 import 'package:path/path.dart' as path;    
 import './src/policy.dart';

class AwsS3 {
  static Future<String> uploadFile(
      {
      String accessKey,    
      String secretKey,
      String bucket,
      String destDir,    
      String region = 'us-east-2',
      File file,

      String filename}) async {
    final endpoint = 'https://$bucket.s3-$region.amazonaws.com';
    final uploadDest = '$destDir/${filename ?? path.basename(file.path)}';

    final stream = http.ByteStream(Stream.castFrom(file.openRead()));
    final length = await file.length();

    final uri = Uri.parse(endpoint);
    final req = http.MultipartRequest("POST", uri);
    final multipartFile = http.MultipartFile('file', stream, length, filename: path.basename(file.path));

    final policy = Policy.fromS3PresignedPost(uploadDest, bucket, accessKey, 15, length, region: region);
    final key = SigV4.calculateSigningKey(secretKey, policy.datetime, region, 's3');
    final signature = SigV4.calculateSignature(key, policy.encode());

    req.files.add(multipartFile);
    req.fields['key'] = policy.key;
    req.fields['acl'] = 'public-read';
    req.fields['X-Amz-Credential'] = policy.credential;
    req.fields['X-Amz-Algorithm'] = 'AWS4-HMAC-SHA256';
    req.fields['X-Amz-Date'] = policy.datetime;
    req.fields['Policy'] = policy.encode();
    req.fields['X-Amz-Signature'] = signature;

    try {
      final res = await req.send();

      if (res.statusCode == 204) return '$endpoint/$uploadDest';
    } catch (e) {
      print(e.toString());
    }
  }
}

Solution

  • 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';