Skip to content

Commit

Permalink
chore: update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
achingbrain committed Nov 26, 2024
1 parent 53e18d7 commit 17bd4fd
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 27 deletions.
65 changes: 42 additions & 23 deletions packages/transport-websockets/src/listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import net from 'node:net'
import os from 'node:os'
import { TypedEventEmitter, setMaxListeners } from '@libp2p/interface'
import { ipPortToMultiaddr as toMultiaddr } from '@libp2p/utils/ip-port-to-multiaddr'
import { multiaddr, protocols } from '@multiformats/multiaddr'
import { multiaddr } from '@multiformats/multiaddr'
import { WebSockets, WebSocketsSecure } from '@multiformats/multiaddr-matcher'
import duplex from 'it-ws/duplex'
import { pEvent } from 'p-event'
Expand Down Expand Up @@ -138,7 +138,6 @@ export class WebSocketListener extends TypedEventEmitter<ListenerEvents> impleme
}

Check warning on line 138 in packages/transport-websockets/src/listener.ts

View check run for this annotation

Codecov / codecov/patch

packages/transport-websockets/src/listener.ts#L135-L138

Added lines #L135 - L138 were not covered by tests

// store the socket so we can close it when the listener closes
// TODO: is this necessary if we can `this.https.closeAllConnections`?
this.sockets.add(socket)
socket.on('close', () => {
this.sockets.delete(socket)
Expand Down Expand Up @@ -233,7 +232,7 @@ export class WebSocketListener extends TypedEventEmitter<ListenerEvents> impleme
const { host, port } = ma.toOptions()
this.addr = `${host}:${port}`

this.server.listen(port)
this.server.listen(port, host)

await new Promise<void>((resolve, reject) => {
const onListening = (): void => {
Expand Down Expand Up @@ -313,7 +312,6 @@ export class WebSocketListener extends TypedEventEmitter<ListenerEvents> impleme
}

getAddrs (): Multiaddr[] {
const multiaddrs: Multiaddr[] = []
const address = this.server.address()

if (address == null) {
Expand All @@ -328,16 +326,10 @@ export class WebSocketListener extends TypedEventEmitter<ListenerEvents> impleme
throw new Error('Listener is not ready yet')
}

const protos = this.listeningMultiaddr.protos()

// because TCP will only return the IPv6 version, we need to capture from
// the passed multiaddr
if (protos.some(proto => proto.code === protocols('ip4').code)) {
const wsProto = protos.some(proto => proto.code === protocols('ws').code) ? '/ws' : '/wss'
let m = this.listeningMultiaddr.decapsulate('tcp')
m = m.encapsulate(`/tcp/${address.port}${wsProto}`)
const options = m.toOptions()
const options = this.listeningMultiaddr.toOptions()
const multiaddrs: Multiaddr[] = []

if (options.family === 4) {
if (options.host === '0.0.0.0') {
Object.values(os.networkInterfaces()).forEach(niInfos => {
if (niInfos == null) {
Expand All @@ -346,24 +338,51 @@ export class WebSocketListener extends TypedEventEmitter<ListenerEvents> impleme

niInfos.forEach(ni => {
if (ni.family === 'IPv4') {
multiaddrs.push(multiaddr(`/ip${options.family}/${ni.address}/${options.transport}/${options.port}/ws`))
multiaddrs.push(multiaddr(`/ip${options.family}/${ni.address}/${options.transport}/${address.port}`))
}
})
})
} else {
multiaddrs.push(multiaddr(`/ip${options.family}/${options.host}/${options.transport}/${address.port}`))
}
} else if (options.family === 6) {
if (options.host === '::') {
Object.values(os.networkInterfaces()).forEach(niInfos => {
if (niInfos == null) {
return
}

if (this.https != null && WebSockets.exactMatch(m)) {
multiaddrs.push(multiaddr(`/ip${options.family}/${ni.address}/${options.transport}/${options.port}/tls/ws`))
}
niInfos.forEach(ni => {
if (ni.family === 'IPv6') {
multiaddrs.push(multiaddr(`/ip${options.family}/${ni.address}/${options.transport}/${address.port}`))
}
})
})

Check warning on line 360 in packages/transport-websockets/src/listener.ts

View check run for this annotation

Codecov / codecov/patch

packages/transport-websockets/src/listener.ts#L350-L360

Added lines #L350 - L360 were not covered by tests
} else {
if (this.https != null && WebSockets.exactMatch(m)) {
multiaddrs.push(m.decapsulate('/ws').encapsulate('/tls/ws'))
} else {
multiaddrs.push(m)
}
multiaddrs.push(multiaddr(`/ip${options.family}/${options.host}/${options.transport}/${address.port}`))
}
}

return multiaddrs
const insecureMultiaddrs: Multiaddr[] = []

if (this.http != null) {
multiaddrs.forEach(ma => {
insecureMultiaddrs.push(ma.encapsulate('/ws'))
})
}

const secureMultiaddrs: Multiaddr[] = []

if (this.https != null) {
multiaddrs.forEach(ma => {
secureMultiaddrs.push(ma.encapsulate('/tls/ws'))
})
}

return [
...insecureMultiaddrs,
...secureMultiaddrs
]
}

private httpRequestHandler (req: http.IncomingMessage, res: http.ServerResponse): void {
Expand Down
74 changes: 70 additions & 4 deletions packages/transport-websockets/test/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ describe('listen', () => {
it('should error on starting two listeners on same address', async () => {
listener = ws.createListener({ upgrader })
const dumbServer = http.createServer()
await new Promise<void>(resolve => dumbServer.listen(ma.toOptions().port, resolve))
const options = ma.toOptions()
await new Promise<void>(resolve => dumbServer.listen(options.port, options.host, resolve))
await expect(listener.listen(ma)).to.eventually.rejectedWith('listen EADDRINUSE')
await new Promise<void>(resolve => dumbServer.close(() => { resolve() }))
})
Expand Down Expand Up @@ -152,7 +153,7 @@ describe('listen', () => {
})

it('getAddrs preserves p2p Id', async () => {
const ma = multiaddr('/ip4/127.0.0.1/tcp/47382/ws/p2p/Qmb6owHp6eaWArVbcJJbQSyifyJBttMMjYV76N2hMbf5Vw')
const ma = multiaddr('/ip4/127.0.0.1/tcp/47382/ws')
listener = ws.createListener({ upgrader })

await listener.listen(ma)
Expand Down Expand Up @@ -335,7 +336,7 @@ describe('dial', () => {
describe('ip4 with wss', () => {
let ws: Transport
let listener: Listener
const ma = multiaddr('/ip4/127.0.0.1/tcp/37284/wss')
const ma = multiaddr('/ip4/127.0.0.1/tcp/37284/tls/ws')

beforeEach(async () => {
ws = webSockets({
Expand Down Expand Up @@ -614,7 +615,7 @@ describe('filter addrs', () => {
})
})

describe('auto-tls', () => {
describe('auto-tls (IPv4)', () => {
let ws: Transport
let listener: Listener
let events: TypedEventEmitter<Libp2pEvents>
Expand Down Expand Up @@ -652,7 +653,72 @@ describe('auto-tls', () => {
const addrs = listener.getAddrs()
expect(addrs).to.have.lengthOf(1)
expect(WebSockets.exactMatch(addrs[0])).to.be.true()
const listeningPromise = pEvent(listener, 'listening')

events.safeDispatchEvent<TLSCertificate>('certificate:provision', {
detail: {
key: fs.readFileSync('./test/fixtures/key.pem', {
encoding: 'utf-8'
}),
cert: fs.readFileSync('./test/fixtures/certificate.pem', {
encoding: 'utf-8'
})
}
})

await listeningPromise

const addrs2 = listener.getAddrs()
expect(addrs2).to.have.lengthOf(2)
expect(WebSockets.exactMatch(addrs2[0])).to.be.true()
expect(WebSocketsSecure.exactMatch(addrs2[1])).to.be.true()

const wsOptions = addrs2[0].toOptions()
const wssOptions = addrs2[1].toOptions()

expect(wsOptions.host).to.equal(wssOptions.host)
expect(wsOptions.port).to.equal(wssOptions.port)
})
})

describe('auto-tls (IPv6)', () => {
let ws: Transport
let listener: Listener
let events: TypedEventEmitter<Libp2pEvents>
const ma = multiaddr('/ip6/::1/tcp/37284/ws')

beforeEach(async () => {
events = new TypedEventEmitter()

const upgrader = stubInterface<Upgrader>({
upgradeInbound: Sinon.stub().resolves(),
upgradeOutbound: async () => {
return stubInterface<Connection>()
}

Check warning on line 697 in packages/transport-websockets/test/node.ts

View check run for this annotation

Codecov / codecov/patch

packages/transport-websockets/test/node.ts#L696-L697

Added lines #L696 - L697 were not covered by tests
})

ws = webSockets({
websocket: {
rejectUnauthorized: false
}
})({
events,
logger: defaultLogger()
})
listener = ws.createListener({
upgrader
})
await listener.listen(ma)
})

afterEach(async () => {
await listener.close()
})

it('should listen on wss after a certificate is found', async () => {
const addrs = listener.getAddrs()
expect(addrs).to.have.lengthOf(1)
expect(WebSockets.exactMatch(addrs[0])).to.be.true()
const listeningPromise = pEvent(listener, 'listening')

events.safeDispatchEvent<TLSCertificate>('certificate:provision', {
Expand Down

0 comments on commit 17bd4fd

Please sign in to comment.