http
http copied to clipboard
Flutter Web (only) fails uploading file from web using StreamedRequest (corrupt)
I have the following code:
Future<dynamic> sendStreamAsync({
required Uri uri,
required Stream<List<int>> stream,
required int length,
Map<String, String>? headers,
}) async {
headers = headers ?? Map<String, String>();
headers[HttpHeaders.contentTypeHeader] = CONTENT_TYPE_BINARY;
headers[HttpHeaders.cacheControlHeader] = 'no-cache';
while (true) {
final request = http.StreamedRequest("POST", uri);
request.maxRedirects = 0;
request.headers.addAll(headers);
request.contentLength = length;
stream.listen((chunk) {
print(chunk.length); //debug
request.sink.add(chunk);
}, onDone: () {
request.sink.close();
});
final response = await request.send();
}
CONTENT_TYPE_BINARY is just octet_stream.
With or without the request.contentLength set, the file uploads to the server, the server processes it, but the file that the server receives is corrupt.
(It's also not obvious, but it does do it, how request.sink.add(chunk) is ever called since it definitely executes.
This code works fine on android and ios.
The stream is recovered from the dart.html launch a file chooser using file_picker if it matters, but I've inspected the PlatformFile that is returned and it is a normal website file object (and it can be directly turned into an Image that displays fine in Flutter)
It appears that there are bytes missing off the end of the file.
Further converting it to this:
final request = http.MultipartRequest("POST", uri);
request.maxRedirects = 0;
request.headers.addAll(headers);
//request.contentLength = await stream.length;
request.files
.add(http.MultipartFile("file", stream, length, filename: fileName));
Results in the same problem.
In both cases the server receives 245,000 as the length of the stream versus 137,000 that flutter thinks is the length of the file.