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
17 import os.path
18
19 try:
20 sys.path.remove(os.path.dirname(os.path.abspath(__file__)))
21 except ValueError:
22 pass
23
24 google = __import__('google.appengine.ext.webapp')
25 webapp = google.appengine.ext.webapp
26
27 from pyamf import remoting
28 from pyamf.remoting import gateway
29
30 __all__ = ['WebAppGateway']
31
32
34 """
35 Google App Engine Remoting Gateway.
36 """
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 self.request.amf_request = message
56
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.response.headers['Server'] = gateway.SERVER_NAME
65 self.error(405)
66 self.response.out.write("405 Method Not Allowed\n\n"
67 "To access this PyAMF gateway you must use POST requests "
68 "(%s received)" % self.request.method)
69
71 body = self.request.body_file.read()
72 stream = None
73 timezone_offset = self._get_timezone_offset()
74
75
76
77 try:
78 request = remoting.decode(body, strict=self.strict,
79 logger=self.logger, timezone_offset=timezone_offset)
80 except (KeyboardInterrupt, SystemExit):
81 raise
82 except:
83 fe = gateway.format_exception()
84
85 if self.logger:
86 self.logger.exception(fe)
87
88 response = ("400 Bad Request\n\nThe request body was unable to "
89 "be successfully decoded.")
90
91 if self.debug:
92 response += "\n\nTraceback:\n\n%s" % fe
93
94 self.error(400)
95 self.response.headers['Content-Type'] = 'text/plain'
96 self.response.headers['Server'] = gateway.SERVER_NAME
97 self.response.out.write(response)
98
99 return
100
101 if self.logger:
102 self.logger.info("AMF Request: %r" % request)
103
104
105 try:
106 response = self.getResponse(request)
107 except (KeyboardInterrupt, SystemExit):
108 raise
109 except:
110 fe = gateway.format_exception()
111
112 if self.logger:
113 self.logger.exception(fe)
114
115 response = "500 Internal Server Error\n\nThe request was " \
116 "unable to be successfully processed."
117
118 if self.debug:
119 response += "\n\nTraceback:\n\n%s" % fe
120
121 self.error(500)
122 self.response.headers['Content-Type'] = 'text/plain'
123 self.response.headers['Server'] = gateway.SERVER_NAME
124 self.response.out.write(response)
125
126 return
127
128 if self.logger:
129 self.logger.info("AMF Response: %r" % response)
130
131
132 try:
133 stream = remoting.encode(response, strict=self.strict,
134 logger=self.logger, timezone_offset=timezone_offset)
135 except:
136 fe = gateway.format_exception()
137
138 if self.logger:
139 self.logger.exception(fe)
140
141 response = "500 Internal Server Error\n\nThe request was " \
142 "unable to be encoded."
143
144 if self.debug:
145 response += "\n\nTraceback:\n\n%s" % fe
146
147 self.error(500)
148 self.response.headers['Content-Type'] = 'text/plain'
149 self.response.headers['Server'] = gateway.SERVER_NAME
150 self.response.out.write(response)
151
152 return
153
154 response = stream.getvalue()
155
156 self.response.headers['Content-Type'] = remoting.CONTENT_TYPE
157 self.response.headers['Content-Length'] = str(len(response))
158 self.response.headers['Server'] = gateway.SERVER_NAME
159
160 self.response.out.write(response)
161
164