示例#1
0
    def _parseFrames(self):
        """
        Find frames in incoming data and pass them to the underlying protocol.
        """
        try:
            frames, rest = _parseFrames("".join(self._buffer))
        except _WSException:
            # Couldn't parse all the frames, something went wrong, let's bail.
            log.err()
            self.loseConnection()
            return

        self._buffer[:] = [rest]

        for frame in frames:
            opcode, data = frame
            if opcode == _CONTROLS.NORMAL:
                # Business as usual. Decode the frame, if we have a decoder.
                # Pass the frame to the underlying protocol.
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == _CONTROLS.CLOSE:
                # The other side wants us to close. I wonder why?
                reason, text = data
                log.msg("Closing connection: %r (%d)" % (text, reason))

                # Close the connection.
                self.loseConnection()
                return
            elif opcode == _CONTROLS.PING:
                # 5.5.2 PINGs must be responded to with PONGs.
                # 5.5.3 PONGs must contain the data that was sent with the
                # provoking PING.
                self.transport.write(_makeFrame(data, _opcode=_CONTROLS.PONG))
示例#2
0
    def parseFrames(self):
        """
        Find frames in incoming data and pass them to the underlying protocol.
        """

        try:
            frames, self.buf = parse_hybi07_frames(self.buf)
        except WSException:
            # Couldn't parse all the frames, something went wrong, let's bail.
            log.err()
            self.loseConnection()
            return

        for frame in frames:
            opcode, data = frame
            if opcode == NORMAL:
                # Business as usual. Decode the frame, if we have a decoder.
                if self.codec:
                    data = decoders[self.codec](data)
                # Pass the frame to the underlying protocol.
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == CLOSE:
                # The other side wants us to close. I wonder why?
                reason, text = data
                log.msg("Closing connection: %r (%d)" % (text, reason))

                # Close the connection.
                self.loseConnection()
                return
            elif opcode == PING:
                # 5.5.2 PINGs must be responded to with PONGs.
                # 5.5.3 PONGs must contain the data that was sent with the
                # provoking PING.
                raise AssertionError("this doesn't work")  # due to unknown symbol below
    def dataReceived(self, data):
        # type: (bytes) -> None
        if not self.tlsStarted:
            ProtocolWrapper.dataReceived(self, data)
            return

        self.encrypted += data

        try:
            while 1:
                decryptedData = self._decrypt()

                self._check()

                encryptedData = self._encrypt()
                ProtocolWrapper.write(self, encryptedData)

                ProtocolWrapper.dataReceived(self, decryptedData)

                if decryptedData == b'' and encryptedData == b'':
                    break
        except BIO.BIOError as e:
            # See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS
            # for the error codes returned by SSL_get_verify_result.
            e.args = (m2.ssl_get_verify_result(self.ssl._ptr()), e.args[0])
            raise e
示例#4
0
文件: txws.py 项目: voneiden/txWS
    def parseFrames(self):
        """
        Find frames in incoming data and pass them to the underlying protocol.
        """

        if self.flavor == HYBI00:
            parser = parse_hybi00_frames
        elif self.flavor in (HYBI07, HYBI10, RFC6455):
            parser = parse_hybi07_frames
        else:
            raise WSException("Unknown flavor %r" % self.flavor)

        try:
            frames, self.buf = parser(self.buf)
        except WSException as wse:
            # Couldn't parse all the frames, something went wrong, let's bail.
            self.close(wse.args[0])
            return

        for frame in frames:
            opcode, data = frame
            if opcode == NORMAL:
                # Business as usual. Decode the frame, if we have a decoder.
                if self.codec:
                    data = decoders[self.codec](data)
                # Pass the frame to the underlying protocol.
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == CLOSE:
                # The other side wants us to close. I wonder why?
                reason, text = data
                log.msg("Closing connection: %r (%d)" % (text, reason))

                # Close the connection.
                self.close()
示例#5
0
    def parseFrames(self):
        """
        Find frames in incoming data and pass them to the underlying protocol.
        """

        try:
            frames, self.buf = parse_hybi07_frames(self.buf)
        except WSException:
            # Couldn't parse all the frames, something went wrong, let's bail.
            log.err()
            self.loseConnection()
            return

        for frame in frames:
            opcode, data = frame
            if opcode == NORMAL:
                # Business as usual. Decode the frame, if we have a decoder.
                if self.codec:
                    data = decoders[self.codec](data)
                # Pass the frame to the underlying protocol.
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == CLOSE:
                # The other side wants us to close. I wonder why?
                reason, text = data
                log.msg("Closing connection: %r (%d)" % (text, reason))

                # Close the connection.
                self.loseConnection()
                return
            elif opcode == PING:
                # 5.5.2 PINGs must be responded to with PONGs.
                # 5.5.3 PONGs must contain the data that was sent with the
                # provoking PING.
                raise AssertionError(
                    "this doesn't work")  # due to unknown symbol below
