Skip to content

Instantly share code, notes, and snippets.

@tshinnic
Created December 1, 2011 00:40
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tshinnic/1412297 to your computer and use it in GitHub Desktop.
Save tshinnic/1412297 to your computer and use it in GitHub Desktop.
Example of binding socket for nodejs HTTP client request (for discussion only)
// One shot request HTTP client - show local/remote addresses
//
// Attempt to use a modified Agent that has own self.createConnection()
// that binds the client socket to a particular address.
var assert = require('assert'),
dns = require('dns'),
http = require('http'),
net = require('net'),
util = require('util');
function ltrc() { console.log.apply(this, arguments); }
//- - - - - - - - - - - - - - - - - - - - - - - -
var host_port = 5439;
var host_host = '192.168.57.162';
host_host = 'tlsf16a';
host_host = '127.0.0.1';
//host_host = 'localhost';
var clnt_host = '192.168.57.162'; // works
//clnt_host = 'tlsf16a'; // forced to 127.0.0.1 does not work !?!
//clnt_host = '127.0.0.1'; // works
//clnt_host = 'localhost'; // works? is 127.0.0.1
//clnt_host = 'localhost4'; // works? is 127.0.0.1
//clnt_host = 'freakout'; // forced to 127.0.0.1 !!
// Apparently net._createServerHandle(clnt_host) cannot accept a host name
// which would need to be resolved - only IP addresses are acceptable?
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// An alternate for http.Agent, which however merely sets its own
// implementation of self.createConnection() in order to force a
// particular binding for the client socket.
function bindingAgent(options) {
http.Agent.call(this, options);
// We are changing only this one property of Agent
this.createConnection = bindingCreateConnection;
}
util.inherits(bindingAgent, http.Agent);
function bindingCreateConnection(port, host, options) {
ltrc(' bindingCreateConnection(%j,%j,%j) called....', port, host, options);
ltrc(' binding new client socket to %j', clnt_host);
var socket;
socket = new net.Socket({ handle: net._createServerHandle(clnt_host)});
socket.connect(port, host);
socket.marker_of_insanity = 'hiya';
return socket;
}
var optionsAgent = {};
var ourBindingAgent = new bindingAgent(optionsAgent);
//- - - - - - - - - - - - - - - - - - - - - - - -
var options = { 'host': host_host, 'port': host_port };
// >>>> Set to true to enable our experiment with alternate realities <<<<
if (1) {
options.agent = ourBindingAgent;
}
var creq = http.get(options);
creq.on('response', function (res) {
var socket = creq.connection;
if (socket) {
var host_bound_addr = { 'address': socket.remoteAddress,
'port': socket.remotePort };
ltrc(' Server address %j', host_bound_addr );
var clnt_bound_addr = socket.address();
ltrc(' Client address %j', clnt_bound_addr );
ltrc(' (insanity: %j )', socket.marker_of_insanity ? 'yes' : 'no');
}
ltrc(' Resp STATUS: %j', res.statusCode);
var headers = res.headers;
var keys = Object.keys(headers);
ltrc(' HEADERS: (%d)', keys.length);
for( var idx=0, l=keys.length; idx < l ; idx++) {
var key = keys[idx];
ltrc(' %j %j', key, headers[key]);
}
res.setEncoding('utf8');
res.on('data', function (chunk) {
ltrc(' DATA: %j', chunk);
});
});
creq.on('error', function (err) {
ltrc(' Resp ERROR: %j', err.message);
});
// vim:ft=javascript:ts=2:sw=2:et:is:hls:ss=10:tw=160:
// Simple HTTP server just for testing
var assert = require('assert'),
dns = require('dns'),
http = require('http'),
util = require('util');
function ltrc() { console.log.apply(this, arguments); }
/- - - - - - - - - - - - - - - - - - - - - - - -
var our_port = 5439;
var our_host = '192.168.57.162';
our_host = 'tlsf16a';
our_host = '127.0.0.1';
our_host = 'localhost';
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Create a server just to dump information about requests
function onRequest(req, res) {
var socket = req.connection;
var host_bound_addr = socket.address();
ltrc('\nHTTP request to %j', host_bound_addr );
var clnt_bound_addr = { 'address': socket.remoteAddress,
'port': socket.remotePort };
ltrc('HTTP request from %j', clnt_bound_addr );
var headers = req.headers;
var keys = Object.keys(headers);
ltrc('\nHTTP request headers: (%j)', keys.length );
for( var idx=0, l=keys.length; idx < l ; idx++) {
var key = keys[idx];
ltrc(' %j %j', key, headers[key]);
}
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('okay');
}
var hsrvr = http.createServer(onRequest);
function onListening() {
var srvr = this;
var host_bound_addr = srvr.address();
ltrc('HTTP server is listening on %j', host_bound_addr );
}
hsrvr.listen(our_port, our_host, onListening);
// vim:ft=javascript:ts=2:sw=2:et:is:hls:ss=10:tw=160:
Using normal http.Agent that does nothing regarding socket binding:
[Tom@tlsf16a testing]$ ../node063 httpclnt03.js
Server address {"address":"127.0.0.1","port":5439}
>>>> Client address {"port":45146,"family":2,"address":"127.0.0.1"}
(insanity: "no" )
Resp STATUS: 200
HEADERS: (3)
"content-type" "text/plain"
"connection" "keep-alive"
"transfer-encoding" "chunked"
DATA: "okay"
Using own Agent that forces client binding:
[Tom@tlsf16a testing]$ ../node063 httpclnt03.js
bindingCreateConnection(5439,"127.0.0.1",{}) called....
binding new client socket to "192.168.57.162"
Server address {"address":"127.0.0.1","port":5439}
>>>> Client address {"port":50797,"family":2,"address":"192.168.57.162"}
(insanity: "yes" )
Resp STATUS: 200
HEADERS: (3)
"content-type" "text/plain"
"connection" "keep-alive"
"transfer-encoding" "chunked"
DATA: "okay"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment