Source code for pyramid_rpc.amfgateway

"""Pyramid View Gateway implementation.

A :class:`~pyramid_rpc.amfgateway.PyramidGateway` instance implements a
Pyramid view compatible callable object, allowing it to be configured like any
other Pyramid view.

"""
import pyamf
from pyamf import remoting
from pyamf.remoting import gateway

from pyramid.httpexceptions import (
    HTTPBadRequest,
    HTTPInternalServerError,
    HTTPMethodNotAllowed,
)
from pyramid.response import Response


[docs]class PyramidGateway(gateway.BaseGateway): """Pyramid View Remoting Gateway :param expose_request: Defaults to True. Whether or not the service function should be called with the Pyramid request object. :param debug: Boolean toggling debug mode. """ def __init__(self, *args, **kwargs): kwargs['expose_request'] = kwargs.get('expose_request', True) gateway.BaseGateway.__init__(self, *args, **kwargs) def getResponse(self, request, amf_request): """Process the AMF request, returning an AMF response""" response = remoting.Envelope(amf_request.amfVersion) for name, message in amf_request: request.amf_request = message processor = self.getProcessor(message) response[name] = processor(message, http_request=request) return response def __call__(self, request): """Processes and dispatches the request""" if request.method != 'POST': return HTTPMethodNotAllowed(['POST']) body = request.body stream = None timezone_offset = self._get_timezone_offset() # Decode the request try: amf_request = remoting.decode(body, strict=self.strict, logger=self.logger, timezone_offset=timezone_offset) except (pyamf.DecodeError, IOError): if self.logger: self.logger.exception('Error decoding AMF request') response = "400 Bad Request\n\nThe request body was unable to " \ "be successfully decoded." if self.debug: response += "\n\nTraceback:\n\n%s" % gateway.format_exception() return HTTPBadRequest(detail=response) except Exception: if self.logger: self.logger.exception('Unexpected error decoding AMF request') response = ("500 Internal Server Error\n\nAn unexpected error " "occurred whilst decoding.") if self.debug: response += "\n\nTraceback:\n\n%s" % gateway.format_exception() return HTTPInternalServerError(detail=response) if self.logger: self.logger.debug("AMF Request: %r" % amf_request) # Process the request try: response = self.getResponse(request, amf_request) except Exception: if self.logger: self.logger.exception('Error processing AMF request') response = ("500 Internal Server Error\n\nThe request was " "unable to be successfully processed.") if self.debug: response += "\n\nTraceback:\n\n%s" % gateway.format_exception() return HTTPInternalServerError(detail=response) if self.logger: self.logger.debug("AMF Response: %r" % response) # Encode the response try: stream = remoting.encode(response, strict=self.strict, timezone_offset=timezone_offset) except: if self.logger: self.logger.exception('Error encoding AMF request') response = ("500 Internal Server Error\n\nThe request was " "unable to be encoded.") if self.debug: response += "\n\nTraceback:\n\n%s" % gateway.format_exception() return HTTPInternalServerError(detail=response) buf = stream.getvalue() http_response = Response(content_type=remoting.CONTENT_TYPE) http_response.headers['Server'] = gateway.SERVER_NAME http_response.write(buf) return http_response