From 39d85d1a1a5b9ff423b1d790ca5ea9ca14459518 Mon Sep 17 00:00:00 2001 From: Luna Mendes Date: Sun, 17 Jun 2018 17:07:52 -0300 Subject: [PATCH] add basis of websockets --- Pipfile | 1 + Pipfile.lock | 6 +++++- litecord/blueprints/auth.py | 5 ----- litecord/errors.py | 10 ++++++++++ litecord/gateway/__init__.py | 1 + litecord/gateway/gateway.py | 32 ++++++++++++++++++++++++++++++++ run.py | 10 ++++++++++ 7 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 litecord/gateway/__init__.py create mode 100644 litecord/gateway/gateway.py diff --git a/Pipfile b/Pipfile index cb632ed..7c0cdbb 100644 --- a/Pipfile +++ b/Pipfile @@ -7,6 +7,7 @@ name = "pypi" bcrypt = "==3.1.4" itsdangerous = "==0.24" asyncpg = "==0.16.0" +websockets = "==5.0.1" Quart = "==0.6.0" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index 94d965d..57da1a8 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e8807281b43032a3fde4598f48c98436b8ef50fe332a413e71c37062a16b61d9" + "sha256": "e37a82fc53dadfc4b8ebbded3bb043d686fa5c2cde07b11589430586e236386b" }, "host-environment-markers": { "implementation_name": "cpython", @@ -113,6 +113,10 @@ "hashes": [], "version": "==3.6.5" }, + "websockets": { + "hashes": [], + "version": "==5.0.1" + }, "wsproto": { "hashes": [], "version": "==0.11.0" diff --git a/litecord/blueprints/auth.py b/litecord/blueprints/auth.py index 5d2fa78..478d321 100644 --- a/litecord/blueprints/auth.py +++ b/litecord/blueprints/auth.py @@ -29,9 +29,6 @@ async def check_password(pwd_hash, given_password) -> bool: pwd_hash = pwd_hash.encode('utf-8') given_password = given_password.encode('utf-8') - print(repr(pwd_hash)) - print(repr(given_password)) - future = app.loop.run_in_executor( None, bcrypt.checkpw, given_password, pwd_hash) @@ -73,8 +70,6 @@ async def register(): @bp.route('/login', methods=['POST']) async def login(): """Login one user into Litecord.""" - print(request.headers) - j = await request.get_json() email, password = j['email'], j['password'] diff --git a/litecord/errors.py b/litecord/errors.py index 936d6ec..12f99f6 100644 --- a/litecord/errors.py +++ b/litecord/errors.py @@ -8,3 +8,13 @@ class LitecordError(Exception): class AuthError(LitecordError): status_code = 403 + + +class WebsocketClose(Exception): + @property + def code(self): + return self.args[0] + + @property + def reason(self): + return self.args[1] diff --git a/litecord/gateway/__init__.py b/litecord/gateway/__init__.py new file mode 100644 index 0000000..116175c --- /dev/null +++ b/litecord/gateway/__init__.py @@ -0,0 +1 @@ +from .gateway import websocket_handler diff --git a/litecord/gateway/gateway.py b/litecord/gateway/gateway.py new file mode 100644 index 0000000..ef4eff7 --- /dev/null +++ b/litecord/gateway/gateway.py @@ -0,0 +1,32 @@ +import urllib.parse + + +async def websocket_handler(ws, url): + qs = urllib.parse.parse_qs( + urllib.parse.urlparse(url).query + ) + + print(qs) + + try: + gw_version = qs['v'][0] + gw_encoding = qs['encoding'][0] + except (KeyError, IndexError): + return await ws.close(1000, 'Invalid query args') + + if gw_version not in ('6',): + return await ws.close(1000, 'Invalid gateway version') + + if gw_encoding not in ('json', 'etf'): + return await ws.close(1000, 'Invalid gateway encoding') + + try: + gw_compress = qs['compress'][0] + except (KeyError, IndexError): + gw_compress = None + + if gw_compress and gw_compress not in ('zlib-stream',): + return await ws.close(1000, 'Invalid gateway compress') + + await ws.close(code=1000, reason='ass') + return diff --git a/run.py b/run.py index a683948..28f2898 100644 --- a/run.py +++ b/run.py @@ -1,12 +1,14 @@ import logging import asyncio +import websockets import asyncpg from quart import Quart, g, jsonify import config from litecord.blueprints import gateway, auth +from litecord.gateway import websocket_handler from litecord.errors import LitecordError logging.basicConfig(level=logging.INFO) @@ -37,6 +39,14 @@ async def app_before_serving(): app.loop = asyncio.get_event_loop() g.loop = asyncio.get_event_loop() + # start the websocket, etc + host, port = app.config['WS_HOST'], app.config['WS_PORT'] + log.info(f'starting websocket at {host} {port}') + ws_future = websockets.serve( + websocket_handler, host, port) + + await ws_future + @app.after_serving async def app_after_serving():