Exemplo n.º 1
0
 def read_some(self, max_len):
     """See :meth:`versile.reactor.io.IVByteInput.read_some`"""
     if not self.was_connected:
         raise VIOError('Socket was not connected')
     if self._sock_in_closed:
         if isinstance(self._sock_in_closed_reason, VFIOCompleted):
             raise VIOCompleted()
         else:
             raise VIOLost()
     if not self.sock:
         raise VIOError('No socket')
     try:
         if _pyver == 2:
             data = _s2b(self.sock.recv(max_len))
         else:
             data = self.sock.recv(max_len)
     except IOError as e:
         if e.errno in _errno_block:
             return b''
         elif (e.errno in (errno.EPIPE, errno.ENOTCONN)
               and not self._sock_verified):
             # ISSUE - these have been seen to be raised after
             # socket thinks it is connected due to select() event,
             # however ignoring it causes the connection to be
             # 'resumed'. For now we log a message and resume.
             self.log.debug('Ignoring post-connect read errno %s' % e.errno)
             return b''
         else:
             self.log.debug('Read got errno %s' % e.errno)
             raise VIOError('Socket read error, errno %s' % e.errno)
     else:
         if not data:
             raise VIOCompleted()
         self._sock_verified = True
         return data
Exemplo n.º 2
0
 def write_some(self, data):
     """See :meth:`versile.reactor.io.IVByteOutput.write_some`\ ."""
     if not self.was_connected:
         raise VIOError('Socket not connected')
     if self._sock_out_closed:
         if isinstance(self._sock_out_closed_reason, VFIOCompleted):
             raise VIOCompleted()
         else:
             raise VIOLost()
     if not self.sock:
         raise VIOError('No socket')
     try:
         if _pyver == 2:
             num_written = self.sock.send(_b2s(data))
         else:
             num_written = self.sock.send(data)
     except IOError as e:
         if e.errno in _errno_block:
             return 0
         elif (e.errno in (errno.EPIPE, errno.ENOTCONN)
               and not self._sock_verified):
             # ISSUE - these have been seen to be raised after
             # socket thinks it is connected due to select() event,
             # however ignoring it causes the connection to be
             # 'resumed'. For now we log a message and resume.
             self.log.debug('Ignoring post-connect write errno %s' %
                            e.errno)
             return 0
         else:
             self.log.debug('Write got errno %s' % e.errno)
             raise VIOError('Socket write error, errno %s' % e.errno)
     else:
         self._sock_verified = True
         return num_written
Exemplo n.º 3
0
    def read_some(self, max_len):
        """See :meth:`versile.reactor.io.IVByteInput.read_some`.

        .. note::

            Whereas :meth:`versile.reactor.io.sock.VSocket.read_some`
            is non-blocking, reading on a TLS socket is a blocking
            operation. This is due to limitations of the python 2.6
            ssl module. If non-blocking behavior is required, then
            :func:`select.select` or similar should be called to check
            whether the socket has data.

        This method may not return data even though data was available
        on the underlying socket when the method was called. This is
        because the TLS layer can only provide data when a full
        encrypted frame has been received.

        """
        if not self.was_connected:
            raise VIOError('Socket was not connected')
        if self._sock_in_closed:
            if isinstance(self._sock_in_closed_reason, VFIOCompleted):
                raise VIOCompleted()
            else:
                raise VIOLost()
        if not self.sock:
            raise VIOError('No socket')
        self._tls_read_pending = False
        try:
            data = self.sock.read(max_len)
        except IOError as e:
            if e.errno in _errno_wouldblock:
                return b''
            elif (e.errno in (errno.EPIPE, errno.ENOTCONN)
                  and not self._sock_verified):
                # ISSUE - see VSocket.read_some comments
                self.log.debug('Ignoring post-connect read errno %s' % e.errno)
                return b''
            else:
                self.log.debug('Read got errno %s' % e.errno)
                raise VIOError('Socket read error, errno %s' % e.errno)
        except ssl.SSLError as e:
            if e.args[0] in (ssl.SSL_ERROR_WANT_READ,
                             ssl.SSL_ERROR_WANT_WRITE):
                # Full frame of decrypted data not yet available
                return b''
        else:
            if not data:
                raise VIOCompleted()
            if self.sock.pending():
                self.log.debug('SSL data pending')
                self._tls_read_pending = True
                self.reactor.schedule(0.0, self.do_read)
            self._sock_verified = True
            return data
