@@ -7,7 +7,7 @@ import QUICServer from '@/QUICServer';
77import QUICClient from '@/QUICClient' ;
88import QUICStream from '@/QUICStream' ;
99import * as testsUtils from './utils' ;
10- import { generateTLSConfig } from './utils' ;
10+ import { generateTLSConfig , sleep } from './utils' ;
1111
1212describe ( QUICStream . name , ( ) => {
1313 const logger = new Logger ( `${ QUICStream . name } Test` , LogLevel . WARN , [
@@ -1414,4 +1414,82 @@ describe(QUICStream.name, () => {
14141414 ] ) ;
14151415 await client . destroy ( { force : true } ) ;
14161416 } ) ;
1417+ test ( 'new streams are rejected when a connection is ending' , async ( ) => {
1418+ const message = Buffer . from ( 'The Quick Brown Fox Jumped Over The Lazy Dog' ) ;
1419+ const connectionEventProm =
1420+ utils . promise < events . EventQUICServerConnection > ( ) ;
1421+ const tlsConfig = await generateTLSConfig ( defaultType ) ;
1422+ const server = new QUICServer ( {
1423+ crypto : {
1424+ key,
1425+ ops : serverCrypto ,
1426+ } ,
1427+ logger : logger . getChild ( QUICServer . name ) ,
1428+ config : {
1429+ key : tlsConfig . leafKeyPairPEM . privateKey ,
1430+ cert : tlsConfig . leafCertPEM ,
1431+ verifyPeer : false ,
1432+ } ,
1433+ } ) ;
1434+ socketCleanMethods . extractSocket ( server ) ;
1435+ server . addEventListener (
1436+ events . EventQUICServerConnection . name ,
1437+ ( e : events . EventQUICServerConnection ) => connectionEventProm . resolveP ( e ) ,
1438+ ) ;
1439+ await server . start ( {
1440+ host : localhost ,
1441+ } ) ;
1442+ const client = await QUICClient . createQUICClient ( {
1443+ host : localhost ,
1444+ port : server . port ,
1445+ localHost : localhost ,
1446+ crypto : {
1447+ ops : clientCrypto ,
1448+ } ,
1449+ logger : logger . getChild ( QUICClient . name ) ,
1450+ config : {
1451+ verifyPeer : false ,
1452+ } ,
1453+ } ) ;
1454+ socketCleanMethods . extractSocket ( client ) ;
1455+ const conn = ( await connectionEventProm . p ) . detail ;
1456+
1457+ // Do the test
1458+ const { p : waitP , resolveP : waitResolveP } = utils . promise ( ) ;
1459+ const activeServerStreams : Array < Promise < void > > = [ ] ;
1460+ conn . addEventListener (
1461+ events . EventQUICConnectionStream . name ,
1462+ async ( streamEvent : events . EventQUICConnectionStream ) => {
1463+ const stream = streamEvent . detail ;
1464+ await waitP ;
1465+ const streamProm = stream . readable . pipeTo ( stream . writable ) ;
1466+ activeServerStreams . push ( streamProm ) ;
1467+ } ,
1468+ ) ;
1469+
1470+ const stream = client . connection . newStream ( ) ;
1471+ const writer = stream . writable . getWriter ( ) ;
1472+ await writer . write ( message ) ;
1473+ await writer . close ( ) ;
1474+
1475+ // Start unforced close of client
1476+ const clientDestroyP = client . destroy ( { force : false } ) ;
1477+ // Yield to allow `destroy` to progress
1478+ await sleep ( 0 ) ;
1479+ // New client streams should throw
1480+ expect ( ( ) => client . connection . newStream ( ) ) . toThrow ( ) ;
1481+ // Creating a stream on the server side should throw
1482+ const newStream = conn . newStream ( ) ;
1483+ await newStream . writable . close ( ) ;
1484+ const asd = ( async ( ) => {
1485+ for await ( const _ of newStream . readable ) {
1486+ // Do nothing
1487+ }
1488+ } ) ( ) ;
1489+ await expect ( asd ) . rejects . toThrow ( 'read 1' ) ;
1490+
1491+ waitResolveP ( ) ;
1492+ await clientDestroyP ;
1493+ await server . stop ( { force : true } ) ;
1494+ } ) ;
14171495} ) ;
0 commit comments