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 errror
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
122
128
130 ro_response = generate_acknowledgement(ro_request)
131
132 service_name = ro_request.operation
133
134 if hasattr(ro_request, 'destination') and ro_request.destination:
135 service_name = '%s.%s' % (ro_request.destination, service_name)
136
137 service_request = self.gateway.getServiceRequest(amf_request,
138 service_name)
139
140
141 self.gateway.preprocessRequest(service_request, *ro_request.body,
142 **kwargs)
143
144 ro_response.body = self.gateway.callServiceRequest(service_request,
145 *ro_request.body, **kwargs)
146
147 return remoting.Response(ro_response)
148
149 - def __call__(self, amf_request, **kwargs):
150 """
151 Processes an AMF3 Remote Object request.
152
153 @param amf_request: The request to be processed.
154 @type amf_request: L{Request<pyamf.remoting.Request>}
155
156 @return: The response to the request.
157 @rtype: L{Response<pyamf.remoting.Response>}
158 """
159 ro_request = amf_request.body[0]
160
161 try:
162 return self._getBody(amf_request, ro_request, **kwargs)
163 except (KeyboardInterrupt, SystemExit):
164 raise
165 except:
166 return remoting.Response(self.buildErrorResponse(ro_request),
167 status=remoting.STATUS_ERROR)
168