From bb0ee69088dcc02e36b265420f9c1392f6fa6318 Mon Sep 17 00:00:00 2001 From: cgeek <cem.moreau@gmail.com> Date: Sat, 14 Jul 2018 19:19:21 +0200 Subject: [PATCH] [enh] upgrade to ws@1.1.5 + abstract it in the code --- app/lib/common-libs/websocket.ts | 38 ++++++++++++++++++++++++ app/modules/bma/lib/bma.ts | 15 +++++----- app/modules/ws2p/lib/WS2PConnection.ts | 4 +-- app/modules/ws2p/lib/WS2PServer.ts | 3 +- package.json | 1 + test/integration/misc/http-api.ts | 14 ++++----- test/integration/tools/toolbox.ts | 8 ++--- test/integration/ws2p/ws2p_connection.ts | 2 +- yarn.lock | 7 +++++ 9 files changed, 68 insertions(+), 24 deletions(-) create mode 100644 app/lib/common-libs/websocket.ts diff --git a/app/lib/common-libs/websocket.ts b/app/lib/common-libs/websocket.ts new file mode 100644 index 000000000..a9589d2ab --- /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 ee53a3726..575ab3eb0 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 dad3bdbee..0f8cf34a7 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 d0eec6b8f..a9091d43e 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 9a6d2ee54..b722a32a9 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 c79f927dd..349ebabc3 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 dca1313dc..677c3b2a8 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 268e1b8e3..84defd19e 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 628bef378..f2fb84001 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" -- GitLab