示例#6
0
    def dataReceived(self, data):
        if not self.tlsStarted:
            ProtocolWrapper.dataReceived(self, data)
            return

        self.encrypted += data

        try:
            while 1:
                decryptedData = self._decrypt()

                self._check()

                encryptedData = self._encrypt()
                ProtocolWrapper.write(self, encryptedData)

                ProtocolWrapper.dataReceived(self, decryptedData)

                if decryptedData == '' and encryptedData == '':
                    break
        except M2Crypto.BIO.BIOError as e:
            # See http://www.openssl.org/docs/apps/verify.html#DIAGNOSTICS
            # for the error codes returned by SSL_get_verify_result.
            e.args = (m2.ssl_get_verify_result(self.ssl._ptr()), e.args[0])
            raise e
示例#7
0
    def _parseFrames(self):
        """
        Find frames in incoming data and pass them to the underlying protocol.
        """
        try:
            frames, rest = _parseFrames("".join(self._buffer))
        except _WSException:
            # Couldn't parse all the frames, something went wrong, let's bail.
            log.err()
            self.loseConnection()
            return

        self._buffer[:] = [rest]

        for frame in frames:
            opcode, data = frame
            if opcode == _CONTROLS.NORMAL:
                # Business as usual. Decode the frame, if we have a decoder.
                # Pass the frame to the underlying protocol.
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == _CONTROLS.CLOSE:
                # The other side wants us to close. I wonder why?
                reason, text = data
                log.msg("Closing connection: %r (%d)" % (text, reason))

                # Close the connection.
                self.loseConnection()
                return
            elif opcode == _CONTROLS.PING:
                # 5.5.2 PINGs must be responded to with PONGs.
                # 5.5.3 PONGs must contain the data that was sent with the
                # provoking PING.
                self.transport.write(_makeFrame(data, _opcode=_CONTROLS.PONG))
示例#8
0
    def parseFrames(self):
        """
        Find frames in incoming data and pass them to the underlying protocol.
        """

        if self.flavor == HYBI00:
            parser = parse_hybi00_frames
        elif self.flavor in (HYBI07, HYBI10, RFC6455):
            parser = parse_hybi07_frames
        else:
            raise WSException("Unknown flavor %r" % self.flavor)

        try:
            frames, self.buf = parser(self.buf)
        except WSException as wse:
            # Couldn't parse all the frames, something went wrong, let's bail.
            self.close(wse.args[0])
            return

        for frame in frames:
            opcode, data = frame
            if opcode == NORMAL:
                # Business as usual. Decode the frame, if we have a decoder.
                if self.codec:
                    data = decoders[self.codec](data)
                # Pass the frame to the underlying protocol.
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == CLOSE:
                # The other side wants us to close. I wonder why?
                reason, text = data
                log.msg("Closing connection: %r (%d)" % (text, reason))

                # Close the connection.
                self.close()
示例#9
0
 def dataReceived(self, data):
     if not data:
         return
     try:
         dat = json.loads(data)
     except ValueError:
         self.transport.loseConnection()
     else:
         for d in dat:
             ProtocolWrapper.dataReceived(self, d)
示例#10
0
 def dataReceived(self, data):
     if not data:
         return
     try:
         dat = json.loads(data)
     except ValueError:
         self.transport.loseConnection()
     else:
         for d in dat:
             ProtocolWrapper.dataReceived(self, d)
示例#11
0
 def dataReceived(self, data):
     if not data:
         return
     try:
         dat = json.loads(data)
     except ValueError:
         self.transport.loseConnection()
     else:
         for d in dat:
             d = normalize(d, self.parent._options['encoding'])
             ProtocolWrapper.dataReceived(self, d)
示例#12
0
 def dataReceived(self, data):
     try:
         if not self.tlsStarted:
             ProtocolWrapper.dataReceived(self, data)
         else:
             self.fakeSocket.data += data
             while self.fakeSocket.data:
                 AsyncStateMachine.inReadEvent(self)
     except TLSError, e:
         self.connectionLost(Failure(e))
         ProtocolWrapper.loseConnection(self)
