Reputation: 5614
I'm developing a tiny HTTP server to use in unit tests. The code is below.
Why the body
value is available in req.on()
but not in res.end()
?
Reproduce
const WebhookServer = require('./webhook_server');
const server = new WebhookServer();
server.listen();
$ curl -XPOST http://localhost:1088 -d '{"num":1}'
{"method":"POST","body":"","type":"test"}
last body:
body: {"num":1}
last body:
body: {"num":1}
Server code
const http = require('http')
const kill = require('kill-port');
class WebhookServer {
constructor({ port = 1088, host = 'localhost' } = {}) {
this.port = port;
this.host = host;
}
listen() {
this.server = http.createServer((req, res) => {
if (['POST', 'PUT'].includes(req.method)) {
let body = '';
req.on('data', (data) => {
body += data;
console.log('body:', body);
});
res.writeHead(200, { 'Content-Type': 'application/json' });
console.log('last body:', body);
res.end(JSON.stringify({ method: req.method, body, type: 'test' }));
} else { // GET, DELETE
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ method: req.method, type: 'test' }));
}
});
this.server.listen(this.port, this.host);
}
kill() {
return kill(this.port);
}
}
module.exports = WebhookServer;
Upvotes: 0
Views: 43
Reputation: 3966
You need to let the server finish reading incoming data.
As req
is a readable stream, if you do res.end
in req.on("end")
event handler, it should work.
Check following code that worked for me -
const http = require('http')
const kill = require('kill-port');
class WebhookServer {
constructor({ port = 1088, host = 'localhost' } = {}) {
this.port = port;
this.host = host;
}
listen() {
this.server = http.createServer((req, res) => {
if (['POST', 'PUT'].includes(req.method)) {
let body = '';
req.on('data', (data) => {
body += data;
console.log('body:', body);
});
// wait for the reading process to finish
req.on("end", () => {
res.writeHead(200, { 'Content-Type': 'application/json' });
console.log('last body:', body);
res.end(JSON.stringify({ method: req.method, body, type: 'test' }));
})
} else { // GET, DELETE
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ method: req.method, type: 'test' }));
}
});
this.server.listen(this.port, this.host, () => {
console.log("started!");
});
}
kill() {
return kill(this.port);
}
}
module.exports = WebhookServer;
Request
curl -XPOST http://localhost:1088 -d '{"num":1}'
Output
{"method":"POST","body":"{\"num\":1}","type":"test"}
Upvotes: 2