This little library can be used to provide two TCP services on the same port, as long as one is HTTP and the other is anything but HTTP.
npm install --save http-fallback
const FallbackHttpServer = require('http-fallback');
const server = new FallbackHttpServer();
// You can also use Express, etc.
server.on('request', (req, res) => {
response.writeHead(200, {'Content-Type': 'text/html'});
res.end('<h1>Hello, World Wide Web!</h1>');
});
// On non-HTTP connections, act like a TCP echo service.
server.on('fallbackConnection', (socket) => {
socket.on('data', (data) => {
socket.write(data);
});
socket.on('end', () => socket.end());
});
// One port, two services!
server.listen(8000);
Also see examples/bzfs-proxy.js.
This class inherits from http.Server
(and forwards all constructor arguments). It has the following additional event:
socket
<net.Socket>
Emitted when the HTTP parser encounters an invalid HTTP request at the beginning of a connection. The socket connection is not managed anymore by http.Server
.
The first chunk of data, which the HTTP parser rejected, will be emitted as a 'data'
event on socket
synchronously after this event is emitted.
This event will not be emitted after a valid HTTP request has been processed. Instead, 'clientError'
will be emitted or a 400 code will be sent to the client like a normal http.Server
.
This will work as long as your TCP service always begins by sending a string that is not an HTTP method name from the client to the server.
There is no way for the server side of your TCP service to begin communication because 'fallbackConnection'
is only emitted after the HTTP parser has received invalid data.
This will not work either if the beginning of the data sent by the client to the server can be mistaken as an HTTP request. If this occurs, all the normal HTTP events and behavior will be emitted and 'fallbackConnection'
will not be.
Just submit an issue or, better yet, fork and open a pull request.
Some unimplemented features that might pique your interest:
- Support for
https.Server
. - Support for
readable.pipe()
. - Support for
'readable'
, andreadable.read()
.