示例#13
0
 def dataReceived(self, data):
     if not data:
         return
     try:
         dat = json.loads(data)
     except ValueError:
         self.transport.loseConnection()
     else:
         for d in dat:
             d = normalize(d, self.parent._options['encoding'])
             ProtocolWrapper.dataReceived(self, d)
示例#14
0
 def dataReceived(self, data):
     try:
         if not self.tlsStarted:
             ProtocolWrapper.dataReceived(self, data)
         else:
             self.fakeSocket.data += data
             while self.fakeSocket.data:
                 AsyncStateMachine.inReadEvent(self)
     except TLSError, e:
         self.connectionLost(Failure(e))
         ProtocolWrapper.loseConnection(self)
示例#15
0
    def _flushReceiveBIO(self):
        """
        Try to receive any application-level bytes which are now available
        because of a previous write into the receive BIO.  This will take
        care of delivering any application-level bytes which are received to
        the protocol, as well as handling of the various exceptions which
        can come from trying to get such bytes.
        """
        # Keep trying this until an error indicates we should stop or we
        # close the connection.  Looping is necessary to make sure we
        # process all of the data which was put into the receive BIO, as
        # there is no guarantee that a single recv call will do it all.
        while not self._lostTLSConnection:
            try:
                bytes = self._tlsConnection.recv(2**15)
            except WantReadError:
                # The newly received bytes might not have been enough to produce
                # any application data.
                break
            except ZeroReturnError:
                # TLS has shut down and no more TLS data will be received over
                # this connection.
                self._shutdownTLS()
                # Passing in None means the user protocol's connnectionLost
                # will get called with reason from underlying transport:
                self._tlsShutdownFinished(None)
            except Error as e:
                # Something went pretty wrong.  For example, this might be a
                # handshake failure (because there were no shared ciphers, because
                # a certificate failed to verify, etc).  TLS can no longer proceed.

                # Squash EOF in violation of protocol into ConnectionLost; we
                # create Failure before calling _flushSendBio so that no new
                # exception will get thrown in the interim.
                if e.args[0] == -1 and e.args[1] == 'Unexpected EOF':
                    failure = Failure(CONNECTION_LOST)
                else:
                    failure = Failure()

                self._flushSendBIO()
                self._tlsShutdownFinished(failure)
            else:
                # If we got application bytes, the handshake must be done by
                # now.  Keep track of this to control error reporting later.
                self._handshakeDone = True
                if not self._aborted:
                    ProtocolWrapper.dataReceived(self, bytes)

        # The received bytes might have generated a response which needs to be
        # sent now.  For example, the handshake involves several round-trip
        # exchanges without ever producing application-bytes.
        self._flushSendBIO()
示例#16
0
文件: tls.py 项目: Architektor/PySnip
    def _flushReceiveBIO(self):
        """
        Try to receive any application-level bytes which are now available
        because of a previous write into the receive BIO.  This will take
        care of delivering any application-level bytes which are received to
        the protocol, as well as handling of the various exceptions which
        can come from trying to get such bytes.
        """
        # Keep trying this until an error indicates we should stop or we
        # close the connection.  Looping is necessary to make sure we
        # process all of the data which was put into the receive BIO, as
        # there is no guarantee that a single recv call will do it all.
        while not self._lostTLSConnection:
            try:
                bytes = self._tlsConnection.recv(2 ** 15)
            except WantReadError:
                # The newly received bytes might not have been enough to produce
                # any application data.
                break
            except ZeroReturnError:
                # TLS has shut down and no more TLS data will be received over
                # this connection.
                self._shutdownTLS()
                # Passing in None means the user protocol's connnectionLost
                # will get called with reason from underlying transport:
                self._tlsShutdownFinished(None)
            except Error as e:
                # Something went pretty wrong.  For example, this might be a
                # handshake failure (because there were no shared ciphers, because
                # a certificate failed to verify, etc).  TLS can no longer proceed.

                # Squash EOF in violation of protocol into ConnectionLost; we
                # create Failure before calling _flushSendBio so that no new
                # exception will get thrown in the interim.
                if e.args[0] == -1 and e.args[1] == 'Unexpected EOF':
                    failure = Failure(CONNECTION_LOST)
                else:
                    failure = Failure()

                self._flushSendBIO()
                self._tlsShutdownFinished(failure)
            else:
                # If we got application bytes, the handshake must be done by
                # now.  Keep track of this to control error reporting later.
                self._handshakeDone = True
                if not self._aborted:
                    ProtocolWrapper.dataReceived(self, bytes)

        # The received bytes might have generated a response which needs to be
        # sent now.  For example, the handshake involves several round-trip
        # exchanges without ever producing application-bytes.
        self._flushSendBIO()
