Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Content-Type from binary/octet-stream to image/jpeg #27

Closed
Josue10599 opened this issue Feb 27, 2020 · 3 comments
Closed

Change Content-Type from binary/octet-stream to image/jpeg #27

Josue10599 opened this issue Feb 27, 2020 · 3 comments

Comments

@Josue10599
Copy link

I'm making a POST request to Amazon S3 by sending an image together; however, when uploading the image, it assumes the default value as if I had not sent the content metadata, causing it to be downloaded when opening the image in the browser.

Code:

final _client = Dio( );
final int length = await image.length();
final String filename = '$path${DateTime.now().millisecondsSinceEpoch}.jpeg';
final String key = filename;
final Policy policy = Policy.fromS3PreSignedPost(
      key,
      bucketId,
      500,
      accessKey,
      length,
      sessionToken,
      region: region,
    );
final List<int> signKey = SigV4.calculateSigningKey(secretKey, policy.datetime, region, service);
final String signature = SigV4.calculateSignature(signKey, policy.encode( ));
final FormData formData = FormData.fromMap({
        'key': policy.key,
        'acl': 'public-read',
        'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
        'X-Amz-Credential': policy.credential,
        'X-Amz-Date': policy.datetime,
        'Policy': policy.encode(),
        'X-Amz-Signature': signature,
        'x-amz-security-token': sessionToken,
        'file': await MultipartFile.fromFile(
          image.path,
        filename: filename,
        contentType: MediaType('image', 'jpeg'),
      ),
});
await _client.post(post, data: formData);
@furaiev
Copy link
Owner

furaiev commented Feb 27, 2020

Pls take a look at this working code, it seems like this is the same as you trying to implement
https://github.com/conghua2411/FlutterDemoEverything/blob/e07cd5e1c9f751395a050a9a37ed09e821ee607b/lib/aws_cognito_dev_upload_s3/aws_cognito_dev_upload_s3.dart

@Josue10599
Copy link
Author

Por favor, dê uma olhada neste código funcional, parece que é o mesmo que você está tentando implementar
https://github.com/conghua2411/FlutterDemoEverything/blob/e07cd5e1c9f751395a050a9a37ed09e821ee607b/lib/aws_cognito_dev_upload_s3/aws_cognito_dev_upload_s3/aws_cognito_dev_upload_s3/aws_cognito

Unfortunately it had the same effect, when uploading the image and opening it on AWS it looks like this:
Captura de Tela 2020-02-28 às 08 27 26

I need metadata to look like this:
Captura de Tela 2020-02-28 às 08 30 45

I have the need to change the metadata, because when opening the link, the image is downloaded automatically, and instead I need the image to be opened when clicking on the link, due to my web application that also includes the images. If you have any suggestions on what to do, I will be very grateful!

@Josue10599
Copy link
Author

I found out how to solve this problem, two fields must be added, one in Policy and the other in Body, looking like this:

final Dio _client = Dio();
_client.interceptors.add(LogInterceptor());
final int length = await image.length();
final String filename = '${DateTime.now().millisecondsSinceEpoch}.jpg';
final String key = path + filename;
final Policy policy = Policy.fromS3PreSignedPost(
  key,
  bucketId,
  500,
  accessKey,
  length,
  sessionToken,
  region: region,
);
final List<int> signKey =
    SigV4.calculateSigningKey(secretKey, policy.datetime, region, service);
final String signature = SigV4.calculateSignature(signKey, policy.encode());
final FormData formData = FormData.fromMap({
  'key': policy.key,
  'acl': 'public-read',
  'X-Amz-Algorithm': 'AWS4-HMAC-SHA256',
  'X-Amz-Credential': policy.credential,
  'X-Amz-Date': policy.datetime,
  'Policy': policy.encode(),
  'X-Amz-Signature': signature,
  'x-amz-security-token': sessionToken,
  'Content-Type': 'image/jpeg',
  'file': await MultipartFile.fromFile(
    image.path,
    filename: filename,
  )
});
Response response = await _client.post(post, data: formData);
_client.close();
String linkImage = response.headers.map['location'].first;
class Policy {
  String expiration;
  String region;
  String bucket;
  String key;
  String credential;
  String datetime;
  String sessionToken;
  int maxFileSize;

  Policy(this.key, this.bucket, this.datetime, this.expiration, this.credential,
      this.maxFileSize, this.sessionToken,
      {this.region = AWS_REGION_FTALK});

  factory Policy.fromS3PreSignedPost(
    String key,
    String bucket,
    int expiryMinutes,
    String accessKeyId,
    int maxFileSize,
    String sessionToken, {
    String region,
  }) {
    final datetime = SigV4.generateDatetime();
    final expiration = (DateTime.now())
        .add(Duration(minutes: expiryMinutes))
        .toUtc()
        .toString()
        .split(' ')
        .join('T');
    final cred =
        '$accessKeyId/${SigV4.buildCredentialScope(datetime, region, 's3')}';
    final policy = Policy(
        key, bucket, datetime, expiration, cred, maxFileSize, sessionToken,
        region: region);
    return policy;
  }

  String encode() {
    final bytes = utf8.encode(toString());
    return base64.encode(bytes);
  }

  @override
  String toString() {
    return '''
{ "expiration": "${this.expiration}",
  "conditions": [
    {"bucket": "${this.bucket}"},
    ["starts-with", "\$key", "${this.key}"],
    ["starts-with", "\$Content-Type", "image/"],
    {"acl": "public-read"},
    ["content-length-range", 1, ${this.maxFileSize}],
    {"x-amz-credential": "${this.credential}"},
    {"x-amz-algorithm": "AWS4-HMAC-SHA256"},
    {"x-amz-date": "${this.datetime}" },
    {"x-amz-security-token": "${this.sessionToken}" }
  ]
}
''';
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants