📄 qhttp.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.******************************************************************************///#define QHTTP_DEBUG#include <qplatformdefs.h>#include "qhttp.h"#ifndef QT_NO_HTTP#include "private/qobject_p.h"#include "qtcpsocket.h"#include "qsslsocket.h"#include "qtextstream.h"#include "qmap.h"#include "qlist.h"#include "qstring.h"#include "qstringlist.h"#include "qbuffer.h"#include "private/qringbuffer_p.h"#include "qcoreevent.h"#include "qurl.h"#include "qnetworkproxy.h"#include "qauthenticator.h"#include "qauthenticator_p.h"#include "qdebug.h"class QHttpRequest{public: QHttpRequest() { id = idCounter.fetchAndAdd(1); } virtual ~QHttpRequest() { } virtual void start(QHttp *) = 0; virtual bool hasRequestHeader(); virtual QHttpRequestHeader requestHeader(); virtual QIODevice *sourceDevice() = 0; virtual QIODevice *destinationDevice() = 0; int id;private: static QBasicAtomic idCounter;};class QHttpPrivate : public QObjectPrivate{public: Q_DECLARE_PUBLIC(QHttp) inline QHttpPrivate() : socket(0), reconnectAttempts(2), deleteSocket(0), state(QHttp::Unconnected), error(QHttp::NoError), port(0), mode(QHttp::ConnectionModeHttp), toDevice(0), postDevice(0), bytesDone(0), chunkedSize(-1), repost(false) { } inline ~QHttpPrivate() { while (!pending.isEmpty()) delete pending.takeFirst(); if (deleteSocket) delete socket; } // private slots void _q_startNextRequest(); void _q_slotReadyRead(); void _q_slotConnected(); void _q_slotError(QAbstractSocket::SocketError); void _q_slotClosed(); void _q_slotBytesWritten(qint64 numBytes); void _q_slotDoFinished(); void _q_slotSendRequest(); int addRequest(QHttpRequest *); void finishedWithSuccess(); void finishedWithError(const QString &detail, int errorCode); void init(); void setState(int); void closeConn(); void setSock(QTcpSocket *sock); QTcpSocket *socket; int reconnectAttempts; bool deleteSocket; QList<QHttpRequest *> pending; QHttp::State state; QHttp::Error error; QString errorString; QString hostName; quint16 port; QHttp::ConnectionMode mode; QByteArray buffer; QIODevice *toDevice; QIODevice *postDevice; qint64 bytesDone; qint64 bytesTotal; qint64 chunkedSize; QHttpRequestHeader header; bool readHeader; QString headerStr; QHttpResponseHeader response; QRingBuffer rba;#ifndef QT_NO_NETWORKPROXY QNetworkProxy proxy; QAuthenticator proxyAuthenticator;#endif QAuthenticator authenticator; bool repost;};QBasicAtomic QHttpRequest::idCounter = Q_ATOMIC_INIT(1);bool QHttpRequest::hasRequestHeader(){ return false;}QHttpRequestHeader QHttpRequest::requestHeader(){ return QHttpRequestHeader();}/**************************************************** * * QHttpNormalRequest * ****************************************************/class QHttpNormalRequest : public QHttpRequest{public: QHttpNormalRequest(const QHttpRequestHeader &h, QIODevice *d, QIODevice *t) : header(h), to(t) { is_ba = false; data.dev = d; } QHttpNormalRequest(const QHttpRequestHeader &h, QByteArray *d, QIODevice *t) : header(h), to(t) { is_ba = true; data.ba = d; } ~QHttpNormalRequest() { if (is_ba) delete data.ba; } void start(QHttp *); bool hasRequestHeader(); QHttpRequestHeader requestHeader(); QIODevice *sourceDevice(); QIODevice *destinationDevice();protected: QHttpRequestHeader header;private: union { QByteArray *ba; QIODevice *dev; } data; bool is_ba; QIODevice *to;};void QHttpNormalRequest::start(QHttp *http){ if (!http->d_func()->socket) http->d_func()->setSock(0); http->d_func()->header = header; if (is_ba) { http->d_func()->buffer = *data.ba; if (http->d_func()->buffer.size() > 0) http->d_func()->header.setContentLength(http->d_func()->buffer.size()); http->d_func()->postDevice = 0; } else { http->d_func()->buffer = QByteArray(); if (data.dev && (data.dev->isOpen() || data.dev->open(QIODevice::ReadOnly))) { http->d_func()->postDevice = data.dev; if (http->d_func()->postDevice->size() > 0) http->d_func()->header.setContentLength(http->d_func()->postDevice->size()); } else { http->d_func()->postDevice = 0; } } if (to && (to->isOpen() || to->open(QIODevice::WriteOnly))) http->d_func()->toDevice = to; else http->d_func()->toDevice = 0; http->d_func()->reconnectAttempts = 2; http->d_func()->_q_slotSendRequest();}bool QHttpNormalRequest::hasRequestHeader(){ return true;}QHttpRequestHeader QHttpNormalRequest::requestHeader(){ return header;}QIODevice *QHttpNormalRequest::sourceDevice(){ if (is_ba) return 0; return data.dev;}QIODevice *QHttpNormalRequest::destinationDevice(){ return to;}/**************************************************** * * QHttpPGHRequest * (like a QHttpNormalRequest, but for the convenience * functions put(), get() and head() -- i.e. set the * host header field correctly before sending the * request) * ****************************************************/class QHttpPGHRequest : public QHttpNormalRequest{public: QHttpPGHRequest(const QHttpRequestHeader &h, QIODevice *d, QIODevice *t) : QHttpNormalRequest(h, d, t) { } QHttpPGHRequest(const QHttpRequestHeader &h, QByteArray *d, QIODevice *t) : QHttpNormalRequest(h, d, t) { } ~QHttpPGHRequest() { } void start(QHttp *);};void QHttpPGHRequest::start(QHttp *http){ if (http->d_func()->port && http->d_func()->port != 80) header.setValue(QLatin1String("Host"), http->d_func()->hostName + QLatin1Char(':') + QString::number(http->d_func()->port)); else header.setValue(QLatin1String("Host"), http->d_func()->hostName); QHttpNormalRequest::start(http);}/**************************************************** * * QHttpSetHostRequest * ****************************************************/class QHttpSetHostRequest : public QHttpRequest{public: QHttpSetHostRequest(const QString &h, quint16 p, QHttp::ConnectionMode m) : hostName(h), port(p), mode(m) { } void start(QHttp *); QIODevice *sourceDevice() { return 0; } QIODevice *destinationDevice() { return 0; }private: QString hostName; quint16 port; QHttp::ConnectionMode mode;};void QHttpSetHostRequest::start(QHttp *http){ http->d_func()->hostName = hostName; http->d_func()->port = port; http->d_func()->mode = mode; http->d_func()->finishedWithSuccess();}/**************************************************** * * QHttpSetUserRequest * ****************************************************/class QHttpSetUserRequest : public QHttpRequest{public: QHttpSetUserRequest(const QString &userName, const QString &password) : user(userName), pass(password) { } void start(QHttp *); QIODevice *sourceDevice() { return 0; } QIODevice *destinationDevice() { return 0; }private: QString user; QString pass;};void QHttpSetUserRequest::start(QHttp *http){ http->d_func()->authenticator.setUser(user); http->d_func()->authenticator.setPassword(pass); http->d_func()->finishedWithSuccess();}#ifndef QT_NO_NETWORKPROXY/**************************************************** * * QHttpSetProxyRequest * ****************************************************/class QHttpSetProxyRequest : public QHttpRequest{public: inline QHttpSetProxyRequest(const QNetworkProxy &proxy) { this->proxy = proxy; } inline void start(QHttp *http) { http->d_func()->proxy = proxy; QString user = proxy.user(); if (!user.isEmpty()) http->d_func()->proxyAuthenticator.setUser(user); QString password = proxy.password(); if (!password.isEmpty()) http->d_func()->proxyAuthenticator.setPassword(password); http->d_func()->finishedWithSuccess(); } inline QIODevice *sourceDevice() { return 0; } inline QIODevice *destinationDevice() { return 0; }private: QNetworkProxy proxy;};#endif/**************************************************** * * QHttpSetSocketRequest * ****************************************************/class QHttpSetSocketRequest : public QHttpRequest{public: QHttpSetSocketRequest(QTcpSocket *s) : socket(s) { } void start(QHttp *); QIODevice *sourceDevice() { return 0; } QIODevice *destinationDevice() { return 0; }private: QTcpSocket *socket;};void QHttpSetSocketRequest::start(QHttp *http){ http->d_func()->setSock(socket); http->d_func()->finishedWithSuccess();}/**************************************************** * * QHttpCloseRequest * ****************************************************/class QHttpCloseRequest : public QHttpRequest{public: QHttpCloseRequest() { } void start(QHttp *); QIODevice *sourceDevice() { return 0; } QIODevice *destinationDevice() { return 0; }};void QHttpCloseRequest::start(QHttp *http)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -