Search code examples
javascriptnode.jssessionexpressexpress-session

Unable to write to the stream using the reference stored in express-session


In my project, I am uploading a huge file of few GBs to the server, in chunks - 10MB chunk at a time, using the blueimp jQuery-File-Upload plugin.

I have a writeStream at the Node.js backend attached to a express-session, just so the file uploads from 2 different users do not get messed up. I create a writeStream for every upload and attach it to the session.

The problem is that, when the first data chunk is received at the backend, the writeStream.write is not found in the session.

Relevant part of my Node.js / Express.js code:

// session config:
expressApp.use(session({
    genid: function(req) {
        return uuidV1();
    },
    secret: '***',
    resave: true,
    saveUninitialized: true,
    cookie: { secure: false }
}));

// create writeStream
expressApp.post('/createStream', function(request, response) {

    request.session.wstream = fileSystem.createWriteStream(uploadsDirectoryLocation + '/' + request.body.fileName);

    request.session.wstream.on('finish', function() {
        console.log('*********************************** file has been written ***********************************');
    });

    response.send({ response: 'success' });

});


// on every chunk received, write to the stream
expressApp.post('/uploadFile', function(request, response) {

    var size = 0;

    console.log(request.session.wstream);  // the attached 'wstream' does show up

    request.on('data', function(data) {
        size += data.length;

        request.session.wstream.write(data);  // app crashes here

        console.log('Got chunk: ' + data.length + ' total: ' + size);
        console.log('data', data);
    });

    request.on('end', function() {
        console.log("total size = " + size);
        response.send("response");
    });

    request.on('error', function(e) {
        console.log("ERROR: " + e.message);
        response.send("response");
    });

});

// close the stream
expressApp.post('/closeStream', function(request, response) {

    request.session.wstream.end();

    response.send({ response: 'success' });

});

The exact error is:

        streamObj.wstream.write(data);
                         ^

TypeError: Cannot read property 'write' of undefined

What am I doing wrong here?

EDIT:

However, If am not attaching the writeStream to the session and keeping it global, it does work. But, not for different sessions.

How do I fix this?


Solution

  • I head back from one of the express-session repo maintainers on GitHub:

    The reason is that the data in req.session is saved to the database using JSON.stringify, and functions cannot be represented in there. You can only store simple values like numbers and strings in req.session, not complex functions, unfortunately.

    I resolved the issue by eliminating writeStream completely and using openSync to create an empty file and appendFileSync to append data to the file on every chunk received.