mirror of
https://github.com/bitinflow/server.git
synced 2026-03-13 21:45:54 +00:00
refactor to use http agent interface for tunnels
This commit is contained in:
69
lib/Client.js
Normal file
69
lib/Client.js
Normal file
@@ -0,0 +1,69 @@
|
||||
import http from 'http';
|
||||
|
||||
import TunnelAgent from './TunnelAgent';
|
||||
|
||||
// A client encapsulates req/res handling using an agent
|
||||
//
|
||||
// If an agent is destroyed, the request handling will error
|
||||
// The caller is responsible for handling a failed request
|
||||
class Client {
|
||||
constructor(options) {
|
||||
this.agent = options.agent;
|
||||
}
|
||||
|
||||
handleRequest(req, res) {
|
||||
const opt = {
|
||||
path: req.url,
|
||||
agent: this.agent,
|
||||
method: req.method,
|
||||
headers: req.headers
|
||||
};
|
||||
|
||||
const clientReq = http.request(opt, (clientRes) => {
|
||||
// write response code and headers
|
||||
res.writeHead(clientRes.statusCode, clientRes.headers);
|
||||
clientRes.pipe(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) => {
|
||||
|
||||
});
|
||||
|
||||
req.pipe(clientReq);
|
||||
}
|
||||
|
||||
handleUpgrade(req, socket) {
|
||||
this.agent.createConnection({}, (err, conn) => {
|
||||
// any errors getting a connection mean we cannot service this request
|
||||
if (err) {
|
||||
socket.end();
|
||||
return;
|
||||
}
|
||||
|
||||
// socket met have disconnected while we waiting for a socket
|
||||
if (!socket.readable || !socket.writable) {
|
||||
socket.end();
|
||||
return;
|
||||
}
|
||||
|
||||
// websocket requests are special in that we simply re-create the header info
|
||||
// then directly pipe the socket data
|
||||
// avoids having to rebuild the request and handle upgrades via the http client
|
||||
const arr = [`${req.method} ${req.url} HTTP/${req.httpVersion}`];
|
||||
for (let i=0 ; i < (req.rawHeaders.length-1) ; i+=2) {
|
||||
arr.push(`${req.rawHeaders[i]}: ${req.rawHeaders[i+1]}`);
|
||||
}
|
||||
|
||||
arr.push('');
|
||||
arr.push('');
|
||||
|
||||
conn.pipe(socket).pipe(conn);
|
||||
conn.write(arr.join('\r\n'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default Client;
|
||||
Reference in New Issue
Block a user