First, I created a sample HttpServer console app using shelf-related packages to make sure I have the correct code to handle the image upload URI handler. The console app was able to receive and save the image correctly then I tried the same code to Flutter Android app with only one minor difference which is the location of the saved image file.
Here's the code:
import 'package:shelf_router/shelf_router.dart' as srouter;
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as io;
import 'package:mime/mime.dart';
import 'package:path_provider/path_provider.dart' as prod;
var app = srouter.Router();
final directory = await prod.getExternalStorageDirectory();
app.post('/upload', (Request request) async {
String? boundary = request.headers['content-type'];
final payload = await request.read();
final boundWord = 'boundary=';
if (boundary != null) {
var boundIndex = boundary.indexOf(boundWord);
boundary = boundary.substring(boundIndex + boundWord.length);
final transformer = MimeMultipartTransformer(boundary);
final parts = await transformer.bind(payload).toList();
for (var part in parts) {
final content = await part.toList();
await File('${directory?.path}/newImgFile.png').writeAsBytes(content[0]);
}
}
return Response.ok('Upload done');
});
await io.serve(app, '0.0.0.0', 8080);
When I ran this and I send an image file using curl, it seems that it does everything correctly but when I checked the saved newImgFile, it's incorrect.
The file size doesn't match at all. I had my test image is in 900 KB but it was saved with much less than that (I think it was 30 KB).
I did notice one thing that's different on the content after this code line:
final content = await part.toList();
With the same image upload, content is a list of only 1 item for HttpServer console app but for HttpServer Flutter Android app, content is a list with 2 items.
I don't know if that's going to help in solving this issue but that's a difference that I am noticing.