Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uploading a large file using stream.pipe(req) does not work #1654

Open
gramakri opened this issue Dec 17, 2021 · 1 comment
Open

Uploading a large file using stream.pipe(req) does not work #1654

gramakri opened this issue Dec 17, 2021 · 1 comment

Comments

@gramakri
Copy link

Uploading files larger than the read stream's highWatermark does not work.

This is tested with node 16.13.1

Sample server:

const express = require('express'),
    fs = require('fs'),
    http = require('http');

function upload(req, res) {
    const out = fs.createWriteStream('/tmp/out');
    req.pipe(out).on('finish', function () {
        console.log('upload finished');
        res.status(200).send({});
    });
}

const app = express();
app.post('/upload', upload);

http.createServer({}, app).listen(3000, function () {
    console.log('listening on port 3000');
});

You can test the server itself works using curl -F file=@largefile.txt -X POST http://localhost:3000/upload

Superagent upload code:

'use strict';
  
const fs = require('fs'),
    superagent = require('superagent');

const readStream = fs.createReadStream('./largefile.txt');
const request = superagent.post('http://localhost:3000/upload')
request.on('response', function (response) {
    console.log('got response', response.status);
});
readStream.pipe(request);

The code above will just "hang" if largefile.txt is more than twice the highWaterMark. For fs, the default water mark is 64KB. So, if the file is say 200KB, the upload code will hang.

@gramakri
Copy link
Author

The reason the code hangs is because the 'drain' event is only emitted once at https://github.com/visionmedia/superagent/blob/048cf185d954028b1dccde0717d2488b2284c297/src/node/index.js#L799

Changing that bit of code to the below makes the upload work.

  req.on('drain', () => {
    this.emit('drain');
  });

'drain' event can be emitted multiple times (each time req.write() returns false).

@gramakri gramakri changed the title Uploading a large file using req.pipe() does not work Uploading a large file using stream.pipe(req) does not work Dec 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant