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 @since: 0.3.1
14 """
15
16 import sys, os.path
17
18 try:
19 sys.path.remove(os.path.dirname(os.path.abspath(__file__)))
20 except ValueError:
21 pass
22
23 google = __import__('google')
24 __import__('google.appengine.ext.webapp')
25
26 webapp = google.appengine.ext.webapp
27
28 import pyamf
29 from pyamf import remoting
30 from pyamf.remoting import gateway
31
32 __all__ = ['WebAppGateway']
33
35 """
36 Google App Engine Remoting Gateway.
37 """
38 __name__ = None
39
42
44 """
45 Processes the AMF request, returning an AMF response.
46
47 @param request: The AMF Request.
48 @type request: L{Envelope<pyamf.remoting.Envelope>}
49 @rtype: L{Envelope<pyamf.remoting.Envelope>}
50 @return: The AMF Response.
51 """
52 response = remoting.Envelope(request.amfVersion, request.clientType)
53
54 for name, message in request:
55 processor = self.getProcessor(message)
56 response[name] = processor(message, http_request=self.request)
57
58 return response
59
61 self.response.headers['Content-Type'] = 'text/plain'
62 self.response.headers['Server'] = gateway.SERVER_NAME
63 self.error(405)
64 self.response.out.write("405 Method Not Allowed\n\n" + \
65 "To access this PyAMF gateway you must use POST requests " + \
66 "(%s received)" % self.request.method)
67
69 body = self.request.body_file.read()
70 stream = None
71
72 context = pyamf.get_context(pyamf.AMF0)
73
74
75 try:
76 request = remoting.decode(body, context, strict=self.strict)
77 except:
78 fe = gateway.format_exception()
79 self.logger.exception(fe)
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" % fe
86
87 self.error(400)
88 self.response.headers['Content-Type'] = 'text/plain'
89 self.response.headers['Server'] = gateway.SERVER_NAME
90 self.response.out.write(response)
91
92 return
93
94 self.logger.debug("AMF Request: %r" % request)
95
96
97 try:
98 response = self.getResponse(request)
99 except (KeyboardInterrupt, SystemExit):
100 raise
101 except:
102 fe = gateway.format_exception()
103 self.logger.exception(fe)
104
105 response = "500 Internal Server Error\n\nThe request was " \
106 "unable to be successfully processed."
107
108 if self.debug:
109 response += "\n\nTraceback:\n\n%s" % fe
110
111 self.error(500)
112 self.response.headers['Content-Type'] = 'text/plain'
113 self.response.headers['Server'] = gateway.SERVER_NAME
114 self.response.out.write(response)
115
116 return
117
118 self.logger.debug("AMF Response: %r" % response)
119
120
121 try:
122 stream = remoting.encode(response, context, strict=self.strict)
123 except:
124 fe = gateway.format_exception()
125 self.logger.exception(fe)
126
127 response = "500 Internal Server Error\n\nThe request was " \
128 "unable to be encoded."
129
130 if self.debug:
131 response += "\n\nTraceback:\n\n%s" % fe
132
133 self.error(500)
134 self.response.headers['Content-Type'] = 'text/plain'
135 self.response.headers['Server'] = gateway.SERVER_NAME
136 self.response.out.write(response)
137
138 return
139
140 response = stream.getvalue()
141
142 self.response.headers['Content-Type'] = remoting.CONTENT_TYPE
143 self.response.headers['Content-Length'] = str(len(response))
144 self.response.headers['Server'] = gateway.SERVER_NAME
145
146 self.response.out.write(response)
147
150