1
2
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 @author: U{Arnar Birgisson<mailto:arnarbi@gmail.com>}
13
14 @since: 0.1.0
15 """
16
17 django = __import__('django')
18 http = django.http
19
20 import pyamf
21 from pyamf import remoting
22 from pyamf.remoting import gateway
23
24 __all__ = ['DjangoGateway']
25
27 """
28 An instance of this class is suitable as a Django view.
29
30 An example usage would be through C{urlconf}::
31
32 from django.conf.urls.defaults import *
33
34 urlpatterns = patterns('',
35 (r'^gateway/', 'yourproject.yourapp.gateway.gw_instance'),
36 )
37
38 where C{yourproject.yourapp.gateway.gw_instance} refers to an instance of
39 this class.
40
41 @ivar expose_request: The standard Django view always has the request
42 object as the first parameter. To disable this functionality, set this
43 to C{False}.
44 @type expose_request: C{bool}
45 """
46
51
53 """
54 Processes the AMF request, returning an AMF response.
55
56 @param http_request: The underlying HTTP Request.
57 @type http_request: C{HTTPRequest<django.core.http.HTTPRequest>}
58 @param request: The AMF Request.
59 @type request: L{Envelope<pyamf.remoting.Envelope>}
60 @rtype: L{Envelope<pyamf.remoting.Envelope>}
61 @return: The AMF Response.
62 """
63 response = remoting.Envelope(request.amfVersion, request.clientType)
64
65 for name, message in request:
66 processor = self.getProcessor(message)
67 response[name] = processor(message, http_request=http_request)
68
69 return response
70
72 """
73 Processes and dispatches the request.
74
75 @param http_request: The C{HTTPRequest} object.
76 @type http_request: C{HTTPRequest}
77 @return: The response to the request.
78 @rtype: C{HTTPResponse}
79 """
80 if http_request.method != 'POST':
81 return http.HttpResponseNotAllowed(['POST'])
82
83 context = pyamf.get_context(pyamf.AMF0)
84 stream = None
85 http_response = http.HttpResponse()
86
87
88 try:
89 request = remoting.decode(http_request.raw_post_data, context)
90 except pyamf.DecodeError:
91 self.logger.debug(gateway.format_exception())
92 http_response.status_code = 400
93
94 return http_response
95
96 self.logger.debug("AMF Request: %r" % request)
97
98
99 try:
100 response = self.getResponse(http_request, request)
101 except (KeyboardInterrupt, SystemExit):
102 raise
103 except:
104 self.logger.debug(gateway.format_exception())
105
106 return http.HttpResponseServerError()
107
108 self.logger.debug("AMF Response: %r" % response)
109
110
111 try:
112 stream = remoting.encode(response, context)
113 except pyamf.EncodeError:
114 self.logger.debug(gateway.format_exception())
115
116 return http.HttpResponseServerError('Unable to encode the response')
117
118 buf = stream.getvalue()
119 http_response['Content-Type'] = remoting.CONTENT_TYPE
120 http_response['Content-Length'] = str(len(buf))
121 http_response.write(buf)
122
123 return http_response
124