all repos — wsabi @ c64953fdfcd1e69b9900fb8da4218ab8fc81bb14

websocket proxy that sends stats to statsd

Initial implementation of /check-health endpoint

POST a JSON like so:

{
    "reqType": "ws",
    "host": "some.host",
    "port": 7070
}

and it'll verify if it's reachable.  Further iterations will check for
protocol (XMPP, websocket, XMPP over websocket), and try initiating a
stream.
Anirudh Oppiliappan x@icyphox.sh
Wed, 22 Jul 2020 22:24:03 +0530
commit

c64953fdfcd1e69b9900fb8da4218ab8fc81bb14

parent

04e6bb49fd7bd6f8575872fb9ec2e6004f03b091

2 files changed, 41 insertions(+), 17 deletions(-)

jump to
M src/wsabi.nimsrc/wsabi.nim

@@ -4,37 +4,33 @@ asyncdispatch,

asynchttpserver, strformat, asyncnet, - utils/args, + wsabipkg/args, strutils, + json, uri + var server = newAsyncHttpServer() remote: WebSocket client: WebSocket + clients: seq[WebSocket] proc connectRemote(host: string) {.async.} = remote = await newWebSocket(host, protocol = "xmpp") let - hostPort = remote.tcpSocket.getPeerAddr() - address = hostPort[0] - port = hostPort[1].int - echo fmt"connected to {address}:{port}" + (address, port) = remote.tcpSocket.getPeerAddr() + echo fmt"connected to {address}:{port.int}" -# Fetch from remote and send to client proc commRemoteClient() {.async.} = + ## Fetch from remote and send to client while remote.readyState == Open: var data = await remote.receiveStrPacket() echo "from remote: ", data await client.send(data) - -# Sends a message to, and returns a response from the remote -# proc sendRemote(ws: WebSocket, data: string): Future[string] {.async.} = -# await ws.send(data) -# result = await ws.receiveStrPacket() - proc localServer(req: Request) {.async, gcsafe.} = + ## Listen on localhost:PORT/ws if req.url.path == "/ws": var newreq = req

@@ -53,20 +49,48 @@ packet = await client.receiveStrPacket()

repacket = packet.replace("127.0.0.1", by=bits.hostname) echo "from local: " & repacket - # TODO: don't hardcode these replacements await remote.send(repacket) - # reres = res.replace(bits.hostname, by="127.0.0.1") - # echo "got response: ", reres - # await client.send(reres) except WebSocketError: echo "client closed socket: ", getCurrentExceptionMsg() + ## Health check endpoint + if req.url.path == "/check-health": + if req.reqMethod == HttpPost: + type + HealthCheck = object + reqType: string + host: string + port: int + + let + hcJson = parseJson(req.body) + hc = to(hcJson, HealthCheck) + + try: + echo &"trying to reach {hc.host}:{hc.port}" + discard await asyncnet.dial(hc.host, Port(hc.port)) + let r = %*{"status": "OK"} + await req.respond( + Http200, $r, + newHttpHeaders([("Content-Type", "application/json")]) + ) + except OSError: + echo "unable to reach specified host:port pair" + let r = %*{ + "status": "error", + "msg": "unable to reach specified host:port pair" + } + await req.respond( + Http400, $r, + newHttpHeaders([("Content-Type", "application/json")]) + ) + when isMainModule: parseArgs() echo "connecting to remote host..." waitFor connectRemote(remoteHost[0]) - echo fmt"local server listening on ws://127.0.0.1:{localPort}" + echo fmt"local server running at ws://127.0.0.1:{localPort}/ws" asyncCheck server.serve(Port(localPort), localServer) asyncCheck commRemoteClient()