@@ -41,6 +41,7 @@ import {
41
41
import { ProtoGrpcType as TestServiceGrpcType } from './generated/test_service' ;
42
42
import { Request__Output } from './generated/Request' ;
43
43
import { CompressionAlgorithms } from '../src/compression-algorithms' ;
44
+ import { SecureContextOptions } from 'tls' ;
44
45
45
46
const loadedTestServiceProto = protoLoader . loadSync (
46
47
path . join ( __dirname , 'fixtures/test_service.proto' ) ,
@@ -746,6 +747,116 @@ describe('Echo service', () => {
746
747
) ;
747
748
} ) ;
748
749
750
+ describe ( 'ServerCredentials watcher' , ( ) => {
751
+ let server : Server ;
752
+ let serverPort : number ;
753
+ const protoFile = path . join ( __dirname , 'fixtures' , 'echo_service.proto' ) ;
754
+ const echoService = loadProtoFile ( protoFile )
755
+ . EchoService as ServiceClientConstructor ;
756
+
757
+ class ToggleableSecureServerCredentials extends ServerCredentials {
758
+ private contextOptions : SecureContextOptions ;
759
+ constructor ( key : Buffer , cert : Buffer ) {
760
+ super ( ) ;
761
+ this . contextOptions = { key, cert} ;
762
+ this . enable ( ) ;
763
+ }
764
+ enable ( ) {
765
+ this . updateSecureContextOptions ( this . contextOptions ) ;
766
+ }
767
+ disable ( ) {
768
+ this . updateSecureContextOptions ( null ) ;
769
+ }
770
+ _isSecure ( ) : boolean {
771
+ return true ;
772
+ }
773
+ _equals ( other : grpc . ServerCredentials ) : boolean {
774
+ return this === other ;
775
+ }
776
+ }
777
+
778
+ const serverCredentials = new ToggleableSecureServerCredentials ( key , cert ) ;
779
+
780
+ const serviceImplementation = {
781
+ echo ( call : ServerUnaryCall < any , any > , callback : sendUnaryData < any > ) {
782
+ callback ( null , call . request ) ;
783
+ } ,
784
+ echoBidiStream ( call : ServerDuplexStream < any , any > ) {
785
+ call . on ( 'data' , data => {
786
+ call . write ( data ) ;
787
+ } ) ;
788
+ call . on ( 'end' , ( ) => {
789
+ call . end ( ) ;
790
+ } ) ;
791
+ } ,
792
+ } ;
793
+
794
+ before ( done => {
795
+ server = new Server ( ) ;
796
+ server . addService ( echoService . service , serviceImplementation ) ;
797
+
798
+ server . bindAsync (
799
+ 'localhost:0' ,
800
+ serverCredentials ,
801
+ ( err , port ) => {
802
+ assert . ifError ( err ) ;
803
+ serverPort = port ;
804
+ done ( ) ;
805
+ }
806
+ ) ;
807
+ } ) ;
808
+
809
+ after ( done => {
810
+ client . close ( ) ;
811
+ server . tryShutdown ( done ) ;
812
+ } ) ;
813
+
814
+ it ( 'should make successful requests only when the credentials are enabled' , done => {
815
+ const client1 = new echoService (
816
+ `localhost:${ serverPort } ` ,
817
+ grpc . credentials . createSsl ( ca ) ,
818
+ {
819
+ 'grpc.ssl_target_name_override' : 'foo.test.google.fr' ,
820
+ 'grpc.default_authority' : 'foo.test.google.fr' ,
821
+ 'grpc.use_local_subchannel_pool' : 1
822
+ }
823
+ ) ;
824
+ const testMessage = { value : 'test value' , value2 : 3 } ;
825
+ client1 . echo ( testMessage , ( error : ServiceError , response : any ) => {
826
+ assert . ifError ( error ) ;
827
+ assert . deepStrictEqual ( response , testMessage ) ;
828
+ serverCredentials . disable ( ) ;
829
+ const client2 = new echoService (
830
+ `localhost:${ serverPort } ` ,
831
+ grpc . credentials . createSsl ( ca ) ,
832
+ {
833
+ 'grpc.ssl_target_name_override' : 'foo.test.google.fr' ,
834
+ 'grpc.default_authority' : 'foo.test.google.fr' ,
835
+ 'grpc.use_local_subchannel_pool' : 1
836
+ }
837
+ ) ;
838
+ client2 . echo ( testMessage , ( error : ServiceError , response : any ) => {
839
+ assert ( error ) ;
840
+ assert . strictEqual ( error . code , grpc . status . UNAVAILABLE ) ;
841
+ serverCredentials . enable ( ) ;
842
+ const client3 = new echoService (
843
+ `localhost:${ serverPort } ` ,
844
+ grpc . credentials . createSsl ( ca ) ,
845
+ {
846
+ 'grpc.ssl_target_name_override' : 'foo.test.google.fr' ,
847
+ 'grpc.default_authority' : 'foo.test.google.fr' ,
848
+ 'grpc.use_local_subchannel_pool' : 1
849
+ }
850
+ ) ;
851
+ client3 . echo ( testMessage , ( error : ServiceError , response : any ) => {
852
+ assert . ifError ( error ) ;
853
+ done ( ) ;
854
+ } ) ;
855
+ } ) ;
856
+ } ) ;
857
+ } ) ;
858
+ } ) ;
859
+
749
860
/* This test passes on Node 18 but fails on Node 16. The failure appears to
750
861
* be caused by https://github.com/nodejs/node/issues/42713 */
751
862
it . skip ( 'should continue a stream after server shutdown' , done => {
0 commit comments