src/wsabi.nim (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
import ws, asyncdispatch, asynchttpserver, strformat, asyncnet, 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 (address, port) = remote.tcpSocket.getPeerAddr() echo fmt"connected to {address}:{port.int}" 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) proc localServer(req: Request) {.async, gcsafe.} = ## Listen on localhost:PORT/ws if req.url.path == "/ws": var newreq = req # TODO: loop through for all remote hosts let bits = parseUri(remoteHost[0]) newreq.headers["host"] = @[fmt"{bits.hostname}:{bits.port}"] newreq.headers["hostname"] = @[bits.hostname] client = await newWebSocket(newreq, protocol = "xmpp") try: while client.readyState == Open: # TODO: don't hardcode these replacements var packet = await client.receiveStrPacket() repacket = packet.replace("127.0.0.1", by=bits.hostname) echo "from local: " & repacket await remote.send(repacket) 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 running at ws://127.0.0.1:{localPort}/ws" asyncCheck server.serve(Port(localPort), localServer) asyncCheck commRemoteClient() runForever() |