UNPKG

2.97 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 req = this.http(opts)
98
99 if (opts.timeout) req.setTimeout(opts.timeout, destroyer(req))
100 if (opts.json && opts.json !== true) opts.body = JSON.stringify(opts.json)
101 if (opts.auth) (opts.headers = opts.headers || {})['X-Registry-Auth'] = new Buffer(JSON.stringify(opts.auth)+'\n').toString('base64')
102
103 req.on('response', function(res) {
104 if (res.statusCode > 299) onerror(req, res, cb)
105 else if (opts.buffer) onbuffer(req, res, cb)
106 else if (opts.json) onjson(req, res, cb)
107 else onstream(req, res, cb)
108 })
109
110 req.on('error', cb)
111 req.on('close', function() {
112 cb(new Error('Premature close'))
113 })
114
115 if (method !== 'POST' && method !== 'PUT') req.end()
116 else if (opts.body) req.end(opts.body)
117
118 return req
119}
120
121module.exports = API
\No newline at end of file