1
2
3
4 """
5 AMF3 RemoteObject support.
6
7 @see: U{RemoteObject on LiveDocs
8 <http://livedocs.adobe.com/flex/3/langref/mx/rpc/remoting/RemoteObject.html>}
9
10 @since: 0.1.0
11 """
12
13 import calendar
14 import time
15 import uuid
16 import sys
17
18 import pyamf
19 from pyamf import remoting
20 from pyamf.flex import messaging
21
22
24 """
25 Base server error.
26 """
27
28
30 """
31 A catchall error.
32 """
33 _amf_code = 'Server.Call.Failed'
34
35
37 return str(uuid.uuid4())
38
39
51
52
54 """
55 Builds an L{ErrorMessage<pyamf.flex.messaging.ErrorMessage>} based on the
56 last traceback and the request that was sent.
57 """
58 import traceback
59
60 if hasattr(cls, '_amf_code'):
61 code = cls._amf_code
62 else:
63 code = cls.__name__
64
65 detail = ''
66 rootCause = None
67
68 if include_traceback:
69 detail = []
70 rootCause = e
71
72 for x in traceback.format_exception(cls, e, tb):
73 detail.append(x.replace("\\n", ''))
74
75 return messaging.ErrorMessage(messageId=generate_random_id(),
76 clientId=generate_random_id(), timestamp=calendar.timegm(time.gmtime()),
77 correlationId = request.messageId, faultCode=code, faultString=str(e),
78 faultDetail=str(detail), extendedData=detail, rootCause=rootCause)
79
80
84
86 """
87 Builds an error response.
88
89 @param request: The AMF request
90 @type request: L{Request<pyamf.remoting.Request>}
91 @return: The AMF response
92 @rtype: L{Response<pyamf.remoting.Response>}
93 """
94 if error is not None:
95 cls, e, tb = error
96 else:
97 cls, e, tb = sys.exc_info()
98
99 return generate_error(request, cls, e, tb, self.gateway.debug)
100
101 - def _getBody(self, amf_request, ro_request, **kwargs):
102 """
103 @raise ServerCallFailed: Unknown request.
104 """
105 if isinstance(ro_request, messaging.CommandMessage):
106 return self._processCommandMessage(amf_request, ro_request, **kwargs)
107 elif isinstance(ro_request, messaging.RemotingMessage):
108 return self._processRemotingMessage(amf_request, ro_request, **kwargs)
109 elif isinstance(ro_request, messaging.AsyncMessage):
110 return self._processAsyncMessage(amf_request, ro_request, **kwargs)
111 else:
112 raise ServerCallFailed("Unknown request: %s" % ro_request)
113
131
137
139 ro_response = generate_acknowledgement(ro_request)
140
141 service_name = ro_request.operation
142
143 if hasattr(ro_request, 'destination') and ro_request.destination:
144 service_name = '%s.%s' % (ro_request.destination, service_name)
145
146 service_request = self.gateway.getServiceRequest(amf_request,
147 service_name)
148
149
150 self.gateway.preprocessRequest(service_request, *ro_request.body,
151 **kwargs)
152
153 ro_response.body = self.gateway.callServiceRequest(service_request,
154 *ro_request.body, **kwargs)
155
156 return remoting.Response(ro_response)
157
158 - def __call__(self, amf_request, **kwargs):
159 """
160 Processes an AMF3 Remote Object request.
161
162 @param amf_request: The request to be processed.
163 @type amf_request: L{Request<pyamf.remoting.Request>}
164
165 @return: The response to the request.
166 @rtype: L{Response<pyamf.remoting.Response>}
167 """
168 ro_request = amf_request.body[0]
169
170 try:
171 return self._getBody(amf_request, ro_request, **kwargs)
172 except (KeyboardInterrupt, SystemExit):
173 raise
174 except:
175 return remoting.Response(self.buildErrorResponse(ro_request),
176 status=remoting.STATUS_ERROR)
177