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
|
||||
```
|
||||
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
|
||||
```diff
|
||||
+ 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
|
||||
|
||||
---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")
|
||||
ok(res)
|
||||
|
||||
proc normalizeUri*(remoteUri: Uri): Uri =
|
||||
var r = remoteUri
|
||||
if (len(r.scheme) == 0) and (len(r.username) == 0) and
|
||||
(len(r.password) == 0) and (len(r.hostname) == 0) and
|
||||
(len(r.port) == 0) and (len(r.path) > 0):
|
||||
# When `scheme` is not specified and `port` is not specified - whole
|
||||
# hostname is stored in `path`.`query` and `anchor` could still be present.
|
||||
# test.com
|
||||
# test.com?q=query
|
||||
# test.com?q=query#anchor=anchor
|
||||
parseUri("http://" & $remoteUri & ":" & $defaultEth2RestPort)
|
||||
elif (len(r.scheme) > 0) and (len(r.username) == 0) and
|
||||
(len(r.password) == 0) and (len(r.hostname) == 0) and
|
||||
(len(r.port) == 0) and (len(r.path) > 0):
|
||||
# When `scheme` is not specified but `port` is specified - whole
|
||||
# hostname is stored in `scheme` and `port` is in `path`.
|
||||
# 192.168.0.1:5052
|
||||
# test.com:5052
|
||||
# test.com:5052?q=query
|
||||
# test.com:5052?q=query#anchor=anchor
|
||||
parseUri("http://" & $remoteUri)
|
||||
elif (len(r.scheme) > 0) and (len(r.hostname) > 0):
|
||||
# When `scheme` is specified, but `port` is not we use default.
|
||||
# http://192.168.0.1
|
||||
# http://test.com
|
||||
# http://test.com?q=query
|
||||
# http://test.com?q=query#anchor=anchor
|
||||
if len(r.port) == 0: r.port = $defaultEth2RestPort
|
||||
r
|
||||
proc normalizeUri*(r: Uri): Result[Uri, cstring] =
|
||||
const
|
||||
MissingPortNumber = cstring("Missing port number")
|
||||
MissingHostname = cstring("Missing hostname")
|
||||
UnknownScheme = cstring("Unknown scheme value")
|
||||
|
||||
if ($r).toLowerAscii().startsWith("http://") or
|
||||
($r).toLowerAscii().startsWith("https://"):
|
||||
# When a scheme is provided, only a hostname is required
|
||||
if len(r.hostname) == 0: return err(MissingHostname)
|
||||
return ok(r)
|
||||
|
||||
# Check for unknown scheme
|
||||
if ($r).contains("://"):
|
||||
return err(UnknownScheme)
|
||||
|
||||
# Add the default scheme (http)
|
||||
let normalized =
|
||||
if ($r).startsWith("//"):
|
||||
parseUri("http:" & $r)
|
||||
else:
|
||||
remoteUri
|
||||
parseUri("http://" & $r)
|
||||
|
||||
if len(normalized.hostname) == 0:
|
||||
return err(MissingHostname)
|
||||
|
||||
if len(normalized.port) == 0:
|
||||
return err(MissingPortNumber)
|
||||
|
||||
ok(normalized)
|
||||
|
||||
proc init*(t: typedesc[BeaconNodeServerRef], remote: Uri,
|
||||
index: int): Result[BeaconNodeServerRef, string] =
|
||||
doAssert(index >= 0)
|
||||
let
|
||||
flags = {RestClientFlag.CommaSeparatedArray}
|
||||
remoteUri = normalizeUri(remote)
|
||||
remoteUri = normalizeUri(remote).valueOr:
|
||||
return err("Invalid URL: " & $error)
|
||||
client =
|
||||
block:
|
||||
let res = RestClientRef.new($remoteUri, flags = flags)
|
||||
|
|
|
@ -49,7 +49,8 @@ import # Unit test
|
|||
./test_signing_node,
|
||||
./consensus_spec/all_tests as consensus_all_tests,
|
||||
./slashing_protection/test_fixtures,
|
||||
./slashing_protection/test_slashing_protection_db
|
||||
./slashing_protection/test_slashing_protection_db,
|
||||
./test_validator_client
|
||||
|
||||
when not defined(i386):
|
||||
# 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