127 lines
2.7 KiB
JavaScript
127 lines
2.7 KiB
JavaScript
|
|
||
|
/**
|
||
|
* Module dependencies.
|
||
|
*/
|
||
|
|
||
|
var proxyAgent = require('proxy-agent');
|
||
|
var debug = require('debug')('superagent-proxy');
|
||
|
|
||
|
/**
|
||
|
* Module exports.
|
||
|
*/
|
||
|
|
||
|
module.exports = setup;
|
||
|
|
||
|
/**
|
||
|
* Adds a `.proxy(uri)` function to the "superagent" module's Request class.
|
||
|
*
|
||
|
* ``` js
|
||
|
* var request = require('superagent');
|
||
|
* require('superagent-proxy')(request);
|
||
|
*
|
||
|
* request
|
||
|
* .get(uri)
|
||
|
* .proxy(uri)
|
||
|
* .end(fn);
|
||
|
* ```
|
||
|
*
|
||
|
* Or, you can pass in a `superagent.Request` instance, and it's like calling the
|
||
|
* `.proxy(uri)` function on it, but without extending the prototype:
|
||
|
*
|
||
|
* ``` js
|
||
|
* var request = require('superagent');
|
||
|
* var proxy = require('superagent-proxy');
|
||
|
*
|
||
|
* proxy(request.get(uri), uri).end(fn);
|
||
|
* ```
|
||
|
*
|
||
|
* @param {Object} superagent The `superagent` exports object
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function setup (superagent, uri) {
|
||
|
var Request = superagent.Request;
|
||
|
if (Request) {
|
||
|
// the superagent exports object - extent Request with "proxy"
|
||
|
Request.prototype.proxy = proxy;
|
||
|
return superagent;
|
||
|
} else {
|
||
|
// assume it's a `superagent.Request` instance
|
||
|
return proxy.call(superagent, uri);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets the proxy server to use for this HTTP(s) request.
|
||
|
*
|
||
|
* @param {String} uri proxy url
|
||
|
* @api public
|
||
|
*/
|
||
|
|
||
|
function proxy (uri) {
|
||
|
debug('Request#proxy(%o)', uri);
|
||
|
|
||
|
// we need to observe the `url` field from now on... Superagent sometimes
|
||
|
// re-uses the `req` instance but changes its `url` field (i.e. in the case of
|
||
|
// a redirect), so when that happens we need to potentially re-set the proxy
|
||
|
// agent
|
||
|
setupUrl(this);
|
||
|
|
||
|
// attempt to get a proxying `http.Agent` instance
|
||
|
var agent = proxyAgent(uri);
|
||
|
|
||
|
// if we have an `http.Agent` instance then call the .agent() function
|
||
|
if (agent) this.agent(agent);
|
||
|
|
||
|
// store the proxy URI in case of changes to the `url` prop in the future
|
||
|
this._proxyUri = uri;
|
||
|
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sets up a get/set descriptor for the `url` property of the provided `req`
|
||
|
* Request instance. This is so that we can re-run the "proxy agent" logic when
|
||
|
* the `url` field is changed, i.e. during a 302 Redirect scenario.
|
||
|
*
|
||
|
* @api private
|
||
|
*/
|
||
|
|
||
|
function setupUrl (req) {
|
||
|
var desc = Object.getOwnPropertyDescriptor(req, 'url');
|
||
|
if (desc.get == getUrl && desc.set == setUrl) return; // already patched
|
||
|
|
||
|
// save current value
|
||
|
req._url = req.url;
|
||
|
|
||
|
desc.get = getUrl;
|
||
|
desc.set = setUrl;
|
||
|
delete desc.value;
|
||
|
delete desc.writable;
|
||
|
|
||
|
Object.defineProperty(req, 'url', desc);
|
||
|
debug('patched superagent Request "url" property for changes');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* `url` property getter.
|
||
|
*
|
||
|
* @api protected
|
||
|
*/
|
||
|
|
||
|
function getUrl () {
|
||
|
return this._url;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* `url` property setter.
|
||
|
*
|
||
|
* @api protected
|
||
|
*/
|
||
|
|
||
|
function setUrl (v) {
|
||
|
debug('set `.url`: %o', v);
|
||
|
this._url = v;
|
||
|
proxy.call(this, this._proxyUri);
|
||
|
}
|