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  | 
