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, time, uuid, sys
14
15 import pyamf
16 from pyamf import remoting
17 from pyamf.flex import messaging
18
19 error_alias = pyamf.get_class_alias(messaging.ErrorMessage)
20
22 """
23 Base server error.
24 """
25
27 """
28 A catchall error.
29 """
30 _amf_code = 'Server.Call.Failed'
31
32 pyamf.register_class(ServerCallFailed, attrs=error_alias.attrs)
33
34 del error_alias
35
37 return str(uuid.uuid4())
38
50
52 """
53 Builds an L{ErrorMessage<pyamf.flex.messaging.ErrorMessage>} based on the
54 last traceback and the request that was sent.
55 """
56 import traceback
57
58 if hasattr(cls, '_amf_code'):
59 code = cls._amf_code
60 else:
61 code = cls.__name__
62
63 detail = []
64
65 for x in traceback.format_exception(cls, e, tb):
66 detail.append(x.replace("\\n", ''))
67
68 return messaging.ErrorMessage(messageId=generate_random_id(),
69 clientId=generate_random_id(), timestamp=calendar.timegm(time.gmtime()),
70 correlationId = request.messageId, faultCode=code, faultString=str(e),
71 faultDetail=str(detail), extendedData=detail)
72
76
78 """
79 Builds an error response.
80
81 @param request: The AMF request
82 @type request: L{Request<pyamf.remoting.Request>}
83 @return: The AMF response
84 @rtype: L{Response<pyamf.remoting.Response>}
85 """
86 if error is not None:
87 cls, e, tb = error
88 else:
89 cls, e, tb = sys.exc_info()
90
91 return generate_error(request, cls, e, tb)
92
93 - def _getBody(self, amf_request, ro_request, **kwargs):
94 """
95 @raise ServerCallFailed: Unknown request.
96 """
97 if isinstance(ro_request, messaging.CommandMessage):
98 return self._processCommandMessage(amf_request, ro_request, **kwargs)
99 elif isinstance(ro_request, messaging.RemotingMessage):
100 return self._processRemotingMessage(amf_request, ro_request, **kwargs)
101 elif isinstance(ro_request, messaging.AsyncMessage):
102 return self._processAsyncMessage(amf_request, ro_request, **kwargs)
103 else:
104 raise ServerCallFailed("Unknown request: %s" % ro_request)
105
123
129
131 ro_response = generate_acknowledgement(ro_request)
132
133 service_name = ro_request.operation
134
135 if hasattr(ro_request, 'destination') and ro_request.destination:
136 service_name = '%s.%s' % (ro_request.destination, service_name)
137
138 service_request = self.gateway.getServiceRequest(amf_request,
139 service_name)
140
141
142 self.gateway.preprocessRequest(service_request, *ro_request.body,
143 **kwargs)
144
145 ro_response.body = self.gateway.callServiceRequest(service_request,
146 *ro_request.body, **kwargs)
147
148 return remoting.Response(ro_response)
149
150 - def __call__(self, amf_request, **kwargs):
151 """
152 Processes an AMF3 Remote Object request.
153
154 @param amf_request: The request to be processed.
155 @type amf_request: L{Request<pyamf.remoting.Request>}
156
157 @return: The response to the request.
158 @rtype: L{Response<pyamf.remoting.Response>}
159 """
160 ro_request = amf_request.body[0]
161
162 try:
163 return self._getBody(amf_request, ro_request, **kwargs)
164 except (KeyboardInterrupt, SystemExit):
165 raise
166 except:
167 return remoting.Response(self.buildErrorResponse(ro_request),
168 status=remoting.STATUS_ERROR)
169