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 @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
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
49
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
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
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
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
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