Exemplo n.º 4
0
    def write_some(self, data):
        """See :meth:`versile.reactor.io.IVByteOutput.write_some`\ .

        .. note::

            Whereas :meth:`versile.reactor.io.sock.VSocket.write_some`
            is non-blocking, writing to a TLS socket is a blocking
            operation. This is due to limitations of the python 2.6
            ssl module. If non-blocking behavior is required then
            :func:`select.select` or similar should be called to check
            whether the socket is ready for writing.

        """
        if not self.was_connected:
            raise VIOError('Socket not connected')
        if self._sock_out_closed:
            if isinstance(self._sock_out_closed_reason, VFIOCompleted):
                raise VIOCompleted()
            else:
                raise VIOLost()
        if not self.sock:
            raise VIOError('No socket')
        try:
            num_written = self.sock.write(data)
        except IOError as e:
            if e.errno in _errno_wouldblock:
                return 0
            elif (e.errno in (errno.EPIPE, errno.ENOTCONN)
                  and not self._sock_verified):
                # ISSUE - see VSocket.write_some comments
                self.log.debug('Ignoring post-connect write errno %s' %
                               e.errno)
                return 0
            else:
                self.log.debug('Write got errno %s' % e.errno)
                raise VIOError('Socket write error, errno %s' % e.errno)
        else:
            self._sock_verified = True
            return num_written
Exemplo n.º 5
0
    def _sock_do_activation_write(self):
        if not self._tls_handshake_done:
            try:
                self.sock.do_handshake()
            except ssl.SSLError as e:
                if e.args[0] == ssl.SSL_ERROR_WANT_READ:
                    self.log.debug('do_handshake wr want_read')
                    self.start_reading()
                    self.stop_writing()
                    return False
                elif e.args[0] == ssl.SSL_ERROR_WANT_WRITE:
                    self.log.debug('do_handshake wr want_write')
                    self.stop_reading()
                    self.start_writing()
                    return False
                else:
                    raise VIOError('SSL handshake problem')
            except AttributeError:
                # ISSUE - workaround for ssl async problem, stop
                # socket I/O for 1.0s
                self.log.debug('do_handshake wr attr.err')
                self.stop_reading()
                self.stop_writing()

                def _wakeup():
                    self.start_reading()
                    self.start_writing()

                self.reactor.schedule(1.0, _wakeup)  # HARDCODED wait time
            else:
                self.log.debug('TLS handshake was completed')
                if self.__finalize_tls_handshake():
                    self._tls_handshake_done = True
                    self.log.debug('TLS connection authorized')
                else:
                    self.close_io(VFIOLost())
                    raise VIOLost('TLS connection was not authorized')
        return self._tls_handshake_done
Exemplo n.º 6
0
 def write_some(self, data):
     """See :meth:`versile.reactor.io.IVByteOutput.write_some`\ ."""
     if self._out_closed:
         if isinstance(self._out_closed_reason, VFIOCompleted):
             raise VIOCompleted()
         else:
             raise VIOLost()
     try:
         if _pyver == 2:
             data = _b2s(data)
         num_written = os.write(self._fd, data)
     except OSError as e:
         if e.errno in _errno_block:
             return 0
         else:
             self.log.debug('Write got errno %s' % e.errno)
             raise VIOError('Pipe read error')
     else:
         if num_written > 0:
             return num_written
         else:
             self.log.debug('Pipe write error')
             raise VIOError('Pipe write error')
Exemplo n.º 7
0
 def read_some(self, max_len):
     """See :meth:`versile.reactor.io.IVByteInput.read_some`"""
     if self._in_closed:
         if isinstance(self._in_closed_reason, VFIOCompleted):
             raise VIOCompleted()
         else:
             raise VIOLost()
     try:
         data = os.read(self._fd, max_len)
         if _pyver == 2:
             data = _s2b(data)
     except OSError as e:
         if e.errno in _errno_block:
             return b''
         else:
             self.log.debug('Read got errno %s' % e.errno)
             raise VIOError('Pipe read error')
     else:
         if data:
             return data
         else:
             self.log.debug('Pipe read error')
             raise VIOError('Pipe read error')