UNPKG

3.09 kBJavaScriptView Raw
1var host = require('docker-host')
2var xtend = require('xtend')
3var once = require('once')
4var querystring = require('querystring')
5var concat = require('concat-stream')
6
7var noop = function() {}
8
9var onjson = function(req, res, cb) {
10 res.pipe(concat({encoding:'buffer'}, function(buf) {
11 try {
12 buf = JSON.parse(buf)
13 } catch (err) {
14 return cb(err)
15 }
16 cb(null, buf)
17 }))
18}
19
20var onbuffer = function(req, res, cb) {
21 res.pipe(concat({encoding:'buffer'}, function(buf) {
22 cb(null, buf)
23 }))
24}
25
26var onstream = function(req, res, cb) {
27 req.on('close', function() {
28 res.emit('close')
29 })
30 req.on('error', function(err) {
31 res.emit('error', err)
32 })
33 cb(null, res)
34}
35
36var onerror = function(req, res, cb) {
37 res.pipe(concat({encoding:'buffer'}, function(buf) {
38 var err = new Error(buf.toString().trim() || 'Bad status code: '+res.statusCode)
39 err.statusCode = res.statusCode
40 cb(err)
41 }))
42}
43
44var destroyer = function(req) {
45 return function() {
46 req.destroy()
47 }
48}
49
50var API = function(remote, defaults) {
51 if (!(this instanceof API)) return new API(remote, defaults)
52
53 if (typeof remote === 'object' && !defaults) {
54 defaults = remote
55 remote = null
56 }
57
58 this.defaults = xtend(host(remote), defaults)
59 this.http = (this.defaults.protocol === 'https:' ? require('https') : require('http')).request
60}
61
62API.prototype.get = function(path, opts, cb) {
63 return this.request('GET', path, opts, cb)
64}
65
66API.prototype.put = function(path, opts, cb) {
67 return this.request('PUT', path, opts, cb)
68}
69
70API.prototype.post = function(path, opts, cb) {
71 return this.request('POST', path, opts, cb)
72}
73
74API.prototype.head = function(path, opts, cb) {
75 return this.request('HEAD', path, opts, cb)
76}
77
78API.prototype.del = API.prototype.delete = function(path, opts, cb) {
79 return this.request('DELETE', path, opts, cb)
80}
81
82API.prototype.request = function(method, path, opts, cb) {
83 if (typeof opts === 'function') {
84 cb = opts
85 opts = null
86 }
87
88 cb = once(cb || noop)
89 opts = xtend(this.defaults, opts)
90
91 if (opts.qs) path += '?'+querystring.stringify(opts.qs)
92 if (opts.version) path = '/'+opts.version+path
93
94 opts.method = method
95 opts.path = path
96
97 var headers = opts.headers
98 if (headers) {
99 Object.keys(headers).forEach(function(name) {
100 if (typeof headers[name] === 'object' && headers[name]) headers[name] = new Buffer(JSON.stringify(headers[name])+'\n').toString('base64')
101 })
102 }
103
104 var req = this.http(opts)
105
106 if (opts.timeout) req.setTimeout(opts.timeout, destroyer(req))
107 if (opts.json && opts.json !== true) opts.body = JSON.stringify(opts.json)
108
109 req.on('response', function(res) {
110 if (res.statusCode > 299) onerror(req, res, cb)
111 else if (opts.buffer) onbuffer(req, res, cb)
112 else if (opts.json) onjson(req, res, cb)
113 else onstream(req, res, cb)
114 })
115
116 req.on('error', cb)
117 req.on('close', function() {
118 cb(new Error('Premature close'))
119 })
120
121 if (method !== 'POST' && method !== 'PUT') req.end()
122 else if (opts.body) req.end(opts.body)
123
124 return req
125}
126
127module.exports = API
\No newline at end of file