11'use strict'
22
3- const Wreck = require ( 'wreck' )
43const Qs = require ( 'qs' )
54const ndjson = require ( 'ndjson' )
6- const getFilesStream = require ( './get-files-stream' )
7-
85const isNode = require ( 'detect-node' )
6+ const once = require ( 'once' )
7+ const concat = require ( 'concat-stream' )
8+
9+ const getFilesStream = require ( './get-files-stream' )
10+ const request = require ( './request' )
911
1012// -- Internal
1113
1214function parseChunkedJson ( res , cb ) {
13- const parsed = [ ]
1415 res
1516 . pipe ( ndjson . parse ( ) )
16- . on ( 'data' , ( obj ) => {
17- parsed . push ( obj )
18- } )
19- . on ( 'end' , ( ) => {
20- cb ( null , parsed )
21- } )
17+ . once ( 'error' , cb )
18+ . pipe ( concat ( ( data ) => cb ( null , data ) ) )
2219}
2320
24- function onRes ( buffer , cb , uri ) {
25- return ( err , res ) => {
26- if ( err ) {
27- return cb ( err )
28- }
21+ function parseRaw ( res , cb ) {
22+ res
23+ . once ( 'error' , cb )
24+ . pipe ( concat ( ( data ) => cb ( null , data ) ) )
25+ }
26+
27+ function parseJson ( res , cb ) {
28+ res
29+ . once ( 'error' , cb )
30+ . pipe ( concat ( ( data ) => {
31+ if ( ! data || data . length === 0 ) {
32+ return cb ( )
33+ }
34+
35+ if ( Buffer . isBuffer ( data ) ) {
36+ data = data . toString ( )
37+ }
2938
39+ let res
40+ try {
41+ res = JSON . parse ( data )
42+ } catch ( err ) {
43+ return cb ( err )
44+ }
45+
46+ cb ( null , res )
47+ } ) )
48+ }
49+
50+ function onRes ( buffer , cb ) {
51+ return ( res ) => {
3052 const stream = Boolean ( res . headers [ 'x-stream-output' ] )
3153 const chunkedObjects = Boolean ( res . headers [ 'x-chunked-output' ] )
3254 const isJson = res . headers [ 'content-type' ] &&
@@ -35,7 +57,7 @@ function onRes (buffer, cb, uri) {
3557 if ( res . statusCode >= 400 || ! res . statusCode ) {
3658 const error = new Error ( `Server responded with ${ res . statusCode } ` )
3759
38- return Wreck . read ( res , { json : true } , ( err , payload ) => {
60+ parseJson ( res , ( err , payload ) => {
3961 if ( err ) {
4062 return cb ( err )
4163 }
@@ -51,20 +73,21 @@ function onRes (buffer, cb, uri) {
5173 return cb ( null , res )
5274 }
5375
54- if ( chunkedObjects ) {
55- if ( isJson ) {
56- return parseChunkedJson ( res , cb )
57- }
76+ if ( chunkedObjects && isJson ) {
77+ return parseChunkedJson ( res , cb )
78+ }
5879
59- return Wreck . read ( res , null , cb )
80+ if ( isJson ) {
81+ return parseJson ( res , cb )
6082 }
6183
62- Wreck . read ( res , { json : isJson } , cb )
84+ parseRaw ( res , cb )
6385 }
6486}
6587
6688function requestAPI ( config , options , callback ) {
6789 options . qs = options . qs || { }
90+ callback = once ( callback )
6891
6992 if ( Array . isArray ( options . files ) ) {
7093 options . qs . recursive = true
@@ -99,29 +122,38 @@ function requestAPI (config, options, callback) {
99122 // this option is only used internally, not passed to daemon
100123 delete options . qs . followSymlinks
101124
102- const port = config . port ? `:${ config . port } ` : ''
103-
104- const opts = {
105- method : 'POST' ,
106- uri : `${ config . protocol } ://${ config . host } ${ port } ${ config [ 'api-path' ] } ${ options . path } ?${ Qs . stringify ( options . qs , { arrayFormat : 'repeat' } ) } ` ,
107- headers : { }
108- }
125+ const method = 'POST'
126+ const headers = { }
109127
110128 if ( isNode ) {
111129 // Browsers do not allow you to modify the user agent
112- opts . headers [ 'User-Agent' ] = config [ 'user-agent' ]
130+ headers [ 'User-Agent' ] = config [ 'user-agent' ]
113131 }
114132
115133 if ( options . files ) {
116134 if ( ! stream . boundary ) {
117135 return callback ( new Error ( 'No boundary in multipart stream' ) )
118136 }
119137
120- opts . headers [ 'Content-Type' ] = `multipart/form-data; boundary=${ stream . boundary } `
121- opts . payload = stream
138+ headers [ 'Content-Type' ] = `multipart/form-data; boundary=${ stream . boundary } `
139+ }
140+
141+ const qs = Qs . stringify ( options . qs , { arrayFormat : 'repeat' } )
142+ const req = request ( config . protocol ) ( {
143+ hostname : config . host ,
144+ path : `${ config [ 'api-path' ] } ${ options . path } ?${ qs } ` ,
145+ port : config . port ,
146+ method : method ,
147+ headers : headers
148+ } , onRes ( options . buffer , callback ) )
149+
150+ if ( options . files ) {
151+ stream . pipe ( req )
152+ } else {
153+ req . end ( )
122154 }
123155
124- return Wreck . request ( opts . method , opts . uri , opts , onRes ( options . buffer , callback , opts . uri ) )
156+ return req
125157}
126158
127159//
0 commit comments