@@ -15,7 +15,7 @@ class OpenEO {
15
15
var connection = new Connection ( url ) ;
16
16
return connection . capabilities ( ) . then ( capabilities => {
17
17
// Check whether back-end is accessible and supports a correct version.
18
- if ( capabilities . version ( ) . startsWith ( "0.3" ) ) {
18
+ if ( capabilities . version ( ) . startsWith ( "0.3. " ) ) {
19
19
if ( authType !== null ) {
20
20
switch ( authType ) {
21
21
case 'basic' :
@@ -35,7 +35,7 @@ class OpenEO {
35
35
}
36
36
37
37
version ( ) {
38
- return "0.3.2 " ;
38
+ return "0.3.3 " ;
39
39
}
40
40
}
41
41
@@ -113,22 +113,12 @@ class Connection {
113
113
return Promise . reject ( new Error ( "Not implemented yet." ) ) ;
114
114
}
115
115
116
- _base64encode ( str ) {
117
- var buffer ;
118
- if ( str instanceof Buffer ) {
119
- buffer = str ;
120
- } else {
121
- buffer = Buffer . from ( str . toString ( ) , 'binary' ) ;
122
- }
123
- return buffer . toString ( 'base64' ) ;
124
- }
125
-
126
116
authenticateBasic ( username , password ) {
127
117
return this . _send ( {
128
118
method : 'get' ,
129
119
responseType : 'json' ,
130
120
url : '/credentials/basic' ,
131
- headers : { 'Authorization' : 'Basic ' + this . _base64encode ( username + ':' + password ) } // btoa is JS's ugly name for encodeBase64
121
+ headers : { 'Authorization' : 'Basic ' + Util . base64encode ( username + ':' + password ) }
132
122
} ) . then ( response => {
133
123
if ( ! response . data . user_id ) {
134
124
throw new Error ( "No user_id returned." ) ;
@@ -403,41 +393,6 @@ class Connection {
403
393
unsubscribe ( topic , parameters , callback ) {
404
394
return this . subscriptionsObject . unsubscribe ( topic , parameters , callback ) ;
405
395
}
406
-
407
- _saveToFileNode ( data , filename ) {
408
- var fs = require ( 'fs' ) ;
409
- return new Promise ( ( resolve , reject ) => {
410
- var writeStream = fs . createWriteStream ( filename ) ;
411
- writeStream . on ( 'close' , ( err ) => {
412
- if ( err ) {
413
- return reject ( err ) ;
414
- }
415
- resolve ( ) ;
416
- } ) ;
417
- data . pipe ( writeStream ) ;
418
- } ) ;
419
- }
420
-
421
- /* istanbul ignore next */
422
- _saveToFileBrowser ( data , filename ) {
423
- // based on: https://github.com/kennethjiang/js-file-download/blob/master/file-download.js
424
- var blob = new Blob ( [ data ] , { type : 'application/octet-stream' } ) ;
425
- var blobURL = window . URL . createObjectURL ( blob ) ;
426
- var tempLink = document . createElement ( 'a' ) ;
427
- tempLink . style . display = 'none' ;
428
- tempLink . href = blobURL ;
429
- tempLink . setAttribute ( 'download' , filename ) ;
430
-
431
- if ( typeof tempLink . download === 'undefined' ) {
432
- tempLink . setAttribute ( 'target' , '_blank' ) ;
433
- }
434
-
435
- document . body . appendChild ( tempLink ) ;
436
- tempLink . click ( ) ;
437
- document . body . removeChild ( tempLink ) ;
438
- window . URL . revokeObjectURL ( blobURL ) ;
439
- return Promise . resolve ( ) ;
440
- }
441
396
}
442
397
443
398
@@ -461,7 +416,7 @@ class Subscriptions {
461
416
if ( ! this . listeners . has ( topic ) ) {
462
417
this . listeners . set ( topic , new Map ( ) ) ;
463
418
}
464
- this . listeners . get ( topic ) . set ( JSON . stringify ( parameters ) , callback ) ;
419
+ this . listeners . get ( topic ) . set ( Util . hash ( parameters ) , callback ) ;
465
420
}
466
421
467
422
this . _sendSubscription ( 'subscribe' , topic , parameters ) ;
@@ -477,7 +432,7 @@ class Subscriptions {
477
432
478
433
// remove the applicable sub-callback
479
434
if ( topicListeners instanceof Map ) {
480
- topicListeners . delete ( JSON . stringify ( parameters ) ) ;
435
+ topicListeners . delete ( Util . hash ( parameters ) ) ;
481
436
} else {
482
437
return Promise . reject ( new Error ( "this.listeners must be a Map of Maps" ) ) ;
483
438
}
@@ -539,8 +494,8 @@ class Subscriptions {
539
494
var callback ;
540
495
// we should now have a Map in which to look for the correct listener
541
496
if ( topicListeners && topicListeners instanceof Map ) {
542
- callback = topicListeners . get ( '{}' ) // default: without parameters
543
- || topicListeners . get ( '{" job_id":"' + json . payload . job_id + '"}' ) ;
497
+ callback = topicListeners . get ( Util . hash ( { } ) ) // default: without parameters
498
+ || topicListeners . get ( Util . hash ( { job_id : json . payload . job_id } ) ) ;
544
499
// more parameter checks possible
545
500
}
546
501
// if we now have a function, we can call it with the information
@@ -765,11 +720,11 @@ class File extends BaseEntity {
765
720
766
721
_saveToFile ( data , filename ) {
767
722
if ( isNode ) {
768
- return this . connection . _saveToFileNode ( data , filename ) ;
723
+ return Util . saveToFileNode ( data , filename ) ;
769
724
}
770
725
else {
771
726
/* istanbul ignore next */
772
- return this . connection . _saveToFileBrowser ( data , filename ) ;
727
+ return Util . saveToFileBrowser ( data , filename ) ;
773
728
}
774
729
}
775
730
@@ -901,7 +856,7 @@ class Job extends BaseEntity {
901
856
let parsedUrl = url . parse ( link ) ;
902
857
let targetPath = path . join ( targetFolder , path . basename ( parsedUrl . pathname ) ) ;
903
858
let p = this . connection . download ( link , false )
904
- . then ( response => this . connection . _saveToFileNode ( response . data , targetPath ) )
859
+ . then ( response => Util . saveToFileNode ( response . data , targetPath ) )
905
860
. then ( ( ) => files . push ( targetPath ) ) ;
906
861
promises . push ( p ) ;
907
862
}
@@ -976,9 +931,97 @@ class Service extends BaseEntity {
976
931
}
977
932
}
978
933
934
+ class Util {
935
+
936
+ static base64encode ( str ) {
937
+ if ( typeof btoa === 'function' ) {
938
+ // btoa is JS's ugly name for encodeBase64
939
+ return btoa ( str ) ;
940
+ }
941
+ else {
942
+ var buffer ;
943
+ if ( str instanceof Buffer ) {
944
+ buffer = str ;
945
+ } else {
946
+ buffer = Buffer . from ( str . toString ( ) , 'binary' ) ;
947
+ }
948
+ return buffer . toString ( 'base64' ) ;
949
+ }
950
+ }
951
+
952
+ // Non-crypthographic / unsafe hashing for objects
953
+ static hash ( o ) {
954
+ switch ( typeof o ) {
955
+ case 'boolean' :
956
+ return Util . hashString ( "b:" + o . toString ( ) ) ;
957
+ case 'number' :
958
+ return Util . hashString ( "n:" + o . toString ( ) ) ;
959
+ case 'string' :
960
+ return Util . hashString ( "s:" + o ) ;
961
+ case 'object' :
962
+ if ( o === null ) {
963
+ return Util . hashString ( "n:" ) ;
964
+ }
965
+ else {
966
+ return Util . hashString ( Object . keys ( o ) . sort ( ) . map ( k => "o:" + k + ":" + Util . hash ( o [ k ] ) ) . join ( "::" ) ) ;
967
+ }
968
+ default :
969
+ return Util . hashString ( typeof o ) ;
970
+ }
971
+ }
972
+
973
+ // See: https://en.wikipedia.org/wiki/Jenkins_hash_function
974
+ static hashString ( b ) {
975
+ for ( var a = 0 , c = b . length ; c -- ; ) {
976
+ a += b . charCodeAt ( c ) ;
977
+ a += a << 10 ;
978
+ a ^= a >> 6 ;
979
+ }
980
+ a += a << 3 ;
981
+ a ^= a >> 11 ;
982
+ a += a << 15 ;
983
+ return ( ( a & 4294967295 ) >>> 0 ) . toString ( 16 ) ;
984
+ }
985
+
986
+ static saveToFileNode ( data , filename ) {
987
+ var fs = require ( 'fs' ) ;
988
+ return new Promise ( ( resolve , reject ) => {
989
+ var writeStream = fs . createWriteStream ( filename ) ;
990
+ writeStream . on ( 'close' , ( err ) => {
991
+ if ( err ) {
992
+ return reject ( err ) ;
993
+ }
994
+ resolve ( ) ;
995
+ } ) ;
996
+ data . pipe ( writeStream ) ;
997
+ } ) ;
998
+ }
999
+
1000
+ /* istanbul ignore next */
1001
+ static saveToFileBrowser ( data , filename ) {
1002
+ // based on: https://github.com/kennethjiang/js-file-download/blob/master/file-download.js
1003
+ var blob = new Blob ( [ data ] , { type : 'application/octet-stream' } ) ;
1004
+ var blobURL = window . URL . createObjectURL ( blob ) ;
1005
+ var tempLink = document . createElement ( 'a' ) ;
1006
+ tempLink . style . display = 'none' ;
1007
+ tempLink . href = blobURL ;
1008
+ tempLink . setAttribute ( 'download' , filename ) ;
1009
+
1010
+ if ( typeof tempLink . download === 'undefined' ) {
1011
+ tempLink . setAttribute ( 'target' , '_blank' ) ;
1012
+ }
1013
+
1014
+ document . body . appendChild ( tempLink ) ;
1015
+ tempLink . click ( ) ;
1016
+ document . body . removeChild ( tempLink ) ;
1017
+ window . URL . revokeObjectURL ( blobURL ) ;
1018
+ return Promise . resolve ( ) ;
1019
+ }
1020
+ }
979
1021
980
1022
let toExport = {
981
- OpenEO : OpenEO
1023
+ OpenEO : OpenEO ,
1024
+ Util : Util
982
1025
} ;
983
1026
984
1027
// explanation: https://www.matteoagosti.com/blog/2013/02/24/writing-javascript-modules-for-both-browser-and-node/
0 commit comments