mirror of
https://github.com/logos-storage/nim-websock.git
synced 2026-01-05 23:23:10 +00:00
wip: modeling extensions api (#48)
This commit is contained in:
parent
1fed598d8c
commit
e632202037
@ -55,7 +55,7 @@ template remainder*(frame: Frame): uint64 =
|
|||||||
proc encode*(
|
proc encode*(
|
||||||
frame: Frame,
|
frame: Frame,
|
||||||
offset = 0,
|
offset = 0,
|
||||||
extensions: seq[Extension] = @[]): Future[seq[byte]] {.async.} =
|
extensions: seq[Ext] = @[]): Future[seq[byte]] {.async.} =
|
||||||
## Encodes a frame into a string buffer.
|
## Encodes a frame into a string buffer.
|
||||||
## See https://tools.ietf.org/html/rfc6455#section-5.2
|
## See https://tools.ietf.org/html/rfc6455#section-5.2
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ proc decode*(
|
|||||||
_: typedesc[Frame],
|
_: typedesc[Frame],
|
||||||
reader: AsyncStreamReader,
|
reader: AsyncStreamReader,
|
||||||
masked: bool,
|
masked: bool,
|
||||||
extensions: seq[Extension] = @[]): Future[Frame] {.async.} =
|
extensions: seq[Ext] = @[]): Future[Frame] {.async.} =
|
||||||
## Read and Decode incoming header
|
## Read and Decode incoming header
|
||||||
##
|
##
|
||||||
|
|
||||||
|
|||||||
@ -61,7 +61,7 @@ proc send*(
|
|||||||
mask: ws.masked,
|
mask: ws.masked,
|
||||||
data: data, # allow sending data with close messages
|
data: data, # allow sending data with close messages
|
||||||
maskKey: maskKey)
|
maskKey: maskKey)
|
||||||
.encode()))
|
.encode(extensions = ws.extensions)))
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -212,7 +212,8 @@ proc readFrame*(ws: WSSession): Future[Frame] {.async.} =
|
|||||||
##
|
##
|
||||||
|
|
||||||
while ws.readyState != ReadyState.Closed:
|
while ws.readyState != ReadyState.Closed:
|
||||||
let frame = await Frame.decode(ws.stream.reader, ws.masked)
|
let frame = await Frame.decode(
|
||||||
|
ws.stream.reader, ws.masked, ws.extensions)
|
||||||
debug "Decoded new frame", opcode = frame.opcode, len = frame.length, mask = frame.mask
|
debug "Decoded new frame", opcode = frame.opcode, len = frame.length, mask = frame.mask
|
||||||
|
|
||||||
# return the current frame if it's not one of the control frames
|
# return the current frame if it's not one of the control frames
|
||||||
|
|||||||
18
ws/types.nim
18
ws/types.nim
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
{.push raises: [Defect].}
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
|
import std/tables
|
||||||
import pkg/[chronos, chronos/streams/tlsstream]
|
import pkg/[chronos, chronos/streams/tlsstream]
|
||||||
import ./utils
|
import ./utils
|
||||||
|
|
||||||
@ -89,11 +90,15 @@ type
|
|||||||
CloseCb* = proc(code: Status, reason: string):
|
CloseCb* = proc(code: Status, reason: string):
|
||||||
CloseResult {.gcsafe, raises: [Defect].}
|
CloseResult {.gcsafe, raises: [Defect].}
|
||||||
|
|
||||||
Extension* = ref object of RootObj
|
Ext* = ref object of RootObj
|
||||||
name*: string
|
name*: string
|
||||||
|
options*: Table[string, string]
|
||||||
|
|
||||||
|
ExtFactory* = proc(name: string, options: Table[string, string]):
|
||||||
|
Ext {.raises: [Defect].}
|
||||||
|
|
||||||
WebSocket* = ref object of RootObj
|
WebSocket* = ref object of RootObj
|
||||||
extensions: seq[Extension] # extension active for this session
|
extensions*: seq[Ext]
|
||||||
version*: uint
|
version*: uint
|
||||||
key*: string
|
key*: string
|
||||||
readyState*: ReadyState
|
readyState*: ReadyState
|
||||||
@ -127,11 +132,14 @@ type
|
|||||||
WSInvalidOpcodeError* = object of WebSocketError
|
WSInvalidOpcodeError* = object of WebSocketError
|
||||||
WSInvalidUTF8* = object of WebSocketError
|
WSInvalidUTF8* = object of WebSocketError
|
||||||
|
|
||||||
proc `name=`*(self: Extension, name: string) =
|
proc `name=`*(self: Ext, name: string) =
|
||||||
raiseAssert "Can't change extensions name!"
|
raiseAssert "Can't change extensions name!"
|
||||||
|
|
||||||
method decode*(self: Extension, frame: Frame): Future[Frame] {.base, async.} =
|
method decode*(self: Ext, frame: Frame): Future[Frame] {.base, async.} =
|
||||||
raiseAssert "Not implemented!"
|
raiseAssert "Not implemented!"
|
||||||
|
|
||||||
method encode*(self: Extension, frame: Frame): Future[Frame] {.base, async.} =
|
method encode*(self: Ext, frame: Frame): Future[Frame] {.base, async.} =
|
||||||
|
raiseAssert "Not implemented!"
|
||||||
|
|
||||||
|
method toHttpOptions*(self: Ext): string =
|
||||||
raiseAssert "Not implemented!"
|
raiseAssert "Not implemented!"
|
||||||
|
|||||||
10
ws/ws.nim
10
ws/ws.nim
@ -35,6 +35,7 @@ export utils, session, frame, types, http
|
|||||||
type
|
type
|
||||||
WSServer* = ref object of WebSocket
|
WSServer* = ref object of WebSocket
|
||||||
protocols: seq[string]
|
protocols: seq[string]
|
||||||
|
factories: seq[ExtFactory]
|
||||||
|
|
||||||
func toException(e: string): ref WebSocketError =
|
func toException(e: string): ref WebSocketError =
|
||||||
(ref WebSocketError)(msg: e)
|
(ref WebSocketError)(msg: e)
|
||||||
@ -46,6 +47,7 @@ proc connect*(
|
|||||||
_: type WebSocket,
|
_: type WebSocket,
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
protocols: seq[string] = @[],
|
protocols: seq[string] = @[],
|
||||||
|
extensions: seq[Ext] = @[],
|
||||||
flags: set[TLSFlags] = {},
|
flags: set[TLSFlags] = {},
|
||||||
version = WSDefaultVersion,
|
version = WSDefaultVersion,
|
||||||
frameSize = WSDefaultFrameSize,
|
frameSize = WSDefaultFrameSize,
|
||||||
@ -105,6 +107,7 @@ proc connect*(
|
|||||||
stream: client.stream,
|
stream: client.stream,
|
||||||
readyState: ReadyState.Open,
|
readyState: ReadyState.Open,
|
||||||
masked: true,
|
masked: true,
|
||||||
|
extensions: @extensions,
|
||||||
rng: rng,
|
rng: rng,
|
||||||
frameSize: frameSize,
|
frameSize: frameSize,
|
||||||
onPing: onPing,
|
onPing: onPing,
|
||||||
@ -116,6 +119,7 @@ proc connect*(
|
|||||||
address: TransportAddress,
|
address: TransportAddress,
|
||||||
path: string,
|
path: string,
|
||||||
protocols: seq[string] = @[],
|
protocols: seq[string] = @[],
|
||||||
|
extensions: seq[Ext] = @[],
|
||||||
secure = false,
|
secure = false,
|
||||||
flags: set[TLSFlags] = {},
|
flags: set[TLSFlags] = {},
|
||||||
version = WSDefaultVersion,
|
version = WSDefaultVersion,
|
||||||
@ -142,6 +146,7 @@ proc connect*(
|
|||||||
return await WebSocket.connect(
|
return await WebSocket.connect(
|
||||||
uri = parseUri(uri),
|
uri = parseUri(uri),
|
||||||
protocols = protocols,
|
protocols = protocols,
|
||||||
|
extensions = extensions,
|
||||||
flags = flags,
|
flags = flags,
|
||||||
version = version,
|
version = version,
|
||||||
frameSize = frameSize,
|
frameSize = frameSize,
|
||||||
@ -155,6 +160,7 @@ proc connect*(
|
|||||||
port: Port,
|
port: Port,
|
||||||
path: string,
|
path: string,
|
||||||
protocols: seq[string] = @[],
|
protocols: seq[string] = @[],
|
||||||
|
extensions: seq[Ext] = @[],
|
||||||
secure = false,
|
secure = false,
|
||||||
flags: set[TLSFlags] = {},
|
flags: set[TLSFlags] = {},
|
||||||
version = WSDefaultVersion,
|
version = WSDefaultVersion,
|
||||||
@ -168,6 +174,7 @@ proc connect*(
|
|||||||
address = initTAddress(host, port),
|
address = initTAddress(host, port),
|
||||||
path = path,
|
path = path,
|
||||||
protocols = protocols,
|
protocols = protocols,
|
||||||
|
extensions = extensions,
|
||||||
flags = flags,
|
flags = flags,
|
||||||
version = version,
|
version = version,
|
||||||
frameSize = frameSize,
|
frameSize = frameSize,
|
||||||
@ -253,11 +260,11 @@ proc handleRequest*(
|
|||||||
proc new*(
|
proc new*(
|
||||||
_: typedesc[WSServer],
|
_: typedesc[WSServer],
|
||||||
protos: openArray[string] = [""],
|
protos: openArray[string] = [""],
|
||||||
|
factories: openArray[ExtFactory] = [],
|
||||||
frameSize = WSDefaultFrameSize,
|
frameSize = WSDefaultFrameSize,
|
||||||
onPing: ControlCb = nil,
|
onPing: ControlCb = nil,
|
||||||
onPong: ControlCb = nil,
|
onPong: ControlCb = nil,
|
||||||
onClose: CloseCb = nil,
|
onClose: CloseCb = nil,
|
||||||
extensions: openArray[Extension] = [],
|
|
||||||
rng: Rng = nil): WSServer =
|
rng: Rng = nil): WSServer =
|
||||||
|
|
||||||
return WSServer(
|
return WSServer(
|
||||||
@ -265,6 +272,7 @@ proc new*(
|
|||||||
masked: false,
|
masked: false,
|
||||||
rng: if isNil(rng): newRng() else: rng,
|
rng: if isNil(rng): newRng() else: rng,
|
||||||
frameSize: frameSize,
|
frameSize: frameSize,
|
||||||
|
factories: @factories,
|
||||||
onPing: onPing,
|
onPing: onPing,
|
||||||
onPong: onPong,
|
onPong: onPong,
|
||||||
onClose: onClose)
|
onClose: onClose)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user