parseMultipart function

Future parseMultipart(
  1. Req req, {
  2. void onFieldListener(
    1. String name,
    2. Object field
    )?,
  3. void onFileListener(
    1. String name,
    2. UploadedFile file
    )?,
  4. void onErrorListener(
    1. dynamic error
    )?,
  5. void onEndListener()?,
})

Parse multipart request into map body and uploaded files

Implementation

Future parseMultipart(
  Req req, {
  void Function(String name, Object field)? onFieldListener,
  void Function(String name, UploadedFile file)? onFileListener,
  void Function(dynamic error)? onErrorListener,
  void Function()? onEndListener,
}) async {
  var multiparts = await req.request.multiparts;

  Map<String, dynamic> body = {};
  List<UploadedFile> files = [];

  if (multiparts != null) {
    try {
      await for (HttpMultipartFormData part in multiparts) {
        final parameters = part.contentDisposition.parameters;
        final name = parameters['name'] ?? 'file';
        final filename = parameters['filename'];

        if (part.isBinary || filename != null) {
          // combine each bytes in part data
          final builder = await part.fold(
            BytesBuilder(copy: false),
            (BytesBuilder bytes, data) {
              if (data is String) {
                return bytes..add((data).codeUnits);
              } else {
                return bytes..add(data as List<int>);
              }
            },
          );

          final data = builder.takeBytes();
          final mimeType = part.contentType!.mimeType;

          files.add(UploadedFile(
            name: name,
            filename: filename!,
            type: mimeType,
            data: data,
          ));
        } else if (part.isText) {
          // call sanitizeHtml for xss clean
          final value = await part.join();
          final name = part.contentDisposition.parameters["name"];

          if (name != null) {
            body.addAll(parseUrlEncoded('$name=$value'));
            onFieldListener?.call(name, body[name]);
          }
        }
      }
    } catch (e) {
      onErrorListener?.call(e);
      return e;
    } finally {
      onEndListener?.call();
    }
  }

  return [body, files];
}