0

Using the packages express and ````ftp``` I try to simply get files from an ftp and return them by HTTP GET to the client requesting.

The first request goes through fine, but when I try calling it again I run into Exception: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

I've tried to use the solutions from Error: Can't set headers after they are sent to the client like having a return when sending, not setting , unfortunately none of the worked for me.

This is ALL the code:

const express = require('express');
const ftp = require('ftp');

const app = express();
const port = 3000;
const c = new ftp();

app.get('/files', (req, res) => {

    c.on('ready', () => {
        c.list((err, list) => {
            c.end();
            return res.setHeader("Content-Type", "application/json").status(200).send({data: list});            
        });
    });

    c.connect({
        host: 'xxx',
        user: 'xxx',
        password: 'xxx',
    });
});

app.listen(port, () => {
    console.log(`Example app listening on port ${port}`);
});

I think it might be something with the c.list() callback, however I cannot for the love of god find what is wrong with it, as the res.send() does not get called twice anytime.

LordScrat
  • 180
  • 1
  • 10
  • Try changing `c.on(` to `c.once(`. You likely have an issue with stale requests receiving the ready event multiple times. – Aurast Nov 24 '22 at 16:00
  • `return res.setHeader` - this return is inside nested functions. It’s not going to return from app.get, but from the innermost function. – James Nov 24 '22 at 16:05
  • Is there special needs that `c.end()` (ending the response process) is called before `return` statement is even reached? – Aleksandar Nov 24 '22 at 16:15

1 Answers1

1

The problem is you have just one ftp object, and every request subscribes to (and never unsubscribes from) the ready event, and the ready event fires every time you call connect() , which you do for every request. So when the second request calls connect(), the event fires for both the first and second request. This leads to setHeader() being called a second time for the first request, hence the error.

Using once() instead of on() so that the event handler it only called once should resolve the issue, though there are probably better ways to write this code (use a promise API or promisify this one, only initialize a connection to the FTP server once instead of for every request).

Aurast
  • 3,189
  • 15
  • 24