diff --git a/examples/client.nim b/examples/client.nim index 2a9baee157..ea61b9917e 100644 --- a/examples/client.nim +++ b/examples/client.nim @@ -17,7 +17,7 @@ proc main() {.async.} = while true: try: await ws.send(reqData) - let (buff, _) = await ws.recv() + let buff = await ws.recv() if buff.len <= 0: break diff --git a/examples/server.nim b/examples/server.nim index e007d29ce4..523b610624 100644 --- a/examples/server.nim +++ b/examples/server.nim @@ -19,12 +19,14 @@ proc process(r: RequestFence): Future[HttpResponseRef] {.async.} = debug "Websocket handshake completed." while true: - let (recvData, opcode) = await ws.recv() + let recvData = await ws.recv() if ws.readyState == ReadyState.Closed: debug "Websocket closed." break + debug "Client Response: ", size = recvData.len - await ws.send(recvData, Opcode.Text) + await ws.send(recvData, + if ws.binary: Opcode.Binary else: Opcode.Text) except WebSocketError as exc: error "WebSocket error:", exception = exc.msg diff --git a/examples/tlsclient.nim b/examples/tlsclient.nim index 5cb117e8f8..345d8899bd 100644 --- a/examples/tlsclient.nim +++ b/examples/tlsclient.nim @@ -18,7 +18,7 @@ proc main() {.async.} = try: echo "sending client " await ws.send(reqData) - let (buff, _) = await ws.recv() + let buff = await ws.recv() if buff.len <= 0: break let dataStr = string.fromBytes(buff) diff --git a/examples/tlsserver.nim b/examples/tlsserver.nim index e87539a5eb..010bc02bea 100644 --- a/examples/tlsserver.nim +++ b/examples/tlsserver.nim @@ -25,7 +25,7 @@ proc process(r: RequestFence): Future[HttpResponseRef] {.async.} = debug "Websocket handshake completed." # Only reads header for data frame. echo "receiving server " - let (recvData, opcode) = await ws.recv() + let recvData = await ws.recv() if recvData.len <= 0: debug "Empty messages" break @@ -33,7 +33,8 @@ proc process(r: RequestFence): Future[HttpResponseRef] {.async.} = if ws.readyState == ReadyState.Closed: return debug "Response: ", data = string.fromBytes(recvData) - await ws.send(recvData, Opcode.Text) + await ws.send(recvData, + if ws.binary: Opcode.Binary else: Opcode.Text) except WebSocketError: error "WebSocket error:", exception = getCurrentExceptionMsg() discard await request.respond(Http200, "Hello World") diff --git a/tests/testtlswebsockets.nim b/tests/testtlswebsockets.nim index 0a4c9e1c47..102fa33ef0 100644 --- a/tests/testtlswebsockets.nim +++ b/tests/testtlswebsockets.nim @@ -136,7 +136,7 @@ suite "Test websocket TLS transmission": let request = r.get() check request.uri.path == "/wss" let ws = await createServer(request, "proto") - let (servRes, _) = await ws.recv() + let servRes = await ws.recv() check string.fromBytes(servRes) == testString await waitForClose(ws) return dumbResponse() @@ -191,6 +191,6 @@ suite "Test websocket TLS transmission": protocols = @["proto"], clientFlags) - let (clientRes, _) = await wsClient.recv() + let clientRes = await wsClient.recv() check string.fromBytes(clientRes) == testString await waitForClose(wsClient) diff --git a/tests/testwebsockets.nim b/tests/testwebsockets.nim index a3139bedb0..dd4c63cb4d 100644 --- a/tests/testwebsockets.nim +++ b/tests/testwebsockets.nim @@ -145,7 +145,7 @@ suite "Test transmission": let request = r.get() check request.uri.path == "/ws" let ws = await createServer(request, "proto") - let (servRes, _) = await ws.recv() + let servRes = await ws.recv() check string.fromBytes(servRes) == testString let res = HttpServerRef.new( @@ -169,7 +169,7 @@ suite "Test transmission": let request = r.get() check request.uri.path == "/ws" let ws = await createServer(request, "proto") - let (servRes, _) = await ws.recv() + let servRes = await ws.recv() check string.fromBytes(servRes) == testString await waitForClose(ws) @@ -212,7 +212,7 @@ suite "Test transmission": path = "/ws", protocols = @["proto"]) - let (clientRes, _) = await wsClient.recv() + var clientRes = await wsClient.recv() check string.fromBytes(clientRes) == testString await waitForClose(wsClient) @@ -241,11 +241,11 @@ suite "Test ping-pong": let ws = await createServer( request, "proto", - onPing = proc(data: openArray[byte] = []) = + onPing = proc(data: openArray[byte]) = ping = true ) - let (respData, _) = await ws.recv() + let respData = await ws.recv() check string.fromBytes(respData) == testString await waitForClose(ws) @@ -260,7 +260,7 @@ suite "Test ping-pong": path = "/ws", protocols = @["proto"], frameSize = maxFrameSize, - onPong = proc(data: openArray[byte] = []) = + onPong = proc(data: openArray[byte]) = pong = true ) @@ -310,7 +310,7 @@ suite "Test ping-pong": let ws = await createServer( request, "proto", - onPong = proc(data: openArray[byte] = []) = + onPong = proc(data: openArray[byte]) = pong = true ) @@ -326,7 +326,7 @@ suite "Test ping-pong": Port(8888), path = "/ws", protocols = @["proto"], - onPing = proc(data: openArray[byte] = []) = + onPing = proc(data: openArray[byte]) = ping = true ) @@ -346,7 +346,7 @@ suite "Test ping-pong": let ws = await createServer( request, "proto", - onPing = proc(data: openArray[byte] = []) = + onPing = proc(data: openArray[byte]) = ping = true ) await waitForClose(ws) @@ -363,7 +363,7 @@ suite "Test ping-pong": Port(8888), path = "/ws", protocols = @["proto"], - onPong = proc(data: openArray[byte] = []) = + onPong = proc(data: openArray[byte]) = pong = true ) @@ -731,7 +731,8 @@ suite "Test Closing": getTracker("stream.server").isLeaked() == false getTracker("stream.transport").isLeaked() == false -suite "Test text message with payload": + +suite "Test Payload": teardown: await server.closeWait() @@ -762,7 +763,7 @@ suite "Test text message with payload": path = "/ws", protocols = @["proto"]) - await wsClient.ping(toBytes(str)) + await wsClient.ping(str.toBytes()) await wsClient.close() test "Test single empty payload": @@ -773,7 +774,7 @@ suite "Test text message with payload": let request = r.get() check request.uri.path == "/ws" let ws = await createServer(request, "proto") - let (servRes, _) = await ws.recv() + let servRes = await ws.recv() check string.fromBytes(servRes) == emptyStr await waitForClose(ws) @@ -799,7 +800,7 @@ suite "Test text message with payload": let request = r.get() check request.uri.path == "/ws" let ws = await createServer(request, "proto") - let (servRes, _) = await ws.recv() + let servRes = await ws.recv() check string.fromBytes(servRes) == emptyStr await waitForClose(ws) @@ -845,7 +846,7 @@ suite "Test text message with payload": Port(8888), path = "/ws", protocols = @["proto"], - onPong = proc(data: openArray[byte] = []) = + onPong = proc(data: openArray[byte]) = pong = true ) @@ -874,10 +875,12 @@ suite "Test Binary message with Payload": let request = r.get() check request.uri.path == "/ws" let ws = await createServer(request, "proto") - let (servRes, opcode) = await ws.recv() + let servRes = await ws.recv() + check: servRes == emptyData - opcode == Opcode.Binary + ws.binary == true + await waitForClose(ws) let res = HttpServerRef.new( @@ -902,10 +905,12 @@ suite "Test Binary message with Payload": let request = r.get() check request.uri.path == "/ws" let ws = await createServer(request, "proto") - let (servRes, opcode) = await ws.recv() + let servRes = await ws.recv() + check: servRes == emptyData - opcode == Opcode.Binary + ws.binary == true + await waitForClose(ws) let res = HttpServerRef.new( @@ -935,13 +940,15 @@ suite "Test Binary message with Payload": let ws = await createServer( request, "proto", - onPing = proc() = - ping = true + onPing = proc(data: openArray[byte]) = + ping = true ) - let (res, opcode) = await ws.recv() + + let res = await ws.recv() check: res == testData - opcode == Opcode.Binary + ws.binary == true + await waitForClose(ws) let res = HttpServerRef.new( @@ -954,8 +961,8 @@ suite "Test Binary message with Payload": Port(8888), path = "/ws", protocols = @["proto"], - onPong = proc() = - pong = true + onPong = proc(data: openArray[byte]) = + pong = true ) await wsClient.send(testData, Opcode.Binary) @@ -972,13 +979,15 @@ suite "Test Binary message with Payload": let ws = await createServer( request, "proto", - onPing = proc() = - ping = true + onPing = proc(data: openArray[byte]) = + ping = true ) - let (res, opcode) = await ws.recv() + + let res = await ws.recv() check: res == testData - opcode == Opcode.Binary + ws.binary == true + await waitForClose(ws) let res = HttpServerRef.new( @@ -991,8 +1000,8 @@ suite "Test Binary message with Payload": Port(8888), path = "/ws", protocols = @["proto"], - onPong = proc() = - pong = true + onPong = proc(data: openArray[byte]) = + pong = true ) await wsClient.send(testData, Opcode.Binary) diff --git a/ws/ws.nim b/ws/ws.nim index 1ddf4a6897..fc9d232383 100644 --- a/ws/ws.nim +++ b/ws/ws.nim @@ -146,6 +146,7 @@ type protocol*: string readyState*: ReadyState masked*: bool # send masked packets + binary*: bool # is payload binary? rng*: ref BrHmacDrbgContext frameSize: int frame: Frame @@ -576,7 +577,7 @@ proc ping*(ws: WebSocket, data: seq[byte] = @[]): Future[void] = proc recv*( ws: WebSocket, data: pointer, - size: int): Future[(int, Opcode)] {.async.} = + size: int): Future[int] {.async.} = ## Attempts to read up to `size` bytes ## ## Will read as many frames as necessary @@ -587,10 +588,8 @@ proc recv*( ## one byte is available ## - var - consumed = 0 - pbuffer = cast[ptr UncheckedArray[byte]](data) - opcode = Opcode.Text + var consumed = 0 + var pbuffer = cast[ptr UncheckedArray[byte]](data) try: # read the first frame @@ -618,6 +617,7 @@ proc recv*( raise newException(WSOpcodeMismatchError, "expected continue frame") + ws.binary = ws.frame.opcode == Opcode.Binary if ws.frame.fin and ws.frame.remainder().int <= 0: ws.frame = nil break @@ -640,7 +640,7 @@ proc recv*( consumed += read ws.frame.consumed += read.uint64 - return (consumed.int, opcode) + return consumed.int except WebSocketError as exc: debug "Websocket error", exc = exc.msg @@ -655,7 +655,7 @@ proc recv*( proc recv*( ws: WebSocket, - size = WSMaxMessageSize): Future[(seq[byte], Opcode)] {.async.} = + size = WSMaxMessageSize): Future[seq[byte]] {.async.} = ## Attempt to read a full message up to max `size` ## bytes in `frameSize` chunks. ## @@ -667,16 +667,11 @@ proc recv*( ## ## In all other cases it awaits a full message. ## - var - res: seq[byte] - opcode = Opcode.Text + var res: seq[byte] try: while ws.readyState != ReadyState.Closed: - var - buf = newSeq[byte](ws.frameSize) - read: int - - (read, opcode) = await ws.recv(addr buf[0], buf.len) + var buf = newSeq[byte](ws.frameSize) + let read = await ws.recv(addr buf[0], buf.len) if read <= 0: break @@ -702,7 +697,7 @@ proc recv*( except CatchableError as exc: debug "Exception reading frames", exc = exc.msg - return (res, opcode) + return res proc close*( ws: WebSocket,