Package pyamf :: Package remoting :: Package gateway :: Module django

[hide private]
[frames] | no frames]

# Source Code for Module pyamf.remoting.gateway.django

      1  # Copyright (c) 2007-2009 The PyAMF Project.
      2  # See LICENSE for details.
      3
      4  """
      5  Gateway for the Django framework.
      6
      7  This gateway allows you to expose functions in Django to AMF clients and
      8  servers.
      9
     10  @see: U{Django homepage (external)<http://djangoproject.com>}
     11
     12  @since: 0.1.0
     13  """
     14
     15  django = __import__('django.http')
     16  http = django.http
     17
     18  import pyamf
     19  from pyamf import remoting
     20  from pyamf.remoting import gateway
     21
     22  __all__ = ['DjangoGateway']
     23
     24 -class DjangoGateway(gateway.BaseGateway):
     25      """
     26      An instance of this class is suitable as a Django view.
     27
     28      An example usage would be through C{urlconf}::
     29
     30          from django.conf.urls.defaults import *
     31
     32          urlpatterns = patterns('',
     33              (r'^gateway/', 'yourproject.yourapp.gateway.gw_instance'),
     34          )
     35
     36      where C{yourproject.yourapp.gateway.gw_instance} refers to an instance of
     37      this class.
     38
     39      @ivar expose_request: The standard Django view always has the request
     40          object as the first parameter. To disable this functionality, set this
     41          to C{False}.
     42      @type expose_request: C{bool}
     43      """
     44
     45 -    def __init__(self, *args, **kwargs):
     46          kwargs['expose_request'] = kwargs.get('expose_request', True)
     47
     48          gateway.BaseGateway.__init__(self, *args, **kwargs)
     49
     50 -    def getResponse(self, http_request, request):
     51          """
     52          Processes the AMF request, returning an AMF response.
     53
     54          @param http_request: The underlying HTTP Request.
     55          @type http_request: C{HTTPRequest<django.core.http.HTTPRequest>}
     56          @param request: The AMF Request.
     57          @type request: L{Envelope<pyamf.remoting.Envelope>}
     58          @rtype: L{Envelope<pyamf.remoting.Envelope>}
     59          @return: The AMF Response.
     60          """
     61          response = remoting.Envelope(request.amfVersion, request.clientType)
     62
     63          for name, message in request:
     64              processor = self.getProcessor(message)
     65              response[name] = processor(message, http_request=http_request)
     66
     67          return response
     68
     69 -    def __call__(self, http_request):
     70          """
     71          Processes and dispatches the request.
     72
     73          @param http_request: The C{HTTPRequest} object.
     74          @type http_request: C{HTTPRequest}
     75          @return: The response to the request.
     76          @rtype: C{HTTPResponse}
     77          """
     78          if http_request.method != 'POST':
     79              return http.HttpResponseNotAllowed(['POST'])
     80
     81          context = pyamf.get_context(pyamf.AMF0)
     82          stream = None
     83
     84          # Decode the request
     85          try:
     86              request = remoting.decode(http_request.raw_post_data, context, strict=self.strict)
     87          except (pyamf.DecodeError, EOFError):
     88              fe = gateway.format_exception()
     89              self.logger.exception(fe)
     90
     91              response = "400 Bad Request\n\nThe request body was unable to " \
     92                  "be successfully decoded."
     93
     94              if self.debug:
     95                  response += "\n\nTraceback:\n\n%s" % fe
     96
     97              return http.HttpResponseBadRequest(mimetype='text/plain', content=response)
     98          except (KeyboardInterrupt, SystemExit):
     99              raise
    100          except:
    101              fe = gateway.format_exception()
    102              self.logger.exception(fe)
    103
    104              response = "500 Internal Server Error\n\nAn unexpected error occurred."
    105
    106              if self.debug:
    107                  response += "\n\nTraceback:\n\n%s" % fe
    108
    109              return http.HttpResponseServerError(mimetype='text/plain', content=response)
    110
    111          self.logger.debug("AMF Request: %r" % request)
    112
    113          # Process the request
    114          try:
    115              response = self.getResponse(http_request, request)
    116          except (KeyboardInterrupt, SystemExit):
    117              raise
    118          except:
    119              fe = gateway.format_exception()
    120              self.logger.exception(fe)
    121
    122              response = "500 Internal Server Error\n\nThe request was " \
    123                  "unable to be successfully processed."
    124
    125              if self.debug:
    126                  response += "\n\nTraceback:\n\n%s" % fe
    127
    128              return http.HttpResponseServerError(mimetype='text/plain', content=response)
    129
    130          self.logger.debug("AMF Response: %r" % response)
    131
    132          # Encode the response
    133          try:
    134              stream = remoting.encode(response, context, strict=self.strict)
    135          except:
    136              fe = gateway.format_exception()
    137              self.logger.exception(fe)
    138
    139              response = "500 Internal Server Error\n\nThe request was " \
    140                  "unable to be encoded."
    141
    142              if self.debug:
    143                  response += "\n\nTraceback:\n\n%s" % fe
    144
    145              return http.HttpResponseServerError(mimetype='text/plain', content=response)
    146
    147          buf = stream.getvalue()
    148
    149          http_response = http.HttpResponse(mimetype=remoting.CONTENT_TYPE)
    150          http_response['Server'] = gateway.SERVER_NAME
    151          http_response['Content-Length'] = str(len(buf))
    152
    153          http_response.write(buf)
    154
    155          return http_response
    156