from HTTPServlet import HTTPServlet import traceback, sys class RPCServlet(HTTPServlet): def call(self, methodName, *args, **keywords): """ Subclasses may override this class for custom handling of methods. """ if methodName in self.exposedMethods(): return getattr(self, methodName)( *args, **keywords) else: raise NotImplementedError, methodName def exposedMethods(self): """ Subclasses should return a list of methods that will be exposed through XML-RPC. """ return ['exposedMethods'] def resultForException(self, e, trans): """ 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') assert setting in ('occurred', 'exception', 'traceback'), 'setting=%r' % setting if setting=='occurred': result = 'unhandled exception' elif setting=='exception': result = str(e) elif setting=='traceback': result = ''.join(traceback.format_exception(*sys.exc_info())) return result def sendOK(self, contentType, contents, trans, contentEncoding=None): """ Sends 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) def handleException(self, transaction): """ If ReportRPCExceptionsInWebKit 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 WebKit 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('ReportRPCExceptionsInWebKit') if setting: transaction.response().flush() transaction.application().handleExceptionInTransaction(sys.exc_info(), transaction)