StreamedMultipartExtractable class final
Hands a multipart/form-data body to the handler a part at a time.
The difference from MultipartExtractable, which buffers the whole body:
this never holds more than one chunk, so an upload can be written straight to
disk or to object storage. That is what makes a file larger than memory
possible at all.
The cost is that the parts are ordered and consumable once. A handler that needs to look at part three before part one has to buffer, and should use the buffering extractor instead.
Future<Map<String, Object?>> upload(Request request) async {
final body = await request.extract(const StreamedMultipartExtractable());
var bytes = 0;
await body.forEachPart((part) async {
if (!part.isFile) return;
final file = File('uploads/${newId()}').openWrite();
bytes = await part.writeTo(file, limit: 50 * 1024 * 1024);
await file.close();
});
return {'bytes': bytes};
}
limit bounds the whole body, and it is enforced as the bytes flow
rather than up front: a streamed upload usually arrives without a
content-length, so there is nothing to check before reading. A part that
pushes the total past it fails with 413 mid-stream, which is the earliest
anything can.
- Implemented types
Constructors
- StreamedMultipartExtractable({int limit = 64 * 1024 * 1024})
-
Streams the multipart body, capped at
limitbytes in total.const
Properties
Methods
-
extract(
Request request) → Future< Result< StreamedMultipart, Rejection> > -
Produces the value, or the rejection that stops the handler.
override
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited