scoped-http-client
Version:
http client request wrapper
285 lines (253 loc) • 7.34 kB
JavaScript
// Generated by CoffeeScript 1.9.3
var ScopedClient, extend, http, https, path, qs, reduce, url;
path = require('path');
http = require('http');
https = require('https');
url = require('url');
qs = require('querystring');
ScopedClient = (function() {
ScopedClient.nonPassThroughOptions = ['headers', 'hostname', 'encoding', 'auth', 'port', 'protocol', 'agent', 'httpAgent', 'httpsAgent', 'query', 'host', 'path', 'pathname', 'slashes', 'hash'];
function ScopedClient(url, options) {
this.options = this.buildOptions(url, options);
this.passthroughOptions = reduce(extend({}, this.options), ScopedClient.nonPassThroughOptions);
}
ScopedClient.prototype.request = function(method, reqBody, callback) {
var agent, err, headers, port, req, requestModule, requestOptions, sendingData;
if (typeof reqBody === 'function') {
callback = reqBody;
reqBody = null;
}
try {
headers = extend({}, this.options.headers);
sendingData = reqBody && reqBody.length > 0;
headers.Host = this.options.hostname;
if (this.options.port) {
headers.Host += ":" + this.options.port;
}
if (callback === void 0) {
headers['Content-Length'] = sendingData ? Buffer.byteLength(reqBody, this.options.encoding) : 0;
}
if (this.options.auth) {
headers['Authorization'] = 'Basic ' + new Buffer(this.options.auth).toString('base64');
}
port = this.options.port || ScopedClient.defaultPort[this.options.protocol] || 80;
agent = this.options.agent;
if (this.options.protocol === 'https:') {
requestModule = https;
if (this.options.httpsAgent) {
agent = this.options.httpsAgent;
}
} else {
requestModule = http;
if (this.options.httpAgent) {
agent = this.options.httpAgent;
}
}
requestOptions = {
port: port,
host: this.options.hostname,
method: method,
path: this.fullPath(),
headers: headers,
agent: agent
};
extend(requestOptions, this.passthroughOptions);
req = requestModule.request(requestOptions);
if (this.options.timeout) {
req.setTimeout(this.options.timeout, function() {
return req.abort();
});
}
if (callback) {
req.on('error', callback);
}
if (sendingData) {
req.write(reqBody, this.options.encoding);
}
if (callback) {
callback(null, req);
}
} catch (_error) {
err = _error;
if (callback) {
callback(err, req);
}
}
return (function(_this) {
return function(callback) {
if (callback) {
req.on('response', function(res) {
var body;
res.setEncoding(_this.options.encoding);
body = '';
res.on('data', function(chunk) {
return body += chunk;
});
return res.on('end', function() {
return callback(null, res, body);
});
});
req.on('error', function(error) {
return callback(error, null, null);
});
}
req.end();
return _this;
};
})(this);
};
ScopedClient.prototype.fullPath = function(p) {
var full, search;
search = qs.stringify(this.options.query);
full = this.join(p);
if (search.length > 0) {
full += "?" + search;
}
return full;
};
ScopedClient.prototype.scope = function(url, options, callback) {
var override, scoped;
override = this.buildOptions(url, options);
scoped = new ScopedClient(this.options).protocol(override.protocol).host(override.hostname).path(override.pathname);
if (typeof url === 'function') {
callback = url;
} else if (typeof options === 'function') {
callback = options;
}
if (callback) {
callback(scoped);
}
return scoped;
};
ScopedClient.prototype.join = function(suffix) {
var p;
p = this.options.pathname || '/';
if (suffix && suffix.length > 0) {
if (suffix.match(/^\//)) {
return suffix;
} else {
return path.join(p, suffix);
}
} else {
return p;
}
};
ScopedClient.prototype.path = function(p) {
this.options.pathname = this.join(p);
return this;
};
ScopedClient.prototype.query = function(key, value) {
var base;
(base = this.options).query || (base.query = {});
if (typeof key === 'string') {
if (value) {
this.options.query[key] = value;
} else {
delete this.options.query[key];
}
} else {
extend(this.options.query, key);
}
return this;
};
ScopedClient.prototype.host = function(h) {
if (h && h.length > 0) {
this.options.hostname = h;
}
return this;
};
ScopedClient.prototype.port = function(p) {
if (p && (typeof p === 'number' || p.length > 0)) {
this.options.port = p;
}
return this;
};
ScopedClient.prototype.protocol = function(p) {
if (p && p.length > 0) {
this.options.protocol = p;
}
return this;
};
ScopedClient.prototype.encoding = function(e) {
if (e == null) {
e = 'utf-8';
}
this.options.encoding = e;
return this;
};
ScopedClient.prototype.timeout = function(time) {
this.options.timeout = time;
return this;
};
ScopedClient.prototype.auth = function(user, pass) {
if (!user) {
this.options.auth = null;
} else if (!pass && user.match(/:/)) {
this.options.auth = user;
} else {
this.options.auth = user + ":" + pass;
}
return this;
};
ScopedClient.prototype.header = function(name, value) {
this.options.headers[name] = value;
return this;
};
ScopedClient.prototype.headers = function(h) {
extend(this.options.headers, h);
return this;
};
ScopedClient.prototype.buildOptions = function() {
var i, options, ty;
options = {};
i = 0;
while (arguments[i]) {
ty = typeof arguments[i];
if (ty === 'string') {
extend(options, url.parse(arguments[i], true));
delete options.url;
delete options.href;
delete options.search;
} else if (ty !== 'function') {
extend(options, arguments[i]);
}
i += 1;
}
options.headers || (options.headers = {});
if (options.encoding == null) {
options.encoding = 'utf-8';
}
return options;
};
return ScopedClient;
})();
ScopedClient.methods = ["GET", "POST", "PATCH", "PUT", "DELETE", "HEAD"];
ScopedClient.methods.forEach(function(method) {
return ScopedClient.prototype[method.toLowerCase()] = function(body, callback) {
return this.request(method, body, callback);
};
});
ScopedClient.prototype.del = ScopedClient.prototype['delete'];
ScopedClient.defaultPort = {
'http:': 80,
'https:': 443,
http: 80,
https: 443
};
extend = function(a, b) {
Object.keys(b).forEach(function(prop) {
return a[prop] = b[prop];
});
return a;
};
reduce = function(a, b) {
var j, len, propName;
for (j = 0, len = b.length; j < len; j++) {
propName = b[j];
delete a[propName];
}
return a;
};
exports.create = function(url, options) {
return new ScopedClient(url, options);
};