uNetworking/uWebSockets.js

Multipart images are broken.

def-roth opened this issue · 6 comments

The following code produces results for arbitrary files exept for images. I'm running around in circles here and I bet it's just me doing something wrong. Different types of buffer allocations have been tried. Storing them in an Array and concatenating them (doesn't work) or calling buffer.toString(). At least this works as minimum reproducible I guess.

const {App : UWS_APP,} = require('uWebSockets.js');
const fs = require('fs');


const port  = 56122;

const ssApp = UWS_APP({});

ssApp
  .post('/*', (res, req) => {

    let file = Buffer.alloc(0);


    let filename = req
      .getHeader("content-disposition")
      ?.split("filename=\"")
      ?.[1]
      ?.slice(0, -1)

    res.onData((chunk, isLast) => {

      file = Buffer.concat([file, Buffer.from(chunk)]);


      if (isLast) {

        fs.writeFileSync(filename, file);
        res.end('ok done');

      }

    });

    res.onAborted(() => {

    });
  })
  .listen(port, ()=>{});


ssApp
  .options("/*", (res) => {

    res.onAborted(() => {});

    res.cork(() =>
      res.writeHeader("Access-Control-Allow-Origin", "*")
        .writeHeader("Access-Control-Allow-Methods", "*")
        .writeHeader("Access-Control-Allow-Headers", "*")
        .endWithoutBody()
    )

  });

Multipart uploads need to be parsed, have you tried getParts

If I read the getParts interface correct that is problematic as it returns array buffers which become memory intensive when dealing with huge files.

There are streaming multipart parsers you would need to find one that works for you
npmjs.com/search?q=multipart

All good. This was an error on my end. I had to implement parsing myself as the requirements are pretty special, but working with the stream was a charm. Thanks for the hint though!

getParts is not very well designed like you mention it uses in-memory buffers rather than streaming. This interface was added for a customer who wanted it like this. I would rather have streams but, yeah..

I can add a PR to the examples as a starting point how to solve this. Yet I think there is no silver bullet here, neither memory nor disk are optimal and both have huge foot gun potential. Although most developers will never need a filesize larger than 5mb.