cant upload image on aws s3 via nodejs and flutter with presigned url
1,110
S3 Presigned URLs require raw bytes as the body, not multipart files. Thus, I used the following code:
List<int> content = await file.readAsBytes();
var streamed = http.StreamedRequest("PUT", Uri.parse(url));
streamed.headers["Content-Type"] = mimeType;
streamed.headers["Content-Length"] = "${content.length}";
streamed.sink.add(content);
streamed.sink.close();
var response = await streamed.send();
Author by
arnabbabai
Updated on December 09, 2022Comments
-
arnabbabai over 1 year
i was trying to do image upload with dart/flutter with aws s3 bucket with presigned url via nodejs. i successfully generated the presigned url and send it back to front end but cant not make the put request over s3 with the file.if i am printing the statuscode i am getting a 400.
import 'dart:io'; import 'dart:convert'; import 'package:path/path.dart'; import 'package:async/async.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:http/http.dart' as http; import 'package:http_parser/http_parser.dart'; import 'package:mime/mime.dart'; import '../global.dart'; class AddAccount extends StatelessWidget { Widget build(context) { return Scaffold( appBar: AppBar( iconTheme: IconThemeData( color: Colors.grey ), title: Text('Add Account', style: TextStyle(color: Colors.black54, fontSize: 20.0)), backgroundColor: Colors.white, ), body: addAccountBody(context), ); } Widget addAccountBody(context){ return ListView( children: <Widget>[ TextField( decoration: InputDecoration( labelText: 'email' ), textCapitalization: TextCapitalization.characters, ), TextField( decoration: InputDecoration( labelText: 'name' ), textCapitalization: TextCapitalization.characters, ), OutlineButton( onPressed: (){ openImagePicker(context); }, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon(Icons.camera_alt), Text('add image') ], ), ) ], ); } void openImagePicker(BuildContext context){ showModalBottomSheet( context: context, builder: (BuildContext context) { return Container( height: 80.0, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ IconButton( onPressed: (){ getImage(context, ImageSource.camera); }, icon: Icon(Icons.camera_alt), ), SizedBox(width: 20.0,), IconButton( onPressed: () async { File image = await getImage(context, ImageSource.gallery); http.Response response = await http.get('$url1/api/upload', headers: { "x-auth" : 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI1YzQ0M2M0NDE0NjkxODM3ZTQxNTMxZTgiLCJhY2Nlc3MiOiJhdXRoIiwiaWF0IjoxNTQ3OTc1NzQ5fQ.73_tyhu3vTpsnMncmjTS0xDBec08pScxpa35yRlLuzQ' }); Map<String, dynamic> uploadUrl = json.decode(response.body); final dataType = lookupMimeType(image.path).split("/"); final imageUploadRequest = http.MultipartRequest("PUT", Uri.parse(uploadUrl['url'])); final file = await http.MultipartFile.fromPath("${uploadUrl['key']}", image.path, contentType: MediaType(dataType[0], dataType[1])); imageUploadRequest.files.add(file); imageUploadRequest.fields['user'] = Uri.encodeComponent('user'); imageUploadRequest.headers['Content-Type'] = 'image/jpeg'; print(file.contentType); try{ final streamedResponse = await imageUploadRequest.send(); final res = await http.Response.fromStream(streamedResponse); print(res.statusCode); }catch(e){ print(e); } }, icon: Icon(Icons.camera), ), ], ), ); } ); } Future<File> getImage(BuildContext context, ImageSource sourse) async { File file = await ImagePicker.pickImage(source: sourse, maxWidth: 400.0); Navigator.pop(context); return file; } }
flutter code
const AWS = require('aws-sdk'); const uuid = require('uuid/v1'); const keys = require('../config/keys'); const { authenticate } = require('../middleware/authenticate') const s3 = new AWS.S3({ accessKeyId: keys.accessKeyId, secretAccessKey: keys.secretAccessKey }); module.exports = (app) => { app.get('/api/upload', authenticate, (req,res) => { console.log(req.user.id); const key = `${req.user.id}/${uuid()}.jpeg`; s3.getSignedUrl('putObject', { Bucket: 'flutter-bucket', ContentType: 'image/jpeg', Key: key }, (err, url) => { res.send({key, url}); }) }); }
node code