Reading the ssh2 HTTPAgent Source Code
·
2 min read
·
252
Words
·
-Views
-Comments
The
ssh2
package ships HTTP agents that intercept requests and forward them through an SSH connection. I recently needed a custom agent, so I dug through the implementation.
The agent lives in lib/http-agents.js
:
const { Agent: HttpAgent } = require('http');
const { Agent: HttpsAgent } = require('https');
for (const ctor of [HttpAgent, HttpsAgent]) {
// ...
exports[ctor === HttpAgent ? 'SSHTTPAgent' : 'SSHTTPSAgent'] = SSHAgent;
}
A loop adapts Node’s built-in Agent
constructors and exports derived classes.
Node’s Agent
signature:
new Agent([options])
ssh2’s agent accepts two arguments because it also needs SSH configuration:
constructor(connectCfg, agentOptions) {
super(agentOptions);
this._connectCfg = connectCfg;
this._defaultSrcIP = (agentOptions && agentOptions.srcIP) || 'localhost';
}
connectCfg
holds SSH connection parameters.agentOptions
is passed to Node’sAgent
. ssh2 addssrcIP
, controlling the source IP for the TCP socket.
createConnection(options, cb)
is invoked by the pooling mechanism to obtain a TCP socket. The agent:
- Creates an SSH
Client
and connects usingconnectCfg
. - On
ready
, callsforwardOut
to open a TCP stream. - Calls
cb(null, decorateStream(stream, ctor, options));
so the stream exposes the methods expected by HTTP(S) consumers.
Error-handling highlights:
- If the TCP communication errors, the error is passed to
cb
and the SSH client closes. - If the TCP connection closes, the SSH client closes; no error is passed to
cb
because the closure is expected.
When creating the local endpoint, a port must be bound. If localPort
isn’t supplied, it defaults to 0
, letting the OS choose an ephemeral port (not literally port 0):
const srcPort = (options && options.localPort) || 0;