

def starttls(socket, success=None, failure=None, io=None, **options):
    'Wrap an active socket in an SSL socket.'
    options.setdefault('do_handshake_on_connect', False)
    options.setdefault('ssl_version', ssl.PROTOCOL_SSLv23)

    def done():
        'Handshake finished successfully.'
        io.remove_handler(wrapped.fileno())
        (success and success(wrapped))

    def error():
        'The handshake failed.'
        if failure:
            return failure(wrapped)
        io.remove_handler(wrapped.fileno())
        wrapped.close()

    def handshake(fd, events):
        'Handler for SSL handshake negotiation.  See Python docs for\n        ssl.do_handshake().'
        if (events & io.ERROR):
            error()
            return
        try:
            new_state = io.ERROR
            wrapped.do_handshake()
            return done()
        except ssl.SSLError as exc:
            if (exc.args[0] == ssl.SSL_ERROR_WANT_READ):
                new_state |= io.READ
            elif (exc.args[0] == ssl.SSL_ERROR_WANT_WRITE):
                new_state |= io.WRITE
            else:
                logging.exception('starttls: caught exception during handshake')
                error()
        if (new_state != state[0]):
            state[0] = new_state
            io.update_handler(fd, new_state)
    io = (io or loop())
    state = [io.ERROR]
    io.remove_handler(socket.fileno())
    wrapped = SSLSocket(socket, **options)
    wrapped.setblocking(0)
    io.add_handler(wrapped.fileno(), handshake, failure[0])
    handshake(wrapped.fileno(), 0)
    return wrapped

dataset/ETHPy150Open HenryHu/pybbs/xmpp/aio.py starttls/VarMisuse@331/454 `state`->`failure`