DEV Community

Cover image for Custom Multipart Request in Dart for Video Uploads
Saurabh Saha
Saurabh Saha

Posted on

Custom Multipart Request in Dart for Video Uploads

When implementing video uploads from Camera in our Flutter web application, we initially used http.MultipartRequest to send the video file. However, we ran into multiple issues with the backend, which was using Express.js + Multer for handling file uploads.

Initial Dart Code (That Didn't Work)

  final request = http.MultipartRequest('POST', uri);
  request.headers.addAll(headers);
  request.files.add(await http.MultipartFile.fromBytes(fileType, 
 bytes, contentType: mediaType));
  final response = await request.send();
Enter fullscreen mode Exit fullscreen mode

NodeJS Multer Code

Our backend was using Express.js with Multer to handle the video uploads:

const upload = multer({
    dest: 'uploads/',
    limits: {
        fileSize: 100 * 1024 * 1024, // ✅ Set max file size to 100MB
        fieldSize: 25 * 1024 * 1024, // ✅ Increase field size limit (for form fields)
    }
});

app.post('/upload', upload.single('videoResume'), (req, res) => {
    if (!req.file) {
        return res.status(400).send('No file uploaded.');
    }

    console.log("File uploaded: ${req.file.originalname}");
    res.status(200).send('File uploaded successfully.');
});

Enter fullscreen mode Exit fullscreen mode

Issues Faced with Multer in Node.js

1️⃣ File Length Too Long Issue
Multer would sometimes reject the request, stating that the file was too long or exceeding expected limits.

Even after increasing fileSize in Multer's configuration, the issue persisted.

2️⃣ req.file Undefined Issue

Multer did not recognize the uploaded file at all.

req.file was undefined, meaning the file wasn't being parsed correctly.

The request headers and structure seemed correct, yet the backend couldn't extract the file.

Solution: Writing a Custom Multipart Request

After multiple failed attempts we decided to manually construct the multipart request, ensuring that:

  1. ✅ The file is properly wrapped in a multipart boundary.
  2. ✅ The correct Content-Type is used.
  3. ✅ The request format is exactly as expected by the backend.

Final Working Dart Code (Manual Multipart Request)

Future<dynamic> multipartRequestWebVideo(
    String url, XFile videoFile, String fileType) async {
  try {
    final bytes = await videoFile.readAsBytes();
    final boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'; // Random boundary string
    final uri = Uri.parse(url);

    // Start building the body
    String body = '';
    body += '--$boundary\r\n';
    body += 'Content-Disposition: form-data; name="$fileType"; filename="${videoFile.name}"\r\n';
    body += 'Content-Type: video/webm\r\n\r\n';

    // Convert the body to a Uint8List (for binary data)
    List<int> bodyBytes = []..addAll(utf8.encode(body))..addAll(bytes);

    // Append the closing boundary
    bodyBytes.addAll(utf8.encode('\r\n--$boundary--\r\n'));

    // Get headers from our function (which adds auth tokens, etc.)
    var headers = await addHeaders(isMultiPart: true, isStream: true);

    // Override necessary headers
    headers['Content-Type'] = 'multipart/form-data; boundary=$boundary';
    headers['Content-Length'] = bodyBytes.length.toString();

    // Send the request
    final response = await http.post(
      uri,
      headers: headers,
      body: bodyBytes,
    );
  } catch (e) {
    return {
      'error': e.toString(),
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

Given the limited time we had, we decided to create a custom multipart request from scratch.

Top comments (0)