def _reader(self, number): # The function must not be called if it does not return with no data with a smaller size as parameter if not self.io: self.close() raise NotConnected('Trying to read on a closed TCP conncetion') if number == 0: yield '' return while not self.reading(): yield '' data = '' reported = '' while True: try: while True: if self.defensive and random.randint(0, 2): raise socket.error(errno.EAGAIN, 'raising network error in purpose') read = self.io.recv(number) if not read: self.close() self.logger.wire("%s %s lost TCP session with peer" % (self.name(), self.peer)) raise LostConnection( 'the TCP connection was closed by the remote end') data += read number -= len(read) if not number: self.logger.wire( LazyFormat( "%s %-32s RECEIVED " % (self.name(), '%s / %s' % (self.local, self.peer)), read)) yield data return yield '' except socket.timeout, exc: self.close() self.logger.wire("%s %s peer is too slow" % (self.name(), self.peer)) raise TooSlowError( 'Timeout while reading data from the network (%s)' % errstr(exc)) except socket.error, exc: if exc.args[0] in error.block: message = "%s %s blocking io problem mid-way through reading a message %s, trying to complete" % ( self.name(), self.peer, errstr(exc)) if message != reported: reported = message self.logger.wire(message, 'debug') yield '' elif exc.args[0] in error.fatal: self.close() raise LostConnection('issue reading on the socket: %s' % errstr(exc)) # what error could it be ! else: self.logger.wire( "%s %s undefined error reading on socket" % (self.name(), self.peer)) raise NetworkError( 'Problem while reading data from the network (%s)' % errstr(exc))