예제 #1
0
void SslTlsSocket::delayedStart()
{
    QSslSocket *sock = qobject_cast<QSslSocket *>(d);
    Q_ASSERT(sock);

    switch (m_proxySettings) {
    case Streams::ProxySettings::RespectSystemProxy:
    {
        QNetworkProxy setting;
        QNetworkProxyQuery query = QNetworkProxyQuery(host, port, m_protocolTag, QNetworkProxyQuery::TcpSocket);

        // set to true if a capable setting is found
        bool capableSettingFound = false;

        // set to true if at least one valid setting is found
        bool settingFound = false;

        // FIXME: this static function works particularly slow in Windows
        QList<QNetworkProxy> proxySettingsList = QNetworkProxyFactory::systemProxyForQuery(query);

        /* Proxy Settings are read from the user's environment variables by the above static method.
         * A peculiar case is with *nix systems, where an undefined environment variable is returned as
         * an empty string. Such entries *might* exist in our proxySettingsList, and shouldn't be processed.
         * One good check is to use hostName() of the QNetworkProxy object, and treat the Proxy Setting as invalid if
         * the host name is empty. */
        Q_FOREACH (setting, proxySettingsList) {
            if (!setting.hostName().isEmpty()) {
                settingFound = true;

                // now check whether setting has capabilities
                if (setting.capabilities().testFlag(QNetworkProxy::TunnelingCapability)) {
                    sock->setProxy(setting);
                    capableSettingFound = true;
                    break;
                }
            }
        }

        if (!settingFound || proxySettingsList.isEmpty()) {
            sock->setProxy(QNetworkProxy::NoProxy);
        } else if (!capableSettingFound) {
            emit disconnected(tr("The underlying socket is having troubles when processing connection to %1:%2: %3")
                              .arg(host, QString::number(port), QStringLiteral("Cannot find proxy setting capable of tunneling")));
        }
        break;
    }
    case Streams::ProxySettings::DirectConnect:
        sock->setProxy(QNetworkProxy::NoProxy);
        break;
    }

    if (startEncrypted)
        sock->connectToHostEncrypted(host, port);
    else
        sock->connectToHost(host, port);
}
예제 #2
0
void ClientSyncer::connectToCore(const QVariantMap &conn) {
  resetConnection();
  coreConnectionInfo = conn;

  if(conn["Host"].toString().isEmpty()) {
    emit connectionError(tr("No Host to connect to specified."));
    return;
  }

  Q_ASSERT(!_socket);
#ifdef HAVE_SSL
  QSslSocket *sock = new QSslSocket(Client::instance());
#else
  if(conn["useSsl"].toBool()) {
    emit connectionError(tr("<b>This client is built without SSL Support!</b><br />Disable the usage of SSL in the account settings."));
    return;
  }
  QTcpSocket *sock = new QTcpSocket(Client::instance());
#endif

#ifndef QT_NO_NETWORKPROXY
  if(conn.contains("useProxy") && conn["useProxy"].toBool()) {
    QNetworkProxy proxy((QNetworkProxy::ProxyType)conn["proxyType"].toInt(), conn["proxyHost"].toString(), conn["proxyPort"].toUInt(), conn["proxyUser"].toString(), conn["proxyPassword"].toString());
    sock->setProxy(proxy);
  }
#endif

  _socket = sock;
  connect(sock, SIGNAL(readyRead()), this, SLOT(coreHasData()));
  connect(sock, SIGNAL(connected()), this, SLOT(coreSocketConnected()));
  connect(sock, SIGNAL(disconnected()), this, SLOT(coreSocketDisconnected()));
  connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(coreSocketError(QAbstractSocket::SocketError)));
  connect(sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SIGNAL(socketStateChanged(QAbstractSocket::SocketState)));
  sock->connectToHost(conn["Host"].toString(), conn["Port"].toUInt());
}
/*!
    \internal
 */
