ginsfsm / ginsfsm / protocols / sockjs / server / transports / xhr.py

The default branch has multiple heads

# -*- coding: utf-8 -*-
"""
    Xhr-Polling transport implementation
"""
import logging

from pyramid.view import view_config
from pyramid.security import authenticated_userid
from pyramid.httpexceptions import HTTPNotFound, HTTPServerError

from ginsfsm.gobj import GObj
from ginsfsm.protocols.sockjs.server import proto
from ginsfsm.protocols.sockjs.server.transports import pollingbase

#----------------------------------------------------------------#
#                   GXhrPolling GClass
#----------------------------------------------------------------#
GXHRPOLLING_GCONFIG = {
    'sockjs_server': [None, None, 0, None, ""],
}


class GXhrPolling(GObj):
    """  GXhrPolling GObj.
    """
    def __init__(self):
        GObj.__init__(self, {}, GXHRPOLLING_GCONFIG)

    def start_up(self):
        """ Initialization zone.
        """


#----------------------------------------------------------------#
#                   GXhrPolling Views
#----------------------------------------------------------------#
@view_config(
    context=GXhrPolling,
    name='',
    attr='options',
    request_method='OPTIONS',
)
@view_config(
    context=GXhrPolling,
    name='',
    attr='post',
    request_method='POST',
)
class XhrPollingTransport(pollingbase.PollingTransportBase):
    """xhr-polling transport implementation"""
    name = 'xhr'

    def post(self):
        #response = self.set_response(self.request.response)
        #response = self.set_response(self)  # Response is self.
        response = self
        # Start response
        self.preflight()
        self.handle_session_cookie()
        self.disable_cache()

        self.sid = self.context.parent.re_matched_name  # session_id
        if self.context.sockjs_server.per_user:
            self.sid = (authenticated_userid(self.request), self.sid)

        # Get or create session without starting heartbeat
        if not self._attach_session(self.sid, False):
            return response  # HTTPServerError("Error in attach_session.")

        # Might get already detached because connection was closed in on_open
        if not self.session:
            return response  # HTTPServerError("Error, no session.")

        if not self.session.send_queue:
            print ">>>>>>>SEND_QUEUE"
            self.session.start_heartbeat()
        else:
            print ">>>>>>>FLUSHHH"
            self.session.flush()

        return response

    def send_pack(self, message, binary=False):
        if binary:
            raise Exception('binary not supported for XhrPollingTransport')

        if not self.active:
            return

        self.active = False

        try:
            self.response.content_type = 'application/javascript'
            self.response.charset = 'UTF-8'

            print "zzzzz", message
            self.set_body(message + '\n')
            self.context.gaplic.add_callback(self.send_complete)
            #self.flush(callback=self.send_complete)
        except:
            # If connection dropped, make sure we close offending session
            # instead of propagating error all way up.

            # TODO: ERROR self.session.delayed_close()
            pass

#----------------------------------------------------------------#
#                   GXhrSend GClass
#----------------------------------------------------------------#
GXHRSEND_GCONFIG = {
    'sockjs_server': [None, None, 0, None, ""],
}


class GXhrSend(GObj):
    """  GXhr GObj.
    """
    def __init__(self):
        GObj.__init__(self, {}, GXHRSEND_GCONFIG)

    def start_up(self):
        """ Initialization zone.
        """


#----------------------------------------------------------------#
#                   GXhrSend Views
#----------------------------------------------------------------#
@view_config(
    context=GXhrSend,
    name='',
    attr='options',
    request_method='OPTIONS',
)
@view_config(
    context=GXhrSend,
    name='',
    attr='post',
    request_method='POST',
)
class XhrSendHandler(pollingbase.PollingTransportBase):
    def post(self):
        #response = self.set_response(self.request.response)
        #response = self.set_response(self)  # Response is self.
        response = self

        self.sid = self.context.parent.re_matched_name  # session_id
        if self.context.sockjs_server.per_user:
            self.sid = (authenticated_userid(self.request), self.sid)

        # Start response
        self.preflight()
        self.handle_session_cookie()
        self.disable_cache()

        session = self._get_session(self.sid)

        if session is None:
            return HTTPNotFound('Session not found')

        data = self.request.body_file.read()
        if not data:
            return HTTPServerError("Payload expected.")

        try:
            messages = proto.json_decode(data)
        except:
            return HTTPServerError("Broken JSON encoding.")

        try:
            session.on_messages(messages)
        except Exception:
            logging.exception('XHR incoming')
            session.close()
            return HTTPServerError('XHR incoming')

        self.set_status(204)
        self.response.content_type = 'text/plain'
        self.response.charset = 'UTF-8'
        return response
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.