Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit 38088fe

Browse files
Switch to superagent instead of raw http.request
1 parent c874ec6 commit 38088fe

File tree

5 files changed

+100
-91
lines changed

5 files changed

+100
-91
lines changed

.eslintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
{
2+
"parser": "babel-eslint",
23
"extends": "standard"
34
}

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
"multipart-stream": "^2.0.0",
1111
"vinyl": "^0.5.1",
1212
"vinyl-fs-browser": "^2.1.1-1",
13-
"vinyl-multipart-stream": "^1.2.6"
13+
"vinyl-multipart-stream": "^1.2.6",
14+
"superagent": "github:visionmedia/superagent"
1415
},
1516
"browserify": {
1617
"transform": [
@@ -25,6 +26,7 @@
2526
"url": "https://github.com/ipfs/js-ipfs-api"
2627
},
2728
"devDependencies": {
29+
"babel-eslint": "^4.1.3",
2830
"brfs": "^1.4.1",
2931
"browserify": "^11.0.0",
3032
"concurrently": "^0.1.1",

src/json-parser.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module.exports = function safeJSONParser (buffer, res, done) {
2+
var headers = !!res.headers
3+
var stream = headers && !!res.headers['x-stream-output']
4+
var chunkedObjects = headers && !!res.headers['x-chunked-output']
5+
6+
// No need to parse
7+
if (stream && !buffer) return done()
8+
if (chunkedObjects && buffer) return done()
9+
10+
var objects = []
11+
var data = ''
12+
res.text = ''
13+
res.setEncoding('utf8')
14+
15+
res.on('data', function (chunk) {
16+
res.text += chunk
17+
18+
if (!chunkedObjects) {
19+
data += chunk
20+
return
21+
}
22+
23+
try {
24+
var obj = JSON.parse(chunk.toString())
25+
objects.push(obj)
26+
} catch (e) {
27+
chunkedObjects = false
28+
data += chunk
29+
}
30+
})
31+
32+
res.on('end', function () {
33+
var parsed
34+
35+
if (!chunkedObjects) {
36+
try {
37+
parsed = JSON.parse(data)
38+
data = parsed
39+
} catch (e) {}
40+
} else {
41+
data = objects
42+
}
43+
44+
return done(null, data)
45+
})
46+
}

src/request-api.js

Lines changed: 45 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,63 @@
1-
var http = require('http')
2-
var qs = require('querystring')
3-
var getFilesStream = require('./get-files-stream')
4-
5-
exports = module.exports = function getRequestAPI (config) {
6-
return requestAPI
7-
8-
function requestAPI (path, args, opts, files, buffer, cb) {
9-
var query, stream, contentType
10-
contentType = 'application/json'
1+
var request = require('superagent')
112

12-
if (Array.isArray(path)) path = path.join('/')
3+
var safeJSONParser = require('./json-parser')
4+
var getFilesStream = require('./get-files-stream')
135

14-
opts = opts || {}
6+
var isNode = !global.window
157

16-
if (args && !Array.isArray(args)) args = [args]
17-
if (args) opts.arg = args
8+
function requestAPI (config, path, args, opts, files, buffer, cb) {
9+
opts = opts || {}
10+
if (Array.isArray(path)) path = path.join('/')
11+
if (args && !Array.isArray(args)) args = [args]
12+
if (args) opts.arg = args
1813

19-
if (files) {
20-
stream = getFilesStream(files, opts)
21-
if (!stream.boundary) {
22-
throw new Error('no boundary in multipart stream')
23-
}
24-
contentType = 'multipart/form-data; boundary=' + stream.boundary
25-
}
26-
27-
if (typeof buffer === 'function') {
28-
cb = buffer
29-
buffer = false
30-
}
14+
if (typeof buffer === 'function') {
15+
cb = buffer
16+
buffer = false
17+
}
3118

32-
// this option is only used internally, not passed to daemon
33-
delete opts.followSymlinks
19+
// this option is only used internally, not passed to daemon
20+
delete opts.followSymlinks
3421

35-
opts['stream-channels'] = true
36-
query = qs.stringify(opts)
22+
var method = files ? 'POST' : 'GET'
23+
var url = `${config.host}:${config.port}${config['api-path']}${path}`
3724

38-
var reqo = {
39-
method: files ? 'POST' : 'GET',
40-
host: config.host,
41-
port: config.port,
42-
path: config['api-path'] + path + '?' + query,
43-
headers: {
44-
'User-Agent': config['user-agent'],
45-
'Content-Type': contentType
46-
},
47-
withCredentials: false
48-
}
25+
var req = request(method, url)
26+
.set('User-Agent', config['user-agent'])
27+
.query(opts)
28+
.query('stream-channels')
29+
.parse(safeJSONParser.bind(null, buffer))
30+
.on('error', cb)
31+
.on('response', res => {
32+
if (res.error) return cb(res.error)
4933

50-
var req = http.request(reqo, function (res) {
51-
var data = ''
52-
var objects = []
53-
var stream = !!res.headers && !!res.headers['x-stream-output']
54-
var chunkedObjects = !!res.headers && !!res.headers['x-chunked-output']
34+
var headers = !!res.headers
35+
var stream = headers && !!res.headers['x-stream-output']
36+
var chunkedObjects = headers && !!res.headers['x-chunked-output']
5537

5638
if (stream && !buffer) return cb(null, res)
5739
if (chunkedObjects && buffer) return cb(null, res)
5840

59-
res.on('data', function (chunk) {
60-
if (!chunkedObjects) {
61-
data += chunk
62-
return data
63-
}
64-
65-
try {
66-
var obj = JSON.parse(chunk.toString())
67-
objects.push(obj)
68-
} catch (e) {
69-
chunkedObjects = false
70-
data += chunk
71-
}
72-
})
73-
res.on('end', function () {
74-
var parsed
75-
76-
if (!chunkedObjects) {
77-
try {
78-
parsed = JSON.parse(data)
79-
data = parsed
80-
} catch (e) {}
81-
} else {
82-
data = objects
83-
}
84-
85-
if (res.statusCode >= 400 || !res.statusCode) {
86-
if (!data) data = new Error()
87-
return cb(data, null)
88-
}
89-
return cb(null, data)
90-
})
91-
res.on('error', function (err) {
92-
return cb(err, null)
93-
})
41+
return cb(null, res.body)
9442
})
9543

96-
req.on('error', function (err) {
97-
return cb(err, null)
98-
})
44+
// Superagent does not support buffering on the client side
45+
if (isNode) {
46+
req.buffer(buffer)
47+
}
9948

100-
if (stream) {
101-
stream.pipe(req)
102-
} else {
103-
req.end()
49+
if (files) {
50+
var stream = getFilesStream(files, opts)
51+
if (!stream.boundary) {
52+
return cb(new Error('no boundary in multipart stream'))
10453
}
105-
106-
return req
54+
req.set('Content-Type', 'multipart/form-data; boundary=' + stream.boundary)
55+
stream.pipe(req)
56+
} else {
57+
req.end()
10758
}
10859
}
60+
61+
module.exports = function getRequestAPI (config) {
62+
return requestAPI.bind(null, config)
63+
}

tasks/test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ gulp.task('test:browser', function (done) {
3434
gulp.task('mocha', function () {
3535
return gulp.src('test/tests.js')
3636
.pipe($.mocha())
37+
.once('error', err => {
38+
console.error(err.stack)
39+
process.exit(1)
40+
})
41+
.once('end', () => process.exit())
3742
})
3843

3944
gulp.task('karma', function (done) {

0 commit comments

Comments
 (0)