-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathRPCServlet.py
91 lines (74 loc) · 3.04 KB
/
RPCServlet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""RPC servlets."""
import traceback
import sys
from HTTPServlet import HTTPServlet
class RPCServlet(HTTPServlet):
"""RPCServlet is a base class for RPC servlets."""
def call(self, methodName, *args, **keywords):
"""Call custom method.
Subclasses may override this class for custom handling of methods.
"""
if methodName not in self.exposedMethods():
raise NotImplementedError(methodName)
return getattr(self, methodName)(*args, **keywords)
def exposedMethods(self):
"""Get exposed methods.
Subclasses should return a list of methods that will be exposed
through XML-RPC.
"""
return ['exposedMethods']
def resultForException(self, e, trans):
"""Get text for exception.
Given an unhandled exception, returns the string that should be
sent back in the RPC response as controlled by the
RPCExceptionReturn setting.
"""
# report exception back to server
setting = trans.application().setting('RPCExceptionReturn')
if setting == 'occurred':
result = 'unhandled exception'
elif setting == 'exception':
result = str(e)
elif setting == 'traceback':
result = ''.join(traceback.format_exception(*sys.exc_info()))
else:
raise ValueError(f'Invalid setting: {setting!r}')
return result
@staticmethod
def sendOK(contentType, contents, trans, contentEncoding=None):
"""Send a 200 OK response with the given contents."""
response = trans.response()
response.setStatus(200, 'OK')
response.setHeader('Content-Type', contentType)
response.setHeader('Content-Length', str(len(contents)))
if contentEncoding:
response.setHeader('Content-Encoding', contentEncoding)
response.write(contents)
@staticmethod
def handleException(transaction):
"""Handle exception.
If ReportRPCExceptionsInWebware is set to True, then flush the response
(because we don't want the standard HTML traceback to be appended to
the response) and then handle the exception in the standard Webware
way. This means logging it to the console, storing it in the error log,
sending error email, etc. depending on the settings.
"""
setting = transaction.application().setting(
'ReportRPCExceptionsInWebware')
if setting:
transaction.response().flush()
transaction.application().handleExceptionInTransaction(
sys.exc_info(), transaction)
def transaction(self):
"""Get the corresponding transaction.
Most uses of RPC will not need this.
"""
return self._transaction
def awake(self, transaction):
"""Begin transaction."""
HTTPServlet.awake(self, transaction)
self._transaction = transaction
def sleep(self, transaction):
"""End transaction."""
self._transaction = None
HTTPServlet.sleep(self, transaction)