openmedialibrary/oml/node/server.py

127 lines
4 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 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
2014-05-14 09:57:11 +00:00
import cert
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-13 10:36:02 +00:00
print key, 'action', 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:
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):
2014-05-14 09:57:11 +00:00
application = tornado.web.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()
http_server = tornado.httpserver.HTTPServer(application, ssl_options={
"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-12 12:57:47 +00:00
host = utils.get_public_ipv6()
2014-05-04 17:26:43 +00:00
state.online = directory.put(settings.sk, {
'host': host,
2014-05-14 09:57:11 +00:00
'port': settings.server['node_port'],
'cert': settings.server['cert']
2014-05-04 17:26:43 +00:00
})
return http_server