nim-websock/tests/testutf8.nim
Dmitriy Ryajov 64da1a4344
Rework http (#38)
* wip

* wip

* move http under ws folder

* use asyctest

* wip

* wip

* rework response sending

* make example work with latest changes

* wip request/response

* misc

* fix example to use new http layer

* pass tls flags to client

* more cleanup

* unused imports

* more unsused imports

* better headers

* add helpre sendError

* export sendError

* attach selected proto to session

* move proto to session

* handle unsupported version

* fix tests

* comment out for now

* fix utf8 tests

* allow tests to be ran in tls

* misc

* use Port type

* add tls flags

* better api

* run tls tests

* fix tests on windows

* allow running tests with tls

* mic

* wip

* fix autobahn ci

* handle close

* cleanup

* logging and error handling

* remove old stream
2021-05-31 20:39:14 -06:00

221 lines
5.7 KiB
Nim

## nim-ws
## Copyright (c) 2021 Status Research & Development GmbH
## Licensed under either of
## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
## * MIT license ([LICENSE-MIT](LICENSE-MIT))
## at your option.
## This file may not be copied, modified, or distributed except according to
## those terms.
import
std/[strutils],
pkg/[
stew/byteutils,
asynctest,
chronos,
chronicles
],
../ws/[ws, utf8_dfa]
suite "UTF-8 DFA validator":
test "single octet":
check:
validateUTF8("\x01")
validateUTF8("\x32")
validateUTF8("\x7f")
validateUTF8("\x80") == false
test "two octets":
check:
validateUTF8("\xc2\x80")
validateUTF8("\xc4\x80")
validateUTF8("\xdf\xbf")
validateUTF8("\xdfu\xc0") == false
validateUTF8("\xdf") == false
test "three octets":
check:
validateUTF8("\xe0\xa0\x80")
validateUTF8("\xe1\x80\x80")
validateUTF8("\xef\xbf\xbf")
validateUTF8("\xef\xbf\xc0") == false
validateUTF8("\xef\xbf") == false
test "four octets":
check:
validateUTF8("\xf0\x90\x80\x80")
validateUTF8("\xf0\x92\x80\x80")
validateUTF8("\xf0\x9f\xbf\xbf")
validateUTF8("\xf0\x9f\xbf\xc0") == false
validateUTF8("\xf0\x9f\xbf") == false
test "overlong sequence":
check:
validateUTF8("\xc0\xaf") == false
validateUTF8("\xe0\x80\xaf") == false
validateUTF8("\xf0\x80\x80\xaf") == false
validateUTF8("\xf8\x80\x80\x80\xaf") == false
validateUTF8("\xfc\x80\x80\x80\x80\xaf") == false
test "max overlong sequence":
check:
validateUTF8("\xc1\xbf") == false
validateUTF8("\xe0\x9f\xbf") == false
validateUTF8("\xf0\x8f\xbf\xbf") == false
validateUTF8("\xf8\x87\xbf\xbf\xbf") == false
validateUTF8("\xfc\x83\xbf\xbf\xbf\xbf") == false
test "distinct codepoint":
check:
validateUTF8("foobar")
validateUTF8("foob\xc3\xa6r")
validateUTF8("foob\xf0\x9f\x99\x88r")
proc waitForClose(ws: WSSession) {.async.} =
try:
while ws.readystate != ReadyState.Closed:
discard await ws.recv()
except CatchableError:
debug "Closing websocket"
# TODO: use new test framework from dryajov
# if it is ready.
var server: HttpServer
let address = initTAddress("127.0.0.1:8888")
suite "UTF-8 validator in action":
teardown:
server.stop()
await server.closeWait()
test "valid UTF-8 sequence":
let testData = "hello world"
proc handle(request: HttpRequest) {.async.} =
check request.uri.path == "/ws"
let server = WSServer.new(protos = ["proto"])
let ws = await server.handleRequest(request)
let res = await ws.recv()
check:
string.fromBytes(res) == testData
ws.binary == false
await waitForClose(ws)
server = HttpServer.create(
address,
handle,
flags = {ReuseAddr})
server.start()
let session = await WebSocket.connect(
"127.0.0.1",
Port(8888),
path = "/ws",
protocols = @["proto"],
)
await session.send(testData)
await session.close()
test "valid UTF-8 sequence in close reason":
let testData = "hello world"
let closeReason = "i want to close"
proc handle(request: HttpRequest) {.async.} =
check request.uri.path == "/ws"
proc onClose(status: Status, reason: string):
CloseResult {.gcsafe, raises: [Defect].} =
try:
check status == Status.Fulfilled
check reason == closeReason
return (status, reason)
except Exception as exc:
raise newException(Defect, exc.msg)
let server = WSServer.new(protos = ["proto"], onClose = onClose)
let ws = await server.handleRequest(request)
let res = await ws.recv()
check:
string.fromBytes(res) == testData
ws.binary == false
await waitForClose(ws)
server = HttpServer.create(
address,
handle,
flags = {ReuseAddr})
server.start()
let session = await WebSocket.connect(
"127.0.0.1",
Port(8888),
path = "/ws",
protocols = @["proto"],
)
await session.send(testData)
await session.close(reason = closeReason)
test "invalid UTF-8 sequence":
# TODO: how to check for Invalid UTF8 exception?
let testData = "hello world\xc0\xaf"
proc handle(request: HttpRequest) {.async.} =
check request.uri.path == "/ws"
let server = WSServer.new(protos = ["proto"])
let ws = await server.handleRequest(request)
discard await ws.recv()
server = HttpServer.create(
address,
handle,
flags = {ReuseAddr})
server.start()
let session = await WebSocket.connect(
"127.0.0.1",
Port(8888),
path = "/ws",
protocols = @["proto"]
)
await session.send(testData)
await waitForClose( session)
check session.readyState == ReadyState.Closed
test "invalid UTF-8 sequence close code":
# TODO: how to check for Invalid UTF8 exception?
let testData = "hello world"
let closeReason = "i want to close\xc0\xaf"
proc handle(request: HttpRequest) {.async.} =
check request.uri.path == "/ws"
let server = WSServer.new(protos = ["proto"])
let ws = await server.handleRequest(request)
let res = await ws.recv()
check:
string.fromBytes(res) == testData
ws.binary == false
server = HttpServer.create(
address,
handle,
flags = {ReuseAddr})
server.start()
let session = await WebSocket.connect(
"127.0.0.1",
Port(8888),
path = "/ws",
protocols = @["proto"]
)
await session.send(testData)
await session.close(reason = closeReason)
await waitForClose( session)
check session.readyState == ReadyState.Closed