📄 qhttpsocketengine.cpp
字号:
// greeting, and then received the response). while (d->state != Connected && d->socket->waitForReadyRead(qt_timeout_value(msecs, stopWatch.elapsed()))) { // Loop while the protocol handshake is taking place. } // Report any error that may occur. if (d->state != Connected) { setError(d->socket->error(), d->socket->errorString()); if (timedOut && d->socket->error() == QAbstractSocket::SocketTimeoutError) *timedOut = true; } return true;}bool QHttpSocketEngine::waitForReadOrWrite(bool *readyToRead, bool *readyToWrite, bool checkRead, bool checkWrite, int msecs, bool *timedOut) const{ Q_UNUSED(checkRead); if (!checkWrite) { // Not interested in writing? Then we wait for read notifications. bool canRead = waitForRead(msecs, timedOut); if (readyToRead) *readyToRead = canRead; return canRead; } // Interested in writing? Then we wait for write notifications. bool canWrite = waitForWrite(msecs, timedOut); if (readyToWrite) *readyToWrite = canWrite; return canWrite;}bool QHttpSocketEngine::isReadNotificationEnabled() const{ Q_D(const QHttpSocketEngine); return d->readNotificationEnabled;}void QHttpSocketEngine::setReadNotificationEnabled(bool enable){ Q_D(QHttpSocketEngine); if (d->readNotificationEnabled == enable) return; d->readNotificationEnabled = enable; if (enable) { // Enabling read notification can trigger a notification. if (bytesAvailable()) slotSocketReadNotification(); }}bool QHttpSocketEngine::isWriteNotificationEnabled() const{ Q_D(const QHttpSocketEngine); return d->writeNotificationEnabled;}void QHttpSocketEngine::setWriteNotificationEnabled(bool enable){ Q_D(QHttpSocketEngine); d->writeNotificationEnabled = enable; if (enable && d->state == Connected && d->socket->state() == QAbstractSocket::ConnectedState) QMetaObject::invokeMethod(this, "writeNotification", Qt::QueuedConnection);}bool QHttpSocketEngine::isExceptionNotificationEnabled() const{ Q_D(const QHttpSocketEngine); return d->exceptNotificationEnabled;}void QHttpSocketEngine::setExceptionNotificationEnabled(bool enable){ Q_D(QHttpSocketEngine); d->exceptNotificationEnabled = enable;}void QHttpSocketEngine::slotSocketConnected(){ Q_D(QHttpSocketEngine); // Send the greeting. const char method[] = "CONNECT"; QByteArray peerAddress = d->peerAddress.toString().toLatin1(); QByteArray path = peerAddress + ':' + QByteArray::number(d->peerPort); QByteArray data = method; data += " "; data += path; data += " HTTP/1.1\r\n"; data += "Proxy-Connection: keep-alive\r\n" "Host: " + peerAddress + "\r\n"; QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator); //qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1); if (priv && priv->method != QAuthenticatorPrivate::None) { data += "Proxy-Authorization: " + priv->calculateResponse(method, path); data += "\r\n"; } data += "\r\n";// qDebug() << ">>>>>>>> sending request" << this;// qDebug() << data;// qDebug() << ">>>>>>>"; d->socket->write(data); d->state = ConnectSent;}void QHttpSocketEngine::slotSocketDisconnected(){}void QHttpSocketEngine::slotSocketReadNotification(){ Q_D(QHttpSocketEngine); if (d->state != Connected && d->socket->bytesAvailable() == 0) return; if (d->state == Connected) { // Forward as a read notification. if (d->readNotificationEnabled) emitReadNotification(); return; } readResponseContent: if (d->state == ReadResponseContent) { char dummybuffer[4096]; while (d->pendingResponseData) { int read = d->socket->read(dummybuffer, qMin(sizeof(dummybuffer), (size_t)d->pendingResponseData)); dummybuffer[read] = 0; if (read == 0) return; if (read == -1) { d->socket->disconnectFromHost(); emitWriteNotification(); return; } d->pendingResponseData -= read; } if (d->pendingResponseData > 0) return; d->state = SendAuthentication; slotSocketConnected(); return; } // Still in handshake mode. Wait until we've got a full response. bool done = false; do { d->readBuffer += d->socket->readLine(); } while (!(done = d->readBuffer.endsWith("\r\n\r\n")) && d->socket->canReadLine()); if (!done) { // Wait for more. return; } QHttpResponseHeader responseHeader(QString::fromLatin1(d->readBuffer)); d->readBuffer.clear(); int statusCode = responseHeader.statusCode(); if (statusCode == 200) { d->state = Connected; } else if (statusCode == 503) { // 503 Service Unavailable: Connection Refused d->socket->close(); setState(QAbstractSocket::UnconnectedState); setError(QAbstractSocket::ConnectionRefusedError, QAbstractSocket::tr("Connection refused")); } else if (statusCode == 407) { if (d->authenticator.isNull()) d->authenticator.detach(); QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator); priv->parseHttpResponse(responseHeader, true); if (priv->phase == QAuthenticatorPrivate::Done) emit proxyAuthenticationRequired(d->proxy, &d->authenticator); // priv->phase will get reset to QAuthenticatorPrivate::Start if the authenticator got modified in the signal above. if (priv->phase == QAuthenticatorPrivate::Done) { setError(QAbstractSocket::ProxyAuthenticationRequiredError, tr("Authentication required")); d->socket->disconnectFromHost(); } else { // close the connection if it isn't already and reconnect using the chose authentication method d->state = SendAuthentication; bool willClose = (responseHeader.value(QLatin1String("Proxy-Connection")).toLower() == QLatin1String("close")); if (willClose) { d->socket->disconnectFromHost(); d->socket->readAll(); d->socket->connectToHost(d->proxy.hostName(), d->proxy.port()); } else { bool ok; int contentLength = responseHeader.value(QLatin1String("Content-Length")).toInt(&ok); if (ok && contentLength > 0) { d->state = ReadResponseContent; d->pendingResponseData = contentLength; goto readResponseContent; } else { d->state = SendAuthentication; slotSocketConnected(); } } return; } } else { qWarning("UNEXPECTED RESPONSE: [%s]", responseHeader.toString().toLatin1().data()); d->socket->disconnectFromHost(); } // The handshake is done; request a new connection attempt by sending a write // notification. emitWriteNotification();}void QHttpSocketEngine::slotSocketBytesWritten(){ Q_D(QHttpSocketEngine); if (d->state == Connected && d->writeNotificationEnabled) emitWriteNotification();}void QHttpSocketEngine::slotSocketError(QAbstractSocket::SocketError error){ Q_D(QHttpSocketEngine); d->readBuffer.clear(); if (d->state == SendAuthentication || d->state == ReadResponseContent) return; d->state = None; setError(error, d->socket->errorString()); if (error == QAbstractSocket::RemoteHostClosedError) emitReadNotification();}void QHttpSocketEngine::slotSocketStateChanged(QAbstractSocket::SocketState state){ Q_UNUSED(state);}void QHttpSocketEngine::emitPendingReadNotification(){ Q_D(QHttpSocketEngine); d->readNotificationPending = false; if (d->readNotificationEnabled) emit readNotification();}void QHttpSocketEngine::emitPendingWriteNotification(){ Q_D(QHttpSocketEngine); d->writeNotificationPending = false; if (d->writeNotificationEnabled) emit writeNotification();}void QHttpSocketEngine::emitReadNotification(){ Q_D(QHttpSocketEngine); d->readNotificationActivated = true; if (d->readNotificationEnabled && !d->readNotificationPending) { d->readNotificationPending = true; QMetaObject::invokeMethod(this, "emitPendingReadNotification", Qt::QueuedConnection); }}void QHttpSocketEngine::emitWriteNotification(){ Q_D(QHttpSocketEngine); d->writeNotificationActivated = true; if (d->writeNotificationEnabled && !d->writeNotificationPending) { d->writeNotificationPending = true; QMetaObject::invokeMethod(this, "emitPendingWriteNotification", Qt::QueuedConnection); }}QHttpSocketEnginePrivate::QHttpSocketEnginePrivate() : readNotificationEnabled(false) , writeNotificationEnabled(false) , exceptNotificationEnabled(false) , readNotificationActivated(false) , writeNotificationActivated(false) , readNotificationPending(false) , writeNotificationPending(false){ socket = 0; state = QHttpSocketEngine::None;}QHttpSocketEnginePrivate::~QHttpSocketEnginePrivate(){}QAbstractSocketEngine *QHttpSocketEngineHandler::createSocketEngine(const QHostAddress &address, QAbstractSocket::SocketType socketType, QObject *parent){ if (socketType != QAbstractSocket::TcpSocket) return 0; if (address == QHostAddress::LocalHost || address == QHostAddress::LocalHostIPv6) return 0; // find proxy info QAbstractSocket *abstractSocket = qobject_cast<QAbstractSocket *>(parent); if (!abstractSocket) return 0; QNetworkProxy proxy = abstractSocket->proxy(); if (proxy.type() == QNetworkProxy::DefaultProxy) proxy = QNetworkProxy::applicationProxy(); if (proxy.type() != QNetworkProxy::HttpProxy) return 0; QHttpSocketEngine *engine = new QHttpSocketEngine(parent); engine->setProxy(proxy); return engine;}QAbstractSocketEngine *QHttpSocketEngineHandler::createSocketEngine(int, QObject *){ return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -