docs: def read(self, timeout=None):
          '''
          Read from the transport. If timeout>0, will only block for `timeout`
          seconds.
          '''
          e = None
          if not hasattr(self, '_sock'):
              return None
  
          try:
              # Note that we ignore both None and 0, i.e. we either block with a
              # timeout or block completely and let gevent sort it out.
              if timeout:
                  self._sock.settimeout(timeout)
              else:
                  self._sock.settimeout(None)
              data = self._sock.recv(
                  self._sock.getsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF))
  
              if len(data):
                  if self.connection.debug > 1:
                      self.connection.logger.debug(
                          'read %d bytes from %s' % (len(data), self._host))
                  if len(self._buffer):
                      self._buffer.extend(data)
                      data = self._buffer
                      self._buffer = bytearray()
                  return data
  
              # Note that no data means the socket is closed and we'll mark that
              # below
  
          except socket.timeout as e:
              # Note that this is implemented differently and though it would be
              # caught as an EnvironmentError, it has no errno. Not sure whose
              # fault that is.
              return None
  
          except EnvironmentError as e:
              # thrown if we have a timeout and no data
              if e.errno in (errno.EAGAIN, errno.EWOULDBLOCK, errno.EINTR):
                  return None
  
              self.connection.logger.exception(
                  'error reading from %s' % (self._host))
  
          self.connection.transport_closed(
              msg='error reading from %s' % (self._host))
          if e:
              raise