New stricter beacon-node URL parsing
This commit is contained in:
parent
8b7ec932cb
commit
a36cacda44
|
@ -570,6 +570,11 @@ OK: 24/24 Fail: 0/24 Skip: 0/24
|
||||||
+ BeaconBlockType OK
|
+ BeaconBlockType OK
|
||||||
```
|
```
|
||||||
OK: 1/1 Fail: 0/1 Skip: 0/1
|
OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||||
|
## Validator Client test suite
|
||||||
|
```diff
|
||||||
|
+ normalizeUri() test vectors OK
|
||||||
|
```
|
||||||
|
OK: 1/1 Fail: 0/1 Skip: 0/1
|
||||||
## Validator change pool testing suite
|
## Validator change pool testing suite
|
||||||
```diff
|
```diff
|
||||||
+ addValidatorChangeMessage/getAttesterSlashingMessage OK
|
+ addValidatorChangeMessage/getAttesterSlashingMessage OK
|
||||||
|
@ -680,4 +685,4 @@ OK: 2/2 Fail: 0/2 Skip: 0/2
|
||||||
OK: 9/9 Fail: 0/9 Skip: 0/9
|
OK: 9/9 Fail: 0/9 Skip: 0/9
|
||||||
|
|
||||||
---TOTAL---
|
---TOTAL---
|
||||||
OK: 389/394 Fail: 0/394 Skip: 5/394
|
OK: 390/395 Fail: 0/395 Skip: 5/395
|
||||||
|
|
|
@ -501,44 +501,44 @@ proc parseRoles*(data: string): Result[set[BeaconNodeRole], cstring] =
|
||||||
return err("Invalid beacon node role string found")
|
return err("Invalid beacon node role string found")
|
||||||
ok(res)
|
ok(res)
|
||||||
|
|
||||||
proc normalizeUri*(remoteUri: Uri): Uri =
|
proc normalizeUri*(r: Uri): Result[Uri, cstring] =
|
||||||
var r = remoteUri
|
const
|
||||||
if (len(r.scheme) == 0) and (len(r.username) == 0) and
|
MissingPortNumber = cstring("Missing port number")
|
||||||
(len(r.password) == 0) and (len(r.hostname) == 0) and
|
MissingHostname = cstring("Missing hostname")
|
||||||
(len(r.port) == 0) and (len(r.path) > 0):
|
UnknownScheme = cstring("Unknown scheme value")
|
||||||
# When `scheme` is not specified and `port` is not specified - whole
|
|
||||||
# hostname is stored in `path`.`query` and `anchor` could still be present.
|
if ($r).toLowerAscii().startsWith("http://") or
|
||||||
# test.com
|
($r).toLowerAscii().startsWith("https://"):
|
||||||
# test.com?q=query
|
# When a scheme is provided, only a hostname is required
|
||||||
# test.com?q=query#anchor=anchor
|
if len(r.hostname) == 0: return err(MissingHostname)
|
||||||
parseUri("http://" & $remoteUri & ":" & $defaultEth2RestPort)
|
return ok(r)
|
||||||
elif (len(r.scheme) > 0) and (len(r.username) == 0) and
|
|
||||||
(len(r.password) == 0) and (len(r.hostname) == 0) and
|
# Check for unknown scheme
|
||||||
(len(r.port) == 0) and (len(r.path) > 0):
|
if ($r).contains("://"):
|
||||||
# When `scheme` is not specified but `port` is specified - whole
|
return err(UnknownScheme)
|
||||||
# hostname is stored in `scheme` and `port` is in `path`.
|
|
||||||
# 192.168.0.1:5052
|
# Add the default scheme (http)
|
||||||
# test.com:5052
|
let normalized =
|
||||||
# test.com:5052?q=query
|
if ($r).startsWith("//"):
|
||||||
# test.com:5052?q=query#anchor=anchor
|
parseUri("http:" & $r)
|
||||||
parseUri("http://" & $remoteUri)
|
else:
|
||||||
elif (len(r.scheme) > 0) and (len(r.hostname) > 0):
|
parseUri("http://" & $r)
|
||||||
# When `scheme` is specified, but `port` is not we use default.
|
|
||||||
# http://192.168.0.1
|
if len(normalized.hostname) == 0:
|
||||||
# http://test.com
|
return err(MissingHostname)
|
||||||
# http://test.com?q=query
|
|
||||||
# http://test.com?q=query#anchor=anchor
|
if len(normalized.port) == 0:
|
||||||
if len(r.port) == 0: r.port = $defaultEth2RestPort
|
return err(MissingPortNumber)
|
||||||
r
|
|
||||||
else:
|
ok(normalized)
|
||||||
remoteUri
|
|
||||||
|
|
||||||
proc init*(t: typedesc[BeaconNodeServerRef], remote: Uri,
|
proc init*(t: typedesc[BeaconNodeServerRef], remote: Uri,
|
||||||
index: int): Result[BeaconNodeServerRef, string] =
|
index: int): Result[BeaconNodeServerRef, string] =
|
||||||
doAssert(index >= 0)
|
doAssert(index >= 0)
|
||||||
let
|
let
|
||||||
flags = {RestClientFlag.CommaSeparatedArray}
|
flags = {RestClientFlag.CommaSeparatedArray}
|
||||||
remoteUri = normalizeUri(remote)
|
remoteUri = normalizeUri(remote).valueOr:
|
||||||
|
return err("Invalid URL: " & $error)
|
||||||
client =
|
client =
|
||||||
block:
|
block:
|
||||||
let res = RestClientRef.new($remoteUri, flags = flags)
|
let res = RestClientRef.new($remoteUri, flags = flags)
|
||||||
|
|
|
@ -49,7 +49,8 @@ import # Unit test
|
||||||
./test_signing_node,
|
./test_signing_node,
|
||||||
./consensus_spec/all_tests as consensus_all_tests,
|
./consensus_spec/all_tests as consensus_all_tests,
|
||||||
./slashing_protection/test_fixtures,
|
./slashing_protection/test_fixtures,
|
||||||
./slashing_protection/test_slashing_protection_db
|
./slashing_protection/test_slashing_protection_db,
|
||||||
|
./test_validator_client
|
||||||
|
|
||||||
when not defined(i386):
|
when not defined(i386):
|
||||||
# Avoids "Out of memory" CI failures
|
# Avoids "Out of memory" CI failures
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
# beacon_chain
|
||||||
|
# Copyright (c) 2018-2023 Status Research & Development GmbH
|
||||||
|
# Licensed and distributed under either of
|
||||||
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
||||||
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||||
|
|
||||||
|
{.push raises: [].}
|
||||||
|
{.used.}
|
||||||
|
|
||||||
|
import std/strutils
|
||||||
|
import unittest2
|
||||||
|
import ../beacon_chain/validator_client/common
|
||||||
|
|
||||||
|
const
|
||||||
|
HostNames = [
|
||||||
|
"[2001:db8::1]",
|
||||||
|
"127.0.0.1",
|
||||||
|
"hostname.com",
|
||||||
|
"localhost",
|
||||||
|
"username:password@[2001:db8::1]",
|
||||||
|
"username:password@127.0.0.1",
|
||||||
|
"username:password@hostname.com",
|
||||||
|
"username:password@localhost",
|
||||||
|
]
|
||||||
|
|
||||||
|
GoodTestVectors = [
|
||||||
|
("http://$1",
|
||||||
|
"ok(http://$1)"),
|
||||||
|
("http://$1?q=query",
|
||||||
|
"ok(http://$1?q=query)"),
|
||||||
|
("http://$1?q=query#anchor",
|
||||||
|
"ok(http://$1?q=query#anchor)"),
|
||||||
|
("http://$1/subpath/",
|
||||||
|
"ok(http://$1/subpath/)"),
|
||||||
|
("http://$1/subpath/q=query",
|
||||||
|
"ok(http://$1/subpath/q=query)"),
|
||||||
|
("http://$1/subpath/q=query#anchor",
|
||||||
|
"ok(http://$1/subpath/q=query#anchor)"),
|
||||||
|
("http://$1/subpath",
|
||||||
|
"ok(http://$1/subpath)"),
|
||||||
|
("http://$1/subpath?q=query",
|
||||||
|
"ok(http://$1/subpath?q=query)"),
|
||||||
|
("http://$1/subpath?q=query#anchor",
|
||||||
|
"ok(http://$1/subpath?q=query#anchor)"),
|
||||||
|
|
||||||
|
("https://$1",
|
||||||
|
"ok(https://$1)"),
|
||||||
|
("https://$1?q=query",
|
||||||
|
"ok(https://$1?q=query)"),
|
||||||
|
("https://$1?q=query#anchor",
|
||||||
|
"ok(https://$1?q=query#anchor)"),
|
||||||
|
("https://$1/subpath/",
|
||||||
|
"ok(https://$1/subpath/)"),
|
||||||
|
("https://$1/subpath/q=query",
|
||||||
|
"ok(https://$1/subpath/q=query)"),
|
||||||
|
("https://$1/subpath/q=query#anchor",
|
||||||
|
"ok(https://$1/subpath/q=query#anchor)"),
|
||||||
|
("https://$1/subpath",
|
||||||
|
"ok(https://$1/subpath)"),
|
||||||
|
("https://$1/subpath?q=query",
|
||||||
|
"ok(https://$1/subpath?q=query)"),
|
||||||
|
("https://$1/subpath?q=query#anchor",
|
||||||
|
"ok(https://$1/subpath?q=query#anchor)"),
|
||||||
|
|
||||||
|
("$1:5052",
|
||||||
|
"ok(http://$1:5052)"),
|
||||||
|
("$1:5052?q=query",
|
||||||
|
"ok(http://$1:5052?q=query)"),
|
||||||
|
("$1:5052?q=query#anchor",
|
||||||
|
"ok(http://$1:5052?q=query#anchor)"),
|
||||||
|
("$1:5052/subpath/",
|
||||||
|
"ok(http://$1:5052/subpath/)"),
|
||||||
|
("$1:5052/subpath/q=query",
|
||||||
|
"ok(http://$1:5052/subpath/q=query)"),
|
||||||
|
("$1:5052/subpath/q=query#anchor",
|
||||||
|
"ok(http://$1:5052/subpath/q=query#anchor)"),
|
||||||
|
("$1:5052/subpath",
|
||||||
|
"ok(http://$1:5052/subpath)"),
|
||||||
|
("$1:5052/subpath?q=query",
|
||||||
|
"ok(http://$1:5052/subpath?q=query)"),
|
||||||
|
("$1:5052/subpath?q=query#anchor",
|
||||||
|
"ok(http://$1:5052/subpath?q=query#anchor)"),
|
||||||
|
|
||||||
|
("bnode://$1:5052",
|
||||||
|
"err(Unknown scheme value)"),
|
||||||
|
("bnode://$1:5052?q=query",
|
||||||
|
"err(Unknown scheme value)"),
|
||||||
|
("bnode://$1:5052?q=query#anchor",
|
||||||
|
"err(Unknown scheme value)"),
|
||||||
|
("bnode://$1:5052/subpath/",
|
||||||
|
"err(Unknown scheme value)"),
|
||||||
|
("bnode://$1:5052/subpath/q=query",
|
||||||
|
"err(Unknown scheme value)"),
|
||||||
|
("bnode://$1:5052/subpath/q=query#anchor",
|
||||||
|
"err(Unknown scheme value)"),
|
||||||
|
("bnode://$1:5052/subpath",
|
||||||
|
"err(Unknown scheme value)"),
|
||||||
|
("bnode://$1:5052/subpath?q=query",
|
||||||
|
"err(Unknown scheme value)"),
|
||||||
|
("bnode://$1:5052/subpath?q=query#anchor",
|
||||||
|
"err(Unknown scheme value)"),
|
||||||
|
|
||||||
|
("//$1:5052",
|
||||||
|
"ok(http://$1:5052)"),
|
||||||
|
("//$1:5052?q=query",
|
||||||
|
"ok(http://$1:5052?q=query)"),
|
||||||
|
("//$1:5052?q=query#anchor",
|
||||||
|
"ok(http://$1:5052?q=query#anchor)"),
|
||||||
|
("//$1:5052/subpath/",
|
||||||
|
"ok(http://$1:5052/subpath/)"),
|
||||||
|
("//$1:5052/subpath/q=query",
|
||||||
|
"ok(http://$1:5052/subpath/q=query)"),
|
||||||
|
("//$1:5052/subpath/q=query#anchor",
|
||||||
|
"ok(http://$1:5052/subpath/q=query#anchor)"),
|
||||||
|
("//$1:5052/subpath",
|
||||||
|
"ok(http://$1:5052/subpath)"),
|
||||||
|
("//$1:5052/subpath?q=query",
|
||||||
|
"ok(http://$1:5052/subpath?q=query)"),
|
||||||
|
("//$1:5052/subpath?q=query#anchor",
|
||||||
|
"ok(http://$1:5052/subpath?q=query#anchor)"),
|
||||||
|
|
||||||
|
("//$1", "err(Missing port number)"),
|
||||||
|
("//$1?q=query", "err(Missing port number)"),
|
||||||
|
("//$1?q=query#anchor", "err(Missing port number)"),
|
||||||
|
("//$1/subpath/", "err(Missing port number)"),
|
||||||
|
("//$1/subpath/q=query", "err(Missing port number)"),
|
||||||
|
("//$1/subpath/q=query#anchor", "err(Missing port number)"),
|
||||||
|
("//$1/subpath", "err(Missing port number)"),
|
||||||
|
("//$1/subpath?q=query", "err(Missing port number)"),
|
||||||
|
("//$1/subpath?q=query#anchor", "err(Missing port number)"),
|
||||||
|
|
||||||
|
("$1", "err(Missing port number)"),
|
||||||
|
("$1?q=query", "err(Missing port number)"),
|
||||||
|
("$1?q=query#anchor", "err(Missing port number)"),
|
||||||
|
("$1/subpath/", "err(Missing port number)"),
|
||||||
|
("$1/subpath/q=query", "err(Missing port number)"),
|
||||||
|
("$1/subpath/q=query#anchor", "err(Missing port number)"),
|
||||||
|
("$1/subpath", "err(Missing port number)"),
|
||||||
|
("$1/subpath?q=query", "err(Missing port number)"),
|
||||||
|
("$1/subpath?q=query#anchor", "err(Missing port number)"),
|
||||||
|
|
||||||
|
("", "err(Missing hostname)")
|
||||||
|
]
|
||||||
|
|
||||||
|
suite "Validator Client test suite":
|
||||||
|
test "normalizeUri() test vectors":
|
||||||
|
for hostname in HostNames:
|
||||||
|
for vector in GoodTestVectors:
|
||||||
|
let expect = vector[1] % (hostname)
|
||||||
|
check $normalizeUri(parseUri(vector[0] % (hostname))) == expect
|
Loading…
Reference in New Issue