# -*- coding: utf-8 -*- # vi:si:et:sw=4:sts=4:ts=4 import os import sys import tornado from tornado.web import StaticFileHandler, Application, FallbackHandler from tornado.wsgi import WSGIContainer from tornado.httpserver import HTTPServer from tornado.ioloop import IOLoop, PeriodicCallback import settings import directory import utils import state import user import json from ed25519_utils import valid import api class NodeHandler(tornado.web.RequestHandler): def initialize(self, app): self.app = app def post(self): request = self.request if request.method == 'POST': ''' API pullChanges [userid] from [to] pushChanges [index, change] requestPeering username message acceptPeering username message rejectPeering message removePeering message ping responds public ip ''' key = str(request.headers['X-Ed25519-Key']) sig = str(request.headers['X-Ed25519-Signature']) data = request.body content = {} if valid(key, data, sig): action, args = json.loads(data) print key, 'action', action, args if action == 'ping': content = { 'ip': request.remote_addr } else: with self.app.app_context(): if action in ( 'requestPeering', 'acceptPeering', 'rejectPeering', 'removePeering' ) or user.models.User.get(key): content = getattr(api, 'api_' + action)(self.app, key, *args) else: print 'PEER', key, 'IS UNKNOWN SEND 403' self.set_status(403) content = { 'status': 'not peered' } content = json.dumps(content) sig = settings.sk.sign(content, encoding='base64') self.set_header('X-Ed25519-Signature', sig) self.write(content) self.finish() def get(self): self.write('Open Media Library') self.finish() class ShareHandler(tornado.web.RequestHandler): def initialize(self, app): self.app = app def get(self, id): with self.app.app_context(): import item.models i = item.models.Item.get(id) if not i: self.set_status(404) self.finish() path = i.get_path() mimetype = { 'epub': 'application/epub+zip', 'pdf': 'application/pdf', 'txt': 'text/plain', }.get(path.split('.')[-1], None) self.set_header('Content-Type', mimetype) print 'GET file', id with open(path, 'rb') as f: while 1: data = f.read(16384) if not data: break self.write(data) self.finish() def start(app): http_server = tornado.web.Application([ (r"/get/(.*)", ShareHandler, dict(app=app)), (r".*", NodeHandler, dict(app=app)), ]) http_server.listen(settings.server['node_port'], settings.server['node_address']) host = utils.get_public_ipv6() state.online = directory.put(settings.sk, { 'host': host, 'port': settings.server['node_port'] }) return http_server