class igerpc_handler: IDENT = 'IGE RPC Request Handler' def __init__(self): self.marshal = IMarshal() self.commandCounter = counter() self.completedCounter = counter() self.exceptionsCounter = counter() def __repr__ (self): return '<%s at %x>' % ( self.IDENT, id (self) ) def match (self, request): if request.uri[:7] == '/IGERPC': return 1 else: return 0 def handle_request (self, request): [path, params, query, fragment] = request.split_uri() if request.command in ('post', 'put'): request.collector = collector (self, request) else: request.error (400) def continue_request (self, data, request): # V11 # packet = self.marshal.decode(unicode(data, 'utf-8')) #@log.debug("RX", len(data), "b") packet = self.marshal.decode(data) packet.clientAddr = request.channel.addr self.commandCounter.increment() try: # generate response try: response = self.call(packet) response.exception = None del response.clientAddr self.completedCounter.increment() except asyncore.ExitNow, e: raise e except Exception, e: # report exception back to client response = packet response.method = None response.params = None response.result = None response.messages = None response.exception = ('%s.%s' % (e.__class__.__module__, e.__class__.__name__), e.args) self.exceptionsCounter.increment()
class IProxy: def __init__(self, method, command, client): self.client = client self.method = method self.command = command self.marshal = IMarshal() def __call__(self, *args): if self.client.msgHandler: self.client.msgHandler(MSG_CMD_BEGIN, None) # retry 'turn in progress' and server restart situations retries = 10 ok = 0 while retries > 0: try: result = self.processCall(args) ok = 1 break except ServerStatusException as e: log.warning("Cannot complete request - retrying...") retries -= 1 time.sleep(1) # this was commented out except Exception as e: log.warning("Cannot complete request") if self.client.msgHandler: self.client.msgHandler(MSG_CMD_END, None) raise e if self.client.msgHandler: self.client.msgHandler(MSG_CMD_END, None) if ok: return result else: raise IClientException('Cannot send request to the server') def processCall(self, args): if not self.client.connected: raise IClientException('Not connected.') # record time of command self.client.lastCommand = time.time() # packet init packet = IPacket() packet.sid = self.client.sid packet.method = self.method if self.command: packet.params = [self.command] packet.params.extend(args) else: packet.params = args log.debug('calling', packet.method, packet.params) # encode # V11 data = self.marshal.encode(packet) self.client.statsBytesOut += len(data) log.debug('->', data) # make call # init connection if self.client.proxy: # use urllib if not self.client.httpConn: log.debug('Using proxy', self.client.proxy) self.client.httpConn = urllib.request.urlopen( {'http': self.client.proxy}) else: if self.client.httpConn: h = self.client.httpConn else: h = http.client.HTTPConnection(self.client.server) self.client.httpConn = h try: if self.client.proxy: fh = self.client.httpConn.open( 'http://%s/IGERPC' % self.client.server, data) # use thread to read response and invoke idle handler # regularly reader = Reader(fh.read) reader.start() while reader.isAlive(): reader.join(0.1) if self.client.idleHandler: self.client.idleHandler() if reader.exception: raise reader.exception else: rspData = reader.result # end of thread dispatcher fh.close() else: h.putrequest('POST', '/IGERPC') # required by HTTP/1.1 h.putheader('Host', self.client.server) # required by IGE-RPC h.putheader("Content-Type", "text/plain") h.putheader("Content-Length", str(len(data))) h.endheaders() h.send(data) # use thread to read response and invoke idle handler # regularly reader = Reader(h.getresponse) reader.start() while reader.isAlive(): reader.join(0.1) if self.client.idleHandler: self.client.idleHandler() if reader.exception: raise reader.exception else: response = reader.result # end of thread dispatcher if response.status != 200: raise ProtocolException(self.client.server + '/IGERPC', response.status, response.reason, response.msg) # use thread to read response and invoke idle handler # regularly reader = Reader(response.read) reader.start() while reader.isAlive(): reader.join(0.1) if self.client.idleHandler: self.client.idleHandler() if reader.exception: raise reader.exception else: rspData = reader.result # end of thread dispatcher except Exception as e: log.warning('Cannot send request to the server') self.client.logged = 0 self.client.connected = 0 raise IClientException('Cannot send request to the server') #@log.debug('<-', rspData) # V11 # packet = self.marshal.decode(unicode(rspData, "utf-8")) self.client.statsBytesIn += len(rspData) packet = self.marshal.decode(rspData) if packet.exception: #@log.debug('raising exception', packet.exception) exception = eval('%s()' % packet.exception[0]) exception.args = packet.exception[1] raise exception # process messages in packet.messages if self.client.msgHandler and packet.messages: for message in packet.messages: log.debug('got message', message) self.client.msgHandler(*message) elif packet.messages: log.debug('throwing away messages', packet.messages) log.debug("Stats: %d B IN / %d B OUT" % (self.client.statsBytesIn, self.client.statsBytesOut)) return packet.result
class igerpc_handler: IDENT = 'IGE RPC Request Handler' def __init__(self): self.marshal = IMarshal() self.commandCounter = counter.counter() self.completedCounter = counter.counter() self.exceptionsCounter = counter.counter() def __repr__(self): return '<%s at %x>' % (self.IDENT, id(self)) def match(self, request): if request.uri[:7] == '/IGERPC': return 1 else: return 0 def handle_request(self, request): [path, params, query, fragment] = request.split_uri() if request.command in ('post', 'put'): request.collector = collector(self, request) else: request.error(400) def continue_request(self, data, request): # V11 # packet = self.marshal.decode(unicode(data, 'utf-8')) #@log.debug("RX", len(data), "b") packet = self.marshal.decode(data) packet.clientAddr = request.channel.addr self.commandCounter.increment() try: # generate response try: response = self.call(packet) response.exception = None del response.clientAddr self.completedCounter.increment() except asyncore.ExitNow as e: raise e except Exception as e: # report exception back to client response = packet response.method = None response.params = None response.result = None response.messages = None response.exception = ( '%s.%s' % (e.__class__.__module__, e.__class__.__name__), e.args) self.exceptionsCounter.increment() except asyncore.ExitNow as e: raise e except Exception as e: # internal error, report as HTTP server error request.error(500) else: # got a valid XML RPC response request['Content-Type'] = 'application/x-ige-packet' # V11 # request.push(self.marshal.encode(response).encode('utf-8')) rsp = self.marshal.encode(response) #@log.debug("TX", len(rsp), "b") request.push(rsp) request.done() def call(self, packet): # override this method to implement RPC methods raise "NotYetImplemented" def status(self): return producers.simple_producer( '<li>%s' % status_handler.html_repr(self) + '<ul>' + ' <li><b>Total Commands:</b> %s' % self.commandCounter + ' <li><b>Completed:</b> %s' % self.completedCounter + ' <li><b>Exceptions:</b> %s' % self.exceptionsCounter + '</ul>')