Refactoring: extract rpc handler from HTTP and WebSocket server
This commit is contained in:
parent
dad0255c71
commit
9a34452e23
|
@ -34,13 +34,63 @@ type
|
|||
HttpAuthHook* = proc(request: HttpRequestRef): Future[HttpResponseRef]
|
||||
{.gcsafe, raises: [Defect, CatchableError].}
|
||||
|
||||
RpcHttpServer* = ref object of RpcServer
|
||||
# This inheritance arrangement is useful for
|
||||
# e.g. combo HTTP server
|
||||
RpcHttpHandler* = ref object of RpcServer
|
||||
maxChunkSize*: int
|
||||
|
||||
RpcHttpServer* = ref object of RpcHttpHandler
|
||||
httpServers: seq[HttpServerRef]
|
||||
authHooks: seq[HttpAuthHook]
|
||||
maxChunkSize: int
|
||||
|
||||
proc serveHTTP*(rpcServer: RpcHttpHandler, request: HttpRequestRef):
|
||||
Future[HttpResponseRef] {.async: (raises: [CancelledError]).} =
|
||||
let
|
||||
headers = HttpTable.init([("Content-Type",
|
||||
"application/json; charset=utf-8")])
|
||||
chunkSize = rpcServer.maxChunkSize
|
||||
|
||||
try:
|
||||
let
|
||||
body = await request.getBody()
|
||||
data = await rpcServer.route(string.fromBytes(body))
|
||||
|
||||
if data.len <= chunkSize:
|
||||
let res = await request.respond(Http200, data, headers)
|
||||
trace "JSON-RPC result has been sent"
|
||||
return res
|
||||
|
||||
let response = request.getResponse()
|
||||
response.status = Http200
|
||||
response.addHeader("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
await response.prepare()
|
||||
let maxLen = data.len
|
||||
|
||||
var len = data.len
|
||||
while len > chunkSize:
|
||||
await response.sendChunk(data[maxLen - len].unsafeAddr, chunkSize)
|
||||
len -= chunkSize
|
||||
|
||||
if len > 0:
|
||||
await response.sendChunk(data[maxLen - len].unsafeAddr, len)
|
||||
|
||||
await response.finish()
|
||||
except CancelledError as exc:
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
debug "Internal error while processing JSON-RPC call"
|
||||
try:
|
||||
return await request.respond(
|
||||
Http503,
|
||||
"Internal error while processing JSON-RPC call: " & exc.msg)
|
||||
except HttpWriteError as exc:
|
||||
error "Something error", msg=exc.msg
|
||||
return defaultResponse()
|
||||
|
||||
proc processClientRpc(rpcServer: RpcHttpServer): HttpProcessCallback2 =
|
||||
return proc (req: RequestFence): Future[HttpResponseRef] {.async: (raises: [CancelledError]).} =
|
||||
return proc (req: RequestFence): Future[HttpResponseRef]
|
||||
{.async: (raises: [CancelledError]).} =
|
||||
if not req.isOk():
|
||||
return defaultResponse()
|
||||
|
||||
|
@ -62,45 +112,7 @@ proc processClientRpc(rpcServer: RpcHttpServer): HttpProcessCallback2 =
|
|||
error "Something error", msg=exc.msg
|
||||
return defaultResponse()
|
||||
|
||||
let
|
||||
headers = HttpTable.init([("Content-Type",
|
||||
"application/json; charset=utf-8")])
|
||||
chunkSize = rpcServer.maxChunkSize
|
||||
|
||||
try:
|
||||
let
|
||||
body = await request.getBody()
|
||||
data = await rpcServer.route(string.fromBytes(body))
|
||||
|
||||
if data.len <= chunkSize:
|
||||
let res = await request.respond(Http200, data, headers)
|
||||
trace "JSON-RPC result has been sent"
|
||||
return res
|
||||
|
||||
let response = request.getResponse()
|
||||
response.status = Http200
|
||||
response.addHeader("Content-Type", "application/json; charset=utf-8")
|
||||
await response.prepare()
|
||||
let maxLen = data.len
|
||||
var len = data.len
|
||||
while len > chunkSize:
|
||||
await response.sendChunk(data[maxLen - len].unsafeAddr, chunkSize)
|
||||
len -= chunkSize
|
||||
if len > 0:
|
||||
await response.sendChunk(data[maxLen - len].unsafeAddr, len)
|
||||
await response.finish()
|
||||
|
||||
except CancelledError as exc:
|
||||
raise exc
|
||||
except CatchableError as exc:
|
||||
debug "Internal error while processing JSON-RPC call"
|
||||
try:
|
||||
return await request.respond(
|
||||
Http503,
|
||||
"Internal error while processing JSON-RPC call: " & exc.msg)
|
||||
except HttpWriteError as exc:
|
||||
error "Something error", msg=exc.msg
|
||||
return defaultResponse()
|
||||
return await rpcServer.serveHTTP(request)
|
||||
|
||||
proc addHttpServer*(
|
||||
rpcServer: RpcHttpServer,
|
||||
|
|
|
@ -28,33 +28,17 @@ type
|
|||
WsAuthHook* = proc(request: HttpRequest): Future[bool]
|
||||
{.gcsafe, raises: [Defect, CatchableError].}
|
||||
|
||||
RpcWebSocketServer* = ref object of RpcServer
|
||||
# This inheritance arrangement is useful for
|
||||
# e.g. combo HTTP server
|
||||
RpcWebSocketHandler* = ref object of RpcServer
|
||||
wsserver*: WSServer
|
||||
|
||||
RpcWebSocketServer* = ref object of RpcWebSocketHandler
|
||||
server: StreamServer
|
||||
wsserver: WSServer
|
||||
authHooks: seq[WsAuthHook]
|
||||
|
||||
proc handleRequest(rpc: RpcWebSocketServer, request: HttpRequest) {.async: (raises: [CancelledError]).} =
|
||||
trace "Handling request:", uri = request.uri.path
|
||||
trace "Initiating web socket connection."
|
||||
|
||||
# if hook result is false,
|
||||
# it means we should return immediately
|
||||
try:
|
||||
for hook in rpc.authHooks:
|
||||
let res = await hook(request)
|
||||
if not res:
|
||||
return
|
||||
except CatchableError as exc:
|
||||
error "Internal error while processing JSON-RPC hook", msg=exc.msg
|
||||
try:
|
||||
await request.sendResponse(Http503,
|
||||
data = "",
|
||||
content = "Internal error, processing JSON-RPC hook: " & exc.msg)
|
||||
return
|
||||
except CatchableError as exc:
|
||||
error "Something error", msg=exc.msg
|
||||
return
|
||||
|
||||
proc serveHTTP*(rpc: RpcWebSocketHandler, request: HttpRequest)
|
||||
{.async: (raises: [CancelledError]).} =
|
||||
try:
|
||||
let server = rpc.wsserver
|
||||
let ws = await server.handleRequest(request)
|
||||
|
@ -99,6 +83,31 @@ proc handleRequest(rpc: RpcWebSocketServer, request: HttpRequest) {.async: (rais
|
|||
except CatchableError as exc:
|
||||
error "Something error", msg=exc.msg
|
||||
|
||||
proc handleRequest(rpc: RpcWebSocketServer, request: HttpRequest)
|
||||
{.async: (raises: [CancelledError]).} =
|
||||
trace "Handling request:", uri = request.uri.path
|
||||
trace "Initiating web socket connection."
|
||||
|
||||
# if hook result is false,
|
||||
# it means we should return immediately
|
||||
try:
|
||||
for hook in rpc.authHooks:
|
||||
let res = await hook(request)
|
||||
if not res:
|
||||
return
|
||||
except CatchableError as exc:
|
||||
error "Internal error while processing JSON-RPC hook", msg=exc.msg
|
||||
try:
|
||||
await request.sendResponse(Http503,
|
||||
data = "",
|
||||
content = "Internal error, processing JSON-RPC hook: " & exc.msg)
|
||||
return
|
||||
except CatchableError as exc:
|
||||
error "Something error", msg=exc.msg
|
||||
return
|
||||
|
||||
await rpc.serveHTTP(request)
|
||||
|
||||
proc initWebsocket(rpc: RpcWebSocketServer, compression: bool,
|
||||
authHooks: seq[WsAuthHook],
|
||||
rng: ref HmacDrbgContext) =
|
||||
|
|
Loading…
Reference in New Issue