📄 qhttpsocketengine.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtNetwork module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qhttpsocketengine_p.h"#include "qtcpsocket.h"#include "qhostaddress.h"#include "qdatetime.h"#include "qhttp.h"#if !defined(QT_NO_NETWORKPROXY) && !defined(QT_NO_HTTP)#include <qdebug.h>#define DEBUGQHttpSocketEngine::QHttpSocketEngine(QObject *parent) : QAbstractSocketEngine(*new QHttpSocketEnginePrivate, parent){}QHttpSocketEngine::~QHttpSocketEngine(){}bool QHttpSocketEngine::initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol){ Q_D(QHttpSocketEngine); if (type != QAbstractSocket::TcpSocket) return false; setProtocol(protocol); setSocketType(type); d->socket = new QTcpSocket(this); // Explicitly disable proxying on the proxy socket itself to avoid // unwanted recursion. QNetworkProxy proxy; proxy.setType(QNetworkProxy::NoProxy); d->socket->setProxy(proxy); // Intercept all the signals. connect(d->socket, SIGNAL(connected()), this, SLOT(slotSocketConnected())); connect(d->socket, SIGNAL(disconnected()), this, SLOT(slotSocketDisconnected())); connect(d->socket, SIGNAL(readyRead()), this, SLOT(slotSocketReadNotification())); connect(d->socket, SIGNAL(readyRead()), this, SLOT(slotSocketReadNotification())); connect(d->socket, SIGNAL(bytesWritten(qint64)), this, SLOT(slotSocketBytesWritten())); connect(d->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotSocketError(QAbstractSocket::SocketError))); connect(d->socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(slotSocketStateChanged(QAbstractSocket::SocketState))); return true;}bool QHttpSocketEngine::initialize(int, QAbstractSocket::SocketState){ return false;}void QHttpSocketEngine::setProxy(const QNetworkProxy &proxy){ Q_D(QHttpSocketEngine); d->proxy = proxy; QString user = proxy.user(); if (!user.isEmpty()) d->authenticator.setUser(user); QString password = proxy.password(); if (!password.isEmpty()) d->authenticator.setPassword(password);}int QHttpSocketEngine::socketDescriptor() const{ Q_D(const QHttpSocketEngine); return d->socket ? d->socket->socketDescriptor() : 0;}bool QHttpSocketEngine::isValid() const{ Q_D(const QHttpSocketEngine); return d->socket;}bool QHttpSocketEngine::connectToHost(const QHostAddress &address, quint16 port){ Q_D(QHttpSocketEngine); // If the handshake is done, enter ConnectedState state and return true. if (d->state == Connected) { setState(QAbstractSocket::ConnectedState); return true; } if (d->state == ConnectSent && d->socketState != QAbstractSocket::ConnectedState) setState(QAbstractSocket::UnconnectedState); // Handshake isn't done. If unconnected, start connecting. if (d->state == None && d->socket->state() == QAbstractSocket::UnconnectedState) { setPeerAddress(address); setPeerPort(port); setState(QAbstractSocket::ConnectingState); d->socket->connectToHost(d->proxy.hostName(), d->proxy.port()); } // If connected (might happen right away, at least for localhost services // on some BSD systems), there might already be bytes available. if (bytesAvailable()) slotSocketReadNotification(); return d->socketState == QAbstractSocket::ConnectedState;}bool QHttpSocketEngine::bind(const QHostAddress &, quint16){ return false;}bool QHttpSocketEngine::listen(){ return false;}int QHttpSocketEngine::accept(){ return 0;}void QHttpSocketEngine::close(){ Q_D(QHttpSocketEngine); if (d->socket) { d->socket->close(); delete d->socket; d->socket = 0; }}qint64 QHttpSocketEngine::bytesAvailable() const{ Q_D(const QHttpSocketEngine); return d->readBuffer.size() + (d->socket ? d->socket->bytesAvailable() : 0);}qint64 QHttpSocketEngine::read(char *data, qint64 maxlen){ Q_D(QHttpSocketEngine); qint64 bytesRead = 0; if (!d->readBuffer.isEmpty()) { // Read as much from the buffer as we can. bytesRead = qMin((qint64)d->readBuffer.size(), maxlen); memcpy(data, d->readBuffer.constData(), bytesRead); data += bytesRead; maxlen -= bytesRead; d->readBuffer = d->readBuffer.mid(bytesRead); } qint64 bytesReadFromSocket = d->socket->read(data, maxlen); if (d->socket->state() == QAbstractSocket::UnconnectedState && d->socket->bytesAvailable() == 0) { emitReadNotification(); } if (bytesReadFromSocket > 0) { // Add to what we read so far. bytesRead += bytesReadFromSocket; } else if (bytesRead == 0) { // If nothing has been read so far, and the direct socket read // failed, return the socket's error. Otherwise, fall through and // return as much as we read so far. close(); setError(QAbstractSocket::RemoteHostClosedError, QLatin1String("Remote host closed")); setState(QAbstractSocket::UnconnectedState); return -1; } return bytesRead;}qint64 QHttpSocketEngine::write(const char *data, qint64 len){ Q_D(QHttpSocketEngine); return d->socket->write(data, len);}#ifndef QT_NO_UDPSOCKETqint64 QHttpSocketEngine::readDatagram(char *, qint64, QHostAddress *, quint16 *){ return 0;}qint64 QHttpSocketEngine::writeDatagram(const char *, qint64, const QHostAddress &, quint16){ return 0;}bool QHttpSocketEngine::hasPendingDatagrams() const{ return false;}qint64 QHttpSocketEngine::pendingDatagramSize() const{ return 0;}#endif // QT_NO_UDPSOCKETint QHttpSocketEngine::option(SocketOption) const{ return -1;}bool QHttpSocketEngine::setOption(SocketOption, int){ return false;}/* Returns the difference between msecs and elapsed. If msecs is -1, however, -1 is returned.*/static int qt_timeout_value(int msecs, int elapsed){ if (msecs == -1) return -1; int timeout = msecs - elapsed; return timeout < 0 ? 0 : timeout;}bool QHttpSocketEngine::waitForRead(int msecs, bool *timedOut) const{ Q_D(const QHttpSocketEngine); if (!d->socket || d->socket->state() == QAbstractSocket::UnconnectedState) return false; QTime stopWatch; stopWatch.start(); // Wait for more data if nothing is available. if (!d->socket->bytesAvailable()) { if (!d->socket->waitForReadyRead(qt_timeout_value(msecs, stopWatch.elapsed()))) { if (d->socket->state() == QAbstractSocket::UnconnectedState) return true; setError(d->socket->error(), d->socket->errorString()); if (timedOut && d->socket->error() == QAbstractSocket::SocketTimeoutError) *timedOut = true; return false; } } // If we're not connected yet, wait until we are, or until an error // occurs. 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 false; } return true;}bool QHttpSocketEngine::waitForWrite(int msecs, bool *timedOut) const{ Q_D(const QHttpSocketEngine); // If we're connected, just forward the call. if (d->state == Connected) { if (d->socket->bytesToWrite()) { if (!d->socket->waitForBytesWritten(msecs)) { if (d->socket->error() == QAbstractSocket::SocketTimeoutError && timedOut) *timedOut = true; return false; } } return true; } QTime stopWatch; stopWatch.start(); // If we're not connected yet, wait until we are, and until bytes have // been received (i.e., the socket has connected, we have sent the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -