|
10 | 10 | {.push raises: [], gcsafe.} |
11 | 11 |
|
12 | 12 | import |
13 | | - std/sequtils, |
14 | 13 | chronicles, |
15 | 14 | chronos, |
16 | 15 | websock/[websock, types], |
17 | 16 | websock/extensions/compression/deflate, |
18 | 17 | json_serialization/std/net as jsnet, |
19 | 18 | ../[errors, server], |
| 19 | + ../private/jrpc_sys, |
20 | 20 | ../clients/websocketclient |
21 | 21 |
|
22 | 22 | export errors, server, jsnet |
|
46 | 46 |
|
47 | 47 | proc serveHTTP*(rpc: RpcWebSocketHandler, request: HttpRequest) |
48 | 48 | {.async: (raises: [CancelledError]).} = |
49 | | - try: |
| 49 | + let ws = try: |
50 | 50 | let server = rpc.wsserver |
51 | 51 | let ws = await server.handleRequest(request) |
52 | 52 | if ws.readyState != ReadyState.Open: |
53 | | - error "Failed to open websocket connection", |
54 | | - address = $request.uri |
| 53 | + error "Failed to open websocket connection", address = $request.uri |
55 | 54 | return |
56 | | - |
57 | | - trace "Websocket handshake completed" |
58 | | - let c = RpcWebSocketClient(transport: ws, remote: $request.uri) |
59 | | - rpc.connections.add(c) |
60 | | - # Provide backwards compat with consumers that don't set a max message size |
61 | | - # for example by constructing RpcWebSocketHandler without going through init |
62 | | - let maxMessageSize = |
63 | | - if rpc.maxMessageSize == 0: defaultMaxMessageSize else: rpc.maxMessageSize |
64 | | - while ws.readyState != ReadyState.Closed: |
65 | | - |
66 | | - let req = await ws.recvMsg(maxMessageSize) |
67 | | - debug "Received JSON-RPC request", |
68 | | - address = $request.uri, |
69 | | - len = req.len |
70 | | - |
71 | | - if ws.readyState == ReadyState.Closed: |
72 | | - # if session already terminated by peer, |
73 | | - # no need to send response |
74 | | - break |
75 | | - |
76 | | - if req.len == 0: |
77 | | - await ws.close( |
78 | | - reason = "cannot process zero length message" |
79 | | - ) |
80 | | - break |
81 | | - |
82 | | - let data = await rpc.route(req) |
83 | | - |
84 | | - if data.len > 0: |
85 | | - await ws.send(data) |
86 | | - |
87 | | - rpc.connections.keepItIf(it != c) |
88 | | - |
| 55 | + ws |
89 | 56 | except WebSocketError as exc: |
90 | | - error "WebSocket error:", |
91 | | - address = $request.uri, msg = exc.msg |
92 | | - |
| 57 | + error "WebSocket error:", address = $request.uri, msg = exc.msg |
| 58 | + return |
93 | 59 | except CancelledError as exc: |
94 | 60 | raise exc |
95 | | - |
96 | 61 | except CatchableError as exc: |
97 | | - debug "Internal error while processing JSON-RPC call", msg=exc.msg |
98 | | - |
99 | | -proc handleRequest(rpc: RpcWebSocketServer, request: HttpRequest) |
100 | | - {.async: (raises: [CancelledError]).} = |
| 62 | + debug "Internal error while processing JSON-RPC call", msg = exc.msg |
| 63 | + return |
| 64 | + |
| 65 | + trace "Websocket handshake completed" |
| 66 | + let c = RpcWebSocketClient( |
| 67 | + transport: ws, |
| 68 | + remote: $request.uri, |
| 69 | + maxMessageSize: rpc.maxMessageSize, |
| 70 | + router: proc(request: RequestBatchRx): Future[string] {.async: (raises: [], raw: true).} = |
| 71 | + rpc.router.route(request), |
| 72 | + ) |
| 73 | + rpc.connections.incl(c) |
| 74 | + |
| 75 | + await c.processMessages() |
| 76 | + |
| 77 | + rpc.connections.excl(c) |
| 78 | + |
| 79 | +proc handleRequest( |
| 80 | + rpc: RpcWebSocketServer, request: HttpRequest |
| 81 | +) {.async: (raises: [CancelledError]).} = |
101 | 82 | trace "Handling request:", uri = $request.uri |
102 | 83 |
|
103 | 84 | # if hook result is false, |
|
0 commit comments