mirror of
https://github.com/status-im/libp2p-test-plans.git
synced 2025-02-17 09:16:41 +00:00
Browser WSS testing (#144)
* Update playwright test * Update multiaddr * WIP: websocket testing in browser * Add v0.42 test * node-image.json * Revert js v0.41 changes * Update versions.ts
This commit is contained in:
parent
a91f5da8cf
commit
1318080e01
@ -2,9 +2,15 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"crypto/x509/pkix"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"math/big"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
@ -80,6 +86,9 @@ func main() {
|
|||||||
case "ws":
|
case "ws":
|
||||||
options = append(options, libp2p.Transport(websocket.New))
|
options = append(options, libp2p.Transport(websocket.New))
|
||||||
listenAddr = fmt.Sprintf("/ip4/%s/tcp/0/ws", ip)
|
listenAddr = fmt.Sprintf("/ip4/%s/tcp/0/ws", ip)
|
||||||
|
case "wss":
|
||||||
|
options = append(options, libp2p.Transport(websocket.New, websocket.WithTLSConfig(generateTLSConfig()), websocket.WithTLSClientConfig(&tls.Config{InsecureSkipVerify: true})))
|
||||||
|
listenAddr = fmt.Sprintf("/ip4/%s/tcp/0/wss", ip)
|
||||||
case "tcp":
|
case "tcp":
|
||||||
options = append(options, libp2p.Transport(tcp.NewTCPTransport))
|
options = append(options, libp2p.Transport(tcp.NewTCPTransport))
|
||||||
listenAddr = fmt.Sprintf("/ip4/%s/tcp/0", ip)
|
listenAddr = fmt.Sprintf("/ip4/%s/tcp/0", ip)
|
||||||
@ -195,3 +204,28 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateTLSConfig() *tls.Config {
|
||||||
|
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
tmpl := &x509.Certificate{
|
||||||
|
SerialNumber: big.NewInt(1),
|
||||||
|
Subject: pkix.Name{},
|
||||||
|
SignatureAlgorithm: x509.SHA256WithRSA,
|
||||||
|
NotBefore: time.Now(),
|
||||||
|
NotAfter: time.Now().Add(time.Hour), // valid for an hour
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
}
|
||||||
|
certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, priv.Public(), priv)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return &tls.Config{
|
||||||
|
Certificates: []tls.Certificate{{
|
||||||
|
PrivateKey: priv,
|
||||||
|
Certificate: [][]byte{certDER},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
82
multidim-interop/js/v0.42/.aegir.js
Normal file
82
multidim-interop/js/v0.42/.aegir.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import { createClient } from 'redis'
|
||||||
|
import http from "http"
|
||||||
|
|
||||||
|
const redis_addr = process.env.redis_addr || 'redis:6379'
|
||||||
|
|
||||||
|
/** @type {import('aegir/types').PartialOptions} */
|
||||||
|
export default {
|
||||||
|
test: {
|
||||||
|
browser: {
|
||||||
|
config: {
|
||||||
|
// Ignore self signed certificates
|
||||||
|
browserContextOptions: { ignoreHTTPSErrors: true }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async before() {
|
||||||
|
const redisClient = createClient({
|
||||||
|
url: `redis://${redis_addr}`
|
||||||
|
})
|
||||||
|
redisClient.on('error', (err) => console.error(`Redis Client Error: ${err}`))
|
||||||
|
await redisClient.connect()
|
||||||
|
|
||||||
|
const requestListener = async function (req, res) {
|
||||||
|
const requestJSON = await new Promise(resolve => {
|
||||||
|
let body = ""
|
||||||
|
req.on('data', function (data) {
|
||||||
|
body += data;
|
||||||
|
});
|
||||||
|
|
||||||
|
req.on('end', function () {
|
||||||
|
resolve(JSON.parse(body))
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
const redisRes = await redisClient.sendCommand(requestJSON)
|
||||||
|
if (redisRes === null) {
|
||||||
|
throw new Error("redis sent back null")
|
||||||
|
}
|
||||||
|
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Access-Control-Allow-Origin': '*'
|
||||||
|
})
|
||||||
|
res.end(JSON.stringify(redisRes))
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error in redis command:", err)
|
||||||
|
res.writeHead(500, {
|
||||||
|
'Access-Control-Allow-Origin': '*'
|
||||||
|
})
|
||||||
|
res.end(err.toString())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const proxyServer = http.createServer(requestListener);
|
||||||
|
await new Promise(resolve => { proxyServer.listen(0, "localhost", () => { resolve() }); })
|
||||||
|
|
||||||
|
return {
|
||||||
|
redisClient,
|
||||||
|
proxyServer: proxyServer,
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
proxyPort: proxyServer.address().port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async after(_, { proxyServer, redisClient }) {
|
||||||
|
await new Promise(resolve => {
|
||||||
|
proxyServer.close(() => resolve());
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
// We don't care if this fails
|
||||||
|
await redisClient.disconnect()
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
bundlesizeMax: '18kB'
|
||||||
|
}
|
||||||
|
}
|
1
multidim-interop/js/v0.42/.dockerignore
Normal file
1
multidim-interop/js/v0.42/.dockerignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules/
|
3
multidim-interop/js/v0.42/.gitignore
vendored
Normal file
3
multidim-interop/js/v0.42/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
dist
|
||||||
|
node-image.json
|
||||||
|
chromium-image.json
|
22
multidim-interop/js/v0.42/ChromiumDockerfile
Normal file
22
multidim-interop/js/v0.42/ChromiumDockerfile
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
|
FROM mcr.microsoft.com/playwright
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
|
||||||
|
COPY package*.json .
|
||||||
|
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Install browsers
|
||||||
|
RUN ./node_modules/.bin/playwright install
|
||||||
|
|
||||||
|
COPY tsconfig.json .
|
||||||
|
COPY .aegir.js .
|
||||||
|
COPY test ./test
|
||||||
|
COPY src ./src
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
ENTRYPOINT [ "npm", "test", "--", "--build", "false", "--types", "false", "-t", "browser" ]
|
17
multidim-interop/js/v0.42/Dockerfile
Normal file
17
multidim-interop/js/v0.42/Dockerfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
FROM node:18
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY package*.json .
|
||||||
|
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
COPY tsconfig.json .
|
||||||
|
COPY .aegir.js .
|
||||||
|
COPY test ./test
|
||||||
|
COPY src ./src
|
||||||
|
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
ENTRYPOINT [ "npm", "test", "--", "--build", "false", "--types", "false", "-t", "node" ]
|
19
multidim-interop/js/v0.42/Makefile
Normal file
19
multidim-interop/js/v0.42/Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
image_name := js-v0.42
|
||||||
|
TEST_SOURCES := $(wildcard test/*.ts)
|
||||||
|
|
||||||
|
all: chromium-image.json node-image.json
|
||||||
|
|
||||||
|
chromium-image.json: ChromiumDockerfile $(TEST_SOURCES) package.json package-lock.json .aegir.js
|
||||||
|
IMAGE_NAME=chromium-${image_name} ../../dockerBuildWrapper.sh -f ChromiumDockerfile .
|
||||||
|
docker image inspect chromium-${image_name} -f "{{.Id}}" | \
|
||||||
|
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
|
||||||
|
|
||||||
|
node-image.json: Dockerfile $(TEST_SOURCES) package.json package-lock.json .aegir.js
|
||||||
|
IMAGE_NAME=node-${image_name} ../../dockerBuildWrapper.sh -f Dockerfile .
|
||||||
|
docker image inspect node-${image_name} -f "{{.Id}}" | \
|
||||||
|
xargs -I {} echo "{\"imageID\": \"{}\"}" > $@
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm *image.json
|
42062
multidim-interop/js/v0.42/package-lock.json
generated
Normal file
42062
multidim-interop/js/v0.42/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
40
multidim-interop/js/v0.42/package.json
Normal file
40
multidim-interop/js/v0.42/package.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"name": "multidim-interop",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Multidimension Interop Test",
|
||||||
|
"type": "module",
|
||||||
|
"main": "index.js",
|
||||||
|
"author": "Glen De Cauwsemaecker <glen@littlebearlabs.io> / @marcopolo",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"start": "node index.js",
|
||||||
|
"build": "aegir build",
|
||||||
|
"test": "aegir test"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@chainsafe/libp2p-noise": "^10.2.0",
|
||||||
|
"@chainsafe/libp2p-yamux": "^3.0.4",
|
||||||
|
"@libp2p/mplex": "^7.1.1",
|
||||||
|
"@libp2p/tcp": "^6.0.8",
|
||||||
|
"@libp2p/webrtc": "^1.0.3",
|
||||||
|
"@libp2p/websockets": "^5.0.4",
|
||||||
|
"@libp2p/webtransport": "^1.0.7",
|
||||||
|
"@multiformats/mafmt": "^11.1.0",
|
||||||
|
"@multiformats/multiaddr": "^11.1.4",
|
||||||
|
"libp2p": "^0.42.0",
|
||||||
|
"node-fetch": "^3.3.0",
|
||||||
|
"redis": "4.5.1"
|
||||||
|
},
|
||||||
|
"browser": {
|
||||||
|
"@libp2p/tcp": false
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"aegir": "^38.1.0",
|
||||||
|
"standard": "^17.0.0",
|
||||||
|
"typescript": "^4.9.4"
|
||||||
|
}
|
||||||
|
}
|
3
multidim-interop/js/v0.42/src/index.ts
Normal file
3
multidim-interop/js/v0.42/src/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
console.log("Everything is defined in the test folder")
|
||||||
|
|
||||||
|
export { }
|
155
multidim-interop/js/v0.42/test/ping.spec.ts
Normal file
155
multidim-interop/js/v0.42/test/ping.spec.ts
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/* eslint-disable no-console */
|
||||||
|
/* eslint-env mocha */
|
||||||
|
|
||||||
|
import { } from 'aegir/chai'
|
||||||
|
import { createLibp2p, Libp2pOptions } from 'libp2p'
|
||||||
|
import { webTransport } from '@libp2p/webtransport'
|
||||||
|
import { tcp } from '@libp2p/tcp'
|
||||||
|
import { webSockets } from '@libp2p/websockets'
|
||||||
|
import { noise } from '@chainsafe/libp2p-noise'
|
||||||
|
import { mplex } from '@libp2p/mplex'
|
||||||
|
import { yamux } from '@chainsafe/libp2p-yamux'
|
||||||
|
import { multiaddr } from '@multiformats/multiaddr'
|
||||||
|
import { webRTC } from '@libp2p/webrtc'
|
||||||
|
|
||||||
|
async function redisProxy(commands: any[]): Promise<any> {
|
||||||
|
const res = await fetch(`http://localhost:${process.env.proxyPort}/`, { body: JSON.stringify(commands), method: "POST" })
|
||||||
|
if (!res.ok) {
|
||||||
|
throw new Error("Redis command failed")
|
||||||
|
}
|
||||||
|
return await res.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('ping test', () => {
|
||||||
|
it('should ping', async () => {
|
||||||
|
const TRANSPORT = process.env.transport
|
||||||
|
const SECURE_CHANNEL = process.env.security
|
||||||
|
const MUXER = process.env.muxer
|
||||||
|
const isDialer = process.env.is_dialer === "true"
|
||||||
|
const IP = process.env.ip || "0.0.0.0"
|
||||||
|
const timeoutSecs: string = process.env.test_timeout_secs || "180"
|
||||||
|
|
||||||
|
const options: Libp2pOptions = {
|
||||||
|
start: true
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (TRANSPORT) {
|
||||||
|
case 'tcp':
|
||||||
|
options.transports = [tcp()]
|
||||||
|
options.addresses = {
|
||||||
|
listen: isDialer ? [] : [`/ip4/${IP}/tcp/0`]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'webtransport':
|
||||||
|
options.transports = [webTransport()]
|
||||||
|
if (!isDialer) {
|
||||||
|
throw new Error("WebTransport is not supported as a listener")
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'webrtc':
|
||||||
|
options.transports = [webRTC()]
|
||||||
|
options.addresses = {
|
||||||
|
listen: isDialer ? [] : [`/ip4/${IP}/udp/0/webrtc`]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'ws':
|
||||||
|
options.transports = [webSockets()]
|
||||||
|
options.addresses = {
|
||||||
|
listen: isDialer ? [] : [`/ip4/${IP}/tcp/0/ws`]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'wss':
|
||||||
|
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
||||||
|
options.transports = [webSockets()]
|
||||||
|
options.addresses = {
|
||||||
|
listen: isDialer ? [] : [`/ip4/${IP}/tcp/0/wss`]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown transport: ${TRANSPORT}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
let skipSecureChannel = false
|
||||||
|
let skipMuxer = false
|
||||||
|
switch (TRANSPORT) {
|
||||||
|
case 'webtransport':
|
||||||
|
case 'webrtc':
|
||||||
|
skipSecureChannel = true
|
||||||
|
skipMuxer = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skipSecureChannel) {
|
||||||
|
switch (SECURE_CHANNEL) {
|
||||||
|
case 'noise':
|
||||||
|
options.connectionEncryption = [noise()]
|
||||||
|
break
|
||||||
|
case 'quic':
|
||||||
|
options.connectionEncryption = [noise()]
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown secure channel: ${SECURE_CHANNEL}`)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Libp2p requires at least one encryption module. Even if unused.
|
||||||
|
options.connectionEncryption = [noise()]
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!skipMuxer) {
|
||||||
|
switch (MUXER) {
|
||||||
|
case 'mplex':
|
||||||
|
options.streamMuxers = [mplex()]
|
||||||
|
break
|
||||||
|
case 'yamux':
|
||||||
|
options.streamMuxers = [yamux()]
|
||||||
|
break
|
||||||
|
case 'quic':
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown muxer: ${MUXER}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const node = await createLibp2p(options)
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (isDialer) {
|
||||||
|
var otherMa = (await redisProxy(["BLPOP", "listenerAddr", timeoutSecs]).catch(err => { throw new Error("Failed to wait for listener") }))[1]
|
||||||
|
// Hack until these are merged:
|
||||||
|
// - https://github.com/multiformats/js-multiaddr/pull/312
|
||||||
|
// - https://github.com/multiformats/js-multiaddr-to-uri/pull/120
|
||||||
|
otherMa = otherMa.replace("/tls/ws", "/wss")
|
||||||
|
otherMa = otherMa.replace("/ip4/192.168.5.124", "/dns4/localhost")
|
||||||
|
|
||||||
|
console.error(`node ${node.peerId} pings: ${otherMa}`)
|
||||||
|
const handshakeStartInstant = Date.now()
|
||||||
|
await node.dial(multiaddr(otherMa))
|
||||||
|
const pingRTT = await node.ping(multiaddr(otherMa))
|
||||||
|
const handshakePlusOneRTT = Date.now() - handshakeStartInstant
|
||||||
|
console.log(JSON.stringify({
|
||||||
|
handshakePlusOneRTTMillis: handshakePlusOneRTT,
|
||||||
|
pingRTTMilllis: pingRTT
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
const multiaddrs = node.getMultiaddrs().map(ma => ma.toString()).filter(maString => !maString.includes("127.0.0.1"))
|
||||||
|
console.error("My multiaddrs are", multiaddrs)
|
||||||
|
// Send the listener addr over the proxy server so this works on both the Browser and Node
|
||||||
|
await redisProxy(["RPUSH", "listenerAddr", multiaddrs[0]])
|
||||||
|
// Wait
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000 * parseInt(timeoutSecs, 10)))
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// Show all errors in an aggregated error
|
||||||
|
if (err instanceof AggregateError) {
|
||||||
|
console.error(`unexpected exception in ping test: ${err}\n Errors:`, err.errors)
|
||||||
|
} else {
|
||||||
|
console.error(`unexpected exception in ping test:`, err)
|
||||||
|
}
|
||||||
|
throw err
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
// We don't care if this fails
|
||||||
|
await node.stop()
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
10
multidim-interop/js/v0.42/tsconfig.json
Normal file
10
multidim-interop/js/v0.42/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"extends": "aegir/src/config/tsconfig.aegir.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "dist"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src",
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
}
|
@ -6,8 +6,10 @@ import rustv048 from "./rust/v0.48/image.json"
|
|||||||
import rustv049 from "./rust/v0.49/image.json"
|
import rustv049 from "./rust/v0.49/image.json"
|
||||||
import rustv050 from "./rust/v0.50/image.json"
|
import rustv050 from "./rust/v0.50/image.json"
|
||||||
import jsV041 from "./js/v0.41/node-image.json"
|
import jsV041 from "./js/v0.41/node-image.json"
|
||||||
|
import jsV042 from "./js/v0.42/node-image.json"
|
||||||
import nimv10 from "./nim/v1.0/image.json"
|
import nimv10 from "./nim/v1.0/image.json"
|
||||||
import chromiumJsV041 from "./js/v0.41/chromium-image.json"
|
import chromiumJsV041 from "./js/v0.41/chromium-image.json"
|
||||||
|
import chromiumJsV042 from "./js/v0.42/chromium-image.json"
|
||||||
|
|
||||||
export type Version = {
|
export type Version = {
|
||||||
id: string,
|
id: string,
|
||||||
@ -48,6 +50,13 @@ export const versions: Array<Version> = [
|
|||||||
secureChannels: ["noise"],
|
secureChannels: ["noise"],
|
||||||
muxers: ["mplex", "yamux"],
|
muxers: ["mplex", "yamux"],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "js-v0.42.0",
|
||||||
|
containerImageID: jsV042.imageID,
|
||||||
|
transports: ["tcp", "ws", { name: "wss", onlyDial: true }],
|
||||||
|
secureChannels: ["noise"],
|
||||||
|
muxers: ["mplex", "yamux"],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "chromium-js-v0.41.0",
|
id: "chromium-js-v0.41.0",
|
||||||
containerImageID: chromiumJsV041.imageID,
|
containerImageID: chromiumJsV041.imageID,
|
||||||
@ -55,6 +64,13 @@ export const versions: Array<Version> = [
|
|||||||
secureChannels: [],
|
secureChannels: [],
|
||||||
muxers: []
|
muxers: []
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "chromium-js-v0.42.0",
|
||||||
|
containerImageID: chromiumJsV042.imageID,
|
||||||
|
transports: [{ name: "webtransport", onlyDial: true }, { name: "webrtc", onlyDial: true }, { name: "wss", onlyDial: true }],
|
||||||
|
secureChannels: ["noise"],
|
||||||
|
muxers: ["mplex", "yamux"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "go-v0.25.1",
|
id: "go-v0.25.1",
|
||||||
containerImageID: gov025.imageID,
|
containerImageID: gov025.imageID,
|
||||||
@ -65,7 +81,7 @@ export const versions: Array<Version> = [
|
|||||||
{
|
{
|
||||||
id: "go-v0.24.2",
|
id: "go-v0.24.2",
|
||||||
containerImageID: gov024.imageID,
|
containerImageID: gov024.imageID,
|
||||||
transports: ["tcp", "ws", "quic", "quic-v1", "webtransport"],
|
transports: ["tcp", "ws", "quic", "quic-v1", "webtransport", "wss"],
|
||||||
secureChannels: ["tls", "noise"],
|
secureChannels: ["tls", "noise"],
|
||||||
muxers: ["mplex", "yamux"],
|
muxers: ["mplex", "yamux"],
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user