void QWebSocketPrivate::open(const QUrl &url, bool mask)
{
    //just delete the old socket for the moment;
    //later, we can add more 'intelligent' handling by looking at the URL
    //m_pSocket.reset();
    Q_Q(QWebSocket);
    if (!url.isValid() || url.toString().contains(QStringLiteral("\r\n"))) {
        setErrorString(QWebSocket::tr("Invalid URL."));
        Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
        return;
    }
    QTcpSocket *pTcpSocket = m_pSocket.take();
    if (pTcpSocket) {
        releaseConnections(pTcpSocket);
        pTcpSocket->deleteLater();
    }
    //if (m_url != url)
    if (Q_LIKELY(!m_pSocket)) {
        m_dataProcessor.clear();
        m_isClosingHandshakeReceived = false;
        m_isClosingHandshakeSent = false;

        setRequestUrl(url);
        QString resourceName = url.path();
        if (resourceName.contains(QStringLiteral("\r\n"))) {
            setRequestUrl(QUrl());  //clear requestUrl
            setErrorString(QWebSocket::tr("Invalid resource name."));
            Q_EMIT q->error(QAbstractSocket::ConnectionRefusedError);
            return;
        }
        if (!url.query().isEmpty()) {
            if (!resourceName.endsWith(QChar::fromLatin1('?'))) {
                resourceName.append(QChar::fromLatin1('?'));
            }
            resourceName.append(url.query());
        }
        if (resourceName.isEmpty())
            resourceName = QStringLiteral("/");
        setResourceName(resourceName);
        enableMasking(mask);

    #ifndef QT_NO_SSL
        if (url.scheme() == QStringLiteral("wss")) {
            if (!QSslSocket::supportsSsl()) {
                const QString message =
                        QWebSocket::tr("SSL Sockets are not supported on this platform.");
                setErrorString(message);
                Q_EMIT q->error(QAbstractSocket::UnsupportedSocketOperationError);
            } else {
                QSslSocket *sslSocket = new QSslSocket;
                m_pSocket.reset(sslSocket);
                if (Q_LIKELY(m_pSocket)) {
                    m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
                    m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
                    m_pSocket->setReadBufferSize(m_readBufferSize);
                    m_pSocket->setPauseMode(m_pauseMode);

                    makeConnections(m_pSocket.data());
                    QObject::connect(sslSocket, &QSslSocket::encryptedBytesWritten, q,
                                     &QWebSocket::bytesWritten);
                    typedef void (QSslSocket:: *sslErrorSignalType)(const QList<QSslError> &);
                    QObject::connect(sslSocket,
                                     static_cast<sslErrorSignalType>(&QSslSocket::sslErrors),
                                     q, &QWebSocket::sslErrors);
                    setSocketState(QAbstractSocket::ConnectingState);

                    sslSocket->setSslConfiguration(m_configuration.m_sslConfiguration);
                    if (Q_UNLIKELY(m_configuration.m_ignoreSslErrors))
                        sslSocket->ignoreSslErrors();
                    else
                        sslSocket->ignoreSslErrors(m_configuration.m_ignoredSslErrors);
    #ifndef QT_NO_NETWORKPROXY
                    sslSocket->setProxy(m_configuration.m_proxy);
    #endif
                    sslSocket->connectToHostEncrypted(url.host(), url.port(443));
                } else {
                    const QString message = QWebSocket::tr("Out of memory.");
                    setErrorString(message);
                    Q_EMIT q->error(QAbstractSocket::SocketResourceError);
                }
            }
        } else
    #endif
        if (url.scheme() == QStringLiteral("ws")) {
            m_pSocket.reset(new QTcpSocket);
            if (Q_LIKELY(m_pSocket)) {
                m_pSocket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
                m_pSocket->setSocketOption(QAbstractSocket::KeepAliveOption, 1);
                m_pSocket->setReadBufferSize(m_readBufferSize);
                m_pSocket->setPauseMode(m_pauseMode);

                makeConnections(m_pSocket.data());
                QObject::connect(m_pSocket.data(), &QAbstractSocket::bytesWritten, q,
                                 &QWebSocket::bytesWritten);
                setSocketState(QAbstractSocket::ConnectingState);
    #ifndef QT_NO_NETWORKPROXY
                m_pSocket->setProxy(m_configuration.m_proxy);
    #endif
                m_pSocket->connectToHost(url.host(), url.port(80));
            } else {
                const QString message = QWebSocket::tr("Out of memory.");
                setErrorString(message);
                Q_EMIT q->error(QAbstractSocket::SocketResourceError);
            }
        } else {
            const QString message =
                    QWebSocket::tr("Unsupported WebSocket scheme: %1").arg(url.scheme());
            setErrorString(message);
            Q_EMIT q->error(QAbstractSocket::UnsupportedSocketOperationError);
        }
    }
}