diff options
Diffstat (limited to 'pyload/remote/wsbackend/AbstractHandler.py')
-rw-r--r-- | pyload/remote/wsbackend/AbstractHandler.py | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/pyload/remote/wsbackend/AbstractHandler.py b/pyload/remote/wsbackend/AbstractHandler.py new file mode 100644 index 000000000..8012d6cd8 --- /dev/null +++ b/pyload/remote/wsbackend/AbstractHandler.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +############################################################################### +# Copyright(c) 2008-2012 pyLoad Team +# http://www.pyload.org +# +# This file is part of pyLoad. +# pyLoad is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# Subjected to the terms and conditions in LICENSE +# +# @author: RaNaN +############################################################################### + +from mod_pywebsocket.msgutil import send_message +from mod_pywebsocket.util import get_class_logger +from pyload.remote.json_converter import loads, dumps + + +class AbstractHandler: + """ + Abstract Handler providing common methods shared across WebSocket handlers + """ + PATH = "/" + + OK = 200 + BAD_REQUEST = 400 + UNAUTHORIZED = 401 + FORBIDDEN = 403 + NOT_FOUND = 404 + ERROR = 500 + + def __init__(self, api): + self.log = get_class_logger() + self.api = api + self.core = api.core + + def do_extra_handshake(self, req): + self.log.debug("WS Connected: %s" % req) + req.api = None #when api is set client is logged in + + # allow login via session when webinterface is active + if self.core.config['webinterface']['activated']: + cookie = req.headers_in.getheader('Cookie') + s = self.load_session(cookie) + if s: + uid = s.get('uid', None) + req.api = self.api.withUserContext(uid) + self.log.debug("WS authenticated user with cookie: %d" % uid) + + self.on_open(req) + + def on_open(self, req): + pass + + def load_session(self, cookies): + from Cookie import SimpleCookie + from beaker.session import Session + from pyload.web.webinterface import session + + cookies = SimpleCookie(cookies) + sid = cookies.get(session.options['key']) + if not sid: + return None + + s = Session({}, use_cookies=False, id=sid.value, **session.options) + if s.is_new: + return None + + return s + + def passive_closing_handshake(self, req): + self.log.debug("WS Closed: %s" % req) + self.on_close(req) + + def on_close(self, req): + pass + + def transfer_data(self, req): + raise NotImplemented + + def handle_call(self, msg, req): + """ Parses the msg for an argument call. If func is null an response was already sent. + + :return: func, args, kwargs + """ + try: + o = loads(msg) + except ValueError, e: #invalid json object + self.log.debug("Invalid Request: %s" % e) + self.send_result(req, self.ERROR, "No JSON request") + return None, None, None + + if not isinstance(o, basestring) and type(o) != list and len(o) not in range(1, 4): + self.log.debug("Invalid Api call: %s" % o) + self.send_result(req, self.ERROR, "Invalid Api call") + return None, None, None + + # called only with name, no args + if isinstance(o, basestring): + return o, [], {} + elif len(o) == 1: # arguments omitted + return o[0], [], {} + elif len(o) == 2: + func, args = o + if type(args) == list: + return func, args, {} + else: + return func, [], args + else: + return tuple(o) + + def do_login(self, req, args, kwargs): + user = self.api.checkAuth(*args, **kwargs) + if user: + req.api = self.api.withUserContext(user.uid) + return self.send_result(req, self.OK, True) + else: + return self.send_result(req, self.FORBIDDEN, "Forbidden") + + def do_logout(self, req): + req.api = None + return self.send_result(req, self.OK, True) + + def send_result(self, req, code, result): + return send_message(req, dumps([code, result])) + + def send(self, req, obj): + return send_message(req, dumps(obj))
\ No newline at end of file |