Skip to content

Instantly share code, notes, and snippets.

@w3fs
Forked from TooTallNate/agent.js
Created June 14, 2018 16:00
Show Gist options
  • Save w3fs/f20e9cdb3283b84c66ed9ee8f790f2bb to your computer and use it in GitHub Desktop.
Save w3fs/f20e9cdb3283b84c66ed9ee8f790f2bb to your computer and use it in GitHub Desktop.

Revisions

  1. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 1 addition and 3 deletions.
    4 changes: 1 addition & 3 deletions usage-https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,7 @@

    /**
    * Usage example of the `HttpsProxyAgent` class proxying an
    * HTTPS (SSL) endpoint over an HTTP (unencrypted) proxy.
    *
    * WARNING: This is a VERY DANGEROUS thing to do!
    * HTTPS (SSL) endpoint over an HTTP(s) proxy.
    */

    var url = require('url');
  2. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -62,6 +62,8 @@ HttpsProxyAgent.prototype.createConnection = function (opts, fn) {

    socket.ondata = function (b, offset, length) {
    var buf = b.slice(offset, length);
    // TODO: verify that the socket is properly connected, check response...

    socket.ondata = null;

    // since the proxy is connecting to an SSL server, we have
  3. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion http-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -74,7 +74,7 @@ HttpProxyAgent.prototype.createConnection = function (opts, fn) {
    var socket;
    var info = {
    host: this.proxy.hostname || this.proxy.host,
    port: +this.proxy.port || 80
    port: +this.proxy.port || (this.secure ? 443 : 80)
    };
    if (this.secure) {
    socket = tls.connect(info);
  4. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -47,7 +47,7 @@ HttpsProxyAgent.prototype.createConnection = function (opts, fn) {
    var socket;
    var info = {
    host: this.proxy.hostname || this.proxy.host,
    port: +this.proxy.port
    port: +this.proxy.port || (this.secure ? 443 : 80)
    };
    if (this.secure) {
    socket = tls.connect(info);
  5. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -31,6 +31,12 @@ function HttpsProxyAgent (opts) {
    }
    inherits(HttpsProxyAgent, Agent);

    /**
    * Default port to connect to.
    */

    Agent.prototype.defaultPort = 443;

    /**
    * Initiates a TCP connection to the specified HTTP proxy server.
    *
  6. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -17,7 +17,7 @@ module.exports = HttpsProxyAgent;

    /**
    * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to the
    * specified "HTTP proxy server" in order to proxy HTTP requests.
    * specified "HTTP(s) proxy server" in order to proxy HTTPS requests.
    *
    * @api public
    */
  7. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 7 additions and 1 deletion.
    8 changes: 7 additions & 1 deletion agent.js
    Original file line number Diff line number Diff line change
    @@ -31,6 +31,12 @@ function Agent () {
    }
    inherits(Agent, EventEmitter);

    /**
    * Default port to connect to.
    */

    Agent.prototype.defaultPort = 80;

    /**
    * Called by node-core's "_http_client.js" module when creating a new HTTP request
    * with this Agent instance.
    @@ -58,7 +64,7 @@ Agent.prototype.addRequest = function (req, host, port, localAddress) {
    // create the `net.Socket` instance
    var info = {
    host: opts.hostname || opts.host,
    port: +opts.port || 80,
    port: +opts.port || this.defaultPort,
    localAddress: opts.localAddress
    };
    this.createConnection(info, function (err, socket) {
  8. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 15 additions and 3 deletions.
    18 changes: 15 additions & 3 deletions http-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -38,13 +38,25 @@ inherits(HttpProxyAgent, Agent);
    */

    HttpProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
    var opts;
    if ('object' == typeof host) {
    // >= v0.11.x API
    opts = host;
    } else {
    // <= v0.10.x API
    opts = {
    host: host,
    port: port,
    localAddress: localAddress
    };
    }

    // change the `http.ClientRequest` instance's "path" field
    // to the absolute path of the URL that will be requested
    var absolute = url.format({
    protocol: 'http:',
    hostname: host,
    port: port,
    hostname: opts.hostname || opts.host,
    port: opts.port,
    pathname: req.path
    });
    req.path = absolute;
    @@ -62,7 +74,7 @@ HttpProxyAgent.prototype.createConnection = function (opts, fn) {
    var socket;
    var info = {
    host: this.proxy.hostname || this.proxy.host,
    port: +this.proxy.port
    port: +this.proxy.port || 80
    };
    if (this.secure) {
    socket = tls.connect(info);
  9. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 18 additions and 6 deletions.
    24 changes: 18 additions & 6 deletions agent.js
    Original file line number Diff line number Diff line change
    @@ -39,17 +39,29 @@ inherits(Agent, EventEmitter);
    */

    Agent.prototype.addRequest = function (req, host, port, localAddress) {
    var opts;
    if ('object' == typeof host) {
    // >= v0.11.x API
    opts = host;
    } else {
    // <= v0.10.x API
    opts = {
    host: host,
    port: port,
    localAddress: localAddress
    };
    }

    // hint to use "Connection: close"
    req.shouldKeepAlive = false;

    // create the `net.Socket` instance
    var opts = {};
    opts.port = port;
    opts.host = host;
    if (localAddress) opts.localAddress = localAddress;

    this.createConnection(opts, function (err, socket) {
    var info = {
    host: opts.hostname || opts.host,
    port: +opts.port || 80,
    localAddress: opts.localAddress
    };
    this.createConnection(info, function (err, socket) {
    if (err) {
    req.emit('error', err);
    } else {
  10. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 2 changed files with 4 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions usage-http-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -9,10 +9,12 @@ var HttpProxyAgent = require('./http-proxy-agent');

    // HTTP proxy to connect to
    var proxy = process.env.http_proxy || 'http://168.63.76.32:3128';
    console.log('using proxy server %j', proxy);
    proxy = url.parse(proxy);

    // HTTP endpoint for the proxy to connect to
    var endpoint = process.argv[2] || 'http://nodejs.org/api/';
    console.log('attempting to GET %j', endpoint);
    var opts = url.parse(endpoint);

    // create an instance of the `HttpProxyAgent` class with the proxy server information
    2 changes: 2 additions & 0 deletions usage-https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -12,10 +12,12 @@ var HttpsProxyAgent = require('./https-proxy-agent');

    // HTTP proxy to connect to
    var proxy = process.env.http_proxy || 'http://168.63.76.32:3128';
    console.log('using proxy server %j', proxy);
    proxy = url.parse(proxy);

    // HTTPS endpoint for the proxy to connect to
    var endpoint = process.argv[2] || 'https://gist.github.com/TooTallNate/5952254/raw/07972db49b5b70a212c39dfee56ed3ab82f8179c/agent.js';
    console.log('attempting to GET %j', endpoint);
    var opts = url.parse(endpoint);

    // create an instance of the `HttpsProxyAgent` class with the proxy server information
  11. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion http-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -62,7 +62,7 @@ HttpProxyAgent.prototype.createConnection = function (opts, fn) {
    var socket;
    var info = {
    host: this.proxy.hostname || this.proxy.host,
    port: this.proxy.port
    port: +this.proxy.port
    };
    if (this.secure) {
    socket = tls.connect(info);
    2 changes: 1 addition & 1 deletion https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -41,7 +41,7 @@ HttpsProxyAgent.prototype.createConnection = function (opts, fn) {
    var socket;
    var info = {
    host: this.proxy.hostname || this.proxy.host,
    port: this.proxy.port
    port: +this.proxy.port
    };
    if (this.secure) {
    socket = tls.connect(info);
  12. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 2 changed files with 22 additions and 64 deletions.
    42 changes: 12 additions & 30 deletions http-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -27,6 +27,7 @@ function HttpProxyAgent (opts) {
    if ('string' == typeof opts) opts = url.parse(opts);
    Agent.call(this);
    this.proxy = opts;
    this.secure = this.proxy.protocol && this.proxy.protocol == 'https:';
    }
    inherits(HttpProxyAgent, Agent);

    @@ -37,7 +38,6 @@ inherits(HttpProxyAgent, Agent);
    */

    HttpProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
    console.error(arguments);

    // change the `http.ClientRequest` instance's "path" field
    // to the absolute path of the URL that will be requested
    @@ -47,8 +47,7 @@ HttpProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
    port: port,
    pathname: req.path
    });
    console.log({ absolute: absolute });
    //req.path = absolute;
    req.path = absolute;

    Agent.prototype.addRequest.apply(this, arguments);
    };
    @@ -60,34 +59,17 @@ HttpProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
    */

    HttpProxyAgent.prototype.createConnection = function (opts, fn) {
    var socket = net.connect({
    var socket;
    var info = {
    host: this.proxy.hostname || this.proxy.host,
    port: this.proxy.port
    });
    var msg = 'CONNECT ' + opts.host + ':' + opts.port + ' HTTP/1.1\r\n' +
    'Host: ' + opts.host + ':' + opts.port + '\r\n' +
    '\r\n';
    console.log(msg);
    socket.write(msg);

    var write = socket.write;
    socket.write = function (b) {
    //console.error(0, 'write(%d bytes)', b.length, b.toString());
    return write.apply(this, arguments);
    };

    socket.ondata = function (b, offset, length) {
    var buf = b.slice(offset, length);
    console.log(buf, buf.toString());

    socket.ondata = null;

    // since the proxy is connecting to an SSL server, we have
    // to upgrade this socket connection to an SSL connection
    socket = tls.connect({
    socket: socket,
    servername: opts.host
    });
    fn(null, socket);
    };
    if (this.secure) {
    socket = tls.connect(info);
    } else {
    socket = net.connect(info);
    }

    fn(null, socket);
    return socket;
    };
    44 changes: 10 additions & 34 deletions https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -27,59 +27,35 @@ function HttpsProxyAgent (opts) {
    if ('string' == typeof opts) opts = url.parse(opts);
    Agent.call(this);
    this.proxy = opts;
    this.secure = this.proxy.protocol && this.proxy.protocol == 'https:';
    }
    inherits(HttpsProxyAgent, Agent);

    /**
    * Called when the node-core HTTP client library is creating a new HTTP request.
    *
    * @api public
    */

    HttpsProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
    console.error(arguments);

    // change the `http.ClientRequest` instance's "path" field
    // to the absolute path of the URL that will be requested
    var absolute = url.format({
    protocol: 'http:',
    hostname: host,
    port: port,
    pathname: req.path
    });
    console.log({ absolute: absolute });
    //req.path = absolute;

    Agent.prototype.addRequest.apply(this, arguments);
    };

    /**
    * Initiates a TCP connection to the specified HTTP proxy server.
    *
    * @api public
    */

    HttpsProxyAgent.prototype.createConnection = function (opts, fn) {
    var socket = net.connect({
    var socket;
    var info = {
    host: this.proxy.hostname || this.proxy.host,
    port: this.proxy.port
    });
    };
    if (this.secure) {
    socket = tls.connect(info);
    } else {
    socket = net.connect(info);
    }

    var msg = 'CONNECT ' + opts.host + ':' + opts.port + ' HTTP/1.1\r\n' +
    'Host: ' + opts.host + ':' + opts.port + '\r\n' +
    '\r\n';
    console.log(msg);
    socket.write(msg);

    var write = socket.write;
    socket.write = function (b) {
    //console.error(0, 'write(%d bytes)', b.length, b.toString());
    return write.apply(this, arguments);
    };

    socket.ondata = function (b, offset, length) {
    var buf = b.slice(offset, length);
    console.log(buf, buf.toString());

    socket.ondata = null;

    // since the proxy is connecting to an SSL server, we have
  13. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 2 changed files with 128 additions and 5 deletions.
    40 changes: 35 additions & 5 deletions http-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,10 @@

    /**
    * Module dependencies.
    */

    var net = require('net');
    var tls = require('tls');
    var url = require('url');
    var Agent = require('./agent');
    var inherits = require('util').inherits;
    @@ -35,6 +37,7 @@ inherits(HttpProxyAgent, Agent);
    */

    HttpProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
    console.error(arguments);

    // change the `http.ClientRequest` instance's "path" field
    // to the absolute path of the URL that will be requested
    @@ -44,7 +47,8 @@ HttpProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
    port: port,
    pathname: req.path
    });
    req.path = absolute;
    console.log({ absolute: absolute });
    //req.path = absolute;

    Agent.prototype.addRequest.apply(this, arguments);
    };
    @@ -55,9 +59,35 @@ HttpProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
    * @api public
    */

    HttpProxyAgent.prototype.createConnection = function (opts) {
    return net.connect({
    host: this.proxy.hostname,
    HttpProxyAgent.prototype.createConnection = function (opts, fn) {
    var socket = net.connect({
    host: this.proxy.hostname || this.proxy.host,
    port: this.proxy.port
    });
    };
    var msg = 'CONNECT ' + opts.host + ':' + opts.port + ' HTTP/1.1\r\n' +
    'Host: ' + opts.host + ':' + opts.port + '\r\n' +
    '\r\n';
    console.log(msg);
    socket.write(msg);

    var write = socket.write;
    socket.write = function (b) {
    //console.error(0, 'write(%d bytes)', b.length, b.toString());
    return write.apply(this, arguments);
    };

    socket.ondata = function (b, offset, length) {
    var buf = b.slice(offset, length);
    console.log(buf, buf.toString());

    socket.ondata = null;

    // since the proxy is connecting to an SSL server, we have
    // to upgrade this socket connection to an SSL connection
    socket = tls.connect({
    socket: socket,
    servername: opts.host
    });
    fn(null, socket);
    };
    };
    93 changes: 93 additions & 0 deletions https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,93 @@

    /**
    * Module dependencies.
    */

    var net = require('net');
    var tls = require('tls');
    var url = require('url');
    var Agent = require('./agent');
    var inherits = require('util').inherits;

    /**
    * Module exports.
    */

    module.exports = HttpsProxyAgent;

    /**
    * The `HttpsProxyAgent` implements an HTTP Agent subclass that connects to the
    * specified "HTTP proxy server" in order to proxy HTTP requests.
    *
    * @api public
    */

    function HttpsProxyAgent (opts) {
    if (!(this instanceof HttpsProxyAgent)) return new HttpsProxyAgent(opts);
    if ('string' == typeof opts) opts = url.parse(opts);
    Agent.call(this);
    this.proxy = opts;
    }
    inherits(HttpsProxyAgent, Agent);

    /**
    * Called when the node-core HTTP client library is creating a new HTTP request.
    *
    * @api public
    */

    HttpsProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
    console.error(arguments);

    // change the `http.ClientRequest` instance's "path" field
    // to the absolute path of the URL that will be requested
    var absolute = url.format({
    protocol: 'http:',
    hostname: host,
    port: port,
    pathname: req.path
    });
    console.log({ absolute: absolute });
    //req.path = absolute;

    Agent.prototype.addRequest.apply(this, arguments);
    };

    /**
    * Initiates a TCP connection to the specified HTTP proxy server.
    *
    * @api public
    */

    HttpsProxyAgent.prototype.createConnection = function (opts, fn) {
    var socket = net.connect({
    host: this.proxy.hostname || this.proxy.host,
    port: this.proxy.port
    });
    var msg = 'CONNECT ' + opts.host + ':' + opts.port + ' HTTP/1.1\r\n' +
    'Host: ' + opts.host + ':' + opts.port + '\r\n' +
    '\r\n';
    console.log(msg);
    socket.write(msg);

    var write = socket.write;
    socket.write = function (b) {
    //console.error(0, 'write(%d bytes)', b.length, b.toString());
    return write.apply(this, arguments);
    };

    socket.ondata = function (b, offset, length) {
    var buf = b.slice(offset, length);
    console.log(buf, buf.toString());

    socket.ondata = null;

    // since the proxy is connecting to an SSL server, we have
    // to upgrade this socket connection to an SSL connection
    socket = tls.connect({
    socket: socket,
    servername: opts.host
    });
    fn(null, socket);
    };
    };
  14. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 1 changed file with 14 additions and 5 deletions.
    19 changes: 14 additions & 5 deletions agent.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@

    /**
    * Module dependencies.
    */
    @@ -47,8 +48,14 @@ Agent.prototype.addRequest = function (req, host, port, localAddress) {
    opts.port = port;
    opts.host = host;
    if (localAddress) opts.localAddress = localAddress;
    var socket = this.createConnection(opts);
    req.onSocket(socket);

    this.createConnection(opts, function (err, socket) {
    if (err) {
    req.emit('error', err);
    } else {
    req.onSocket(socket);
    }
    });
    };

    /**
    @@ -57,6 +64,8 @@ Agent.prototype.addRequest = function (req, host, port, localAddress) {
    * @api public
    */

    Agent.prototype.createConnection = function (opts) {
    return net.connect(opts);
    };
    Agent.prototype.createConnection = function (opts, fn) {
    var socket = net.connect(opts);
    fn(null, socket);
    return socket;
    };
  15. @TooTallNate TooTallNate revised this gist Jul 9, 2013. 2 changed files with 5 additions and 9 deletions.
    14 changes: 5 additions & 9 deletions usage-http-proxy-agent-https.js → usage-https-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -1,13 +1,14 @@

    /**
    * Usage example of the `HttpProxyAgent` class proxying an HTTPS (SSL) endpoint.
    * Usage example of the `HttpsProxyAgent` class proxying an
    * HTTPS (SSL) endpoint over an HTTP (unencrypted) proxy.
    *
    * WARNING: This is a VERY DANGEROUS thing to do!
    */

    var url = require('url');
    var https = require('https');
    var HttpProxyAgent = require('./http-proxy-agent');
    var HttpsProxyAgent = require('./https-proxy-agent');

    // HTTP proxy to connect to
    var proxy = process.env.http_proxy || 'http://168.63.76.32:3128';
    @@ -17,13 +18,8 @@ proxy = url.parse(proxy);
    var endpoint = process.argv[2] || 'https://gist.github.com/TooTallNate/5952254/raw/07972db49b5b70a212c39dfee56ed3ab82f8179c/agent.js';
    var opts = url.parse(endpoint);

    // create an instance of the `HttpProxyAgent` class with the proxy server information
    var agent = new HttpProxyAgent(proxy);
    opts.agent = agent;

    // mark the agent as `secure`, meaning that HTTP requests going to it will
    // be through an SSL socket (and the HTTP CONNECT method will be used)
    opts.agent.secure = true;
    // create an instance of the `HttpsProxyAgent` class with the proxy server information
    opts.agent = new HttpsProxyAgent(proxy);

    https.get(opts, function (res) {
    console.log('"response" event!', res.headers);
  16. @TooTallNate TooTallNate revised this gist Jul 8, 2013. 2 changed files with 11 additions and 5 deletions.
    5 changes: 3 additions & 2 deletions usage-http-proxy-agent-http.js
    Original file line number Diff line number Diff line change
    @@ -16,9 +16,10 @@ var endpoint = process.argv[2] || 'http://nodejs.org/api/';
    var opts = url.parse(endpoint);

    // create an instance of the `HttpProxyAgent` class with the proxy server information
    opts.agent = new HttpProxyAgent(proxy);
    var agent = new HttpProxyAgent(proxy);
    opts.agent = agent;

    var req = http.get(opts, function (res) {
    http.get(opts, function (res) {
    console.log('"response" event!', res.headers);
    res.pipe(process.stdout);
    });
    11 changes: 8 additions & 3 deletions usage-http-proxy-agent-https.js
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    /**
    * Usage example of the `HttpProxyAgent` class proxying an HTTPS (SSL) endpoint.
    *
    * WARNING: this is a VERY DANGEROUS thing to do!
    * WARNING: This is a VERY DANGEROUS thing to do!
    */

    var url = require('url');
    @@ -18,9 +18,14 @@ var endpoint = process.argv[2] || 'https://gist.github.com/TooTallNate/5952254/r
    var opts = url.parse(endpoint);

    // create an instance of the `HttpProxyAgent` class with the proxy server information
    opts.agent = new HttpProxyAgent(proxy);
    var agent = new HttpProxyAgent(proxy);
    opts.agent = agent;

    var req = https.get(opts, function (res) {
    // mark the agent as `secure`, meaning that HTTP requests going to it will
    // be through an SSL socket (and the HTTP CONNECT method will be used)
    opts.agent.secure = true;

    https.get(opts, function (res) {
    console.log('"response" event!', res.headers);
    res.pipe(process.stdout);
    });
  17. @TooTallNate TooTallNate revised this gist Jul 8, 2013. 3 changed files with 29 additions and 3 deletions.
    2 changes: 1 addition & 1 deletion usage-agent.js
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@
    /**
    * Usage example of the `Agent` base class.
    */

    var url = require('url');
    var http = require('http');
    var Agent = require('./agent');
    4 changes: 2 additions & 2 deletions usage-http-proxy-agent-http.js
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,8 @@

    /**
    * Usage example of the `Agent` base class.
    * Usage example of the `HttpProxyAgent` class proxying an HTTP endpoint.
    */

    var url = require('url');
    var http = require('http');
    var HttpProxyAgent = require('./http-proxy-agent');
    26 changes: 26 additions & 0 deletions usage-http-proxy-agent-https.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,26 @@

    /**
    * Usage example of the `HttpProxyAgent` class proxying an HTTPS (SSL) endpoint.
    *
    * WARNING: this is a VERY DANGEROUS thing to do!
    */

    var url = require('url');
    var https = require('https');
    var HttpProxyAgent = require('./http-proxy-agent');

    // HTTP proxy to connect to
    var proxy = process.env.http_proxy || 'http://168.63.76.32:3128';
    proxy = url.parse(proxy);

    // HTTPS endpoint for the proxy to connect to
    var endpoint = process.argv[2] || 'https://gist.github.com/TooTallNate/5952254/raw/07972db49b5b70a212c39dfee56ed3ab82f8179c/agent.js';
    var opts = url.parse(endpoint);

    // create an instance of the `HttpProxyAgent` class with the proxy server information
    opts.agent = new HttpProxyAgent(proxy);

    var req = https.get(opts, function (res) {
    console.log('"response" event!', res.headers);
    res.pipe(process.stdout);
    });
  18. @TooTallNate TooTallNate revised this gist Jul 8, 2013. 3 changed files with 25 additions and 1 deletion.
    1 change: 0 additions & 1 deletion http-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@

    /**
    * Module dependencies.
    */
    1 change: 1 addition & 0 deletions usage-agent.js
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@

    /**
    * Usage example of the `Agent` base class.
    */
    24 changes: 24 additions & 0 deletions usage-http-proxy-agent-http.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,24 @@

    /**
    * Usage example of the `Agent` base class.
    */

    var url = require('url');
    var http = require('http');
    var HttpProxyAgent = require('./http-proxy-agent');

    // HTTP proxy to connect to
    var proxy = process.env.http_proxy || 'http://168.63.76.32:3128';
    proxy = url.parse(proxy);

    // HTTP endpoint for the proxy to connect to
    var endpoint = process.argv[2] || 'http://nodejs.org/api/';
    var opts = url.parse(endpoint);

    // create an instance of the `HttpProxyAgent` class with the proxy server information
    opts.agent = new HttpProxyAgent(proxy);

    var req = http.get(opts, function (res) {
    console.log('"response" event!', res.headers);
    res.pipe(process.stdout);
    });
  19. @TooTallNate TooTallNate revised this gist Jul 8, 2013. 2 changed files with 64 additions and 1 deletion.
    64 changes: 64 additions & 0 deletions http-proxy-agent.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@

    /**
    * Module dependencies.
    */

    var net = require('net');
    var url = require('url');
    var Agent = require('./agent');
    var inherits = require('util').inherits;

    /**
    * Module exports.
    */

    module.exports = HttpProxyAgent;

    /**
    * The `HttpProxyAgent` implements an HTTP Agent subclass that connects to the
    * specified "HTTP proxy server" in order to proxy HTTP requests.
    *
    * @api public
    */

    function HttpProxyAgent (opts) {
    if (!(this instanceof HttpProxyAgent)) return new HttpProxyAgent(opts);
    if ('string' == typeof opts) opts = url.parse(opts);
    Agent.call(this);
    this.proxy = opts;
    }
    inherits(HttpProxyAgent, Agent);

    /**
    * Called when the node-core HTTP client library is creating a new HTTP request.
    *
    * @api public
    */

    HttpProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {

    // change the `http.ClientRequest` instance's "path" field
    // to the absolute path of the URL that will be requested
    var absolute = url.format({
    protocol: 'http:',
    hostname: host,
    port: port,
    pathname: req.path
    });
    req.path = absolute;

    Agent.prototype.addRequest.apply(this, arguments);
    };

    /**
    * Initiates a TCP connection to the specified HTTP proxy server.
    *
    * @api public
    */

    HttpProxyAgent.prototype.createConnection = function (opts) {
    return net.connect({
    host: this.proxy.hostname,
    port: this.proxy.port
    });
    };
    1 change: 0 additions & 1 deletion usage-agent.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@

    /**
    * Usage example of the `Agent` base class.
    */
  20. @TooTallNate TooTallNate revised this gist Jul 8, 2013. 2 changed files with 17 additions and 1 deletion.
    1 change: 0 additions & 1 deletion agent.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@

    /**
    * Module dependencies.
    */
    17 changes: 17 additions & 0 deletions usage-agent.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,17 @@

    /**
    * Usage example of the `Agent` base class.
    */

    var url = require('url');
    var http = require('http');
    var Agent = require('./agent');

    var endpoint = process.argv[2] || 'http://nodejs.org/api/';
    var opts = url.parse(endpoint);
    opts.agent = new Agent();

    var req = http.get(opts, function (res) {
    console.log('"response" event!', res.headers);
    res.pipe(process.stdout);
    });
  21. @TooTallNate TooTallNate created this gist Jul 8, 2013.
    63 changes: 63 additions & 0 deletions agent.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@

    /**
    * Module dependencies.
    */

    var net = require('net');
    var inherits = require('util').inherits;
    var EventEmitter = require('events').EventEmitter;

    /**
    * Module exports.
    */

    module.exports = Agent;

    /**
    * Base HTTP "Agent" class. Emulates the node-core `http.Agent` class, but
    * implemented in a way that can be easily extended for additional functionality.
    *
    * This base implementation does no socket pooling, and opens
    * a new connection for every HTTP request.
    *
    * It behaves more-or-less like `agent: false`.
    *
    * @api public
    */

    function Agent () {
    if (!(this instanceof Agent)) return new Agent();
    EventEmitter.call(this);
    }
    inherits(Agent, EventEmitter);

    /**
    * Called by node-core's "_http_client.js" module when creating a new HTTP request
    * with this Agent instance.
    *
    * @api public
    */

    Agent.prototype.addRequest = function (req, host, port, localAddress) {

    // hint to use "Connection: close"
    req.shouldKeepAlive = false;

    // create the `net.Socket` instance
    var opts = {};
    opts.port = port;
    opts.host = host;
    if (localAddress) opts.localAddress = localAddress;
    var socket = this.createConnection(opts);
    req.onSocket(socket);
    };

    /**
    * Creates and returns a `net.Socket` instance to use for an HTTP request.
    *
    * @api public
    */

    Agent.prototype.createConnection = function (opts) {
    return net.connect(opts);
    };