Open gokkep opened 4 years ago
Hi @gokkep , i'm facing the same issue. Do you discovered a workaround?
Thx
Hi Xt-Man, well no not really. I changed the Eiffel code to support both cases, but it is a hack. This should be solved in the proper way. Shamefull no one of this development team seems to react upon this issue after such long time. Anyone???
Hi @gokkep , i created my own MultipartRequest, works for me, you can try it, let me now if works for you too. MyMultipartRequest.dart `import 'dart:convert'; import 'dart:math';
import 'package:http/http.dart' as http;
final _newlineRegExp = RegExp(r'\r\n|\r|\n');
const List
class MyMultipartRequest extends http.MultipartRequest {
static const int _boundaryLength = 70;
static final Random _random = Random();
MyMultipartRequest(String method, Uri url) : super(method, url);
@override int get contentLength { var length = 0;
fields.forEach((name, value) {
length += '--'.length +
_boundaryLength +
'\r\n'.length +
utf8.encode(_headerForField(name, value)).length +
utf8.encode(value).length +
'\r\n'.length;
});
for (var file in files) {
length += '--'.length +
_boundaryLength +
'\r\n'.length +
utf8.encode(_headerForFile(file)).length +
file.length +
'\r\n'.length;
}
return length + '--'.length + _boundaryLength + '--\r\n'.length;
}
String _headerForFile(http.MultipartFile file) { // var header = 'content-type: ${file.contentType}\r\n' // 'content-disposition: form-data; name="${_browserEncode(file.field)}"';
// if (file.filename != null) {
// header = '$header; filename="${_browserEncode(file.filename)}"';
// }
var header = 'Content-Disposition: form-data; name="${_browserEncode(file.field)}"';
if (file.filename != null) {
header = '$header; filename="${_browserEncode(file.filename)}"';
}
header = '$header\r\n'
'Content-Type: ${file.contentType}';
return '$header\r\n\r\n';
}
/// Encode [value] in the same way browsers do.
String _browserEncode(String value) {
// http://tools.ietf.org/html/rfc2388 mandates some complex encodings for
// field names and file names, but in practice user agents seem not to
// follow this at all. Instead, they URL-encode \r
, \n
, and \r\n
as
// \r\n
; URL-encode "
; and do nothing else (even for %
or non-ASCII
// characters). We follow their behavior.
return value.replaceAll(_newlineRegExp, '%0D%0A').replaceAll('"', '%22');
}
String _headerForField(String name, String value) { var header = 'content-disposition: form-data; name="${_browserEncode(name)}"'; if (!isPlainAscii(value)) { header = '$header\r\n' 'content-type: text/plain; charset=utf-8\r\n' 'content-transfer-encoding: binary'; } return '$header\r\n\r\n'; }
final _asciiOnly = RegExp(r'^[\x00-\x7F]+$');
bool isPlainAscii(String string) => _asciiOnly.hasMatch(string);
@override http.ByteStream finalize() { // TODO: freeze fields and files final boundary = _boundaryString(); headers['content-type'] = 'multipart/form-data; boundary=$boundary'; super.finalize(); return http.ByteStream(_finalize(boundary)); }
Stream<List
for (var field in fields.entries) {
yield separator;
yield utf8.encode(_headerForField(field.key, field.value));
yield utf8.encode(field.value);
yield line;
}
for (final file in files) {
yield separator;
yield utf8.encode(_headerForFile(file));
yield* file.finalize();
yield line;
}
yield close;
}
String _boundaryString() {
var prefix = 'dart-http-boundary-';
var list = List
}`
please use this code its working fine.
fileUpload(Request request, String id) async {
List
await for (var data in request.read()) {
dataBytes.addAll(data);
}
print(request.headers['content-type']);
var header = HeaderValue.parse(request.headers['content-type'].toString());
var boundary = header.parameters['boundary'] as String;
final transform = MimeMultipartTransformer(boundary);
final bodyStream = Stream.fromIterable([dataBytes]);
final parts = await transform.bind(bodyStream).toList();
print(parts);
for (var part in parts) {
print(part.headers);
final contentDisposition = part.headers['content-disposition'];
final content = await part.toList();
await File('$id.jpg').writeAsBytes(content[0]);
}
return Response.ok("ok");
}
- The case of the header, e.g. content-type instead of Content-Type
I filed https://github.com/dart-lang/http/issues/609 as the issue to track support for preserving header case.
2. The two are in reverse order, content-type first should be content-disposition first.
Can you point to where this is specified?
i'm facing the same issue.
Reading RFC 6266 and RFC 2388 and looking at my Eiffel web framework server side library code, to handle uploading of files using multipart/form-data it seems something is off somewhere.
It seems that the class MultipartRequest from your library is doing it wrong and I want to find out if this is true.
When a browser sends a file through multipart/form-data, the header and second line of the content type is send as follows:
Content-Disposition: form-data; name="uploaded_file[]"; filename="Apps.png" Content-Type: image/png
But when I upload a file using the http dart library, I receive:
content-type: image/png content-disposition: form-data; name="uploaded_file[]"; filename="Apps.png"
Two things are noticable:
I think this is wrong and should both be modified.
Can someone check if my statements are true and when due, please change them as soon as possible.
Regards, Paul