openmedialibrary/oml/node/server.py

129 lines
3.9 KiB
Python
Raw Normal View History

2014-05-04 17:26:43 +00:00
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
import os
import tornado
2014-05-17 00:14:15 +00:00
from tornado.web import Application
2014-05-04 17:26:43 +00:00
from tornado.httpserver import HTTPServer
import settings
import directory
import state
import user
import json
2014-05-17 22:18:32 +00:00
from utils import valid, get_public_ipv6
2014-05-04 17:26:43 +00:00
import api
2014-05-14 09:57:11 +00:00
import cert
2014-05-04 17:26:43 +00:00
2014-05-17 14:26:59 +00:00
import logging
logger = logging.getLogger('oml.node.server')
2014-05-04 17:26:43 +00:00
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)
2014-05-17 14:26:59 +00:00
logger.debug('%s action %s %s', key, action, args)
2014-05-04 17:26:43 +00:00
if action == 'ping':
content = {
'ip': request.remote_addr
}
else:
with self.app.app_context():
2014-05-14 09:57:11 +00:00
u = user.models.User.get(key)
2014-05-04 17:26:43 +00:00
if action in (
'requestPeering', 'acceptPeering', 'rejectPeering', 'removePeering'
2014-05-14 09:57:11 +00:00
) or (u and u.peered):
2014-05-04 17:26:43 +00:00
content = getattr(api, 'api_' + action)(self.app, key, *args)
else:
2014-05-17 14:26:59 +00:00
logger.debug('PEER %s IS UNKNOWN SEND 403', key)
2014-05-04 17:26:43 +00:00
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)
2014-05-17 14:26:59 +00:00
logger.debug('GET file %s', id)
2014-05-04 17:26:43 +00:00
with open(path, 'rb') as f:
while 1:
data = f.read(16384)
if not data:
break
self.write(data)
self.finish()
2014-05-17 00:14:15 +00:00
def publish_node():
2014-05-17 22:18:32 +00:00
host = get_public_ipv6()
2014-05-17 00:14:15 +00:00
state.online = directory.put(settings.sk, {
'host': host,
'port': settings.server['node_port'],
'cert': settings.server['cert']
})
2014-05-04 17:26:43 +00:00
def start(app):
2014-05-17 00:14:15 +00:00
application = Application([
2014-05-04 17:26:43 +00:00
(r"/get/(.*)", ShareHandler, dict(app=app)),
(r".*", NodeHandler, dict(app=app)),
])
2014-05-14 09:57:11 +00:00
if not os.path.exists(settings.ssl_cert_path):
settings.server['cert'] = cert.generate_ssl()
2014-05-17 00:14:15 +00:00
http_server = HTTPServer(application, ssl_options={
2014-05-14 09:57:11 +00:00
"certfile": settings.ssl_cert_path,
"keyfile": settings.ssl_key_path
})
2014-05-04 17:26:43 +00:00
http_server.listen(settings.server['node_port'], settings.server['node_address'])
2014-05-17 00:14:15 +00:00
state.main.add_callback(publish_node)
2014-05-04 17:26:43 +00:00
return http_server