1
2
3
4 """
5 Gateway for Google App Engine.
6
7 This gateway allows you to expose functions in Google App Engine web
8 applications to AMF clients and servers.
9
10 @see: U{Google App Engine homepage (external)
11 <http://code.google.com/appengine>}
12
13 @author: U{Nick Joyce<mailto:nick@boxdesign.co.uk>}
14
15 @since: 0.3.1
16 """
17
18 import sys, os.path
19
20 try:
21 sys.path.remove(os.path.dirname(os.path.abspath(__file__)))
22 except ValueError:
23 pass
24
25 google = __import__('google')
26 __import__('google.appengine.ext.webapp')
27
28 webapp = google.appengine.ext.webapp
29
30 import pyamf
31 from pyamf import remoting
32 from pyamf.remoting import gateway
33
34 __all__ = ['WebAppGateway']
35
37 """
38 Google App Engine Remoting Gateway.
39 """
40 __name__ = None
41
44
46 """
47 Processes the AMF request, returning an AMF response.
48
49 @param request: The AMF Request.
50 @type request: L{Envelope<pyamf.remoting.Envelope>}
51 @rtype: L{Envelope<pyamf.remoting.Envelope>}
52 @return: The AMF Response.
53 """
54 response = remoting.Envelope(request.amfVersion, request.clientType)
55
56 for name, message in request:
57 processor = self.getProcessor(message)
58 response[name] = processor(message, http_request=self.request)
59
60 return response
61
63 self.response.headers['Content-Type'] = 'text/plain'
64 self.error(405)
65 self.response.out.write("405 Method Not Allowed\n\n" + \
66 "To access this PyAMF gateway you must use POST requests " + \
67 "(%s received)" % self.request.method)
68
70 body = self.request.body_file.read()
71 stream = None
72
73 context = pyamf.get_context(pyamf.AMF0)
74
75
76 try:
77 request = remoting.decode(body, context)
78 except pyamf.DecodeError:
79 self.logger.debug(gateway.format_exception())
80
81 response = "400 Bad Request\n\nThe request body was unable to " \
82 "be successfully decoded."
83
84 if self.debug:
85 response += "\n\nTraceback:\n\n%s" % gateway.format_exception()
86
87 self.error(400)
88 self.response.headers['Content-Type'] = 'text/plain'
89 self.response.out.write(response)
90
91 return
92
93
94 try:
95 response = self.getResponse(request)
96 except (KeyboardInterrupt, SystemExit):
97 raise
98 except:
99 self.logger.debug(gateway.format_exception())
100
101 response = "500 Internal Server Error\n\nThe request was " \
102 "unable to be successfully processed."
103
104 if self.debug:
105 response += "\n\nTraceback:\n\n%s" % gateway.format_exception()
106
107 self.error(500)
108 self.response.headers['Content-Type'] = 'text/plain'
109 self.response.out.write(response)
110
111 return
112
113
114 try:
115 stream = remoting.encode(response, context)
116 except pyamf.EncodeError:
117 self.logger.debug(gateway.format_exception())
118
119 response = "500 Internal Server Error\n\nThe request was " \
120 "unable to be encoded."
121
122 if self.debug:
123 response += "\n\nTraceback:\n\n%s" % gateway.format_exception()
124
125 self.error(500)
126 self.response.headers['Content-Type'] = 'text/plain'
127 self.response.out.write(response)
128
129 return
130
131 response = stream.getvalue()
132
133 self.response.headers['Content-Type'] = remoting.CONTENT_TYPE
134 self.response.headers['Content-Length'] = str(len(response))
135 self.response.out.write(response)
136
139