示例#17
0
    def parseFrames(self):
        """
        Find frames in incoming data and pass them to the underlying protocol.
        """

        try:
            frames, self.buf = parse_hybi07_frames(self.buf)
        except WSException:
            # Couldn't parse all the frames, something went wrong, let's bail.
            log.err()
            self.loseConnection()
            return

        for frame in frames:
            opcode, data, fin = frame
            if opcode == NORMAL:
                # Business as usual. Decode the frame, if we have a decoder.
                if self.codec:
                    self.complete_data += decoders[self.codec](data)
                # If no decoder, just tack it on as is to any previous frame data.
                else:
                    self.complete_data += data

                # If FIN bit is set this is the last data frame in this context.
                if fin:
                    # Pass the data compiled from the frames to the underlying protocol.
                    ProtocolWrapper.dataReceived(self, self.complete_data)
                    self.complete_data = ""
            elif opcode == CLOSE:
                # The other side wants us to close. I wonder why?
                reason, text = data
                log.msg("Closing connection: %r (%d)" % (text, reason))

                # Close the connection.
                self.loseConnection()
                return
            elif opcode == PING:
                # 5.5.2 PINGs must be responded to with PONGs.
                # 5.5.3 PONGs must contain the data that was sent with the
                # provoking PING.
                pong_data = data

                # DJM/JW - Chrome v39+ Websockets code breaks when you follow 5.5.3!
                if self.dumb_pong:
                    pong_data = ""

                self.transport.write(
                    make_hybi07_frame(pong_data, opcode=PONG)
                )  # DJM - this used to say make_hybi07_packet() but there is no definition for that!
    def parseFrames(self):
        """
        Find frames in incoming data and pass them to the underlying protocol.
        """

        start = self.buf.find("\x00")

        while start != -1:
            end = self.buf.find("\xff")
            if end == -1:
                # Incomplete frame, try again later.
                return
            else:
                frame, self.buf = self.buf[start + 1:end], self.buf[end + 1:]
                # Decode the frame, if we have a decoder.
                if self.codec:
                    frame = decoders[self.codec](frame)
                # Pass the frame to the underlying protocol.
                ProtocolWrapper.dataReceived(self, frame)
            start = self.buf.find("\x00")
示例#19
0
    def handle_frames(self):
        """
        Use the correct frame parser and send parsed data to the underlying
        protocol
        """

        if self.version == HYBI00:
            frame_parser = HyBi00Frame(self.buf)
        elif self.version in (HYBI07, HYBI10, RFC6455):
            frame_parser = HyBi07Frame(self.buf)
        else:
            raise InvalidProtocolVersion(
                'Unknown version {!r}'.format(self.version)
            )

        try:
            frames, self.buf = frame_parser.parse()
        except WebSocketError as error:
            log.err(error)
            self.close(error)
            return

        for frame in frames:
            opcode, data = frame
            if opcode == DATA:
                # pass the frame to the underlying protocol
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == CLOSE:
                # the other side want's to close
                reason, text = data
                log.msg('Closing connection: {!r} ({:d})'.format(
                    text, reason
                ))

                # close the connection
                self.close()
            elif opcode == PING:
                # send pong
                self.transport.write(
                    HyBi07Frame(data).generate(0xa)
                )
示例#20
0
    def handle_frames(self):
        """
        Use the correct frame parser and send parsed data to the underlying
        protocol
        """

        if self.version == HYBI00:
            frame_parser = HyBi00Frame(self.buf)
        elif self.version in (HYBI07, HYBI10, RFC6455):
            frame_parser = HyBi07Frame(self.buf)
        else:
            raise InvalidProtocolVersion(
                'Unknown version {!r}'.format(self.version)
            )

        try:
            frames, self.buf = frame_parser.parse()
        except WebSocketError as error:
            log.err(error)
            self.close(error)
            return

        for frame in frames:
            opcode, data = frame
            if opcode == DATA:
                # pass the frame to the underlying protocol
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == CLOSE:
                # the other side want's to close
                reason, text = data
                log.msg('Closing connection: {!r} ({:d})'.format(
                    text, reason
                ))

                # close the connection
                self.close()
            elif opcode == PING:
                # send pong
                self.transport.write(
                    HyBi07Frame(data).generate(0xa)
                )
