From 9ff365293ff2d3e994ebbd36c6a943ce438d1601 Mon Sep 17 00:00:00 2001 From: TimePath Date: Wed, 26 Aug 2015 09:04:21 +1000 Subject: [PATCH] Initial friend server --- xonstat/crypto-keygen-standalone | 2 +- xonstat/friends.py | 59 ++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 xonstat/friends.py diff --git a/xonstat/crypto-keygen-standalone b/xonstat/crypto-keygen-standalone index 32f91eb..ffe75dd 120000 --- a/xonstat/crypto-keygen-standalone +++ b/xonstat/crypto-keygen-standalone @@ -1 +1 @@ -/usr/local/games/Xonotic/misc/infrastructure/keygen/crypto-keygen-standalone \ No newline at end of file +../../misc/infrastructure/keygen/crypto-keygen-standalone \ No newline at end of file diff --git a/xonstat/friends.py b/xonstat/friends.py new file mode 100644 index 0000000..9f25287 --- /dev/null +++ b/xonstat/friends.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python2 + +from collections import defaultdict, deque +from datetime import date, datetime, time, timedelta + +from flask import Flask, request, abort +from d0_blind_id import d0_blind_id_verify + +import logging + +log = logging.getLogger(__name__) +log.addHandler(logging.StreamHandler()) +log.setLevel(logging.DEBUG) + +keytoid = defaultdict(lambda: len(keytoid)) # TODO: replace with db lookup +queue = defaultdict(lambda: deque(maxlen=20)) +timeoutperiod = timedelta(minutes=15) +activity = defaultdict(lambda: None) + +app = Flask(__name__) + +def accept(): + triple = (request.headers.get('X-D0-Blind-Id-Detached-Signature', None), + request.query_string.decode(), + request.stream.read().decode()) + (idfp, status) = d0_blind_id_verify(*triple) + log.debug("d0_blind_id verification: idfp={0} status={1}".format(idfp, status)) + log.debug("----- BEGIN REQUEST BODY -----\n{0}\n----- END REQUEST BODY -----".format(triple)) + id = keytoid[idfp] + now = datetime.combine(date.today(), time()) + activity[id] = now + return id, now, triple[2] + +@app.route('/send', methods=['POST']) +def send(): + (src, now, msg) = accept() + dst = int(request.args.get('to')) + ret = request.args.get('retain') in ['1'] + activity[src] = now + log.debug("{0}@{1} -> {2}: {3}\n".format(src, now, dst, msg)) + + if ret or activity[dst] and now - timeoutperiod <= activity[dst] <= now + timeoutperiod: + queue[dst].extend([(src, msg)]) + if ret: # TODO: persist + pass + return "" + +@app.route('/recv', methods=['POST']) +def recv(): + (out, now, _) = accept() + q = queue[out] + if not len(q): + abort(404) + (src, msg) = q.popleft() + log.debug("{0}@{1} <- {2}\n".format(out, now, (src, msg))) + return "{0}\n{1}".format(src, msg) + +if __name__ == '__main__': + app.run(debug=True) -- 2.39.2