Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Do websocket module of PySide2 support ssl?



  • OS : win10 64bits
    python : 3.7.3(anaconda)
    install by pip : pip install PySide2
    llvm: libclang-release_70-based-windows-mingw_64\libclang

    1. QWebSocketServer do not has the api setSslConfiguration, if you call it, it will throw error message "PySide2.QtWebSockets.QWebSocketServer' object has no attribute 'setSslConfiguration'
    2. Since there do not exist setSslConfiguration, I set the ssl configuration as global settings

    Codes of server:

    import sys
    
    from PySide2.QtCore import QFile, QIODevice, QObject, Slot
    from PySide2.QtGui import QFont
    from PySide2.QtNetwork import QHostAddress, QSsl, QSslCertificate, QSslKey
    from PySide2.QtNetwork import QSslConfiguration, QSslSocket
    from PySide2.QtWebSockets import QWebSocketServer
    
    
    from PySide2.QtWidgets import QApplication, QPushButton
    
    
    def setSSLConfig():
        certFile = QFile("keys/localhost.cert")
        keyFile = QFile("keys/localhost.key")
        if certFile.open(QIODevice.ReadOnly) is False:
            raise Exception("Cannot open file keys/localhost.cert")
        if keyFile.open(QIODevice.ReadOnly) is False:
            raise Exception("Cannot open file keys/localhost.key")
    
        certificate = QSslCertificate(certFile.readAll(), QSsl.Pem)
        sslKey = QSslKey(keyFile.readAll(), QSsl.Rsa, QSsl.Pem)
        certFile.close()
        keyFile.close()
        sslConfiguration = QSslConfiguration()
        sslConfiguration.setPeerVerifyMode(QSslSocket.VerifyNone)
        sslConfiguration.setLocalCertificate(certificate)
        sslConfiguration.setPrivateKey(sslKey)
        sslConfiguration.setProtocol(QSsl.TlsV1SslV3)
        QSslConfiguration.setDefaultConfiguration(sslConfiguration)
    
    
    class sslServer(QObject):
    
        def __init__(self):
            super(sslServer, self).__init__()
    
            self.__server = QWebSocketServer("server", QWebSocketServer.SecureMode)
    
        def listen(self, address, port):
            if self.__server.isListening() and self.__addrEqual(address) and self.__portEqual(port):
                return True
            if self.__server.listen(address, port):
                print("server connect to address:", address, "port:", port)
                self.__server.newConnection.connect(self.__clientConnected)
                return True
            else:
                print("Cannot connect to server:", address, ", port:", port)
    
            return False
    
        @Slot(int)
        def listenToIPV4(self, port):
            self.listen(QHostAddress.AnyIPv4, port)
    
        def __clientConnected(self):
            print("client connect to the server")
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    
        setSSLConfig()
    
        server = sslServer()
        server.listenToIPV4(1234)
    
        button = QPushButton(text="Press me if you want to close the server")
        button.resize(640, 480)
        button.setFont(QFont("Arial", 20, QFont.Bold))
        button.clicked.connect(button.close)
        button.show()
    
        sys.exit(app.exec_())
    

    Codes of client

    import sys
    
    from PySide2.QtCore import QObject, QTimer, Slot
    from PySide2.QtGui import QFont
    from PySide2.QtNetwork import QAbstractSocket, QSslConfiguration, QSslSocket
    from PySide2.QtWebSockets import QWebSocket
    from PySide2.QtWidgets import QApplication, QPushButton
    
    
    class sslClient(QObject):
    
        def __init__(self):
            super(sslClient, self).__init__()
    
            self.__socket = QWebSocket()
            self.__socket.connected.connect(self.__connected)
            self.__socket.error.connect(self.__error)
            self.__socket.sslErrors.connect(self.__sslError)
    
            self.__socket.open("wss://localhost:1234")
    
            self.__reconnect_timer = QTimer()
            self.__reconnect_timer.timeout.connect(self.__reconnect)
            self.__reconnect_timer.start(60000)
    
        @Slot()
        def __connected(self):
            print("ssl client connected to server")
    
        @Slot(QAbstractSocket.SocketError)
        def __error(self, ecode):
            print("ssl client error code:", ecode, ", error msg:", self.__socket.errorString())
    
        @Slot(list)
        def __sslError(self, errors):
            print("error:", errors)
    
        def __reconnect(self):
            if self.__socket.state() != QAbstractSocket.ConnectedState:
                print("mlClient reconnect to:", self.__socket.requestUrl())
                self.__socket.open(self.__socket.requestUrl())
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    
        sslConfigure = QSslConfiguration.defaultConfiguration()
        sslConfigure.setPeerVerifyMode(QSslSocket.VerifyNone)
        QSslConfiguration.setDefaultConfiguration(sslConfigure)
    
        client = sslClient()
    
        button = QPushButton(text="Press me if you want to close the client")
        button.resize(640, 480)
        button.setFont(QFont("Arial", 20, QFont.Bold))
        button.clicked.connect(button.close)
        button.show()
    
        sys.exit(app.exec_())
    

    Similar codes works fine with c++(Qt5.12.2), any error I commit?Or ssl do not support by QWebSocket module yet?Or this is a bug? Thanks



  • I use asyncio, asyncqt and websockets to replace QWebsocket before Qt for python become more mature

    Edit : This seems like a known issue--Missing ssl support for QWebSocketServer and QWebSocket
    Edit : Check the source codes of PySide2, I am sure the websocket of Qt do not support ssl yet.


Log in to reply