mirror of
https://github.com/bitinflow/server.git
synced 2026-03-13 13:35:53 +00:00
use pump to pipe sockets
Ensures that destination socket close or destroy also does the same for the source socket.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import http from 'http';
|
||||
|
||||
import TunnelAgent from './TunnelAgent';
|
||||
import Debug from 'debug';
|
||||
import pump from 'pump';
|
||||
|
||||
// A client encapsulates req/res handling using an agent
|
||||
//
|
||||
@@ -9,9 +9,11 @@ import TunnelAgent from './TunnelAgent';
|
||||
class Client {
|
||||
constructor(options) {
|
||||
this.agent = options.agent;
|
||||
this.debug = Debug('lt:Client');
|
||||
}
|
||||
|
||||
handleRequest(req, res) {
|
||||
this.debug('> %s', req.url);
|
||||
const opt = {
|
||||
path: req.url,
|
||||
agent: this.agent,
|
||||
@@ -20,23 +22,38 @@ class Client {
|
||||
};
|
||||
|
||||
const clientReq = http.request(opt, (clientRes) => {
|
||||
this.debug('< %s', req.url);
|
||||
// write response code and headers
|
||||
res.writeHead(clientRes.statusCode, clientRes.headers);
|
||||
clientRes.pipe(res);
|
||||
|
||||
// using pump is deliberate - see the pump docs for why
|
||||
pump(clientRes, res);
|
||||
});
|
||||
|
||||
// this can happen when underlying agent produces an error
|
||||
// in our case we 504 gateway error this?
|
||||
// if we have already sent headers?
|
||||
clientReq.once('error', (err) => {
|
||||
|
||||
// TODO(roman): if headers not sent - respond with gateway unavailable
|
||||
});
|
||||
|
||||
req.pipe(clientReq);
|
||||
// using pump is deliberate - see the pump docs for why
|
||||
pump(req, clientReq);
|
||||
}
|
||||
|
||||
handleUpgrade(req, socket) {
|
||||
this.debug('> [up] %s', req.url);
|
||||
socket.once('error', (err) => {
|
||||
// These client side errors can happen if the client dies while we are reading
|
||||
// We don't need to surface these in our logs.
|
||||
if (err.code == 'ECONNRESET' || err.code == 'ETIMEDOUT') {
|
||||
return;
|
||||
}
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
this.agent.createConnection({}, (err, conn) => {
|
||||
this.debug('< [up] %s', req.url);
|
||||
// any errors getting a connection mean we cannot service this request
|
||||
if (err) {
|
||||
socket.end();
|
||||
@@ -45,6 +62,7 @@ class Client {
|
||||
|
||||
// socket met have disconnected while we waiting for a socket
|
||||
if (!socket.readable || !socket.writable) {
|
||||
conn.destroy();
|
||||
socket.end();
|
||||
return;
|
||||
}
|
||||
@@ -60,7 +78,9 @@ class Client {
|
||||
arr.push('');
|
||||
arr.push('');
|
||||
|
||||
conn.pipe(socket).pipe(conn);
|
||||
// using pump is deliberate - see the pump docs for why
|
||||
pump(conn, socket);
|
||||
pump(socket, conn);
|
||||
conn.write(arr.join('\r\n'));
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user