UNPKG

scoped-http-client

Version:
285 lines (253 loc) 7.34 kB
// 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); };