parseMultipart function

FormData parseMultipart(
  1. List<int> body,
  2. String boundary
)

Parses multipart/form-data from raw bytes and boundary.

Implementation

FormData parseMultipart(List<int> body, String boundary) {
  final fields = <String, String>{};
  final files = <String, MultipartFile>{};

  final boundaryBytes = utf8.encode('--$boundary');
  final bodyBytes = Uint8List.fromList(body);

  // Split by boundary
  final parts = <Uint8List>[];
  var start = 0;
  while (start < bodyBytes.length) {
    final idx = _indexOf(bodyBytes, boundaryBytes, start);
    if (idx == -1) break;
    if (start > 0) {
      // Strip leading \r\n and trailing \r\n before boundary
      var partEnd = idx - 2; // skip \r\n before boundary
      if (partEnd > start) {
        parts.add(bodyBytes.sublist(start, partEnd));
      }
    }
    start = idx + boundaryBytes.length;
    // Skip \r\n or -- after boundary
    if (start < bodyBytes.length - 1 && bodyBytes[start] == 13 && bodyBytes[start + 1] == 10) {
      start += 2;
    } else if (start < bodyBytes.length - 1 && bodyBytes[start] == 45 && bodyBytes[start + 1] == 45) {
      break; // final boundary --
    }
  }

  for (final part in parts) {
    // Find header/body separator (\r\n\r\n)
    final sep = _indexOf(part, utf8.encode('\r\n\r\n'), 0);
    if (sep == -1) continue;

    final headerStr = utf8.decode(part.sublist(0, sep));
    final content = part.sublist(sep + 4);

    final disposition = RegExp(r'Content-Disposition:\s*form-data;\s*(.+)', caseSensitive: false)
        .firstMatch(headerStr);
    if (disposition == null) continue;

    final params = disposition.group(1)!;
    final nameMatch = RegExp(r'name="([^"]*)"').firstMatch(params);
    if (nameMatch == null) continue;
    final name = nameMatch.group(1)!;

    final filenameMatch = RegExp(r'filename="([^"]*)"').firstMatch(params);
    if (filenameMatch != null) {
      final contentTypeMatch = RegExp(r'Content-Type:\s*(.+)', caseSensitive: false)
          .firstMatch(headerStr);
      files[name] = MultipartFile(
        name: name,
        filename: filenameMatch.group(1),
        contentType: contentTypeMatch?.group(1)?.trim(),
        bytes: Uint8List.fromList(content),
      );
    } else {
      fields[name] = utf8.decode(content);
    }
  }

  return FormData(fields, files);
}