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.txt 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  conf = __import__('django.conf')
     18  conf = conf.conf
     19
     20  import pyamf
     21  from pyamf import remoting
     22  from pyamf.remoting import gateway
     23
     24  __all__ = ['DjangoGateway']
     25
     26
     27 -class DjangoGateway(gateway.BaseGateway):
     28      """
     29      An instance of this class is suitable as a Django view.
     30
     31      An example usage would be through C{urlconf}::
     32
     33          from django.conf.urls.defaults import *
     34
     35          urlpatterns = patterns('',
     36              (r'^gateway/', 'yourproject.yourapp.gateway.gw_instance'),
     37          )
     38
     39      where C{yourproject.yourapp.gateway.gw_instance} refers to an instance of
     40      this class.
     41
     42      @ivar expose_request: The standard Django view always has the request
     43          object as the first parameter. To disable this functionality, set this
     44          to C{False}.
     45      @type expose_request: C{bool}
     46      """
     47
     48 -    def __init__(self, *args, **kwargs):
     49          kwargs['expose_request'] = kwargs.get('expose_request', True)
     50
     51          try:
     52              tz = conf.settings.AMF_TIME_OFFSET
     53          except AttributeError:
     54              tz = None
     55
     56          try:
     57              debug = conf.settings.DEBUG
     58          except AttributeError:
     59              debug = False
     60
     61          kwargs['timezone_offset'] = kwargs.get('timezone_offset', tz)
     62          kwargs['debug'] = kwargs.get('debug', debug)
     63
     64          gateway.BaseGateway.__init__(self, *args, **kwargs)
     65
     66 -    def getResponse(self, http_request, request):
     67          """
     68          Processes the AMF request, returning an AMF response.
     69
     70          @param http_request: The underlying HTTP Request.
     71          @type http_request: C{HTTPRequest<django.core.http.HTTPRequest>}
     72          @param request: The AMF Request.
     73          @type request: L{Envelope<pyamf.remoting.Envelope>}
     74          @rtype: L{Envelope<pyamf.remoting.Envelope>}
     75          @return: The AMF Response.
     76          """
     77          response = remoting.Envelope(request.amfVersion, request.clientType)
     78
     79          for name, message in request:
     80              http_request.amf_request = message
     81
     82              processor = self.getProcessor(message)
     83              response[name] = processor(message, http_request=http_request)
     84
     85          return response
     86
     87 -    def __call__(self, http_request):
     88          """
     89          Processes and dispatches the request.
     90
     91          @param http_request: The C{HTTPRequest} object.
     92          @type http_request: C{HTTPRequest}
     93          @return: The response to the request.
     94          @rtype: C{HTTPResponse}
     95          """
     96          if http_request.method != 'POST':
     97              return http.HttpResponseNotAllowed(['POST'])
     98
     99          stream = None
    100          timezone_offset = self._get_timezone_offset()
    101
    102          # Decode the request
    103          try:
    104              request = remoting.decode(http_request.raw_post_data,
    105                  strict=self.strict, logger=self.logger,
    106                  timezone_offset=timezone_offset)
    107          except (pyamf.DecodeError, IOError):
    108              fe = gateway.format_exception()
    109
    110              if self.logger:
    111                  self.logger.exception(fe)
    112
    113              response = "400 Bad Request\n\nThe request body was unable to " \
    114                  "be successfully decoded."
    115
    116              if self.debug:
    117                  response += "\n\nTraceback:\n\n%s" % fe
    118
    119              return http.HttpResponseBadRequest(mimetype='text/plain', content=response)
    120          except (KeyboardInterrupt, SystemExit):
    121              raise
    122          except:
    123              fe = gateway.format_exception()
    124
    125              if self.logger:
    126                  self.logger.exception(fe)
    127
    128              response = ('500 Internal Server Error\n\n'
    129                  'An unexpected error occurred.')
    130
    131              if self.debug:
    132                  response += "\n\nTraceback:\n\n%s" % fe
    133
    134              return http.HttpResponseServerError(mimetype='text/plain',
    135                  content=response)
    136
    137          if self.logger:
    138              self.logger.info("AMF Request: %r" % request)
    139
    140          # Process the request
    141          try:
    142              response = self.getResponse(http_request, request)
    143          except (KeyboardInterrupt, SystemExit):
    144              raise
    145          except:
    146              fe = gateway.format_exception()
    147
    148              if self.logger:
    149                  self.logger.exception(fe)
    150
    151              response = "500 Internal Server Error\n\nThe request was " \
    152                  "unable to be successfully processed."
    153
    154              if self.debug:
    155                  response += "\n\nTraceback:\n\n%s" % fe
    156
    157              return http.HttpResponseServerError(mimetype='text/plain',
    158                  content=response)
    159
    160          if self.logger:
    161              self.logger.info("AMF Response: %r" % response)
    162
    163          # Encode the response
    164          try:
    165              stream = remoting.encode(response, strict=self.strict,
    166                  logger=self.logger, timezone_offset=timezone_offset)
    167          except:
    168              fe = gateway.format_exception()
    169
    170              if self.logger:
    171                  self.logger.exception(fe)
    172
    173              response = ("500 Internal Server Error\n\nThe request was "
    174                  "unable to be encoded.")
    175
    176              if self.debug:
    177                  response += "\n\nTraceback:\n\n%s" % fe
    178
    179              return http.HttpResponseServerError(mimetype='text/plain', content=response)
    180
    181          buf = stream.getvalue()
    182
    183          http_response = http.HttpResponse(mimetype=remoting.CONTENT_TYPE)
    184          http_response['Server'] = gateway.SERVER_NAME
    185          http_response['Content-Length'] = str(len(buf))
    186
    187          http_response.write(buf)
    188
    189          return http_response
    190