示例#21
0
    def parseFrames(self):
        try:
            frames, self.buf = _parseFrames(self.buf, self.old)
        except _WSException:
            log.err()
            self.loseConnection()
            return

        for frame in frames:
            opcode, data = frame
            if opcode == _CONTROLS.NORMAL:
                if self.codec:
                    data = _decoders[self.codec](data)
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == _CONTROLS.CLOSE:
                reason, text = data
                log.msg("Closing connection: %r (%d)" % (text, reason))
                self.transport.loseConnection()
                return
            elif opcode == _CONTROLS.PING:
                self.transport.write(_makeFrame(data, self.old, _opcode=_CONTROLS.PONG))
示例#22
0
文件: txws.py 项目: ypwalter/evennia
class WebSocketProtocol(ProtocolWrapper):
    """
    Protocol which wraps another protocol to provide a WebSockets transport
    layer.
    """

    buf = ""
    codec = None
    location = "/"
    host = "example.com"
    origin = "http://example.com"
    state = REQUEST
    flavor = None
    do_binary_frames = False

    def __init__(self, *args, **kwargs):
        ProtocolWrapper.__init__(self, *args, **kwargs)
        self.pending_frames = []

    def setBinaryMode(self, mode):
        """
        If True, send str as binary and unicode as text.
        
        Defaults to false for backwards compatibility.
        """
        self.do_binary_frames = bool(mode)

    def isSecure(self):
        """
        Borrowed technique for determining whether this connection is over
        SSL/TLS.
        """

        return ISSLTransport(self.transport, None) is not None

    def sendCommonPreamble(self):
        """
        Send the preamble common to all WebSockets connections.

        This might go away in the future if WebSockets continue to diverge.
        """

        self.transport.writeSequence([
            "HTTP/1.1 101 FYI I am not a webserver\r\n",
            "Server: TwistedWebSocketWrapper/1.0\r\n",
            "Date: %s\r\n" % datetimeToString(),
            "Upgrade: WebSocket\r\n",
            "Connection: Upgrade\r\n",
        ])

    def sendHyBi00Preamble(self):
        """
        Send a HyBi-00 preamble.
        """

        protocol = "wss" if self.isSecure() else "ws"

        self.sendCommonPreamble()

        self.transport.writeSequence([
            "Sec-WebSocket-Origin: %s\r\n" % self.origin,
            "Sec-WebSocket-Location: %s://%s%s\r\n" %
            (protocol, self.host, self.location),
            "WebSocket-Protocol: %s\r\n" % self.codec,
            "Sec-WebSocket-Protocol: %s\r\n" % self.codec,
            "\r\n",
        ])

    def sendHyBi07Preamble(self):
        """
        Send a HyBi-07 preamble.
        """

        self.sendCommonPreamble()
        challenge = self.headers["Sec-WebSocket-Key"]
        response = make_accept(challenge)

        self.transport.write("Sec-WebSocket-Accept: %s\r\n\r\n" % response)

    def parseFrames(self):
        """
        Find frames in incoming data and pass them to the underlying protocol.
        """

        if self.flavor == HYBI00:
            parser = parse_hybi00_frames
        elif self.flavor in (HYBI07, HYBI10, RFC6455):
            parser = parse_hybi07_frames
        else:
            raise WSException("Unknown flavor %r" % self.flavor)

        try:
            frames, self.buf = parser(self.buf)
        except WSException, wse:
            # Couldn't parse all the frames, something went wrong, let's bail.
            self.close(wse.args[0])
            return

        for frame in frames:
            opcode, data = frame
            if opcode == NORMAL:
                # Business as usual. Decode the frame, if we have a decoder.
                if self.codec:
                    data = decoders[self.codec](data)
                # Pass the frame to the underlying protocol.
                ProtocolWrapper.dataReceived(self, data)
            elif opcode == CLOSE:
                # The other side wants us to close. I wonder why?
                reason, text = data
                log.msg("Closing connection: %r (%d)" % (text, reason))

                # Close the connection.
                self.close()
示例#23
0
 def outReadEvent(self, data):
     if data == "":
         ProtocolWrapper.loseConnection(self)
     else:
         ProtocolWrapper.dataReceived(self, data)
示例#24
0
 def outReadEvent(self, data):
     if data == "":
         ProtocolWrapper.loseConnection(self)
     else:
         ProtocolWrapper.dataReceived(self, data)