@@ -14,9 +14,44 @@ const packageName = 'browserstack-local-nodejs';
14
14
function LocalBinary ( ) {
15
15
this . hostOS = process . platform ;
16
16
this . is64bits = process . arch == 'x64' ;
17
+ this . baseRetries = 10 ;
18
+ this . sourceURL = null ;
19
+ this . downloadErrorMessage = null ;
20
+
21
+ this . getSourceUrl = function ( conf , retries ) {
22
+ /* Request for an endpoint from Rails no more than twice with 5 retries each */
23
+ if ( ! [ 5 , 10 ] . includes ( retries ) && this . sourceURL ) return this . sourceURL ;
24
+
25
+ let cmd , opts ;
26
+ cmd = 'node' ;
27
+ opts = [ path . join ( __dirname , 'fetchDownloadSourceUrl.js' ) , this . key ] ;
28
+ if ( conf . proxyHost && conf . proxyPort ) {
29
+ opts . push ( conf . proxyHost , conf . proxyPort ) ;
30
+ if ( conf . useCaCertificate ) {
31
+ opts . push ( conf . useCaCertificate ) ;
32
+ }
33
+ } else if ( conf . useCaCertificate ) {
34
+ opts . push ( undefined , undefined , conf . useCaCertificate ) ;
35
+ }
17
36
18
- this . getDownloadPath = function ( ) {
19
- let sourceURL = 'https://www.browserstack.com/local-testing/downloads/binaries/' ;
37
+ if ( retries == 5 ) {
38
+ opts . push ( true , this . binaryDownloadError ) ;
39
+ }
40
+
41
+ const userAgent = [ packageName , version ] . join ( '/' ) ;
42
+ const env = Object . assign ( { 'USER_AGENT' : userAgent } , process . env ) ;
43
+ const obj = childProcess . spawnSync ( cmd , opts , { env : env } ) ;
44
+ if ( obj . stdout . length > 0 ) {
45
+ this . sourceURL = obj . stdout ;
46
+ return this . sourceURL ;
47
+ } else if ( obj . stderr . length > 0 ) {
48
+ let output = Buffer . from ( JSON . parse ( JSON . stringify ( obj . stderr ) ) . data ) . toString ( ) ;
49
+ throw ( output ) ;
50
+ }
51
+ }
52
+
53
+ this . getDownloadPath = function ( conf , retries ) {
54
+ let sourceURL = this . getSourceUrl ( conf , retries ) + '/' ;
20
55
21
56
if ( this . hostOS . match ( / d a r w i n | m a c o s / i) ) {
22
57
return sourceURL + 'BrowserStackLocal-darwin-x64' ;
@@ -43,9 +78,10 @@ function LocalBinary(){
43
78
}
44
79
} ;
45
80
46
- this . httpPath = this . getDownloadPath ( ) ;
47
-
48
-
81
+ this . binaryDownloadError = function ( errorMessagePrefix , errorObject ) {
82
+ console . error ( errorMessagePrefix , errorObject ) ;
83
+ this . downloadErrorMessage = errorMessagePrefix + " : " + errorObject ? errorObject . getMessage ( ) : "null" ;
84
+ }
49
85
50
86
this . retryBinaryDownload = function ( conf , destParentDir , callback , retries , binaryPath ) {
51
87
var that = this ;
@@ -66,6 +102,12 @@ function LocalBinary(){
66
102
} ;
67
103
68
104
this . downloadSync = function ( conf , destParentDir , retries ) {
105
+ try {
106
+ this . httpPath = this . getDownloadPath ( conf , retries ) ;
107
+ } catch ( e ) {
108
+ return console . error ( `Unable to fetch the source url to download the binary with error: ${ e } ` ) ;
109
+ }
110
+
69
111
console . log ( 'Downloading in sync' ) ;
70
112
var that = this ;
71
113
if ( ! this . checkPath ( destParentDir ) )
@@ -96,21 +138,27 @@ function LocalBinary(){
96
138
fs . chmodSync ( binaryPath , '0755' ) ;
97
139
return binaryPath ;
98
140
} else {
99
- console . log ( 'failed to download' ) ;
141
+ that . binaryDownloadError ( 'failed to download' ) ;
100
142
return that . retryBinaryDownload ( conf , destParentDir , null , retries , binaryPath ) ;
101
143
}
102
144
} else if ( obj . stderr . length > 0 ) {
103
145
output = Buffer . from ( JSON . parse ( JSON . stringify ( obj . stderr ) ) . data ) . toString ( ) ;
104
- console . error ( output ) ;
146
+ that . binaryDownloadError ( output ) ;
105
147
return that . retryBinaryDownload ( conf , destParentDir , null , retries , binaryPath ) ;
106
148
}
107
149
} catch ( err ) {
108
- console . error ( 'Download failed with error' , err ) ;
150
+ that . binaryDownloadError ( 'Download failed with error' , err ) ;
109
151
return that . retryBinaryDownload ( conf , destParentDir , null , retries , binaryPath ) ;
110
152
}
111
153
} ;
112
154
113
155
this . download = function ( conf , destParentDir , callback , retries ) {
156
+ try {
157
+ this . httpPath = this . getDownloadPath ( conf , retries ) ;
158
+ } catch ( e ) {
159
+ return console . error ( `Unable to fetch the source url to download the binary with error: ${ e } ` ) ;
160
+ }
161
+
114
162
var that = this ;
115
163
if ( ! this . checkPath ( destParentDir ) )
116
164
fs . mkdirSync ( destParentDir ) ;
@@ -152,11 +200,11 @@ function LocalBinary(){
152
200
}
153
201
154
202
response . on ( 'error' , function ( err ) {
155
- console . error ( 'Got Error in binary download response' , err ) ;
203
+ that . binaryDownloadError ( 'Got Error in binary download response' , err ) ;
156
204
that . retryBinaryDownload ( conf , destParentDir , callback , retries , binaryPath ) ;
157
205
} ) ;
158
206
fileStream . on ( 'error' , function ( err ) {
159
- console . error ( 'Got Error while downloading binary file' , err ) ;
207
+ that . binaryDownloadError ( 'Got Error while downloading binary file' , err ) ;
160
208
that . retryBinaryDownload ( conf , destParentDir , callback , retries , binaryPath ) ;
161
209
} ) ;
162
210
fileStream . on ( 'close' , function ( ) {
@@ -165,12 +213,13 @@ function LocalBinary(){
165
213
} ) ;
166
214
} ) ;
167
215
} ) . on ( 'error' , function ( err ) {
168
- console . error ( 'Got Error in binary downloading request' , err ) ;
216
+ that . binaryDownloadError ( 'Got Error in binary downloading request' , err ) ;
169
217
that . retryBinaryDownload ( conf , destParentDir , callback , retries , binaryPath ) ;
170
218
} ) ;
171
219
} ;
172
220
173
- this . binaryPath = function ( conf , callback ) {
221
+ this . binaryPath = function ( conf , key , callback ) {
222
+ this . key = key ;
174
223
var destParentDir = this . getAvailableDirs ( ) ;
175
224
var destBinaryName = ( this . windows ) ? 'BrowserStackLocal.exe' : 'BrowserStackLocal' ;
176
225
var binaryPath = path . join ( destParentDir , destBinaryName ) ;
@@ -180,10 +229,11 @@ function LocalBinary(){
180
229
}
181
230
callback ( binaryPath ) ;
182
231
} else {
232
+ let retries = this . baseRetries ;
183
233
if ( ! callback ) {
184
- return this . downloadSync ( conf , destParentDir , 5 ) ;
234
+ return this . downloadSync ( conf , destParentDir , retries ) ;
185
235
}
186
- this . download ( conf , destParentDir , callback , 5 ) ;
236
+ this . download ( conf , destParentDir , callback , retries ) ;
187
237
}
188
238
} ;
189
239
0 commit comments