browserProxyLease.test.ts 1.9 KB

12345678910111213141516171819202122232425262728
  1. // @vitest-environment node
  2. import {expect,it,vi} from 'vitest'
  3. import {createServer,request} from 'node:http'
  4. const target=vi.hoisted(()=>({port:0}))
  5. vi.mock('../../src/runner/network/publicDestination.js',async importOriginal=>({
  6. ...await importOriginal<object>(),publicDestination:async()=>({host:'fixture.test',address:'127.0.0.1',family:4,port:target.port}),
  7. }))
  8. import {BrowserPublicProxy} from '../../src/runner/browser/publicProxy.js'
  9. it('disconnects an existing response stream when its grant expires and allows an authorized reconnect',async()=>{
  10. const server=createServer((req,res)=>{res.writeHead(200);if(req.url==='/once')res.end('ok');else res.write('stream-start')})
  11. await new Promise<void>(resolve=>server.listen(0,'127.0.0.1',resolve));target.port=(server.address() as {port:number}).port
  12. let allowed=true
  13. const proxy=await BrowserPublicProxy.start(async()=>{if(!allowed)throw new Error('grant expired')},undefined,20)
  14. const headers={'Proxy-Authorization':'Basic '+Buffer.from(`${proxy.username}:${proxy.password}`).toString('base64')}
  15. try{
  16. let interrupted!:()=>void;const ended=new Promise<void>(resolve=>{interrupted=resolve})
  17. await new Promise<void>((resolve,reject)=>{
  18. const req=request(proxy.serverURL,{path:'http://fixture.test/stream',headers},res=>{res.once('data',()=>resolve());res.once('aborted',interrupted);res.on('error',()=>{})})
  19. req.on('error',reject);req.end()
  20. })
  21. allowed=false
  22. await Promise.race([ended,new Promise((_,reject)=>setTimeout(()=>reject(new Error('expired stream stayed connected')),1000))])
  23. allowed=true
  24. const status=await new Promise<number>((resolve,reject)=>{const req=request(proxy.serverURL,{path:'http://fixture.test/once',headers},res=>{res.resume();res.on('end',()=>resolve(res.statusCode!))});req.on('error',reject);req.end()})
  25. expect(status).toBe(200)
  26. }finally{await proxy.close();server.closeAllConnections();await new Promise<void>(resolve=>server.close(()=>resolve()))}
  27. })