diff --git a/app/lib/common-libs/websocket.ts b/app/lib/common-libs/websocket.ts new file mode 100644 index 0000000000000000000000000000000000000000..a9589d2aba1efa73ac575be99124f706f49f17f3 --- /dev/null +++ b/app/lib/common-libs/websocket.ts @@ -0,0 +1,38 @@ +// Source file from duniter: Crypto-currency software to manage libre currency such as Äž1 +// Copyright (C) 2018 Cedric Moreau <cem.moreau@gmail.com> +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +import * as WS from 'ws' + +export class WebSocket extends WS { + constructor(url: string, options?: { agent: any }) { + super(url, { + agent: options && options.agent, + }) + } +} + +export class WebSocketServer extends WS.Server { + constructor(options: { + server?: any, + host?: string, + port?: number, + path?: string + }) { + super({ + server: options.server, + path: options.path, + host: options.host, + port: options.port, + }) + } +} diff --git a/app/modules/bma/lib/bma.ts b/app/modules/bma/lib/bma.ts index ee53a37269369cfe221506b83cfc5a525c196d3e..575ab3eb05369d70d38d08a9398394769eacabff 100644 --- a/app/modules/bma/lib/bma.ts +++ b/app/modules/bma/lib/bma.ts @@ -24,9 +24,9 @@ import {UDBinding} from "./controllers/uds" import {PeerDTO} from "../../../lib/dto/PeerDTO" import {BlockDTO} from "../../../lib/dto/BlockDTO" import {OtherConstants} from "../../../lib/other_constants" +import {WebSocketServer} from "../../../lib/common-libs/websocket" const es = require('event-stream'); -const WebSocketServer = require('ws').Server; export const bma = function(server:Server, interfaces:NetworkInterface[]|null, httpLogs:boolean, logger:any): Promise<BmaApi> { @@ -149,16 +149,17 @@ export const bma = function(server:Server, interfaces:NetworkInterface[]|null, h } } }) - wssHeads.broadcast = (data:any) => wssHeads.clients.forEach((client:any) => client.send(data)); + const wssHeadsBroadcast = (data:any) => wssHeads.clients.forEach((client:any) => client.send(data)); - wssBlock.broadcast = (data:any) => wssBlock.clients.forEach((client:any) => { + const wssBlockBroadcast = (data:any) => wssBlock.clients.forEach((client:any) => { try { client.send(data); } catch (e) { logger && logger.error('error on ws: %s', e); } }); - wssPeer.broadcast = (data:any) => wssPeer.clients.forEach((client:any) => client.send(data)); + + const wssPeerBroadcast = (data:any) => wssPeer.clients.forEach((client:any) => client.send(data)); // Forward current HEAD change server @@ -168,7 +169,7 @@ export const bma = function(server:Server, interfaces:NetworkInterface[]|null, h // Broadcast block currentBlock = e.block; const blockDTO:BlockDTO = BlockDTO.fromJSONObject(currentBlock) - wssBlock.broadcast(JSON.stringify(block2HttpBlock(blockDTO))) + wssBlockBroadcast(JSON.stringify(block2HttpBlock(blockDTO))) } catch (e) { logger && logger.error('error on ws mapSync:', e); } @@ -190,11 +191,11 @@ export const bma = function(server:Server, interfaces:NetworkInterface[]|null, h signature: peerDTO.signature, raw: peerDTO.getRaw() } - wssPeer.broadcast(JSON.stringify(peerResult)); + wssPeerBroadcast(JSON.stringify(peerResult)); } // Broadcast heads else if (data.ws2p === 'heads' && data.added.length) { - wssHeads.broadcast(JSON.stringify(data.added)); + wssHeadsBroadcast(JSON.stringify(data.added)); } } catch (e) { logger && logger.error('error on ws mapSync:', e); diff --git a/app/modules/ws2p/lib/WS2PConnection.ts b/app/modules/ws2p/lib/WS2PConnection.ts index dad3bdbeebe643d18d3bbe02db234d483c126ccb..0f8cf34a77e5f6aeafb579f1b7fc5132eb32b93e 100644 --- a/app/modules/ws2p/lib/WS2PConnection.ts +++ b/app/modules/ws2p/lib/WS2PConnection.ts @@ -20,8 +20,8 @@ import {MembershipDTO} from "../../../lib/dto/MembershipDTO" import {TransactionDTO} from "../../../lib/dto/TransactionDTO" import {PeerDTO} from "../../../lib/dto/PeerDTO" import {WS2PConstants} from './constants'; +import {WebSocket} from "../../../lib/common-libs/websocket" -const ws = require('ws') const SocksProxyAgent = require('socks-proxy-agent'); const nuuid = require('node-uuid'); const logger = require('../../../lib/logger').NewLogger('ws2p') @@ -334,7 +334,7 @@ export class WS2PConnection { requestTimeout: WS2PConstants.REQUEST_TOR_TIMEOUT } } - const websocket = (proxySocksAddress !== undefined) ? new ws(address, { agent: SocksProxyAgent("socks://"+proxySocksAddress) }):new ws(address) + const websocket = (proxySocksAddress !== undefined) ? new WebSocket(address, { agent: SocksProxyAgent("socks://"+proxySocksAddress) }):new WebSocket(address) const onWsOpened:Promise<void> = new Promise(res => { websocket.on('open', () => res()) }) diff --git a/app/modules/ws2p/lib/WS2PServer.ts b/app/modules/ws2p/lib/WS2PServer.ts index d0eec6b8fdd663a6a615acb7bef158490ce67c83..a9091d43ebd0b4fb221c755f99682bc2203c19c2 100644 --- a/app/modules/ws2p/lib/WS2PServer.ts +++ b/app/modules/ws2p/lib/WS2PServer.ts @@ -20,8 +20,7 @@ import {WS2PConstants} from "./constants" import {WS2PMessageHandler} from "./impl/WS2PMessageHandler" import {WS2PStreamer} from "./WS2PStreamer" import {WS2PSingleWriteStream} from "./WS2PSingleWriteStream" - -const WebSocketServer = require('ws').Server +import {WebSocketServer} from "../../../lib/common-libs/websocket" export class WS2PServer extends events.EventEmitter { diff --git a/package.json b/package.json index 9a6d2ee5479aa927da7022113f479d602b4e4d49..b722a32a9d35af7ad12991d1d913e35fbaad55d3 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "url": "https://github.com/duniter/duniter/issues" }, "dependencies": { + "@types/ws": "^5.1.2", "archiver": "1.3.0", "async": "2.2.0", "bindings": "1.2.1", diff --git a/test/integration/misc/http-api.ts b/test/integration/misc/http-api.ts index c79f927ddfb94b382d4e58984cadb32f1a4cb253..349ebabc3f4eefb6c19780da6a1f1999edac56e7 100644 --- a/test/integration/misc/http-api.ts +++ b/test/integration/misc/http-api.ts @@ -11,8 +11,6 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. -"use strict"; - import {ProverConstants} from "../../../app/modules/prover/lib/constants" import {NewTestingServer, TestingServer} from "../tools/toolbox" import {TestUser} from "../tools/TestUser" @@ -24,11 +22,11 @@ import {Underscore} from "../../../app/lib/common-libs/underscore" import {BlockDTO} from "../../../app/lib/dto/BlockDTO" import {shutDownEngine} from "../tools/shutdown-engine" import {expectAnswer, expectError} from "../tools/http-expect" +import {WebSocket} from "../../../app/lib/common-libs/websocket" const should = require('should'); const assert = require('assert'); const rp = require('request-promise'); -const ws = require('ws'); ProverConstants.CORES_MAXIMUM_USE_IN_PARALLEL = 1 @@ -237,7 +235,7 @@ describe("HTTP API", function() { describe("/ws", function() { it('/block should exist', function(done) { - const client = new ws('ws://127.0.0.1:7777/ws/block'); + const client = new WebSocket('ws://127.0.0.1:7777/ws/block'); client.on('open', function open() { client.terminate(); done(); @@ -246,7 +244,7 @@ describe("HTTP API", function() { it('/block should send a block', function(done) { let completed = false - const client = new ws('ws://127.0.0.1:7777/ws/block'); + const client = new WebSocket('ws://127.0.0.1:7777/ws/block'); client.once('message', function message(data:any) { const block = JSON.parse(data); should(block).have.property('number', 4); @@ -262,7 +260,7 @@ describe("HTTP API", function() { it('/block (number 5,6,7) should send a block', async () => { server2.writeBlock(await commit({ time: now + 120 * 5 })) - const client = new ws('ws://127.0.0.1:7777/ws/block'); + const client = new WebSocket('ws://127.0.0.1:7777/ws/block'); let resolve5:any, resolve6:any, resolve7:any const p5 = new Promise(res => resolve5 = res) const p6 = new Promise(res => resolve6 = res) @@ -293,7 +291,7 @@ describe("HTTP API", function() { }) it('/block should answer to pings', function(done) { - const client = new ws('ws://127.0.0.1:7777/ws/block'); + const client = new WebSocket('ws://127.0.0.1:7777/ws/block'); client.on('pong', function message() { client.terminate(); done(); @@ -304,7 +302,7 @@ describe("HTTP API", function() { }); it('/peer (number 5,6,7) should send a peer document', async () => { - const client = new ws('ws://127.0.0.1:30410/ws/peer'); + const client = new WebSocket('ws://127.0.0.1:30410/ws/peer'); let resolve5:any, resolve6:any const p5 = new Promise(res => resolve5 = res) const p6 = new Promise(res => resolve6 = res) diff --git a/test/integration/tools/toolbox.ts b/test/integration/tools/toolbox.ts index dca1313dc5179d6c091ac253f852b23723a7216e..677c3b2a86ee976c3ca8406f5613c3d73be95f74 100644 --- a/test/integration/tools/toolbox.ts +++ b/test/integration/tools/toolbox.ts @@ -49,11 +49,11 @@ import {DataErrors} from "../../../app/lib/common-libs/errors" import {until} from "./test-until" import {sync} from "./test-sync" import {expectAnswer, expectError, expectJSON} from "./http-expect" +import {WebSocketServer} from "../../../app/lib/common-libs/websocket" const assert = require('assert'); const rp = require('request-promise'); const es = require('event-stream'); -const WebSocketServer = require('ws').Server const logger = NewLogger(); require('../../../app/modules/bma').BmaDependency.duniter.methods.noLimit(); // Disables the HTTP limiter @@ -672,10 +672,10 @@ export async function newWS2PBidirectionnalConnection(currency:string, k1:Key, k switch (i) { case 1: s1 = WS2PConnection.newConnectionFromWebSocketServer(ws, serverHandler, new WS2PPubkeyLocalAuth(currency, k1, ""), new WS2PPubkeyRemoteAuth(currency, k1), { - connectionTimeout: 100, - requestTimeout: 100 + connectionTimeout: 1000, + requestTimeout: 1000 }); - s1.connect().catch((e:any) => console.error('WS2P: newConnectionFromWebSocketServer connection error')) + s1.connect().catch((e:any) => console.error('WS2P: newConnectionFromWebSocketServer connection error:', e)) break; } resolveBefore({ diff --git a/test/integration/ws2p/ws2p_connection.ts b/test/integration/ws2p/ws2p_connection.ts index 268e1b8e33b87bb71bac969b064f8d3ba7334439..84defd19e0329e87f6105976ea04209f323d3862 100644 --- a/test/integration/ws2p/ws2p_connection.ts +++ b/test/integration/ws2p/ws2p_connection.ts @@ -25,9 +25,9 @@ import {WS2PResponse} from "../../../app/modules/ws2p/lib/impl/WS2PResponse" import {WS2PConstants} from "../../../app/modules/ws2p/lib/constants" import {assertThrows} from "../../unit-tools" import {NewLogger} from "../../../app/lib/logger" +import {WebSocketServer} from "../../../app/lib/common-libs/websocket" const assert = require('assert'); -const WebSocketServer = require('ws').Server const logger = NewLogger() const gtest = "gtest" diff --git a/yarn.lock b/yarn.lock index 628bef37875fff6082008672239f24474ff0f91f..f2fb840018295aeeb0105b0b57a85800d0ebe0e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -67,6 +67,13 @@ version "8.3.0" resolved "https://registry.yarnpkg.com/@types/should/-/should-8.3.0.tgz#e2b460243685dbe377182f39ef38d37f4d157ada" +"@types/ws@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-5.1.2.tgz#f02d3b1cd46db7686734f3ce83bdf46c49decd64" + dependencies: + "@types/events" "*" + "@types/node" "*" + JSONSelect@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/JSONSelect/-/JSONSelect-0.4.0.tgz#a08edcc67eb3fcbe99ed630855344a0cf282bb8d"