remove news support (#155)

`news` has several resource leaks and other security issues - replaced
by `nim-websock` which is actively maintained.
This commit is contained in:
Jacek Sieka 2022-11-08 14:39:29 +01:00 committed by GitHub
parent e6810af618
commit b4aff8fec5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 64 additions and 132 deletions

View File

@ -13,7 +13,6 @@ requires "nim >= 1.2.0",
"chronos", "chronos",
"httputils", "httputils",
"chronicles", "chronicles",
"https://github.com/status-im/news#status",
"websock", "websock",
"json_serialization" "json_serialization"
@ -30,7 +29,4 @@ proc buildBinary(name: string, srcDir = "./", params = "", cmdParams = "") =
task test, "run tests": task test, "run tests":
buildBinary "all", "tests/", buildBinary "all", "tests/",
params = "-d:json_rpc_websocket_package=websock" params = ""
buildBinary "all", "tests/",
params = "-d:json_rpc_websocket_package=news"

View File

@ -1,7 +0,0 @@
const
json_rpc_websocket_package {.strdefine.} = "news"
useNews* = json_rpc_websocket_package == "news"
when json_rpc_websocket_package notin ["websock", "news"]:
{.fatal: "json_rpc_websocket_package should be set to either 'websock' or 'news'".}

View File

@ -1,37 +1,24 @@
import import
pkg/[chronos, chronos/apps/http/httptable, chronicles], pkg/[chronos, chronos/apps/http/httptable, chronicles],
stew/byteutils, stew/byteutils,
../client, ./config ../client
export client export client
# TODO needs fixes in news {.push raises: [Defect].}
# {.push raises: [Defect].}
logScope: logScope:
topics = "JSONRPC-WS-CLIENT" topics = "JSONRPC-WS-CLIENT"
when useNews: import std/[uri, strutils]
const newsUseChronos = true import pkg/websock/[websock, extensions/compression/deflate]
include pkg/news
type type
RpcWebSocketClient* = ref object of RpcClient RpcWebSocketClient* = ref object of RpcClient
transport*: WebSocket transport*: WSSession
uri*: string uri*: Uri
loop*: Future[void] loop*: Future[void]
getHeaders*: GetJsonRpcRequestHeaders getHeaders*: GetJsonRpcRequestHeaders
else:
import std/[uri, strutils]
import pkg/websock/[websock, extensions/compression/deflate]
type
RpcWebSocketClient* = ref object of RpcClient
transport*: WSSession
uri*: Uri
loop*: Future[void]
getHeaders*: GetJsonRpcRequestHeaders
proc new*( proc new*(
T: type RpcWebSocketClient, getHeaders: GetJsonRpcRequestHeaders = nil): T = T: type RpcWebSocketClient, getHeaders: GetJsonRpcRequestHeaders = nil): T =
@ -62,34 +49,20 @@ method call*(self: RpcWebSocketClient, name: string,
proc processData(client: RpcWebSocketClient) {.async.} = proc processData(client: RpcWebSocketClient) {.async.} =
var error: ref CatchableError var error: ref CatchableError
when useNews: let ws = client.transport
try: try:
while true: while ws.readyState != ReadyState.Closed:
var value = await client.transport.receiveString() var value = await ws.recvMsg()
if value == "":
# transmission ends
break
client.processMessage(value) if value.len == 0:
except CatchableError as e: # transmission ends
error = e break
client.transport.close() client.processMessage(string.fromBytes(value))
else: except CatchableError as e:
let ws = client.transport error = e
try:
while ws.readyState != ReadyState.Closed:
var value = await ws.recvMsg()
if value.len == 0: await client.transport.close()
# transmission ends
break
client.processMessage(string.fromBytes(value))
except CatchableError as e:
error = e
await client.transport.close()
client.transport = nil client.transport = nil
@ -118,53 +91,30 @@ proc addExtraHeaders(
# Apply default origin # Apply default origin
discard headers.hasKeyOrPut("Origin", "http://localhost") discard headers.hasKeyOrPut("Origin", "http://localhost")
when useNews: proc connect*(
func toStringTable(headersTable: HttpTable): StringTableRef = client: RpcWebSocketClient,
let res = newStringTable(modeCaseInsensitive) uri: string,
for header in headersTable: extraHeaders: HttpTable = default(HttpTable),
res[header.key] = header.value.join(",") compression = false,
res hooks: seq[Hook] = @[],
flags: set[TLSFlags] = {}) {.async.} =
proc connect*( proc headersHook(ctx: Hook, headers: var HttpTable): Result[void, string] =
client: RpcWebSocketClient,
uri: string,
extraHeaders: HttpTable = default(HttpTable),
compression = false) {.async.} =
if compression:
warn "compression is not supported with the news back-end"
var headers = HttpTable.init()
headers.addExtraHeaders(client, extraHeaders) headers.addExtraHeaders(client, extraHeaders)
client.transport = await newWebSocket(uri, headers.toStringTable()) ok()
client.uri = uri var ext: seq[ExtFactory] = if compression: @[deflateFactory()]
client.loop = processData(client) else: @[]
else: let uri = parseUri(uri)
proc connect*( let ws = await WebSocket.connect(
client: RpcWebSocketClient, uri=uri,
uri: string, factories=ext,
extraHeaders: HttpTable = default(HttpTable), hooks=hooks & Hook(append: headersHook),
compression = false, flags=flags)
hooks: seq[Hook] = @[], client.transport = ws
flags: set[TLSFlags] = {}) {.async.} = client.uri = uri
proc headersHook(ctx: Hook, headers: var HttpTable): Result[void, string] = client.loop = processData(client)
headers.addExtraHeaders(client, extraHeaders)
ok()
var ext: seq[ExtFactory] = if compression: @[deflateFactory()]
else: @[]
let uri = parseUri(uri)
let ws = await WebSocket.connect(
uri=uri,
factories=ext,
hooks=hooks & Hook(append: headersHook),
flags=flags)
client.transport = ws
client.uri = uri
client.loop = processData(client)
method close*(client: RpcWebSocketClient) {.async.} = method close*(client: RpcWebSocketClient) {.async.} =
await client.loop.cancelAndWait() await client.loop.cancelAndWait()
if not client.transport.isNil: if not client.transport.isNil:
when useNews: await client.transport.close()
client.transport.close()
else:
await client.transport.close()
client.transport = nil client.transport = nil

View File

@ -1,12 +1,9 @@
{. warning[UnusedImport]:off .} {. warning[UnusedImport]:off .}
import import
../json_rpc/clients/config testrpcmacro,
testethcalls,
import testhttp,
testrpcmacro, testethcalls, testhttp, testserverclient testserverclient,
testproxy,
when not useNews: testhook
# The proxy implementation is based on websock
import testproxy
import testhook

View File

@ -1,5 +1,4 @@
import import
json,
nimcrypto, stint, nimcrypto, stint,
ethtypes, ethhexstrings, stintjson, ../json_rpc/rpcserver ethtypes, ethhexstrings, stintjson, ../json_rpc/rpcserver

View File

@ -1,5 +1,5 @@
import import
json, ../json_rpc/router ../json_rpc/router
template `==`*(a, b: distinct (string|StringOfJson)): bool = template `==`*(a, b: distinct (string|StringOfJson)): bool =
string(a) == string(b) string(a) == string(b)

View File

@ -1,5 +1,5 @@
import import
unittest, json, tables, unittest, tables,
stint, ethtypes, ethprocs, stintjson, chronicles, stint, ethtypes, ethprocs, stintjson, chronicles,
../json_rpc/[rpcclient, rpcserver], ./helpers ../json_rpc/[rpcclient, rpcserver], ./helpers

View File

@ -1,7 +1,7 @@
import import
unittest, json, chronicles, unittest,
websock/websock, websock/websock,
../json_rpc/[rpcclient, rpcserver, clients/config] ../json_rpc/[rpcclient, rpcserver]
const const
serverHost = "localhost" serverHost = "localhost"

View File

@ -1,4 +1,4 @@
import unittest, json, strutils import unittest, strutils
import httputils import httputils
import ../json_rpc/[rpcserver, rpcclient] import ../json_rpc/[rpcserver, rpcclient]

View File

@ -1,4 +1,4 @@
import unittest, json, strutils import unittest, strutils
import httputils import httputils
import ../json_rpc/[rpcsecureserver, rpcclient] import ../json_rpc/[rpcsecureserver, rpcclient]
import chronos/[streams/tlsstream, apps/http/httpcommon] import chronos/[streams/tlsstream, apps/http/httpcommon]

View File

@ -1,5 +1,5 @@
import import
unittest, json, chronicles, unittest, chronicles,
../json_rpc/[rpcclient, rpcserver, rpcproxy] ../json_rpc/[rpcclient, rpcserver, rpcproxy]
let srvAddress = initTAddress("127.0.0.1", Port(8545)) let srvAddress = initTAddress("127.0.0.1", Port(8545))

View File

@ -1,4 +1,4 @@
import unittest, json, chronicles, options import unittest, chronicles, options
import ../json_rpc/rpcserver, ./helpers import ../json_rpc/rpcserver, ./helpers
type type

View File

@ -1,9 +1,6 @@
import import
unittest, json, chronicles, unittest, chronicles,
../json_rpc/[rpcclient, rpcserver, clients/config] ../json_rpc/[rpcclient, rpcserver]
const
compressionSupported = useNews
# Create RPC on server # Create RPC on server
proc setupServer*(srv: RpcServer) = proc setupServer*(srv: RpcServer) =
@ -78,13 +75,13 @@ suite "Websocket Server/Client RPC":
suite "Websocket Server/Client RPC with Compression": suite "Websocket Server/Client RPC with Compression":
var srv = newRpcWebSocketServer("127.0.0.1", Port(8545), var srv = newRpcWebSocketServer("127.0.0.1", Port(8545),
compression = compressionSupported) compression = true)
var client = newRpcWebSocketClient() var client = newRpcWebSocketClient()
srv.setupServer() srv.setupServer()
srv.start() srv.start()
waitFor client.connect("ws://127.0.0.1:8545/", waitFor client.connect("ws://127.0.0.1:8545/",
compression = compressionSupported) compression = true)
test "Successful RPC call": test "Successful RPC call":
let r = waitFor client.call("myProc", %[%"abc", %[1, 2, 3, 4]]) let r = waitFor client.call("myProc", %[%"abc", %[1, 2, 3, 4]])