def handle_rpc(self, request, *args, **kwargs): """Handle rpc request. :params request: Django HttpRequest instance. :returns: HttpResponse instance. """ contexts = self.get_contexts(request) p_ctx, others = contexts[0], contexts[1:] if p_ctx.in_error: return self.handle_error(p_ctx, others, p_ctx.in_error) self.get_in_object(p_ctx) if p_ctx.in_error: logger.error(p_ctx.in_error) return self.handle_error(p_ctx, others, p_ctx.in_error) self.get_out_object(p_ctx) if p_ctx.out_error: return self.handle_error(p_ctx, others, p_ctx.out_error) try: self.get_out_string(p_ctx) except Exception, e: logger.exception(e) p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e)) return self.handle_error(p_ctx, others, p_ctx.out_error)
def _handle_rpc_body(self, p_ctx) -> typing.Optional[Fault]: """ Do the heavy lifting of the request handling here. This can be run in a thread. """ self.get_in_object(p_ctx) if p_ctx.in_error: logger.error(p_ctx.in_error) return p_ctx.in_error self.get_out_object(p_ctx) if p_ctx.out_error: logger.error(p_ctx.out_error) return p_ctx.out_error try: self.get_out_string(p_ctx) except Exception as e: p_ctx.out_error = Fault("Server", get_fault_string_from_exception(e)) logger.exception(p_ctx.out_error, exc_info=e) return p_ctx.out_error have_protocol_headers = (isinstance(p_ctx.out_protocol, HttpRpc) and p_ctx.out_header_doc is not None) if have_protocol_headers: p_ctx.transport.resp_headers.update(p_ctx.out_header_doc) return None
def _eb_deferred(ret, request, p_ctx, others, resource): app = p_ctx.app # DRY this with what's in Application.process_request if issubclass(ret.type, Redirect): try: ret.value.do_redirect() # Now that the processing is switched to the outgoing message, # point ctx.protocol to ctx.out_protocol p_ctx.protocol = p_ctx.outprot_ctx _cb_deferred(None, request, p_ctx, others, resource, cb=False) # fire events app.event_manager.fire_event('method_redirect', p_ctx) if p_ctx.service_class is not None: p_ctx.service_class.event_manager.fire_event( 'method_redirect', p_ctx) except Exception as e: logger_server.exception(e) p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e)) # fire events app.event_manager.fire_event('method_redirect_exception', p_ctx) if p_ctx.service_class is not None: p_ctx.service_class.event_manager.fire_event( 'method_redirect_exception', p_ctx) elif issubclass(ret.type, Fault): p_ctx.out_error = ret.value ret = resource.handle_rpc_error(p_ctx, others, p_ctx.out_error, request) # fire events app.event_manager.fire_event('method_exception_object', p_ctx) if p_ctx.service_class is not None: p_ctx.service_class.event_manager.fire_event( 'method_exception_object', p_ctx) request.write(ret) else: p_ctx.out_error = ret.value ret.printTraceback() p_ctx.out_error = InternalError(ret.value) # fire events app.event_manager.fire_event('method_exception_object', p_ctx) if p_ctx.service_class is not None: p_ctx.service_class.event_manager.fire_event( 'method_exception_object', p_ctx) request.finish()
def handle_rpc(self, request, *args, **kwargs): """Handle rpc request. :params request: Django HttpRequest instance. :returns: HttpResponse instance. """ contexts = self.get_contexts(request) p_ctx, others = contexts[0], contexts[1:] # TODO: Rate limiting p_ctx.active = True if p_ctx.in_error: return self.handle_error(p_ctx, others, p_ctx.in_error) self.get_in_object(p_ctx) if p_ctx.in_error: logger.error(p_ctx.in_error) return self.handle_error(p_ctx, others, p_ctx.in_error) self.get_out_object(p_ctx) if p_ctx.out_error: return self.handle_error(p_ctx, others, p_ctx.out_error) try: self.get_out_string(p_ctx) except Exception as e: logger.exception(e) p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e)) return self.handle_error(p_ctx, others, p_ctx.out_error) have_protocol_headers = (isinstance(p_ctx.out_protocol, HttpRpc) and p_ctx.out_header_doc is not None) if have_protocol_headers: p_ctx.transport.resp_headers.update(p_ctx.out_header_doc) if p_ctx.descriptor and p_ctx.descriptor.mtom: raise NotImplementedError if self.chunked: response = StreamingHttpResponse(p_ctx.out_string) else: response = HttpResponse(b''.join(p_ctx.out_string)) return self.response(response, p_ctx, others)
def _eb_deferred(ret, request, p_ctx, others, resource): # DRY this with what's in Application.process_request if ret.check(Redirect): try: ret.value.do_redirect() # Now that the processing is switched to the outgoing message, # point ctx.protocol to ctx.out_protocol p_ctx.protocol = p_ctx.outprot_ctx _cb_deferred(None, request, p_ctx, others, resource, cb=False) p_ctx.fire_event('method_redirect') except Exception as e: logger_server.exception(e) p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e)) p_ctx.fire_event('method_redirect_exception') elif ret.check(Fault): p_ctx.out_error = ret.value ret = resource.handle_rpc_error(p_ctx, others, p_ctx.out_error, request) p_ctx.fire_event('method_exception_object') request.write(ret) else: p_ctx.out_error = InternalError(ret.value) logger.error(ret.getTraceback()) ret = resource.handle_rpc_error(p_ctx, others, p_ctx.out_error, request) p_ctx.fire_event('method_exception_object') request.write(ret) request.finish()
def handle_rpc(self, req_env, start_response): initial_ctx = WsgiMethodContext(self, req_env, self.app.out_protocol.mime_type) self.event_manager.fire_event('wsgi_call', initial_ctx) initial_ctx.in_string, in_string_charset = \ self.__reconstruct_wsgi_request(req_env) contexts = self.generate_contexts(initial_ctx, in_string_charset) p_ctx, others = contexts[0], contexts[1:] if p_ctx.in_error: return self.handle_error(p_ctx, others, p_ctx.in_error, start_response) self.get_in_object(p_ctx) if p_ctx.in_error: logger.error(p_ctx.in_error) return self.handle_error(p_ctx, others, p_ctx.in_error, start_response) self.get_out_object(p_ctx) if p_ctx.out_error: return self.handle_error(p_ctx, others, p_ctx.out_error, start_response) if p_ctx.transport.resp_code is None: p_ctx.transport.resp_code = HTTP_200 try: self.get_out_string(p_ctx) except Exception, e: logger.exception(e) p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e)) return self.handle_error(p_ctx, others, p_ctx.out_error, start_response)
def handle_rpc(self, req_env, start_response): initial_ctx = WsgiMethodContext(self, req_env, self.app.out_protocol.mime_type) self.event_manager.fire_event('wsgi_call', initial_ctx) initial_ctx.in_string, in_string_charset = \ self.__reconstruct_wsgi_request(req_env) contexts = self.generate_contexts(initial_ctx, in_string_charset) p_ctx, others = contexts[0], contexts[1:] # TODO: rate limiting p_ctx.active = True if p_ctx.in_error: return self.handle_error(p_ctx, others, p_ctx.in_error, start_response) self.get_in_object(p_ctx) if p_ctx.in_error: logger.error(p_ctx.in_error) return self.handle_error(p_ctx, others, p_ctx.in_error, start_response) self.get_out_object(p_ctx) if p_ctx.out_error: return self.handle_error(p_ctx, others, p_ctx.out_error, start_response) assert p_ctx.out_object is not None g = next(iter(p_ctx.out_object)) is_generator = len(p_ctx.out_object) == 1 and isgenerator(g) # if the out_object is a generator function, this hack makes the user # code run until first yield, which lets it set response headers and # whatnot before calling start_response. It's important to run this # here before serialization as the user function can also set output # protocol. Is there a better way? if is_generator: first_obj = next(g) p_ctx.out_object = ( chain((first_obj,), g), ) if p_ctx.transport.resp_code is None: p_ctx.transport.resp_code = HTTP_200 try: self.get_out_string(p_ctx) except Exception as e: logger.exception(e) p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e)) return self.handle_error(p_ctx, others, p_ctx.out_error, start_response) if isinstance(p_ctx.out_protocol, HttpRpc) and \ p_ctx.out_header_doc is not None: p_ctx.transport.resp_headers.update(p_ctx.out_header_doc) if p_ctx.descriptor and p_ctx.descriptor.mtom: # when there is more than one return type, the result is # encapsulated inside a list. when there's just one, the result # is returned in a non-encapsulated form. the apply_mtom always # expects the objects to be inside an iterable, hence the # following test. out_type_info = p_ctx.descriptor.out_message._type_info if len(out_type_info) == 1: p_ctx.out_object = [p_ctx.out_object] p_ctx.transport.resp_headers, p_ctx.out_string = apply_mtom( p_ctx.transport.resp_headers, p_ctx.out_string, p_ctx.descriptor.out_message._type_info.values(), p_ctx.out_object, ) self.event_manager.fire_event('wsgi_return', p_ctx) if self.chunked: # the user has not set a content-length, so we delete it as the # input is just an iterable. if 'Content-Length' in p_ctx.transport.resp_headers: del p_ctx.transport.resp_headers['Content-Length'] else: p_ctx.out_string = [''.join(p_ctx.out_string)] try: len(p_ctx.out_string) p_ctx.transport.resp_headers['Content-Length'] = \ str(sum([len(a) for a in p_ctx.out_string])) except TypeError: pass start_response(p_ctx.transport.resp_code, _gen_http_headers(p_ctx.transport.resp_headers)) retval = chain(p_ctx.out_string, self.__finalize(p_ctx)) try: process_contexts(self, others, p_ctx, error=None) except Exception as e: # Report but ignore any exceptions from auxiliary methods. logger.exception(e) return retval
def handle_rpc(self, req_env, start_response): initial_ctx = WsgiMethodContext(self, req_env, self.app.out_protocol.mime_type) self.event_manager.fire_event('wsgi_call', initial_ctx) initial_ctx.in_string, in_string_charset = \ self.__reconstruct_wsgi_request(req_env) contexts = self.generate_contexts(initial_ctx, in_string_charset) p_ctx, others = contexts[0], contexts[1:] # TODO: rate limiting p_ctx.active = True if p_ctx.in_error: return self.handle_error(p_ctx, others, p_ctx.in_error, start_response) self.get_in_object(p_ctx) if p_ctx.in_error: logger.error(p_ctx.in_error) return self.handle_error(p_ctx, others, p_ctx.in_error, start_response) self.get_out_object(p_ctx) if p_ctx.out_error: return self.handle_error(p_ctx, others, p_ctx.out_error, start_response) assert p_ctx.out_object is not None g = next(iter(p_ctx.out_object)) is_generator = len(p_ctx.out_object) == 1 and isgenerator(g) # if the out_object is a generator function, this hack makes the user # code run until first yield, which lets it set response headers and # whatnot before calling start_response. It's important to run this # here before serialization as the user function can also set output # protocol. Is there a better way? if is_generator: first_obj = next(g) p_ctx.out_object = (chain((first_obj, ), g), ) if p_ctx.transport.resp_code is None: p_ctx.transport.resp_code = HTTP_200 try: self.get_out_string(p_ctx) except Exception as e: logger.exception(e) p_ctx.out_error = Fault('Server', get_fault_string_from_exception(e)) return self.handle_error(p_ctx, others, p_ctx.out_error, start_response) if isinstance(p_ctx.out_protocol, HttpRpc) and \ p_ctx.out_header_doc is not None: p_ctx.transport.resp_headers.update(p_ctx.out_header_doc) if p_ctx.descriptor and p_ctx.descriptor.mtom: # when there is more than one return type, the result is # encapsulated inside a list. when there's just one, the result # is returned in a non-encapsulated form. the apply_mtom always # expects the objects to be inside an iterable, hence the # following test. out_type_info = p_ctx.descriptor.out_message._type_info if len(out_type_info) == 1: p_ctx.out_object = [p_ctx.out_object] p_ctx.transport.resp_headers, p_ctx.out_string = apply_mtom( p_ctx.transport.resp_headers, p_ctx.out_string, p_ctx.descriptor.out_message._type_info.values(), p_ctx.out_object, ) self.event_manager.fire_event('wsgi_return', p_ctx) if self.chunked: # the user has not set a content-length, so we delete it as the # input is just an iterable. if 'Content-Length' in p_ctx.transport.resp_headers: del p_ctx.transport.resp_headers['Content-Length'] else: p_ctx.out_string = [''.join(p_ctx.out_string)] try: len(p_ctx.out_string) p_ctx.transport.resp_headers['Content-Length'] = \ str(sum([len(a) for a in p_ctx.out_string])) except TypeError: pass start_response(p_ctx.transport.resp_code, _gen_http_headers(p_ctx.transport.resp_headers)) retval = chain(p_ctx.out_string, self.__finalize(p_ctx)) try: process_contexts(self, others, p_ctx, error=None) except Exception as e: # Report but ignore any exceptions from auxiliary methods. logger.exception(e) return retval