-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest.js
156 lines (131 loc) · 4.23 KB
/
test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
const { spawn } = require('child_process')
const { once } = require('events')
const path = require('path')
const http = require('http')
const createTestnet = require('hyperdht/testnet')
const test = require('brittle')
const HyperDHT = require('hyperdht')
const b4a = require('b4a')
const SERVER_EXECUTABLE = path.join(__dirname, 'server.js')
const CLIENT_EXECUTABLE = path.join(__dirname, 'client.js')
const DEBUG = false
test('Can proxy ', async t => {
const { bootstrap } = await createTestnet(3, t.teardown)
const portToProxy = await setupDummyServer(t.teardown)
const seed = 'a'.repeat(64)
await setupProxyServer(portToProxy, seed, bootstrap, t)
const clientAddress = await setupProxyClient(seed, bootstrap, t, { isPrivate: true })
const res = await request(`http://${clientAddress}`)
t.is(res.data, 'You got served', 'Proxy works')
})
test('Cannot access server with public key', async t => {
t.plan(2)
const { bootstrap } = await createTestnet(3, t.teardown)
const portToProxy = await setupDummyServer(t.teardown)
const seed = 'a'.repeat(64)
await setupProxyServer(portToProxy, seed, bootstrap, t)
const keypair = HyperDHT.keyPair(b4a.from(seed, 'hex'))
{
const dht = new HyperDHT({ bootstrap })
const socket = dht.connect(keypair.publicKey)
socket.on('open', () => t.fail('Should not be able to connect due to firewall'))
socket.on('error', async (e) => {
if (DEBUG) console.log(e)
t.pass('could not connect')
await dht.destroy()
})
}
{
const dht = new HyperDHT({ bootstrap, seed: b4a.from(seed, 'hex') })
const socket = dht.connect(keypair.publicKey)
socket.on('open', async () => {
t.pass('Sanity check: opened socket when using same seed')
await dht.destroy()
})
socket.on('error', e => t.fail('unexpected error'))
}
})
async function setupDummyServer (teardown) {
const server = http.createServer(async (req, res) => {
res.setHeader('Content-Type', 'text/html; charset=utf-8')
res.end('You got served')
})
teardown(() => server.close())
server.listen({ port: 0, host: '127.0.0.1' })
await once(server, 'listening')
return server.address().port
}
async function setupProxyServer (portToProxy, seed, bootstrap, t) {
const setupServer = spawn('node', [SERVER_EXECUTABLE], {
env: {
...process.env,
P2PROXY_PORT: portToProxy,
P2PROXY_SEED: seed,
P2PROXY_BOOTSTRAP: `${bootstrap[0].host}:${bootstrap[0].port}`
}
})
t.teardown(() => setupServer.kill('SIGKILL'))
setupServer.stderr.on('data', (data) => {
console.error(data.toString())
t.fail('Failed to setup proxy server')
})
await new Promise(resolve => {
setupServer.stdout.on('data', (data) => {
if (DEBUG) console.log(data.toString())
if (data.includes('The proxy server is listening')) {
resolve()
}
})
})
}
async function setupProxyClient (seed, bootstrap, t, { isPrivate = false } = {}) {
const setupClient = spawn('node', [CLIENT_EXECUTABLE], {
env: {
...process.env,
P2PROXY_SEED: seed,
P2PROXY_BOOTSTRAP: `${bootstrap[0].host}:${bootstrap[0].port}`
}
})
t.teardown(() => setupClient.kill('SIGKILL'))
setupClient.stderr.on('data', (data) => {
console.error(data.toString())
t.fail('Failed to setup proxy client')
})
const clientAddress = await new Promise(resolve => {
setupClient.stdout.on('data', (data) => {
const msg = data.toString()
if (DEBUG) console.log(msg)
if (msg.includes('The proxy client is listening')) {
const address = msg.match('127.0.0.1:[0-9]+')[0]
resolve(address)
}
})
})
return clientAddress
}
async function request (link, { msTimeout = 5000 } = {}) {
return new Promise((resolve, reject) => {
const req = http.get(link, {
headers: {
Connection: 'close'
}
})
req.setTimeout(msTimeout,
() => {
reject(new Error('Request timeout'))
req.destroy()
}
)
req.on('error', reject)
req.on('response', function (res) {
let buf = ''
res.setEncoding('utf-8')
res.on('data', function (data) {
buf += data
})
res.on('end', function () {
resolve({ status: res.statusCode, data: buf })
})
})
})
}