summaryrefslogtreecommitdiffstats
path: root/src/network/access
diff options
context:
space:
mode:
authorJonas M. Gastal <jgastal@profusion.mobi>2011-12-22 17:42:49 -0200
committerQt by Nokia <qt-info@nokia.com>2012-01-06 23:07:26 +0100
commitb3ce4470ae2ece0c03c66684ca3d9dd13955786b (patch)
tree9e4ef3ec338cb3731bd1df66e0df4c0448a6574b /src/network/access
parent7dca461620ee6d8cce3a74acf2e1530d4497bff9 (diff)
Removing QHttp class, its tests and its usage in examples.
Task-number: QTBUG-22750 Change-Id: I161fad772bfb26797e6ee9d69da925b6747c371f Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Diffstat (limited to 'src/network/access')
-rw-r--r--src/network/access/access.pri4
-rw-r--r--src/network/access/qhttp.cpp3150
-rw-r--r--src/network/access/qhttp.h311
-rw-r--r--src/network/access/qhttpheader.cpp770
-rw-r--r--src/network/access/qhttpheader_p.h147
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp1
6 files changed, 919 insertions, 3464 deletions
diff --git a/src/network/access/access.pri b/src/network/access/access.pri
index 3d5558d334..944855e9d1 100644
--- a/src/network/access/access.pri
+++ b/src/network/access/access.pri
@@ -2,7 +2,7 @@
HEADERS += \
access/qftp.h \
- access/qhttp.h \
+ access/qhttpheader_p.h \
access/qhttpnetworkheader_p.h \
access/qhttpnetworkrequest_p.h \
access/qhttpnetworkreply_p.h \
@@ -39,7 +39,7 @@ HEADERS += \
SOURCES += \
access/qftp.cpp \
- access/qhttp.cpp \
+ access/qhttpheader.cpp \
access/qhttpnetworkheader.cpp \
access/qhttpnetworkrequest.cpp \
access/qhttpnetworkreply.cpp \
diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp
deleted file mode 100644
index 067b7f95d7..0000000000
--- a/src/network/access/qhttp.cpp
+++ /dev/null
@@ -1,3150 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.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 the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//#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"
-# include "qtimer.h"
-#endif
-
-#ifndef QT_NO_HTTP
-
-QT_BEGIN_NAMESPACE
-
-class QHttpNormalRequest;
-class QHttpRequest
-{
-public:
- QHttpRequest() : finished(false)
- { id = idCounter.fetchAndAddRelaxed(1); }
- virtual ~QHttpRequest()
- { }
-
- virtual void start(QHttp *) = 0;
- virtual bool hasRequestHeader();
- virtual QHttpRequestHeader requestHeader();
-
- virtual QIODevice *sourceDevice() = 0;
- virtual QIODevice *destinationDevice() = 0;
-
- int id;
- bool finished;
-
-private:
- static QBasicAtomicInt 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), pendingPost(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);
-#ifndef QT_NO_OPENSSL
- void _q_slotEncryptedBytesWritten(qint64 numBytes);
-#endif
- void _q_slotDoFinished();
- void _q_slotSendRequest();
- void _q_continuePost();
-
- int addRequest(QHttpNormalRequest *);
- int addRequest(QHttpRequest *);
- void finishedWithSuccess();
- void finishedWithError(const QString &detail, int errorCode);
-
- void init();
- void setState(int);
- void closeConn();
- void setSock(QTcpSocket *sock);
-
- void postMoreData();
-
- 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;
- bool hasFinishedWithError;
- bool pendingPost;
- QTimer post100ContinueTimer;
-};
-
-QBasicAtomicInt QHttpRequest::idCounter = Q_BASIC_ATOMIC_INITIALIZER(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();
- inline void setRequestHeader(const QHttpRequestHeader &h) { header = h; }
-
- 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;
-
-#ifdef QT_NO_OPENSSL
- if (mode == QHttp::ConnectionModeHttps) {
- // SSL requested but no SSL support compiled in
- http->d_func()->finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "HTTPS connection requested but SSL support not compiled in")),
- QHttp::UnknownError);
- return;
- }
-#endif
-
- 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 // QT_NO_NETWORKPROXY
-
-/****************************************************
- *
- * 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)
-{
- http->d_func()->closeConn();
-}
-
-class QHttpHeaderPrivate
-{
- Q_DECLARE_PUBLIC(QHttpHeader)
-public:
- inline virtual ~QHttpHeaderPrivate() {}
-
- QList<QPair<QString, QString> > values;
- bool valid;
- QHttpHeader *q_ptr;
-};
-
-/****************************************************
- *
- * QHttpHeader
- *
- ****************************************************/
-
-/*!
- \class QHttpHeader
- \obsolete
- \brief The QHttpHeader class contains header information for HTTP.
-
- \ingroup network
- \inmodule QtNetwork
-
- In most cases you should use the more specialized derivatives of
- this class, QHttpResponseHeader and QHttpRequestHeader, rather
- than directly using QHttpHeader.
-
- QHttpHeader provides the HTTP header fields. A HTTP header field
- consists of a name followed by a colon, a single space, and the
- field value. (See RFC 1945.) Field names are case-insensitive. A
- typical header field looks like this:
- \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 0
-
- In the API the header field name is called the "key" and the
- content is called the "value". You can get and set a header
- field's value by using its key with value() and setValue(), e.g.
- \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 1
-
- Some fields are so common that getters and setters are provided
- for them as a convenient alternative to using \l value() and
- \l setValue(), e.g. contentLength() and contentType(),
- setContentLength() and setContentType().
-
- Each header key has a \e single value associated with it. If you
- set the value for a key which already exists the previous value
- will be discarded.
-
- \sa QHttpRequestHeader QHttpResponseHeader
-*/
-
-/*!
- \fn int QHttpHeader::majorVersion() const
-
- Returns the major protocol-version of the HTTP header.
-*/
-
-/*!
- \fn int QHttpHeader::minorVersion() const
-
- Returns the minor protocol-version of the HTTP header.
-*/
-
-/*!
- Constructs an empty HTTP header.
-*/
-QHttpHeader::QHttpHeader()
- : d_ptr(new QHttpHeaderPrivate)
-{
- Q_D(QHttpHeader);
- d->q_ptr = this;
- d->valid = true;
-}
-
-/*!
- Constructs a copy of \a header.
-*/
-QHttpHeader::QHttpHeader(const QHttpHeader &header)
- : d_ptr(new QHttpHeaderPrivate)
-{
- Q_D(QHttpHeader);
- d->q_ptr = this;
- d->valid = header.d_func()->valid;
- d->values = header.d_func()->values;
-}
-
-/*!
- Constructs a HTTP header for \a str.
-
- This constructor parses the string \a str for header fields and
- adds this information. The \a str should consist of one or more
- "\r\n" delimited lines; each of these lines should have the format
- key, colon, space, value.
-*/
-QHttpHeader::QHttpHeader(const QString &str)
- : d_ptr(new QHttpHeaderPrivate)
-{
- Q_D(QHttpHeader);
- d->q_ptr = this;
- d->valid = true;
- parse(str);
-}
-
-/*! \internal
- */
-QHttpHeader::QHttpHeader(QHttpHeaderPrivate &dd, const QString &str)
- : d_ptr(&dd)
-{
- Q_D(QHttpHeader);
- d->q_ptr = this;
- d->valid = true;
- if (!str.isEmpty())
- parse(str);
-}
-
-/*! \internal
- */
-QHttpHeader::QHttpHeader(QHttpHeaderPrivate &dd, const QHttpHeader &header)
- : d_ptr(&dd)
-{
- Q_D(QHttpHeader);
- d->q_ptr = this;
- d->valid = header.d_func()->valid;
- d->values = header.d_func()->values;
-}
-/*!
- Destructor.
-*/
-QHttpHeader::~QHttpHeader()
-{
-}
-
-/*!
- Assigns \a h and returns a reference to this http header.
-*/
-QHttpHeader &QHttpHeader::operator=(const QHttpHeader &h)
-{
- Q_D(QHttpHeader);
- d->values = h.d_func()->values;
- d->valid = h.d_func()->valid;
- return *this;
-}
-
-/*!
- Returns true if the HTTP header is valid; otherwise returns false.
-
- A QHttpHeader is invalid if it was created by parsing a malformed string.
-*/
-bool QHttpHeader::isValid() const
-{
- Q_D(const QHttpHeader);
- return d->valid;
-}
-
-/*! \internal
- Parses the HTTP header string \a str for header fields and adds
- the keys/values it finds. If the string is not parsed successfully
- the QHttpHeader becomes \link isValid() invalid\endlink.
-
- Returns true if \a str was successfully parsed; otherwise returns false.
-
- \sa toString()
-*/
-bool QHttpHeader::parse(const QString &str)
-{
- Q_D(QHttpHeader);
- QStringList lst;
- int pos = str.indexOf(QLatin1Char('\n'));
- if (pos > 0 && str.at(pos - 1) == QLatin1Char('\r'))
- lst = str.trimmed().split(QLatin1String("\r\n"));
- else
- lst = str.trimmed().split(QLatin1String("\n"));
- lst.removeAll(QString()); // No empties
-
- if (lst.isEmpty())
- return true;
-
- QStringList lines;
- QStringList::Iterator it = lst.begin();
- for (; it != lst.end(); ++it) {
- if (!(*it).isEmpty()) {
- if ((*it)[0].isSpace()) {
- if (!lines.isEmpty()) {
- lines.last() += QLatin1Char(' ');
- lines.last() += (*it).trimmed();
- }
- } else {
- lines.append((*it));
- }
- }
- }
-
- int number = 0;
- it = lines.begin();
- for (; it != lines.end(); ++it) {
- if (!parseLine(*it, number++)) {
- d->valid = false;
- return false;
- }
- }
- return true;
-}
-
-/*! \internal
-*/
-void QHttpHeader::setValid(bool v)
-{
- Q_D(QHttpHeader);
- d->valid = v;
-}
-
-/*!
- Returns the first value for the entry with the given \a key. If no entry
- has this \a key, an empty string is returned.
-
- \sa setValue() removeValue() hasKey() keys()
-*/
-QString QHttpHeader::value(const QString &key) const
-{
- Q_D(const QHttpHeader);
- QString lowercaseKey = key.toLower();
- QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
- while (it != d->values.constEnd()) {
- if ((*it).first.toLower() == lowercaseKey)
- return (*it).second;
- ++it;
- }
- return QString();
-}
-
-/*!
- Returns all the entries with the given \a key. If no entry
- has this \a key, an empty string list is returned.
-*/
-QStringList QHttpHeader::allValues(const QString &key) const
-{
- Q_D(const QHttpHeader);
- QString lowercaseKey = key.toLower();
- QStringList valueList;
- QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
- while (it != d->values.constEnd()) {
- if ((*it).first.toLower() == lowercaseKey)
- valueList.append((*it).second);
- ++it;
- }
- return valueList;
-}
-
-/*!
- Returns a list of the keys in the HTTP header.
-
- \sa hasKey()
-*/
-QStringList QHttpHeader::keys() const
-{
- Q_D(const QHttpHeader);
- QStringList keyList;
- QSet<QString> seenKeys;
- QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
- while (it != d->values.constEnd()) {
- const QString &key = (*it).first;
- QString lowercaseKey = key.toLower();
- if (!seenKeys.contains(lowercaseKey)) {
- keyList.append(key);
- seenKeys.insert(lowercaseKey);
- }
- ++it;
- }
- return keyList;
-}
-
-/*!
- Returns true if the HTTP header has an entry with the given \a
- key; otherwise returns false.
-
- \sa value() setValue() keys()
-*/
-bool QHttpHeader::hasKey(const QString &key) const
-{
- Q_D(const QHttpHeader);
- QString lowercaseKey = key.toLower();
- QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
- while (it != d->values.constEnd()) {
- if ((*it).first.toLower() == lowercaseKey)
- return true;
- ++it;
- }
- return false;
-}
-
-/*!
- Sets the value of the entry with the \a key to \a value.
-
- If no entry with \a key exists, a new entry with the given \a key
- and \a value is created. If an entry with the \a key already
- exists, the first value is discarded and replaced with the given
- \a value.
-
- \sa value() hasKey() removeValue()
-*/
-void QHttpHeader::setValue(const QString &key, const QString &value)
-{
- Q_D(QHttpHeader);
- QString lowercaseKey = key.toLower();
- QList<QPair<QString, QString> >::Iterator it = d->values.begin();
- while (it != d->values.end()) {
- if ((*it).first.toLower() == lowercaseKey) {
- (*it).second = value;
- return;
- }
- ++it;
- }
- // not found so add
- addValue(key, value);
-}
-
-/*!
- Sets the header entries to be the list of key value pairs in \a values.
-*/
-void QHttpHeader::setValues(const QList<QPair<QString, QString> > &values)
-{
- Q_D(QHttpHeader);
- d->values = values;
-}
-
-/*!
- Adds a new entry with the \a key and \a value.
-*/
-void QHttpHeader::addValue(const QString &key, const QString &value)
-{
- Q_D(QHttpHeader);
- d->values.append(qMakePair(key, value));
-}
-
-/*!
- Returns all the entries in the header.
-*/
-QList<QPair<QString, QString> > QHttpHeader::values() const
-{
- Q_D(const QHttpHeader);
- return d->values;
-}
-
-/*!
- Removes the entry with the key \a key from the HTTP header.
-
- \sa value() setValue()
-*/
-void QHttpHeader::removeValue(const QString &key)
-{
- Q_D(QHttpHeader);
- QString lowercaseKey = key.toLower();
- QList<QPair<QString, QString> >::Iterator it = d->values.begin();
- while (it != d->values.end()) {
- if ((*it).first.toLower() == lowercaseKey) {
- d->values.erase(it);
- return;
- }
- ++it;
- }
-}
-
-/*!
- Removes all the entries with the key \a key from the HTTP header.
-*/
-void QHttpHeader::removeAllValues(const QString &key)
-{
- Q_D(QHttpHeader);
- QString lowercaseKey = key.toLower();
- QList<QPair<QString, QString> >::Iterator it = d->values.begin();
- while (it != d->values.end()) {
- if ((*it).first.toLower() == lowercaseKey) {
- it = d->values.erase(it);
- continue;
- }
- ++it;
- }
-}
-
-/*! \internal
- Parses the single HTTP header line \a line which has the format
- key, colon, space, value, and adds key/value to the headers. The
- linenumber is \a number. Returns true if the line was successfully
- parsed and the key/value added; otherwise returns false.
-
- \sa parse()
-*/
-bool QHttpHeader::parseLine(const QString &line, int)
-{
- int i = line.indexOf(QLatin1Char(':'));
- if (i == -1)
- return false;
-
- addValue(line.left(i).trimmed(), line.mid(i + 1).trimmed());
-
- return true;
-}
-
-/*!
- Returns a string representation of the HTTP header.
-
- The string is suitable for use by the constructor that takes a
- QString. It consists of lines with the format: key, colon, space,
- value, "\r\n".
-*/
-QString QHttpHeader::toString() const
-{
- Q_D(const QHttpHeader);
- if (!isValid())
- return QLatin1String("");
-
- QString ret = QLatin1String("");
-
- QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
- while (it != d->values.constEnd()) {
- ret += (*it).first + QLatin1String(": ") + (*it).second + QLatin1String("\r\n");
- ++it;
- }
- return ret;
-}
-
-/*!
- Returns true if the header has an entry for the special HTTP
- header field \c content-length; otherwise returns false.
-
- \sa contentLength() setContentLength()
-*/
-bool QHttpHeader::hasContentLength() const
-{
- return hasKey(QLatin1String("content-length"));
-}
-
-/*!
- Returns the value of the special HTTP header field \c
- content-length.
-
- \sa setContentLength() hasContentLength()
-*/
-uint QHttpHeader::contentLength() const
-{
- return value(QLatin1String("content-length")).toUInt();
-}
-
-/*!
- Sets the value of the special HTTP header field \c content-length
- to \a len.
-
- \sa contentLength() hasContentLength()
-*/
-void QHttpHeader::setContentLength(int len)
-{
- setValue(QLatin1String("content-length"), QString::number(len));
-}
-
-/*!
- Returns true if the header has an entry for the special HTTP
- header field \c content-type; otherwise returns false.
-
- \sa contentType() setContentType()
-*/
-bool QHttpHeader::hasContentType() const
-{
- return hasKey(QLatin1String("content-type"));
-}
-
-/*!
- Returns the value of the special HTTP header field \c content-type.
-
- \sa setContentType() hasContentType()
-*/
-QString QHttpHeader::contentType() const
-{
- QString type = value(QLatin1String("content-type"));
- if (type.isEmpty())
- return QString();
-
- int pos = type.indexOf(QLatin1Char(';'));
- if (pos == -1)
- return type;
-
- return type.left(pos).trimmed();
-}
-
-/*!
- Sets the value of the special HTTP header field \c content-type to
- \a type.
-
- \sa contentType() hasContentType()
-*/
-void QHttpHeader::setContentType(const QString &type)
-{
- setValue(QLatin1String("content-type"), type);
-}
-
-class QHttpResponseHeaderPrivate : public QHttpHeaderPrivate
-{
- Q_DECLARE_PUBLIC(QHttpResponseHeader)
-public:
- int statCode;
- QString reasonPhr;
- int majVer;
- int minVer;
-};
-
-/****************************************************
- *
- * QHttpResponseHeader
- *
- ****************************************************/
-
-/*!
- \class QHttpResponseHeader
- \obsolete
- \brief The QHttpResponseHeader class contains response header information for HTTP.
-
- \ingroup network
- \inmodule QtNetwork
-
- This class is used by the QHttp class to report the header
- information that the client received from the server.
-
- HTTP responses have a status code that indicates the status of the
- response. This code is a 3-digit integer result code (for details
- see to RFC 1945). In addition to the status code, you can also
- specify a human-readable text that describes the reason for the
- code ("reason phrase"). This class allows you to get the status
- code and the reason phrase.
-
- \sa QHttpRequestHeader, QHttp, {HTTP Example}
-*/
-
-/*!
- Constructs an empty HTTP response header.
-*/
-QHttpResponseHeader::QHttpResponseHeader()
- : QHttpHeader(*new QHttpResponseHeaderPrivate)
-{
- setValid(false);
-}
-
-/*!
- Constructs a copy of \a header.
-*/
-QHttpResponseHeader::QHttpResponseHeader(const QHttpResponseHeader &header)
- : QHttpHeader(*new QHttpResponseHeaderPrivate, header)
-{
- Q_D(QHttpResponseHeader);
- d->statCode = header.d_func()->statCode;
- d->reasonPhr = header.d_func()->reasonPhr;
- d->majVer = header.d_func()->majVer;
- d->minVer = header.d_func()->minVer;
-}
-
-/*!
- Copies the contents of \a header into this QHttpResponseHeader.
-*/
-QHttpResponseHeader &QHttpResponseHeader::operator=(const QHttpResponseHeader &header)
-{
- Q_D(QHttpResponseHeader);
- QHttpHeader::operator=(header);
- d->statCode = header.d_func()->statCode;
- d->reasonPhr = header.d_func()->reasonPhr;
- d->majVer = header.d_func()->majVer;
- d->minVer = header.d_func()->minVer;
- return *this;
-}
-
-/*!
- Constructs a HTTP response header from the string \a str. The
- string is parsed and the information is set. The \a str should
- consist of one or more "\r\n" delimited lines; the first line should be the
- status-line (format: HTTP-version, space, status-code, space,
- reason-phrase); each of remaining lines should have the format key, colon,
- space, value.
-*/
-QHttpResponseHeader::QHttpResponseHeader(const QString &str)
- : QHttpHeader(*new QHttpResponseHeaderPrivate)
-{
- parse(str);
-}
-
-/*!
- \since 4.1
-
- Constructs a QHttpResponseHeader, setting the status code to \a code, the
- reason phrase to \a text and the protocol-version to \a majorVer and \a
- minorVer.
-
- \sa statusCode() reasonPhrase() majorVersion() minorVersion()
-*/
-QHttpResponseHeader::QHttpResponseHeader(int code, const QString &text, int majorVer, int minorVer)
- : QHttpHeader(*new QHttpResponseHeaderPrivate)
-{
- setStatusLine(code, text, majorVer, minorVer);
-}
-
-/*!
- \since 4.1
-
- Sets the status code to \a code, the reason phrase to \a text and
- the protocol-version to \a majorVer and \a minorVer.
-
- \sa statusCode() reasonPhrase() majorVersion() minorVersion()
-*/
-void QHttpResponseHeader::setStatusLine(int code, const QString &text, int majorVer, int minorVer)
-{
- Q_D(QHttpResponseHeader);
- setValid(true);
- d->statCode = code;
- d->reasonPhr = text;
- d->majVer = majorVer;
- d->minVer = minorVer;
-}
-
-/*!
- Returns the status code of the HTTP response header.
-
- \sa reasonPhrase() majorVersion() minorVersion()
-*/
-int QHttpResponseHeader::statusCode() const
-{
- Q_D(const QHttpResponseHeader);
- return d->statCode;
-}
-
-/*!
- Returns the reason phrase of the HTTP response header.
-
- \sa statusCode() majorVersion() minorVersion()
-*/
-QString QHttpResponseHeader::reasonPhrase() const
-{
- Q_D(const QHttpResponseHeader);
- return d->reasonPhr;
-}
-
-/*!
- Returns the major protocol-version of the HTTP response header.
-
- \sa minorVersion() statusCode() reasonPhrase()
-*/
-int QHttpResponseHeader::majorVersion() const
-{
- Q_D(const QHttpResponseHeader);
- return d->majVer;
-}
-
-/*!
- Returns the minor protocol-version of the HTTP response header.
-
- \sa majorVersion() statusCode() reasonPhrase()
-*/
-int QHttpResponseHeader::minorVersion() const
-{
- Q_D(const QHttpResponseHeader);
- return d->minVer;
-}
-
-/*! \internal
-*/
-bool QHttpResponseHeader::parseLine(const QString &line, int number)
-{
- Q_D(QHttpResponseHeader);
- if (number != 0)
- return QHttpHeader::parseLine(line, number);
-
- QString l = line.simplified();
- if (l.length() < 10)
- return false;
-
- if (l.left(5) == QLatin1String("HTTP/") && l[5].isDigit() && l[6] == QLatin1Char('.') &&
- l[7].isDigit() && l[8] == QLatin1Char(' ') && l[9].isDigit()) {
- d->majVer = l[5].toLatin1() - '0';
- d->minVer = l[7].toLatin1() - '0';
-
- int pos = l.indexOf(QLatin1Char(' '), 9);
- if (pos != -1) {
- d->reasonPhr = l.mid(pos + 1);
- d->statCode = l.mid(9, pos - 9).toInt();
- } else {
- d->statCode = l.mid(9).toInt();
- d->reasonPhr.clear();
- }
- } else {
- return false;
- }
-
- return true;
-}
-
-/*! \reimp
-*/
-QString QHttpResponseHeader::toString() const
-{
- Q_D(const QHttpResponseHeader);
- QString ret(QLatin1String("HTTP/%1.%2 %3 %4\r\n%5\r\n"));
- return ret.arg(d->majVer).arg(d->minVer).arg(d->statCode).arg(d->reasonPhr).arg(QHttpHeader::toString());
-}
-
-class QHttpRequestHeaderPrivate : public QHttpHeaderPrivate
-{
- Q_DECLARE_PUBLIC(QHttpRequestHeader)
-public:
- QString m;
- QString p;
- int majVer;
- int minVer;
-};
-
-/****************************************************
- *
- * QHttpRequestHeader
- *
- ****************************************************/
-
-/*!
- \class QHttpRequestHeader
- \obsolete
- \brief The QHttpRequestHeader class contains request header information for HTTP.
-
- \ingroup network
- \inmodule QtNetwork
-
- This class is used in the QHttp class to report the header
- information if the client requests something from the server.
-
- HTTP requests have a method which describes the request's action.
- The most common requests are "GET" and "POST". In addition to the
- request method the header also includes a request-URI to specify
- the location for the method to use.
-
- The method, request-URI and protocol-version can be set using a
- constructor or later using setRequest(). The values can be
- obtained using method(), path(), majorVersion() and
- minorVersion().
-
- Note that the request-URI must be in the format expected by the
- HTTP server. That is, all reserved characters must be encoded in
- %HH (where HH are two hexadecimal digits). See
- QUrl::toPercentEncoding() for more information.
-
- Important inherited functions: setValue() and value().
-
- \sa QHttpResponseHeader QHttp
-*/
-
-/*!
- Constructs an empty HTTP request header.
-*/
-QHttpRequestHeader::QHttpRequestHeader()
- : QHttpHeader(*new QHttpRequestHeaderPrivate)
-{
- setValid(false);
-}
-
-/*!
- Constructs a HTTP request header for the method \a method, the
- request-URI \a path and the protocol-version \a majorVer and \a
- minorVer. The \a path argument must be properly encoded for an
- HTTP request.
-*/
-QHttpRequestHeader::QHttpRequestHeader(const QString &method, const QString &path, int majorVer, int minorVer)
- : QHttpHeader(*new QHttpRequestHeaderPrivate)
-{
- Q_D(QHttpRequestHeader);
- d->m = method;
- d->p = path;
- d->majVer = majorVer;
- d->minVer = minorVer;
-}
-
-/*!
- Constructs a copy of \a header.
-*/
-QHttpRequestHeader::QHttpRequestHeader(const QHttpRequestHeader &header)
- : QHttpHeader(*new QHttpRequestHeaderPrivate, header)
-{
- Q_D(QHttpRequestHeader);
- d->m = header.d_func()->m;
- d->p = header.d_func()->p;
- d->majVer = header.d_func()->majVer;
- d->minVer = header.d_func()->minVer;
-}
-
-/*!
- Copies the content of \a header into this QHttpRequestHeader
-*/
-QHttpRequestHeader &QHttpRequestHeader::operator=(const QHttpRequestHeader &header)
-{
- Q_D(QHttpRequestHeader);
- QHttpHeader::operator=(header);
- d->m = header.d_func()->m;
- d->p = header.d_func()->p;
- d->majVer = header.d_func()->majVer;
- d->minVer = header.d_func()->minVer;
- return *this;
-}
-
-/*!
- Constructs a HTTP request header from the string \a str. The \a
- str should consist of one or more "\r\n" delimited lines; the first line
- should be the request-line (format: method, space, request-URI, space
- HTTP-version); each of the remaining lines should have the format key,
- colon, space, value.
-*/
-QHttpRequestHeader::QHttpRequestHeader(const QString &str)
- : QHttpHeader(*new QHttpRequestHeaderPrivate)
-{
- parse(str);
-}
-
-/*!
- This function sets the request method to \a method, the
- request-URI to \a path and the protocol-version to \a majorVer and
- \a minorVer. The \a path argument must be properly encoded for an
- HTTP request.
-
- \sa method() path() majorVersion() minorVersion()
-*/
-void QHttpRequestHeader::setRequest(const QString &method, const QString &path, int majorVer, int minorVer)
-{
- Q_D(QHttpRequestHeader);
- setValid(true);
- d->m = method;
- d->p = path;
- d->majVer = majorVer;
- d->minVer = minorVer;
-}
-
-/*!
- Returns the method of the HTTP request header.
-
- \sa path() majorVersion() minorVersion() setRequest()
-*/
-QString QHttpRequestHeader::method() const
-{
- Q_D(const QHttpRequestHeader);
- return d->m;
-}
-
-/*!
- Returns the request-URI of the HTTP request header.
-
- \sa method() majorVersion() minorVersion() setRequest()
-*/
-QString QHttpRequestHeader::path() const
-{
- Q_D(const QHttpRequestHeader);
- return d->p;
-}
-
-/*!
- Returns the major protocol-version of the HTTP request header.
-
- \sa minorVersion() method() path() setRequest()
-*/
-int QHttpRequestHeader::majorVersion() const
-{
- Q_D(const QHttpRequestHeader);
- return d->majVer;
-}
-
-/*!
- Returns the minor protocol-version of the HTTP request header.
-
- \sa majorVersion() method() path() setRequest()
-*/
-int QHttpRequestHeader::minorVersion() const
-{
- Q_D(const QHttpRequestHeader);
- return d->minVer;
-}
-
-/*! \internal
-*/
-bool QHttpRequestHeader::parseLine(const QString &line, int number)
-{
- Q_D(QHttpRequestHeader);
- if (number != 0)
- return QHttpHeader::parseLine(line, number);
-
- QStringList lst = line.simplified().split(QLatin1String(" "));
- if (lst.count() > 0) {
- d->m = lst[0];
- if (lst.count() > 1) {
- d->p = lst[1];
- if (lst.count() > 2) {
- QString v = lst[2];
- if (v.length() >= 8 && v.left(5) == QLatin1String("HTTP/") &&
- v[5].isDigit() && v[6] == QLatin1Char('.') && v[7].isDigit()) {
- d->majVer = v[5].toLatin1() - '0';
- d->minVer = v[7].toLatin1() - '0';
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-/*! \reimp
-*/
-QString QHttpRequestHeader::toString() const
-{
- Q_D(const QHttpRequestHeader);
- QString first(QLatin1String("%1 %2"));
- QString last(QLatin1String(" HTTP/%3.%4\r\n%5\r\n"));
- return first.arg(d->m).arg(d->p) +
- last.arg(d->majVer).arg(d->minVer).arg(QHttpHeader::toString());
-}
-
-
-/****************************************************
- *
- * QHttp
- *
- ****************************************************/
-/*!
- \class QHttp
- \obsolete
- \reentrant
-
- \brief The QHttp class provides an implementation of the HTTP protocol.
-
- \ingroup network
- \inmodule QtNetwork
-
-
- This class provides a direct interface to HTTP that allows you to
- download and upload data with the HTTP protocol.
- However, for new applications, it is
- recommended to use QNetworkAccessManager and QNetworkReply, as
- those classes possess a simpler, yet more powerful API
- and a more modern protocol implementation.
-
- The class works asynchronously, so there are no blocking
- functions. If an operation cannot be executed immediately, the
- function will still return straight away and the operation will be
- scheduled for later execution. The results of scheduled operations
- are reported via signals. This approach depends on the event loop
- being in operation.
-
- The operations that can be scheduled (they are called "requests"
- in the rest of the documentation) are the following: setHost(),
- get(), post(), head() and request().
-
- All of these requests return a unique identifier that allows you
- to keep track of the request that is currently executed. When the
- execution of a request starts, the requestStarted() signal with
- the identifier is emitted and when the request is finished, the
- requestFinished() signal is emitted with the identifier and a bool
- that indicates if the request finished with an error.
-
- To make an HTTP request you must set up suitable HTTP headers. The
- following example demonstrates how to request the main HTML page
- from the Qt website (i.e., the URL \c http://qt.nokia.com/index.html):
-
- \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 2
-
- For the common HTTP requests \c GET, \c POST and \c HEAD, QHttp
- provides the convenience functions get(), post() and head(). They
- already use a reasonable header and if you don't have to set
- special header fields, they are easier to use. The above example
- can also be written as:
-
- \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 3
-
- For this example the following sequence of signals is emitted
- (with small variations, depending on network traffic, etc.):
-
- \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 4
-
- The dataSendProgress() and dataReadProgress() signals in the above
- example are useful if you want to show a \link QProgressBar
- progress bar\endlink to inform the user about the progress of the
- download. The second argument is the total size of data. In
- certain cases it is not possible to know the total amount in
- advance, in which case the second argument is 0. (If you connect
- to a QProgressBar a total of 0 results in a busy indicator.)
-
- When the response header is read, it is reported with the
- responseHeaderReceived() signal.
-
- The readyRead() signal tells you that there is data ready to be
- read. The amount of data can then be queried with the
- bytesAvailable() function and it can be read with the read()
- or readAll() functions.
-
- If an error occurs during the execution of one of the commands in
- a sequence of commands, all the pending commands (i.e. scheduled,
- but not yet executed commands) are cleared and no signals are
- emitted for them.
-
- For example, if you have the following sequence of requests
-
- \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 5
-
- and the get() request fails because the host lookup fails, then
- the post() request is never executed and the signals would look
- like this:
-
- \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 6
-
- You can then get details about the error with the error() and
- errorString() functions. Note that only unexpected behavior, like
- network failure is considered as an error. If the server response
- contains an error status, like a 404 response, this is reported as
- a normal response case. So you should always check the \link
- QHttpResponseHeader::statusCode() status code \endlink of the
- response header.
-
- The functions currentId() and currentRequest() provide more
- information about the currently executing request.
-
- The functions hasPendingRequests() and clearPendingRequests()
- allow you to query and clear the list of pending requests.
-
- \sa QFtp, QNetworkAccessManager, QNetworkRequest, QNetworkReply,
- {HTTP Example}, {Torrent Example}
-*/
-
-/*!
- Constructs a QHttp object. The \a parent parameter is passed on
- to the QObject constructor.
-*/
-QHttp::QHttp(QObject *parent)
- : QObject(*new QHttpPrivate, parent)
-{
- Q_D(QHttp);
- d->init();
-}
-
-/*!
- Constructs a QHttp object. Subsequent requests are done by
- connecting to the server \a hostName on port \a port.
-
- The \a parent parameter is passed on to the QObject constructor.
-
- \sa setHost()
-*/
-QHttp::QHttp(const QString &hostName, quint16 port, QObject *parent)
- : QObject(*new QHttpPrivate, parent)
-{
- Q_D(QHttp);
- d->init();
-
- d->hostName = hostName;
- d->port = port;
-}
-
-/*!
- Constructs a QHttp object. Subsequent requests are done by
- connecting to the server \a hostName on port \a port using the
- connection mode \a mode.
-
- If port is 0, it will use the default port for the \a mode used
- (80 for Http and 443 for Https).
-
- The \a parent parameter is passed on to the QObject constructor.
-
- \sa setHost()
-*/
-QHttp::QHttp(const QString &hostName, ConnectionMode mode, quint16 port, QObject *parent)
- : QObject(*new QHttpPrivate, parent)
-{
- Q_D(QHttp);
- d->init();
-
- d->hostName = hostName;
- if (port == 0)
- port = (mode == ConnectionModeHttp) ? 80 : 443;
- d->port = port;
- d->mode = mode;
-}
-
-void QHttpPrivate::init()
-{
- Q_Q(QHttp);
- errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Unknown error"));
- QMetaObject::invokeMethod(q, "_q_slotDoFinished", Qt::QueuedConnection);
- post100ContinueTimer.setSingleShot(true);
- QObject::connect(&post100ContinueTimer, SIGNAL(timeout()), q, SLOT(_q_continuePost()));
-}
-
-/*!
- Destroys the QHttp object. If there is an open connection, it is
- closed.
-*/
-QHttp::~QHttp()
-{
- abort();
-}
-
-/*!
- \enum QHttp::ConnectionMode
- \since 4.3
-
- This enum is used to specify the mode of connection to use:
-
- \value ConnectionModeHttp The connection is a regular HTTP connection to the server
- \value ConnectionModeHttps The HTTPS protocol is used and the connection is encrypted using SSL.
-
- When using the HTTPS mode, care should be taken to connect to the sslErrors signal, and
- handle possible SSL errors.
-
- \sa QSslSocket
-*/
-
-/*!
- \enum QHttp::State
-
- This enum is used to specify the state the client is in:
-
- \value Unconnected There is no connection to the host.
- \value HostLookup A host name lookup is in progress.
- \value Connecting An attempt to connect to the host is in progress.
- \value Sending The client is sending its request to the server.
- \value Reading The client's request has been sent and the client
- is reading the server's response.
- \value Connected The connection to the host is open, but the client is
- neither sending a request, nor waiting for a response.
- \value Closing The connection is closing down, but is not yet
- closed. (The state will be \c Unconnected when the connection is
- closed.)
-
- \sa stateChanged() state()
-*/
-
-/*! \enum QHttp::Error
-
- This enum identifies the error that occurred.
-
- \value NoError No error occurred.
- \value HostNotFound The host name lookup failed.
- \value ConnectionRefused The server refused the connection.
- \value UnexpectedClose The server closed the connection unexpectedly.
- \value InvalidResponseHeader The server sent an invalid response header.
- \value WrongContentLength The client could not read the content correctly
- because an error with respect to the content length occurred.
- \value Aborted The request was aborted with abort().
- \value ProxyAuthenticationRequiredError QHttp is using a proxy, and the
- proxy server requires authentication to establish a connection.
- \value AuthenticationRequiredError The web server requires authentication
- to complete the request.
- \value UnknownError An error other than those specified above
- occurred.
-
- \sa error()
-*/
-
-/*!
- \fn void QHttp::stateChanged(int state)
-
- This signal is emitted when the state of the QHttp object changes.
- The argument \a state is the new state of the connection; it is
- one of the \l State values.
-
- This usually happens when a request is started, but it can also
- happen when the server closes the connection or when a call to
- close() succeeded.
-
- \sa get() post() head() request() close() state() State
-*/
-
-/*!
- \fn void QHttp::responseHeaderReceived(const QHttpResponseHeader &resp);
-
- This signal is emitted when the HTTP header of a server response
- is available. The header is passed in \a resp.
-
- \sa get() post() head() request() readyRead()
-*/
-
-/*!
- \fn void QHttp::readyRead(const QHttpResponseHeader &resp)
-
- This signal is emitted when there is new response data to read.
-
- If you specified a device in the request where the data should be
- written to, then this signal is \e not emitted; instead the data
- is written directly to the device.
-
- The response header is passed in \a resp.
-
- You can read the data with the readAll() or read() functions
-
- This signal is useful if you want to process the data in chunks as
- soon as it becomes available. If you are only interested in the
- complete data, just connect to the requestFinished() signal and
- read the data then instead.
-
- \sa get() post() request() readAll() read() bytesAvailable()
-*/
-
-/*!
- \fn void QHttp::dataSendProgress(int done, int total)
-
- This signal is emitted when this object sends data to a HTTP
- server to inform it about the progress of the upload.
-
- \a done is the amount of data that has already arrived and \a
- total is the total amount of data. It is possible that the total
- amount of data that should be transferred cannot be determined, in
- which case \a total is 0.(If you connect to a QProgressBar, the
- progress bar shows a busy indicator if the total is 0).
-
- \warning \a done and \a total are not necessarily the size in
- bytes, since for large files these values might need to be
- "scaled" to avoid overflow.
-
- \sa dataReadProgress(), post(), request(), QProgressBar
-*/
-
-/*!
- \fn void QHttp::dataReadProgress(int done, int total)
-
- This signal is emitted when this object reads data from a HTTP
- server to indicate the current progress of the download.
-
- \a done is the amount of data that has already arrived and \a
- total is the total amount of data. It is possible that the total
- amount of data that should be transferred cannot be determined, in
- which case \a total is 0.(If you connect to a QProgressBar, the
- progress bar shows a busy indicator if the total is 0).
-
- \warning \a done and \a total are not necessarily the size in
- bytes, since for large files these values might need to be
- "scaled" to avoid overflow.
-
- \sa dataSendProgress() get() post() request() QProgressBar
-*/
-
-/*!
- \fn void QHttp::requestStarted(int id)
-
- This signal is emitted when processing the request identified by
- \a id starts.
-
- \sa requestFinished() done()
-*/
-
-/*!
- \fn void QHttp::requestFinished(int id, bool error)
-
- This signal is emitted when processing the request identified by
- \a id has finished. \a error is true if an error occurred during
- the processing; otherwise \a error is false.
-
- \sa requestStarted() done() error() errorString()
-*/
-
-/*!
- \fn void QHttp::done(bool error)
-
- This signal is emitted when the last pending request has finished;
- (it is emitted after the last request's requestFinished() signal).
- \a error is true if an error occurred during the processing;
- otherwise \a error is false.
-
- \sa requestFinished() error() errorString()
-*/
-
-#ifndef QT_NO_NETWORKPROXY
-
-/*!
- \fn void QHttp::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator)
- \since 4.3
-
- This signal can be emitted when a \a proxy that requires
- authentication is used. The \a authenticator object can then be
- filled in with the required details to allow authentication and
- continue the connection.
-
- \note It is not possible to use a QueuedConnection to connect to
- this signal, as the connection will fail if the authenticator has
- not been filled in with new information when the signal returns.
-
- \sa QAuthenticator, QNetworkProxy
-*/
-
-#endif
-
-/*!
- \fn void QHttp::authenticationRequired(const QString &hostname, quint16 port, QAuthenticator *authenticator)
- \since 4.3
-
- This signal can be emitted when a web server on a given \a hostname and \a
- port requires authentication. The \a authenticator object can then be
- filled in with the required details to allow authentication and continue
- the connection.
-
- \note It is not possible to use a QueuedConnection to connect to
- this signal, as the connection will fail if the authenticator has
- not been filled in with new information when the signal returns.
-
- \sa QAuthenticator, QNetworkProxy
-*/
-
-/*!
- \fn void QHttp::sslErrors(const QList<QSslError> &errors)
- \since 4.3
-
- Forwards the sslErrors signal from the QSslSocket used in QHttp. \a errors
- is the list of errors that occurred during the SSL handshake. Unless you
- call ignoreSslErrors() from within a slot connected to this signal when an
- error occurs, QHttp will tear down the connection immediately after
- emitting the signal.
-
- \sa QSslSocket QSslSocket::ignoreSslErrors()
-*/
-
-/*!
- Aborts the current request and deletes all scheduled requests.
-
- For the current request, the requestFinished() signal with the \c
- error argument \c true is emitted. For all other requests that are
- affected by the abort(), no signals are emitted.
-
- Since this slot also deletes the scheduled requests, there are no
- requests left and the done() signal is emitted (with the \c error
- argument \c true).
-
- \sa clearPendingRequests()
-*/
-void QHttp::abort()
-{
- Q_D(QHttp);
- if (d->pending.isEmpty())
- return;
-
- d->finishedWithError(tr("Request aborted"), Aborted);
- clearPendingRequests();
- if (d->socket)
- d->socket->abort();
- d->closeConn();
-}
-
-/*!
- Returns the number of bytes that can be read from the response
- content at the moment.
-
- \sa get() post() request() readyRead() read() readAll()
-*/
-qint64 QHttp::bytesAvailable() const
-{
- Q_D(const QHttp);
-#if defined(QHTTP_DEBUG)
- qDebug("QHttp::bytesAvailable(): %d bytes", (int)d->rba.size());
-#endif
- return qint64(d->rba.size());
-}
-
-/*!
- Reads \a maxlen bytes from the response content into \a data and
- returns the number of bytes read. Returns -1 if an error occurred.
-
- \sa get() post() request() readyRead() bytesAvailable() readAll()
-*/
-qint64 QHttp::read(char *data, qint64 maxlen)
-{
- Q_D(QHttp);
- if (data == 0 && maxlen != 0) {
- qWarning("QHttp::read: Null pointer error");
- return -1;
- }
- if (maxlen >= d->rba.size())
- maxlen = d->rba.size();
- int readSoFar = 0;
- while (!d->rba.isEmpty() && readSoFar < maxlen) {
- int nextBlockSize = d->rba.nextDataBlockSize();
- int bytesToRead = qMin<qint64>(maxlen - readSoFar, nextBlockSize);
- memcpy(data + readSoFar, d->rba.readPointer(), bytesToRead);
- d->rba.free(bytesToRead);
- readSoFar += bytesToRead;
- }
-
- d->bytesDone += maxlen;
-#if defined(QHTTP_DEBUG)
- qDebug("QHttp::read(): read %lld bytes (%lld bytes done)", maxlen, d->bytesDone);
-#endif
- return maxlen;
-}
-
-/*!
- Reads all the bytes from the response content and returns them.
-
- \sa get() post() request() readyRead() bytesAvailable() read()
-*/
-QByteArray QHttp::readAll()
-{
- qint64 avail = bytesAvailable();
- QByteArray tmp;
- tmp.resize(int(avail));
- qint64 got = read(tmp.data(), int(avail));
- tmp.resize(got);
- return tmp;
-}
-
-/*!
- Returns the identifier of the HTTP request being executed or 0 if
- there is no request being executed (i.e. they've all finished).
-
- \sa currentRequest()
-*/
-int QHttp::currentId() const
-{
- Q_D(const QHttp);
- if (d->pending.isEmpty())
- return 0;
- return d->pending.first()->id;
-}
-
-/*!
- Returns the request header of the HTTP request being executed. If
- the request is one issued by setHost() or close(), it
- returns an invalid request header, i.e.
- QHttpRequestHeader::isValid() returns false.
-
- \sa currentId()
-*/
-QHttpRequestHeader QHttp::currentRequest() const
-{
- Q_D(const QHttp);
- if (!d->pending.isEmpty()) {
- QHttpRequest *r = d->pending.first();
- if (r->hasRequestHeader())
- return r->requestHeader();
- }
- return QHttpRequestHeader();
-}
-
-/*!
- Returns the received response header of the most recently finished HTTP
- request. If no response has yet been received
- QHttpResponseHeader::isValid() will return false.
-
- \sa currentRequest()
-*/
-QHttpResponseHeader QHttp::lastResponse() const
-{
- Q_D(const QHttp);
- return d->response;
-}
-
-/*!
- Returns the QIODevice pointer that is used as the data source of the HTTP
- request being executed. If there is no current request or if the request
- does not use an IO device as the data source, this function returns 0.
-
- This function can be used to delete the QIODevice in the slot connected to
- the requestFinished() signal.
-
- \sa currentDestinationDevice() post() request()
-*/
-QIODevice *QHttp::currentSourceDevice() const
-{
- Q_D(const QHttp);
- if (d->pending.isEmpty())
- return 0;
- return d->pending.first()->sourceDevice();
-}
-
-/*!
- Returns the QIODevice pointer that is used as to store the data of the HTTP
- request being executed. If there is no current request or if the request
- does not store the data to an IO device, this function returns 0.
-
- This function can be used to delete the QIODevice in the slot connected to
- the requestFinished() signal.
-
- \sa currentSourceDevice() get() post() request()
-*/
-QIODevice *QHttp::currentDestinationDevice() const
-{
- Q_D(const QHttp);
- if (d->pending.isEmpty())
- return 0;
- return d->pending.first()->destinationDevice();
-}
-
-/*!
- Returns true if there are any requests scheduled that have not yet
- been executed; otherwise returns false.
-
- The request that is being executed is \e not considered as a
- scheduled request.
-
- \sa clearPendingRequests() currentId() currentRequest()
-*/
-bool QHttp::hasPendingRequests() const
-{
- Q_D(const QHttp);
- return d->pending.count() > 1;
-}
-
-/*!
- Deletes all pending requests from the list of scheduled requests.
- This does not affect the request that is being executed. If
- you want to stop this as well, use abort().
-
- \sa hasPendingRequests() abort()
-*/
-void QHttp::clearPendingRequests()
-{
- Q_D(QHttp);
- // delete all entires except the first one
- while (d->pending.count() > 1)
- delete d->pending.takeLast();
-}
-
-/*!
- Sets the HTTP server that is used for requests to \a hostName on
- port \a port.
-
- The function does not block; instead, it returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa get() post() head() request() requestStarted() requestFinished() done()
-*/
-int QHttp::setHost(const QString &hostName, quint16 port)
-{
- Q_D(QHttp);
- return d->addRequest(new QHttpSetHostRequest(hostName, port, ConnectionModeHttp));
-}
-
-/*!
- Sets the HTTP server that is used for requests to \a hostName on
- port \a port using the connection mode \a mode.
-
- If port is 0, it will use the default port for the \a mode used
- (80 for HTTP and 443 for HTTPS).
-
- The function does not block; instead, it returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa get() post() head() request() requestStarted() requestFinished() done()
-*/
-int QHttp::setHost(const QString &hostName, ConnectionMode mode, quint16 port)
-{
-#ifdef QT_NO_OPENSSL
- if (mode == ConnectionModeHttps)
- qWarning("QHttp::setHost: HTTPS connection requested but SSL support not compiled in");
-#endif
- Q_D(QHttp);
- if (port == 0)
- port = (mode == ConnectionModeHttp) ? 80 : 443;
- return d->addRequest(new QHttpSetHostRequest(hostName, port, mode));
-}
-
-/*!
- Replaces the internal QTcpSocket that QHttp uses with \a
- socket. This is useful if you want to use your own custom QTcpSocket
- subclass instead of the plain QTcpSocket that QHttp uses by default.
- QHttp does not take ownership of the socket, and will not delete \a
- socket when destroyed.
-
- The function does not block; instead, it returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- Note: If QHttp is used in a non-GUI thread that runs its own event
- loop, you must move \a socket to that thread before calling setSocket().
-
- \sa QObject::moveToThread(), {Thread Support in Qt}
-*/
-int QHttp::setSocket(QTcpSocket *socket)
-{
- Q_D(QHttp);
- return d->addRequest(new QHttpSetSocketRequest(socket));
-}
-
-/*!
- This function sets the user name \a userName and password \a
- password for web pages that require authentication.
-
- The function does not block; instead, it returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-*/
-int QHttp::setUser(const QString &userName, const QString &password)
-{
- Q_D(QHttp);
- return d->addRequest(new QHttpSetUserRequest(userName, password));
-}
-
-#ifndef QT_NO_NETWORKPROXY
-
-/*!
- Enables HTTP proxy support, using the proxy server \a host on port \a
- port. \a username and \a password can be provided if the proxy server
- requires authentication.
-
- Example:
-
- \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 7
-
- QHttp supports non-transparent web proxy servers only, such as the Squid
- Web proxy cache server (from \l http://www.squid.org/). For transparent
- proxying, such as SOCKS5, use QNetworkProxy instead.
-
- \note setProxy() has to be called before setHost() for it to take effect.
- If setProxy() is called after setHost(), then it will not apply until after
- setHost() is called again.
-
- \sa QFtp::setProxy()
-*/
-int QHttp::setProxy(const QString &host, int port,
- const QString &username, const QString &password)
-{
- Q_D(QHttp);
- QNetworkProxy proxy(QNetworkProxy::HttpProxy, host, port, username, password);
- return d->addRequest(new QHttpSetProxyRequest(proxy));
-}
-
-/*!
- \overload
-
- Enables HTTP proxy support using the proxy settings from \a
- proxy. If \a proxy is a transparent proxy, QHttp will call
- QAbstractSocket::setProxy() on the underlying socket. If the type
- is QNetworkProxy::HttpCachingProxy, QHttp will behave like the
- previous function.
-
- \note for compatibility with Qt 4.3, if the proxy type is
- QNetworkProxy::HttpProxy and the request type is unencrypted (that
- is, ConnectionModeHttp), QHttp will treat the proxy as a caching
- proxy.
-*/
-int QHttp::setProxy(const QNetworkProxy &proxy)
-{
- Q_D(QHttp);
- return d->addRequest(new QHttpSetProxyRequest(proxy));
-}
-
-#endif
-
-/*!
- Sends a get request for \a path to the server set by setHost() or
- as specified in the constructor.
-
- \a path must be a absolute path like \c /index.html or an
- absolute URI like \c http://example.com/index.html and
- must be encoded with either QUrl::toPercentEncoding() or
- QUrl::encodedPath().
-
- If the IO device \a to is 0 the readyRead() signal is emitted
- every time new content data is available to read.
-
- If the IO device \a to is not 0, the content data of the response
- is written directly to the device. Make sure that the \a to
- pointer is valid for the duration of the operation (it is safe to
- delete it when the requestFinished() signal is emitted).
-
- \section1 Request Processing
-
- The function does not block; instead, it returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa setHost(), post(), head(), request(), requestStarted(),
- requestFinished(), done()
-*/
-int QHttp::get(const QString &path, QIODevice *to)
-{
- Q_D(QHttp);
- QHttpRequestHeader header(QLatin1String("GET"), path);
- header.setValue(QLatin1String("Connection"), QLatin1String("Keep-Alive"));
- return d->addRequest(new QHttpPGHRequest(header, (QIODevice *) 0, to));
-}
-
-/*!
- Sends a post request for \a path to the server set by setHost() or
- as specified in the constructor.
-
- \a path must be an absolute path like \c /index.html or an
- absolute URI like \c http://example.com/index.html and
- must be encoded with either QUrl::toPercentEncoding() or
- QUrl::encodedPath().
-
- The incoming data comes via the \a data IO device.
-
- If the IO device \a to is 0 the readyRead() signal is emitted
- every time new content data is available to read.
-
- If the IO device \a to is not 0, the content data of the response
- is written directly to the device. Make sure that the \a to
- pointer is valid for the duration of the operation (it is safe to
- delete it when the requestFinished() signal is emitted).
-
- The function does not block; instead, it returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa setHost() get() head() request() requestStarted() requestFinished() done()
-*/
-int QHttp::post(const QString &path, QIODevice *data, QIODevice *to )
-{
- Q_D(QHttp);
- QHttpRequestHeader header(QLatin1String("POST"), path);
- header.setValue(QLatin1String("Connection"), QLatin1String("Keep-Alive"));
- return d->addRequest(new QHttpPGHRequest(header, data, to));
-}
-
-/*!
- \overload
-
- \a data is used as the content data of the HTTP request.
-*/
-int QHttp::post(const QString &path, const QByteArray &data, QIODevice *to)
-{
- Q_D(QHttp);
- QHttpRequestHeader header(QLatin1String("POST"), path);
- header.setValue(QLatin1String("Connection"), QLatin1String("Keep-Alive"));
- return d->addRequest(new QHttpPGHRequest(header, new QByteArray(data), to));
-}
-
-/*!
- Sends a header request for \a path to the server set by setHost()
- or as specified in the constructor.
-
- \a path must be an absolute path like \c /index.html or an
- absolute URI like \c http://example.com/index.html.
-
- The function does not block; instead, it returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa setHost() get() post() request() requestStarted() requestFinished() done()
-*/
-int QHttp::head(const QString &path)
-{
- Q_D(QHttp);
- QHttpRequestHeader header(QLatin1String("HEAD"), path);
- header.setValue(QLatin1String("Connection"), QLatin1String("Keep-Alive"));
- return d->addRequest(new QHttpPGHRequest(header, (QIODevice*)0, 0));
-}
-
-/*!
- Sends a request to the server set by setHost() or as specified in
- the constructor. Uses the \a header as the HTTP request header.
- You are responsible for setting up a header that is appropriate
- for your request.
-
- The incoming data comes via the \a data IO device.
-
- If the IO device \a to is 0 the readyRead() signal is emitted
- every time new content data is available to read.
-
- If the IO device \a to is not 0, the content data of the response
- is written directly to the device. Make sure that the \a to
- pointer is valid for the duration of the operation (it is safe to
- delete it when the requestFinished() signal is emitted).
-
- The function does not block; instead, it returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- \sa setHost() get() post() head() requestStarted() requestFinished() done()
-*/
-int QHttp::request(const QHttpRequestHeader &header, QIODevice *data, QIODevice *to)
-{
- Q_D(QHttp);
- return d->addRequest(new QHttpNormalRequest(header, data, to));
-}
-
-/*!
- \overload
-
- \a data is used as the content data of the HTTP request.
-*/
-int QHttp::request(const QHttpRequestHeader &header, const QByteArray &data, QIODevice *to )
-{
- Q_D(QHttp);
- return d->addRequest(new QHttpNormalRequest(header, new QByteArray(data), to));
-}
-
-/*!
- Closes the connection; this is useful if you have a keep-alive
- connection and want to close it.
-
- For the requests issued with get(), post() and head(), QHttp sets
- the connection to be keep-alive. You can also do this using the
- header you pass to the request() function. QHttp only closes the
- connection to the HTTP server if the response header requires it
- to do so.
-
- The function does not block; instead, it returns immediately. The request
- is scheduled, and its execution is performed asynchronously. The
- function returns a unique identifier which is passed by
- requestStarted() and requestFinished().
-
- When the request is started the requestStarted() signal is
- emitted. When it is finished the requestFinished() signal is
- emitted.
-
- If you want to close the connection immediately, you have to use
- abort() instead.
-
- \sa stateChanged() abort() requestStarted() requestFinished() done()
-*/
-int QHttp::close()
-{
- Q_D(QHttp);
- return d->addRequest(new QHttpCloseRequest());
-}
-
-/*!
- \obsolete
-
- Behaves the same as close().
-*/
-int QHttp::closeConnection()
-{
- Q_D(QHttp);
- return d->addRequest(new QHttpCloseRequest());
-}
-
-int QHttpPrivate::addRequest(QHttpNormalRequest *req)
-{
- QHttpRequestHeader h = req->requestHeader();
- if (h.path().isEmpty()) {
- // note: the following qWarning is autotested. If you change it, change the test too.
- qWarning("QHttp: empty path requested is invalid -- using '/'");
- h.setRequest(h.method(), QLatin1String("/"), h.majorVersion(), h.minorVersion());
- req->setRequestHeader(h);
- }
-
- // contine below
- return addRequest(static_cast<QHttpRequest *>(req));
-}
-
-int QHttpPrivate::addRequest(QHttpRequest *req)
-{
- Q_Q(QHttp);
- pending.append(req);
-
- if (pending.count() == 1) {
- // don't emit the requestStarted() signal before the id is returned
- QMetaObject::invokeMethod(q, "_q_startNextRequest", Qt::QueuedConnection);
- }
- return req->id;
-}
-
-void QHttpPrivate::_q_startNextRequest()
-{
- Q_Q(QHttp);
- if (pending.isEmpty())
- return;
- QHttpRequest *r = pending.first();
-
- error = QHttp::NoError;
- errorString = QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Unknown error"));
-
- if (q->bytesAvailable() != 0)
- q->readAll(); // clear the data
- emit q->requestStarted(r->id);
- r->start(q);
-}
-
-void QHttpPrivate::_q_slotSendRequest()
-{
- if (hostName.isNull()) {
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "No server set to connect to")),
- QHttp::UnknownError);
- return;
- }
-
- QString connectionHost = hostName;
- int connectionPort = port;
- bool sslInUse = false;
-
-#ifndef QT_NO_OPENSSL
- QSslSocket *sslSocket = qobject_cast<QSslSocket *>(socket);
- if (mode == QHttp::ConnectionModeHttps || (sslSocket && sslSocket->isEncrypted()))
- sslInUse = true;
-#endif
-
-#ifndef QT_NO_NETWORKPROXY
- bool cachingProxyInUse = false;
- bool transparentProxyInUse = false;
- if (proxy.type() == QNetworkProxy::DefaultProxy)
- proxy = QNetworkProxy::applicationProxy();
-
- if (proxy.type() == QNetworkProxy::HttpCachingProxy) {
- if (proxy.hostName().isEmpty())
- proxy.setType(QNetworkProxy::NoProxy);
- else
- cachingProxyInUse = true;
- } else if (proxy.type() == QNetworkProxy::HttpProxy) {
- // Compatibility behaviour: HttpProxy can be used to mean both
- // transparent and caching proxy
- if (proxy.hostName().isEmpty()) {
- proxy.setType(QNetworkProxy::NoProxy);
- } else if (sslInUse) {
- // Disallow use of caching proxy with HTTPS; instead fall back to
- // transparent HTTP CONNECT proxying.
- transparentProxyInUse = true;
- } else {
- proxy.setType(QNetworkProxy::HttpCachingProxy);
- cachingProxyInUse = true;
- }
- }
-
- // Proxy support. Insert the Proxy-Authorization item into the
- // header before it's sent off to the proxy.
- if (cachingProxyInUse) {
- QUrl proxyUrl;
- proxyUrl.setScheme(QLatin1String("http"));
- proxyUrl.setHost(hostName);
- if (port && port != 80)
- proxyUrl.setPort(port);
- QString request = QString::fromAscii(proxyUrl.resolved(QUrl::fromEncoded(header.path().toLatin1())).toEncoded());
-
- header.setRequest(header.method(), request, header.majorVersion(), header.minorVersion());
- header.setValue(QLatin1String("Proxy-Connection"), QLatin1String("keep-alive"));
-
- QAuthenticatorPrivate *auth = QAuthenticatorPrivate::getPrivate(proxyAuthenticator);
- if (auth && auth->method != QAuthenticatorPrivate::None) {
- QByteArray response = auth->calculateResponse(header.method().toLatin1(), header.path().toLatin1());
- header.setValue(QLatin1String("Proxy-Authorization"), QString::fromLatin1(response));
- }
-
- connectionHost = proxy.hostName();
- connectionPort = proxy.port();
- }
-
- if (transparentProxyInUse || sslInUse) {
- socket->setProxy(proxy);
- }
-#endif
-
- // Username support. Insert the user and password into the query
- // string.
- QAuthenticatorPrivate *auth = QAuthenticatorPrivate::getPrivate(authenticator);
- if (auth && auth->method != QAuthenticatorPrivate::None) {
- QByteArray response = auth->calculateResponse(header.method().toLatin1(), header.path().toLatin1());
- header.setValue(QLatin1String("Authorization"), QString::fromLatin1(response));
- }
-
- // Do we need to setup a new connection or can we reuse an
- // existing one?
- if (socket->peerName() != connectionHost || socket->peerPort() != connectionPort
- || socket->state() != QTcpSocket::ConnectedState
-#ifndef QT_NO_OPENSSL
- || (sslSocket && sslSocket->isEncrypted() != (mode == QHttp::ConnectionModeHttps))
-#endif
- ) {
- socket->blockSignals(true);
- socket->abort();
- socket->blockSignals(false);
-
- setState(QHttp::Connecting);
-#ifndef QT_NO_OPENSSL
- if (sslSocket && mode == QHttp::ConnectionModeHttps) {
- sslSocket->connectToHostEncrypted(hostName, port);
- } else
-#endif
- {
- socket->connectToHost(connectionHost, connectionPort);
- }
- } else {
- _q_slotConnected();
- }
-
-}
-
-void QHttpPrivate::finishedWithSuccess()
-{
- Q_Q(QHttp);
- if (pending.isEmpty())
- return;
- QHttpRequest *r = pending.first();
-
- // did we recurse?
- if (r->finished)
- return;
- r->finished = true;
- hasFinishedWithError = false;
-
- emit q->requestFinished(r->id, false);
- if (hasFinishedWithError) {
- // we recursed and changed into an error. The finishedWithError function
- // below has emitted the done(bool) signal and cleared the queue by now.
- return;
- }
-
- pending.removeFirst();
- delete r;
-
- if (pending.isEmpty()) {
- emit q->done(false);
- } else {
- _q_startNextRequest();
- }
-}
-
-void QHttpPrivate::finishedWithError(const QString &detail, int errorCode)
-{
- Q_Q(QHttp);
- if (pending.isEmpty())
- return;
- QHttpRequest *r = pending.first();
- hasFinishedWithError = true;
-
- error = QHttp::Error(errorCode);
- errorString = detail;
-
- // did we recurse?
- if (!r->finished) {
- r->finished = true;
- emit q->requestFinished(r->id, true);
- }
-
- while (!pending.isEmpty())
- delete pending.takeFirst();
- emit q->done(hasFinishedWithError);
-}
-
-void QHttpPrivate::_q_slotClosed()
-{
- Q_Q(QHttp);
-
- if (state == QHttp::Reading) {
- if (response.hasKey(QLatin1String("content-length"))) {
- // We got Content-Length, so did we get all bytes?
- if (bytesDone + q->bytesAvailable() != response.contentLength()) {
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Wrong content length")), QHttp::WrongContentLength);
- }
- }
- } else if (state == QHttp::Connecting || state == QHttp::Sending) {
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Server closed connection unexpectedly")), QHttp::UnexpectedClose);
- }
-
- postDevice = 0;
- if (state != QHttp::Closing)
- setState(QHttp::Closing);
- QMetaObject::invokeMethod(q, "_q_slotDoFinished", Qt::QueuedConnection);
-}
-
-void QHttpPrivate::_q_continuePost()
-{
- if (pendingPost) {
- pendingPost = false;
- setState(QHttp::Sending);
- _q_slotBytesWritten(0);
- }
-}
-
-void QHttpPrivate::_q_slotConnected()
-{
- if (state != QHttp::Sending) {
- bytesDone = 0;
- setState(QHttp::Sending);
- }
-
- QString str = header.toString();
- bytesTotal = str.length();
- socket->write(str.toLatin1(), bytesTotal);
-#if defined(QHTTP_DEBUG)
- qDebug("QHttp: write request header %p:\n---{\n%s}---", &header, str.toLatin1().constData());
-#endif
-
- if (postDevice) {
- postDevice->seek(0); // reposition the device
- bytesTotal += postDevice->size();
- //check for 100-continue
- if (header.value(QLatin1String("expect")).contains(QLatin1String("100-continue"), Qt::CaseInsensitive)) {
- //create a time out for 2 secs.
- pendingPost = true;
- post100ContinueTimer.start(2000);
- }
- } else {
- bytesTotal += buffer.size();
- socket->write(buffer, buffer.size());
- }
-}
-
-void QHttpPrivate::_q_slotError(QAbstractSocket::SocketError err)
-{
- Q_Q(QHttp);
- postDevice = 0;
-
- if (state == QHttp::Connecting || state == QHttp::Reading || state == QHttp::Sending) {
- switch (err) {
- case QTcpSocket::ConnectionRefusedError:
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Connection refused (or timed out)")), QHttp::ConnectionRefused);
- break;
- case QTcpSocket::HostNotFoundError:
- finishedWithError(QString::fromLatin1(QT_TRANSLATE_NOOP("QHttp", "Host %1 not found"))
- .arg(socket->peerName()), QHttp::HostNotFound);
- break;
- case QTcpSocket::RemoteHostClosedError:
- if (state == QHttp::Sending && reconnectAttempts--) {
- setState(QHttp::Closing);
- setState(QHttp::Unconnected);
- socket->blockSignals(true);
- socket->abort();
- socket->blockSignals(false);
- QMetaObject::invokeMethod(q, "_q_slotSendRequest", Qt::QueuedConnection);
- return;
- }
- break;
-#ifndef QT_NO_NETWORKPROXY
- case QTcpSocket::ProxyAuthenticationRequiredError:
- finishedWithError(socket->errorString(), QHttp::ProxyAuthenticationRequiredError);
- break;
-#endif
- default:
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "HTTP request failed")), QHttp::UnknownError);
- break;
- }
- }
-
- closeConn();
-}
-
-#ifndef QT_NO_OPENSSL
-void QHttpPrivate::_q_slotEncryptedBytesWritten(qint64 written)
-{
- Q_UNUSED(written);
- postMoreData();
-}
-#endif
-
-void QHttpPrivate::_q_slotBytesWritten(qint64 written)
-{
- Q_Q(QHttp);
- bytesDone += written;
- emit q->dataSendProgress(bytesDone, bytesTotal);
- postMoreData();
-}
-
-// Send the POST data
-void QHttpPrivate::postMoreData()
-{
- if (pendingPost)
- return;
-
- if (!postDevice)
- return;
-
- // the following is backported code from Qt 4.6 QNetworkAccessManager.
- // We also have to check the encryptedBytesToWrite() if it is an SSL socket.
-#ifndef QT_NO_OPENSSL
- QSslSocket *sslSocket = qobject_cast<QSslSocket*>(socket);
- // if it is really an ssl socket, check more than just bytesToWrite()
- if ((socket->bytesToWrite() + (sslSocket ? sslSocket->encryptedBytesToWrite() : 0)) == 0) {
-#else
- if (socket->bytesToWrite() == 0) {
-#endif
- int max = qMin<qint64>(4096, postDevice->size() - postDevice->pos());
- QByteArray arr;
- arr.resize(max);
-
- int n = postDevice->read(arr.data(), max);
- if (n < 0) {
- qWarning("Could not read enough bytes from the device");
- closeConn();
- return;
- }
- if (postDevice->atEnd()) {
- postDevice = 0;
- }
-
- socket->write(arr, n);
- }
-}
-
-void QHttpPrivate::_q_slotReadyRead()
-{
- Q_Q(QHttp);
- QHttp::State oldState = state;
- if (state != QHttp::Reading) {
- setState(QHttp::Reading);
- readHeader = true;
- headerStr = QLatin1String("");
- bytesDone = 0;
- chunkedSize = -1;
- repost = false;
- }
-
- while (readHeader) {
- bool end = false;
- QString tmp;
- while (!end && socket->canReadLine()) {
- tmp = QString::fromAscii(socket->readLine());
- if (tmp == QLatin1String("\r\n") || tmp == QLatin1String("\n") || tmp.isEmpty())
- end = true;
- else
- headerStr += tmp;
- }
-
- if (!end)
- return;
-
- response = QHttpResponseHeader(headerStr);
- headerStr = QLatin1String("");
-#if defined(QHTTP_DEBUG)
- qDebug("QHttp: read response header:\n---{\n%s}---", response.toString().toLatin1().constData());
-#endif
- // Check header
- if (!response.isValid()) {
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Invalid HTTP response header")),
- QHttp::InvalidResponseHeader);
- closeConn();
- return;
- }
-
- int statusCode = response.statusCode();
- if (statusCode == 401 || statusCode == 407) { // (Proxy) Authentication required
- QAuthenticator *auth =
-#ifndef QT_NO_NETWORKPROXY
- statusCode == 407
- ? &proxyAuthenticator :
-#endif
- &authenticator;
- if (auth->isNull())
- auth->detach();
- QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(*auth);
- priv->parseHttpResponse(response, (statusCode == 407));
- if (priv->phase == QAuthenticatorPrivate::Done) {
- socket->blockSignals(true);
-#ifndef QT_NO_NETWORKPROXY
- if (statusCode == 407)
- emit q->proxyAuthenticationRequired(proxy, auth);
- else
-#endif
- emit q->authenticationRequired(hostName, port, auth);
- socket->blockSignals(false);
- } else if (priv->phase == QAuthenticatorPrivate::Invalid) {
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Unknown authentication method")),
- QHttp::AuthenticationRequiredError);
- closeConn();
- return;
- }
-
- // priv->phase will get reset to QAuthenticatorPrivate::Start if the authenticator got modified in the signal above.
- if (priv->phase == QAuthenticatorPrivate::Done) {
-#ifndef QT_NO_NETWORKPROXY
- if (statusCode == 407)
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Proxy authentication required")),
- QHttp::ProxyAuthenticationRequiredError);
- else
-#endif
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Authentication required")),
- QHttp::AuthenticationRequiredError);
- closeConn();
- return;
- } else {
- // close the connection if it isn't already and reconnect using the chosen authentication method
- bool willClose = (response.value(QLatin1String("proxy-connection")).toLower() == QLatin1String("close"))
- || (response.value(QLatin1String("connection")).toLower() == QLatin1String("close"));
- if (willClose) {
- if (socket) {
- setState(QHttp::Closing);
- socket->blockSignals(true);
- socket->close();
- socket->blockSignals(false);
- socket->readAll();
- }
- _q_slotSendRequest();
- return;
- } else {
- repost = true;
- }
- }
- } else {
- buffer.clear();
- }
-
- if (response.statusCode() == 100 && pendingPost) {
- // if we have pending POST, start sending data otherwise ignore
- post100ContinueTimer.stop();
- QMetaObject::invokeMethod(q, "_q_continuePost", Qt::QueuedConnection);
- return;
- }
-
- // The 100-continue header is ignored (in case of no 'expect:100-continue' header),
- // because when using the POST method, we send both the request header and data in
- // one chunk.
- if (response.statusCode() != 100) {
- post100ContinueTimer.stop();
- pendingPost = false;
- readHeader = false;
- if (response.hasKey(QLatin1String("transfer-encoding")) &&
- response.value(QLatin1String("transfer-encoding")).toLower().contains(QLatin1String("chunked")))
- chunkedSize = 0;
-
- if (!repost)
- emit q->responseHeaderReceived(response);
- if (state == QHttp::Unconnected || state == QHttp::Closing)
- return;
- } else {
- // Restore the state, the next incoming data will be treated as if
- // we never say the 100 response.
- state = oldState;
- }
- }
-
- bool everythingRead = false;
-
- if (q->currentRequest().method() == QLatin1String("HEAD") ||
- response.statusCode() == 304 || response.statusCode() == 204 ||
- response.statusCode() == 205) {
- // HEAD requests have only headers as replies
- // These status codes never have a body:
- // 304 Not Modified
- // 204 No Content
- // 205 Reset Content
- everythingRead = true;
- } else {
- qint64 n = socket->bytesAvailable();
- QByteArray *arr = 0;
- if (chunkedSize != -1) {
- // transfer-encoding is chunked
- for (;;) {
- // get chunk size
- if (chunkedSize == 0) {
- if (!socket->canReadLine())
- break;
- QString sizeString = QString::fromAscii(socket->readLine());
- int tPos = sizeString.indexOf(QLatin1Char(';'));
- if (tPos != -1)
- sizeString.truncate(tPos);
- bool ok;
- chunkedSize = sizeString.toInt(&ok, 16);
- if (!ok) {
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Invalid HTTP chunked body")),
- QHttp::WrongContentLength);
- closeConn();
- delete arr;
- return;
- }
- if (chunkedSize == 0) // last-chunk
- chunkedSize = -2;
- }
-
- // read trailer
- while (chunkedSize == -2 && socket->canReadLine()) {
- QString read = QString::fromAscii(socket->readLine());
- if (read == QLatin1String("\r\n") || read == QLatin1String("\n"))
- chunkedSize = -1;
- }
- if (chunkedSize == -1) {
- everythingRead = true;
- break;
- }
-
- // make sure that you can read the terminating CRLF,
- // otherwise wait until next time...
- n = socket->bytesAvailable();
- if (n == 0)
- break;
- if (n == chunkedSize || n == chunkedSize+1) {
- n = chunkedSize - 1;
- if (n == 0)
- break;
- }
-
- // read data
- qint64 toRead = chunkedSize < 0 ? n : qMin(n, chunkedSize);
- if (!arr)
- arr = new QByteArray;
- uint oldArrSize = arr->size();
- arr->resize(oldArrSize + toRead);
- qint64 read = socket->read(arr->data()+oldArrSize, toRead);
- arr->resize(oldArrSize + read);
-
- chunkedSize -= read;
-
- if (chunkedSize == 0 && n - read >= 2) {
- // read terminating CRLF
- char tmp[2];
- socket->read(tmp, 2);
- if (tmp[0] != '\r' || tmp[1] != '\n') {
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Invalid HTTP chunked body")),
- QHttp::WrongContentLength);
- closeConn();
- delete arr;
- return;
- }
- }
- }
- } else if (response.hasContentLength()) {
- if (repost && (n < response.contentLength())) {
- // wait for the content to be available fully
- // if repost is required, the content is ignored
- return;
- }
- n = qMin(qint64(response.contentLength() - bytesDone), n);
- if (n > 0) {
- arr = new QByteArray;
- arr->resize(n);
- qint64 read = socket->read(arr->data(), n);
- arr->resize(read);
- }
- if (bytesDone + q->bytesAvailable() + n == response.contentLength())
- everythingRead = true;
- } else if (n > 0) {
- // workaround for VC++ bug
- QByteArray temp = socket->readAll();
- arr = new QByteArray(temp);
- }
-
- if (arr && !repost) {
- n = arr->size();
- if (toDevice) {
- qint64 bytesWritten;
- bytesWritten = toDevice->write(*arr, n);
- delete arr;
- arr = 0;
- // if writing to the device does not succeed, quit with error
- if (bytesWritten == -1 || bytesWritten < n) {
- finishedWithError(QLatin1String(QT_TRANSLATE_NOOP("QHttp", "Error writing response to device")), QHttp::UnknownError);
- } else {
- bytesDone += bytesWritten;
-#if defined(QHTTP_DEBUG)
- qDebug("QHttp::_q_slotReadyRead(): read %lld bytes (%lld bytes done)", n, bytesDone);
-#endif
- }
- if (response.hasContentLength())
- emit q->dataReadProgress(bytesDone, response.contentLength());
- else
- emit q->dataReadProgress(bytesDone, 0);
- } else {
- char *ptr = rba.reserve(arr->size());
- memcpy(ptr, arr->data(), arr->size());
- delete arr;
- arr = 0;
-#if defined(QHTTP_DEBUG)
- qDebug("QHttp::_q_slotReadyRead(): read %lld bytes (%lld bytes done)", n, bytesDone + q->bytesAvailable());
-#endif
- if (response.hasContentLength())
- emit q->dataReadProgress(bytesDone + q->bytesAvailable(), response.contentLength());
- else
- emit q->dataReadProgress(bytesDone + q->bytesAvailable(), 0);
- emit q->readyRead(response);
- }
- }
-
- delete arr;
- }
-
- if (everythingRead) {
- if (repost) {
- _q_slotSendRequest();
- return;
- }
- // Handle "Connection: close"
- if (response.value(QLatin1String("connection")).toLower() == QLatin1String("close")) {
- closeConn();
- } else {
- setState(QHttp::Connected);
- // Start a timer, so that we emit the keep alive signal
- // "after" this method returned.
- QMetaObject::invokeMethod(q, "_q_slotDoFinished", Qt::QueuedConnection);
- }
- }
-}
-
-void QHttpPrivate::_q_slotDoFinished()
-{
- if (state == QHttp::Connected) {
- finishedWithSuccess();
- } else if (state != QHttp::Unconnected) {
- setState(QHttp::Unconnected);
- finishedWithSuccess();
- }
-}
-
-
-/*!
- Returns the current state of the object. When the state changes,
- the stateChanged() signal is emitted.
-
- \sa State stateChanged()
-*/
-QHttp::State QHttp::state() const
-{
- Q_D(const QHttp);
- return d->state;
-}
-
-/*!
- Returns the last error that occurred. This is useful to find out
- what happened when receiving a requestFinished() or a done()
- signal with the \c error argument \c true.
-
- If you start a new request, the error status is reset to \c NoError.
-*/
-QHttp::Error QHttp::error() const
-{
- Q_D(const QHttp);
- return d->error;
-}
-
-/*!
- Returns a human-readable description of the last error that
- occurred. This is useful to present a error message to the user
- when receiving a requestFinished() or a done() signal with the \c
- error argument \c true.
-*/
-QString QHttp::errorString() const
-{
- Q_D(const QHttp);
- return d->errorString;
-}
-
-void QHttpPrivate::setState(int s)
-{
- Q_Q(QHttp);
-#if defined(QHTTP_DEBUG)
- qDebug("QHttp state changed %d -> %d", state, s);
-#endif
- state = QHttp::State(s);
- emit q->stateChanged(s);
-}
-
-void QHttpPrivate::closeConn()
-{
- Q_Q(QHttp);
- // If no connection is open -> ignore
- if (state == QHttp::Closing || state == QHttp::Unconnected)
- return;
-
- postDevice = 0;
- setState(QHttp::Closing);
-
- // Already closed ?
- if (!socket || !socket->isOpen()) {
- QMetaObject::invokeMethod(q, "_q_slotDoFinished", Qt::QueuedConnection);
- } else {
- // Close now.
- socket->close();
- }
-}
-
-void QHttpPrivate::setSock(QTcpSocket *sock)
-{
- Q_Q(const QHttp);
-
- // disconnect all existing signals
- if (socket)
- socket->disconnect();
- if (deleteSocket)
- delete socket;
-
- // use the new QTcpSocket socket, or create one if socket is 0.
- deleteSocket = (sock == 0);
- socket = sock;
- if (!socket) {
-#ifndef QT_NO_OPENSSL
- if (QSslSocket::supportsSsl())
- socket = new QSslSocket();
- else
-#endif
- socket = new QTcpSocket();
- }
-
- // connect all signals
- QObject::connect(socket, SIGNAL(connected()), q, SLOT(_q_slotConnected()));
- QObject::connect(socket, SIGNAL(disconnected()), q, SLOT(_q_slotClosed()));
- QObject::connect(socket, SIGNAL(readyRead()), q, SLOT(_q_slotReadyRead()));
- QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), q, SLOT(_q_slotError(QAbstractSocket::SocketError)));
- QObject::connect(socket, SIGNAL(bytesWritten(qint64)),
- q, SLOT(_q_slotBytesWritten(qint64)));
-#ifndef QT_NO_NETWORKPROXY
- QObject::connect(socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
- q, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
-#endif
-
-#ifndef QT_NO_OPENSSL
- if (qobject_cast<QSslSocket *>(socket)) {
- QObject::connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
- q, SIGNAL(sslErrors(QList<QSslError>)));
- QObject::connect(socket, SIGNAL(encryptedBytesWritten(qint64)),
- q, SLOT(_q_slotEncryptedBytesWritten(qint64)));
- }
-#endif
-}
-
-/*!
- Tells the QSslSocket used for the Http connection to ignore the errors
- reported in the sslErrors() signal.
-
- Note that this function must be called from within a slot connected to the
- sslErrors() signal to have any effect.
-
- \sa QSslSocket QSslSocket::sslErrors()
-*/
-#ifndef QT_NO_OPENSSL
-void QHttp::ignoreSslErrors()
-{
- Q_D(QHttp);
- QSslSocket *sslSocket = qobject_cast<QSslSocket *>(d->socket);
- if (sslSocket)
- sslSocket->ignoreSslErrors();
-}
-#endif
-
-QT_END_NAMESPACE
-
-#include "moc_qhttp.cpp"
-
-#endif
diff --git a/src/network/access/qhttp.h b/src/network/access/qhttp.h
deleted file mode 100644
index 5dd3b5bc3d..0000000000
--- a/src/network/access/qhttp.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.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 the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QHTTP_H
-#define QHTTP_H
-
-#include <QtCore/qobject.h>
-#include <QtCore/qstringlist.h>
-#include <QtCore/qmap.h>
-#include <QtCore/qpair.h>
-#include <QtCore/qscopedpointer.h>
-
-QT_BEGIN_HEADER
-
-QT_BEGIN_NAMESPACE
-
-QT_MODULE(Network)
-
-#ifndef QT_NO_HTTP
-
-class QTcpSocket;
-class QTimerEvent;
-class QIODevice;
-class QAuthenticator;
-class QNetworkProxy;
-class QSslError;
-
-class QHttpPrivate;
-
-class QHttpHeaderPrivate;
-class Q_NETWORK_EXPORT QHttpHeader
-{
-public:
- QHttpHeader();
- QHttpHeader(const QHttpHeader &header);
- QHttpHeader(const QString &str);
- virtual ~QHttpHeader();
-
- QHttpHeader &operator=(const QHttpHeader &h);
-
- void setValue(const QString &key, const QString &value);
- void setValues(const QList<QPair<QString, QString> > &values);
- void addValue(const QString &key, const QString &value);
- QList<QPair<QString, QString> > values() const;
- bool hasKey(const QString &key) const;
- QStringList keys() const;
- QString value(const QString &key) const;
- QStringList allValues(const QString &key) const;
- void removeValue(const QString &key);
- void removeAllValues(const QString &key);
-
- // ### Qt 5: change to qint64
- bool hasContentLength() const;
- uint contentLength() const;
- void setContentLength(int len);
-
- bool hasContentType() const;
- QString contentType() const;
- void setContentType(const QString &type);
-
- virtual QString toString() const;
- bool isValid() const;
-
- virtual int majorVersion() const = 0;
- virtual int minorVersion() const = 0;
-
-protected:
- virtual bool parseLine(const QString &line, int number);
- bool parse(const QString &str);
- void setValid(bool);
-
- QHttpHeader(QHttpHeaderPrivate &dd, const QString &str = QString());
- QHttpHeader(QHttpHeaderPrivate &dd, const QHttpHeader &header);
- QScopedPointer<QHttpHeaderPrivate> d_ptr;
-
-private:
- Q_DECLARE_PRIVATE(QHttpHeader)
-};
-
-class QHttpResponseHeaderPrivate;
-class Q_NETWORK_EXPORT QHttpResponseHeader : public QHttpHeader
-{
-public:
- QHttpResponseHeader();
- QHttpResponseHeader(const QHttpResponseHeader &header);
- QHttpResponseHeader(const QString &str);
- QHttpResponseHeader(int code, const QString &text = QString(), int majorVer = 1, int minorVer = 1);
- QHttpResponseHeader &operator=(const QHttpResponseHeader &header);
-
- void setStatusLine(int code, const QString &text = QString(), int majorVer = 1, int minorVer = 1);
-
- int statusCode() const;
- QString reasonPhrase() const;
-
- int majorVersion() const;
- int minorVersion() const;
-
- QString toString() const;
-
-protected:
- bool parseLine(const QString &line, int number);
-
-private:
- Q_DECLARE_PRIVATE(QHttpResponseHeader)
- friend class QHttpPrivate;
-};
-
-class QHttpRequestHeaderPrivate;
-class Q_NETWORK_EXPORT QHttpRequestHeader : public QHttpHeader
-{
-public:
- QHttpRequestHeader();
- QHttpRequestHeader(const QString &method, const QString &path, int majorVer = 1, int minorVer = 1);
- QHttpRequestHeader(const QHttpRequestHeader &header);
- QHttpRequestHeader(const QString &str);
- QHttpRequestHeader &operator=(const QHttpRequestHeader &header);
-
- void setRequest(const QString &method, const QString &path, int majorVer = 1, int minorVer = 1);
-
- QString method() const;
- QString path() const;
-
- int majorVersion() const;
- int minorVersion() const;
-
- QString toString() const;
-
-protected:
- bool parseLine(const QString &line, int number);
-
-private:
- Q_DECLARE_PRIVATE(QHttpRequestHeader)
-};
-
-class Q_NETWORK_EXPORT QHttp : public QObject
-{
- Q_OBJECT
-
-public:
- enum ConnectionMode {
- ConnectionModeHttp,
- ConnectionModeHttps
- };
-
- explicit QHttp(QObject *parent = 0);
- QHttp(const QString &hostname, quint16 port = 80, QObject *parent = 0);
- QHttp(const QString &hostname, ConnectionMode mode, quint16 port = 0, QObject *parent = 0);
- virtual ~QHttp();
-
- enum State {
- Unconnected,
- HostLookup,
- Connecting,
- Sending,
- Reading,
- Connected,
- Closing
- };
- enum Error {
- NoError,
- UnknownError,
- HostNotFound,
- ConnectionRefused,
- UnexpectedClose,
- InvalidResponseHeader,
- WrongContentLength,
- Aborted,
- AuthenticationRequiredError,
- ProxyAuthenticationRequiredError
- };
-
- int setHost(const QString &hostname, quint16 port = 80);
- int setHost(const QString &hostname, ConnectionMode mode, quint16 port = 0);
-
- int setSocket(QTcpSocket *socket);
- int setUser(const QString &username, const QString &password = QString());
-
-#ifndef QT_NO_NETWORKPROXY
- int setProxy(const QString &host, int port,
- const QString &username = QString(),
- const QString &password = QString());
- int setProxy(const QNetworkProxy &proxy);
-#endif
-
- int get(const QString &path, QIODevice *to=0);
- int post(const QString &path, QIODevice *data, QIODevice *to=0 );
- int post(const QString &path, const QByteArray &data, QIODevice *to=0);
- int head(const QString &path);
- int request(const QHttpRequestHeader &header, QIODevice *device=0, QIODevice *to=0);
- int request(const QHttpRequestHeader &header, const QByteArray &data, QIODevice *to=0);
-
- int closeConnection();
- int close();
-
- qint64 bytesAvailable() const;
- qint64 read(char *data, qint64 maxlen);
- QByteArray readAll();
-
- int currentId() const;
- QIODevice *currentSourceDevice() const;
- QIODevice *currentDestinationDevice() const;
- QHttpRequestHeader currentRequest() const;
- QHttpResponseHeader lastResponse() const;
- bool hasPendingRequests() const;
- void clearPendingRequests();
-
- State state() const;
-
- Error error() const;
- QString errorString() const;
-
-public Q_SLOTS:
- void abort();
-
-#ifndef QT_NO_OPENSSL
- void ignoreSslErrors();
-#endif
-
-Q_SIGNALS:
- void stateChanged(int);
- void responseHeaderReceived(const QHttpResponseHeader &resp);
- void readyRead(const QHttpResponseHeader &resp);
-
- // ### Qt 5: change to qint64
- void dataSendProgress(int, int);
- void dataReadProgress(int, int);
-
- void requestStarted(int);
- void requestFinished(int, bool);
- void done(bool);
-
-#ifndef QT_NO_NETWORKPROXY
- void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *);
-#endif
- void authenticationRequired(const QString &hostname, quint16 port, QAuthenticator *);
-
-#ifndef QT_NO_OPENSSL
- void sslErrors(const QList<QSslError> &errors);
-#endif
-
-private:
- Q_DISABLE_COPY(QHttp)
- Q_DECLARE_PRIVATE(QHttp)
-
- Q_PRIVATE_SLOT(d_func(), void _q_startNextRequest())
- Q_PRIVATE_SLOT(d_func(), void _q_slotReadyRead())
- Q_PRIVATE_SLOT(d_func(), void _q_slotConnected())
- Q_PRIVATE_SLOT(d_func(), void _q_slotError(QAbstractSocket::SocketError))
- Q_PRIVATE_SLOT(d_func(), void _q_slotClosed())
- Q_PRIVATE_SLOT(d_func(), void _q_slotBytesWritten(qint64 numBytes))
-#ifndef QT_NO_OPENSSL
- Q_PRIVATE_SLOT(d_func(), void _q_slotEncryptedBytesWritten(qint64 numBytes))
-#endif
- Q_PRIVATE_SLOT(d_func(), void _q_slotDoFinished())
- Q_PRIVATE_SLOT(d_func(), void _q_slotSendRequest())
- Q_PRIVATE_SLOT(d_func(), void _q_continuePost())
-
- friend class QHttpNormalRequest;
- friend class QHttpSetHostRequest;
- friend class QHttpSetSocketRequest;
- friend class QHttpSetUserRequest;
- friend class QHttpSetProxyRequest;
- friend class QHttpCloseRequest;
- friend class QHttpPGHRequest;
-};
-
-#endif // QT_NO_HTTP
-
-QT_END_NAMESPACE
-
-QT_END_HEADER
-
-#endif // QHTTP_H
diff --git a/src/network/access/qhttpheader.cpp b/src/network/access/qhttpheader.cpp
new file mode 100644
index 0000000000..58c24cf3f5
--- /dev/null
+++ b/src/network/access/qhttpheader.cpp
@@ -0,0 +1,770 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.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 the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//#define QHTTP_DEBUG
+
+#include <qplatformdefs.h>
+#include "qhttpheader_p.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"
+# include "qtimer.h"
+#endif
+
+#ifndef QT_NO_HTTP
+
+QT_BEGIN_NAMESPACE
+
+class QHttpHeaderPrivate
+{
+ Q_DECLARE_PUBLIC(QHttpHeader)
+public:
+ inline virtual ~QHttpHeaderPrivate() {}
+
+ QList<QPair<QString, QString> > values;
+ bool valid;
+ QHttpHeader *q_ptr;
+};
+
+/****************************************************
+ *
+ * QHttpHeader
+ *
+ ****************************************************/
+
+/*!
+ \class QHttpHeader
+ \obsolete
+ \brief The QHttpHeader class contains header information for HTTP.
+
+ \ingroup network
+ \inmodule QtNetwork
+
+ In most cases you should use the more specialized derivatives of
+ this class, QHttpResponseHeader and QHttpRequestHeader, rather
+ than directly using QHttpHeader.
+
+ QHttpHeader provides the HTTP header fields. A HTTP header field
+ consists of a name followed by a colon, a single space, and the
+ field value. (See RFC 1945.) Field names are case-insensitive. A
+ typical header field looks like this:
+ \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 0
+
+ In the API the header field name is called the "key" and the
+ content is called the "value". You can get and set a header
+ field's value by using its key with value() and setValue(), e.g.
+ \snippet doc/src/snippets/code/src_network_access_qhttp.cpp 1
+
+ Some fields are so common that getters and setters are provided
+ for them as a convenient alternative to using \l value() and
+ \l setValue(), e.g. contentLength() and contentType(),
+ setContentLength() and setContentType().
+
+ Each header key has a \e single value associated with it. If you
+ set the value for a key which already exists the previous value
+ will be discarded.
+
+ \sa QHttpRequestHeader QHttpResponseHeader
+*/
+
+/*!
+ \fn int QHttpHeader::majorVersion() const
+
+ Returns the major protocol-version of the HTTP header.
+*/
+
+/*!
+ \fn int QHttpHeader::minorVersion() const
+
+ Returns the minor protocol-version of the HTTP header.
+*/
+
+/*!
+ Constructs an empty HTTP header.
+*/
+QHttpHeader::QHttpHeader()
+ : d_ptr(new QHttpHeaderPrivate)
+{
+ Q_D(QHttpHeader);
+ d->q_ptr = this;
+ d->valid = true;
+}
+
+/*!
+ Constructs a copy of \a header.
+*/
+QHttpHeader::QHttpHeader(const QHttpHeader &header)
+ : d_ptr(new QHttpHeaderPrivate)
+{
+ Q_D(QHttpHeader);
+ d->q_ptr = this;
+ d->valid = header.d_func()->valid;
+ d->values = header.d_func()->values;
+}
+
+/*!
+ Constructs a HTTP header for \a str.
+
+ This constructor parses the string \a str for header fields and
+ adds this information. The \a str should consist of one or more
+ "\r\n" delimited lines; each of these lines should have the format
+ key, colon, space, value.
+*/
+QHttpHeader::QHttpHeader(const QString &str)
+ : d_ptr(new QHttpHeaderPrivate)
+{
+ Q_D(QHttpHeader);
+ d->q_ptr = this;
+ d->valid = true;
+ parse(str);
+}
+
+/*! \internal
+ */
+QHttpHeader::QHttpHeader(QHttpHeaderPrivate &dd, const QString &str)
+ : d_ptr(&dd)
+{
+ Q_D(QHttpHeader);
+ d->q_ptr = this;
+ d->valid = true;
+ if (!str.isEmpty())
+ parse(str);
+}
+
+/*! \internal
+ */
+QHttpHeader::QHttpHeader(QHttpHeaderPrivate &dd, const QHttpHeader &header)
+ : d_ptr(&dd)
+{
+ Q_D(QHttpHeader);
+ d->q_ptr = this;
+ d->valid = header.d_func()->valid;
+ d->values = header.d_func()->values;
+}
+/*!
+ Destructor.
+*/
+QHttpHeader::~QHttpHeader()
+{
+}
+
+/*!
+ Assigns \a h and returns a reference to this http header.
+*/
+QHttpHeader &QHttpHeader::operator=(const QHttpHeader &h)
+{
+ Q_D(QHttpHeader);
+ d->values = h.d_func()->values;
+ d->valid = h.d_func()->valid;
+ return *this;
+}
+
+/*!
+ Returns true if the HTTP header is valid; otherwise returns false.
+
+ A QHttpHeader is invalid if it was created by parsing a malformed string.
+*/
+bool QHttpHeader::isValid() const
+{
+ Q_D(const QHttpHeader);
+ return d->valid;
+}
+
+/*! \internal
+ Parses the HTTP header string \a str for header fields and adds
+ the keys/values it finds. If the string is not parsed successfully
+ the QHttpHeader becomes \link isValid() invalid\endlink.
+
+ Returns true if \a str was successfully parsed; otherwise returns false.
+
+ \sa toString()
+*/
+bool QHttpHeader::parse(const QString &str)
+{
+ Q_D(QHttpHeader);
+ QStringList lst;
+ int pos = str.indexOf(QLatin1Char('\n'));
+ if (pos > 0 && str.at(pos - 1) == QLatin1Char('\r'))
+ lst = str.trimmed().split(QLatin1String("\r\n"));
+ else
+ lst = str.trimmed().split(QLatin1String("\n"));
+ lst.removeAll(QString()); // No empties
+
+ if (lst.isEmpty())
+ return true;
+
+ QStringList lines;
+ QStringList::Iterator it = lst.begin();
+ for (; it != lst.end(); ++it) {
+ if (!(*it).isEmpty()) {
+ if ((*it)[0].isSpace()) {
+ if (!lines.isEmpty()) {
+ lines.last() += QLatin1Char(' ');
+ lines.last() += (*it).trimmed();
+ }
+ } else {
+ lines.append((*it));
+ }
+ }
+ }
+
+ int number = 0;
+ it = lines.begin();
+ for (; it != lines.end(); ++it) {
+ if (!parseLine(*it, number++)) {
+ d->valid = false;
+ return false;
+ }
+ }
+ return true;
+}
+
+/*! \internal
+*/
+void QHttpHeader::setValid(bool v)
+{
+ Q_D(QHttpHeader);
+ d->valid = v;
+}
+
+/*!
+ Returns the first value for the entry with the given \a key. If no entry
+ has this \a key, an empty string is returned.
+
+ \sa setValue() removeValue() hasKey() keys()
+*/
+QString QHttpHeader::value(const QString &key) const
+{
+ Q_D(const QHttpHeader);
+ QString lowercaseKey = key.toLower();
+ QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
+ while (it != d->values.constEnd()) {
+ if ((*it).first.toLower() == lowercaseKey)
+ return (*it).second;
+ ++it;
+ }
+ return QString();
+}
+
+/*!
+ Returns all the entries with the given \a key. If no entry
+ has this \a key, an empty string list is returned.
+*/
+QStringList QHttpHeader::allValues(const QString &key) const
+{
+ Q_D(const QHttpHeader);
+ QString lowercaseKey = key.toLower();
+ QStringList valueList;
+ QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
+ while (it != d->values.constEnd()) {
+ if ((*it).first.toLower() == lowercaseKey)
+ valueList.append((*it).second);
+ ++it;
+ }
+ return valueList;
+}
+
+/*!
+ Returns a list of the keys in the HTTP header.
+
+ \sa hasKey()
+*/
+QStringList QHttpHeader::keys() const
+{
+ Q_D(const QHttpHeader);
+ QStringList keyList;
+ QSet<QString> seenKeys;
+ QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
+ while (it != d->values.constEnd()) {
+ const QString &key = (*it).first;
+ QString lowercaseKey = key.toLower();
+ if (!seenKeys.contains(lowercaseKey)) {
+ keyList.append(key);
+ seenKeys.insert(lowercaseKey);
+ }
+ ++it;
+ }
+ return keyList;
+}
+
+/*!
+ Returns true if the HTTP header has an entry with the given \a
+ key; otherwise returns false.
+
+ \sa value() setValue() keys()
+*/
+bool QHttpHeader::hasKey(const QString &key) const
+{
+ Q_D(const QHttpHeader);
+ QString lowercaseKey = key.toLower();
+ QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
+ while (it != d->values.constEnd()) {
+ if ((*it).first.toLower() == lowercaseKey)
+ return true;
+ ++it;
+ }
+ return false;
+}
+
+/*!
+ Sets the value of the entry with the \a key to \a value.
+
+ If no entry with \a key exists, a new entry with the given \a key
+ and \a value is created. If an entry with the \a key already
+ exists, the first value is discarded and replaced with the given
+ \a value.
+
+ \sa value() hasKey() removeValue()
+*/
+void QHttpHeader::setValue(const QString &key, const QString &value)
+{
+ Q_D(QHttpHeader);
+ QString lowercaseKey = key.toLower();
+ QList<QPair<QString, QString> >::Iterator it = d->values.begin();
+ while (it != d->values.end()) {
+ if ((*it).first.toLower() == lowercaseKey) {
+ (*it).second = value;
+ return;
+ }
+ ++it;
+ }
+ // not found so add
+ addValue(key, value);
+}
+
+/*!
+ Sets the header entries to be the list of key value pairs in \a values.
+*/
+void QHttpHeader::setValues(const QList<QPair<QString, QString> > &values)
+{
+ Q_D(QHttpHeader);
+ d->values = values;
+}
+
+/*!
+ Adds a new entry with the \a key and \a value.
+*/
+void QHttpHeader::addValue(const QString &key, const QString &value)
+{
+ Q_D(QHttpHeader);
+ d->values.append(qMakePair(key, value));
+}
+
+/*!
+ Returns all the entries in the header.
+*/
+QList<QPair<QString, QString> > QHttpHeader::values() const
+{
+ Q_D(const QHttpHeader);
+ return d->values;
+}
+
+/*!
+ Removes the entry with the key \a key from the HTTP header.
+
+ \sa value() setValue()
+*/
+void QHttpHeader::removeValue(const QString &key)
+{
+ Q_D(QHttpHeader);
+ QString lowercaseKey = key.toLower();
+ QList<QPair<QString, QString> >::Iterator it = d->values.begin();
+ while (it != d->values.end()) {
+ if ((*it).first.toLower() == lowercaseKey) {
+ d->values.erase(it);
+ return;
+ }
+ ++it;
+ }
+}
+
+/*!
+ Removes all the entries with the key \a key from the HTTP header.
+*/
+void QHttpHeader::removeAllValues(const QString &key)
+{
+ Q_D(QHttpHeader);
+ QString lowercaseKey = key.toLower();
+ QList<QPair<QString, QString> >::Iterator it = d->values.begin();
+ while (it != d->values.end()) {
+ if ((*it).first.toLower() == lowercaseKey) {
+ it = d->values.erase(it);
+ continue;
+ }
+ ++it;
+ }
+}
+
+/*! \internal
+ Parses the single HTTP header line \a line which has the format
+ key, colon, space, value, and adds key/value to the headers. The
+ linenumber is \a number. Returns true if the line was successfully
+ parsed and the key/value added; otherwise returns false.
+
+ \sa parse()
+*/
+bool QHttpHeader::parseLine(const QString &line, int)
+{
+ int i = line.indexOf(QLatin1Char(':'));
+ if (i == -1)
+ return false;
+
+ addValue(line.left(i).trimmed(), line.mid(i + 1).trimmed());
+
+ return true;
+}
+
+/*!
+ Returns a string representation of the HTTP header.
+
+ The string is suitable for use by the constructor that takes a
+ QString. It consists of lines with the format: key, colon, space,
+ value, "\r\n".
+*/
+QString QHttpHeader::toString() const
+{
+ Q_D(const QHttpHeader);
+ if (!isValid())
+ return QLatin1String("");
+
+ QString ret = QLatin1String("");
+
+ QList<QPair<QString, QString> >::ConstIterator it = d->values.constBegin();
+ while (it != d->values.constEnd()) {
+ ret += (*it).first + QLatin1String(": ") + (*it).second + QLatin1String("\r\n");
+ ++it;
+ }
+ return ret;
+}
+
+/*!
+ Returns true if the header has an entry for the special HTTP
+ header field \c content-length; otherwise returns false.
+
+ \sa contentLength() setContentLength()
+*/
+bool QHttpHeader::hasContentLength() const
+{
+ return hasKey(QLatin1String("content-length"));
+}
+
+/*!
+ Returns the value of the special HTTP header field \c
+ content-length.
+
+ \sa setContentLength() hasContentLength()
+*/
+uint QHttpHeader::contentLength() const
+{
+ return value(QLatin1String("content-length")).toUInt();
+}
+
+/*!
+ Sets the value of the special HTTP header field \c content-length
+ to \a len.
+
+ \sa contentLength() hasContentLength()
+*/
+void QHttpHeader::setContentLength(int len)
+{
+ setValue(QLatin1String("content-length"), QString::number(len));
+}
+
+/*!
+ Returns true if the header has an entry for the special HTTP
+ header field \c content-type; otherwise returns false.
+
+ \sa contentType() setContentType()
+*/
+bool QHttpHeader::hasContentType() const
+{
+ return hasKey(QLatin1String("content-type"));
+}
+
+/*!
+ Returns the value of the special HTTP header field \c content-type.
+
+ \sa setContentType() hasContentType()
+*/
+QString QHttpHeader::contentType() const
+{
+ QString type = value(QLatin1String("content-type"));
+ if (type.isEmpty())
+ return QString();
+
+ int pos = type.indexOf(QLatin1Char(';'));
+ if (pos == -1)
+ return type;
+
+ return type.left(pos).trimmed();
+}
+
+/*!
+ Sets the value of the special HTTP header field \c content-type to
+ \a type.
+
+ \sa contentType() hasContentType()
+*/
+void QHttpHeader::setContentType(const QString &type)
+{
+ setValue(QLatin1String("content-type"), type);
+}
+
+class QHttpResponseHeaderPrivate : public QHttpHeaderPrivate
+{
+ Q_DECLARE_PUBLIC(QHttpResponseHeader)
+public:
+ int statCode;
+ QString reasonPhr;
+ int majVer;
+ int minVer;
+};
+
+/****************************************************
+ *
+ * QHttpResponseHeader
+ *
+ ****************************************************/
+
+/*!
+ \class QHttpResponseHeader
+ \obsolete
+ \brief The QHttpResponseHeader class contains response header information for HTTP.
+
+ \ingroup network
+ \inmodule QtNetwork
+
+ HTTP responses have a status code that indicates the status of the
+ response. This code is a 3-digit integer result code (for details
+ see to RFC 1945). In addition to the status code, you can also
+ specify a human-readable text that describes the reason for the
+ code ("reason phrase"). This class allows you to get the status
+ code and the reason phrase.
+
+ \sa QHttpRequestHeader, {HTTP Example}
+*/
+
+/*!
+ Constructs an empty HTTP response header.
+*/
+QHttpResponseHeader::QHttpResponseHeader()
+ : QHttpHeader(*new QHttpResponseHeaderPrivate)
+{
+ setValid(false);
+}
+
+/*!
+ Constructs a copy of \a header.
+*/
+QHttpResponseHeader::QHttpResponseHeader(const QHttpResponseHeader &header)
+ : QHttpHeader(*new QHttpResponseHeaderPrivate, header)
+{
+ Q_D(QHttpResponseHeader);
+ d->statCode = header.d_func()->statCode;
+ d->reasonPhr = header.d_func()->reasonPhr;
+ d->majVer = header.d_func()->majVer;
+ d->minVer = header.d_func()->minVer;
+}
+
+/*!
+ Copies the contents of \a header into this QHttpResponseHeader.
+*/
+QHttpResponseHeader &QHttpResponseHeader::operator=(const QHttpResponseHeader &header)
+{
+ Q_D(QHttpResponseHeader);
+ QHttpHeader::operator=(header);
+ d->statCode = header.d_func()->statCode;
+ d->reasonPhr = header.d_func()->reasonPhr;
+ d->majVer = header.d_func()->majVer;
+ d->minVer = header.d_func()->minVer;
+ return *this;
+}
+
+/*!
+ Constructs a HTTP response header from the string \a str. The
+ string is parsed and the information is set. The \a str should
+ consist of one or more "\r\n" delimited lines; the first line should be the
+ status-line (format: HTTP-version, space, status-code, space,
+ reason-phrase); each of remaining lines should have the format key, colon,
+ space, value.
+*/
+QHttpResponseHeader::QHttpResponseHeader(const QString &str)
+ : QHttpHeader(*new QHttpResponseHeaderPrivate)
+{
+ parse(str);
+}
+
+/*!
+ \since 4.1
+
+ Constructs a QHttpResponseHeader, setting the status code to \a code, the
+ reason phrase to \a text and the protocol-version to \a majorVer and \a
+ minorVer.
+
+ \sa statusCode() reasonPhrase() majorVersion() minorVersion()
+*/
+QHttpResponseHeader::QHttpResponseHeader(int code, const QString &text, int majorVer, int minorVer)
+ : QHttpHeader(*new QHttpResponseHeaderPrivate)
+{
+ setStatusLine(code, text, majorVer, minorVer);
+}
+
+/*!
+ \since 4.1
+
+ Sets the status code to \a code, the reason phrase to \a text and
+ the protocol-version to \a majorVer and \a minorVer.
+
+ \sa statusCode() reasonPhrase() majorVersion() minorVersion()
+*/
+void QHttpResponseHeader::setStatusLine(int code, const QString &text, int majorVer, int minorVer)
+{
+ Q_D(QHttpResponseHeader);
+ setValid(true);
+ d->statCode = code;
+ d->reasonPhr = text;
+ d->majVer = majorVer;
+ d->minVer = minorVer;
+}
+
+/*!
+ Returns the status code of the HTTP response header.
+
+ \sa reasonPhrase() majorVersion() minorVersion()
+*/
+int QHttpResponseHeader::statusCode() const
+{
+ Q_D(const QHttpResponseHeader);
+ return d->statCode;
+}
+
+/*!
+ Returns the reason phrase of the HTTP response header.
+
+ \sa statusCode() majorVersion() minorVersion()
+*/
+QString QHttpResponseHeader::reasonPhrase() const
+{
+ Q_D(const QHttpResponseHeader);
+ return d->reasonPhr;
+}
+
+/*!
+ Returns the major protocol-version of the HTTP response header.
+
+ \sa minorVersion() statusCode() reasonPhrase()
+*/
+int QHttpResponseHeader::majorVersion() const
+{
+ Q_D(const QHttpResponseHeader);
+ return d->majVer;
+}
+
+/*!
+ Returns the minor protocol-version of the HTTP response header.
+
+ \sa majorVersion() statusCode() reasonPhrase()
+*/
+int QHttpResponseHeader::minorVersion() const
+{
+ Q_D(const QHttpResponseHeader);
+ return d->minVer;
+}
+
+/*! \internal
+*/
+bool QHttpResponseHeader::parseLine(const QString &line, int number)
+{
+ Q_D(QHttpResponseHeader);
+ if (number != 0)
+ return QHttpHeader::parseLine(line, number);
+
+ QString l = line.simplified();
+ if (l.length() < 10)
+ return false;
+
+ if (l.left(5) == QLatin1String("HTTP/") && l[5].isDigit() && l[6] == QLatin1Char('.') &&
+ l[7].isDigit() && l[8] == QLatin1Char(' ') && l[9].isDigit()) {
+ d->majVer = l[5].toLatin1() - '0';
+ d->minVer = l[7].toLatin1() - '0';
+
+ int pos = l.indexOf(QLatin1Char(' '), 9);
+ if (pos != -1) {
+ d->reasonPhr = l.mid(pos + 1);
+ d->statCode = l.mid(9, pos - 9).toInt();
+ } else {
+ d->statCode = l.mid(9).toInt();
+ d->reasonPhr.clear();
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+/*! \reimp
+*/
+QString QHttpResponseHeader::toString() const
+{
+ Q_D(const QHttpResponseHeader);
+ QString ret(QLatin1String("HTTP/%1.%2 %3 %4\r\n%5\r\n"));
+ return ret.arg(d->majVer).arg(d->minVer).arg(d->statCode).arg(d->reasonPhr).arg(QHttpHeader::toString());
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/network/access/qhttpheader_p.h b/src/network/access/qhttpheader_p.h
new file mode 100644
index 0000000000..0d8b4fca13
--- /dev/null
+++ b/src/network/access/qhttpheader_p.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtNetwork module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.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 the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHTTP_H
+#define QHTTP_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qmap.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qscopedpointer.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Network)
+
+#ifndef QT_NO_HTTP
+
+#if 0
+#pragma qt_class(QHttp)
+#endif
+
+class QHttpHeaderPrivate;
+class QHttpHeader
+{
+public:
+ QHttpHeader();
+ QHttpHeader(const QHttpHeader &header);
+ QHttpHeader(const QString &str);
+ virtual ~QHttpHeader();
+
+ QHttpHeader &operator=(const QHttpHeader &h);
+
+ void setValue(const QString &key, const QString &value);
+ void setValues(const QList<QPair<QString, QString> > &values);
+ void addValue(const QString &key, const QString &value);
+ QList<QPair<QString, QString> > values() const;
+ bool hasKey(const QString &key) const;
+ QStringList keys() const;
+ QString value(const QString &key) const;
+ QStringList allValues(const QString &key) const;
+ void removeValue(const QString &key);
+ void removeAllValues(const QString &key);
+
+ // ### Qt 5: change to qint64
+ bool hasContentLength() const;
+ uint contentLength() const;
+ void setContentLength(int len);
+
+ bool hasContentType() const;
+ QString contentType() const;
+ void setContentType(const QString &type);
+
+ virtual QString toString() const;
+ bool isValid() const;
+
+ virtual int majorVersion() const = 0;
+ virtual int minorVersion() const = 0;
+
+protected:
+ virtual bool parseLine(const QString &line, int number);
+ bool parse(const QString &str);
+ void setValid(bool);
+
+ QHttpHeader(QHttpHeaderPrivate &dd, const QString &str = QString());
+ QHttpHeader(QHttpHeaderPrivate &dd, const QHttpHeader &header);
+ QScopedPointer<QHttpHeaderPrivate> d_ptr;
+
+private:
+ Q_DECLARE_PRIVATE(QHttpHeader)
+};
+
+class QHttpResponseHeaderPrivate;
+class QHttpResponseHeader : public QHttpHeader
+{
+public:
+ QHttpResponseHeader();
+ QHttpResponseHeader(const QHttpResponseHeader &header);
+ QHttpResponseHeader(const QString &str);
+ QHttpResponseHeader(int code, const QString &text = QString(), int majorVer = 1, int minorVer = 1);
+ QHttpResponseHeader &operator=(const QHttpResponseHeader &header);
+
+ void setStatusLine(int code, const QString &text = QString(), int majorVer = 1, int minorVer = 1);
+
+ int statusCode() const;
+ QString reasonPhrase() const;
+
+ int majorVersion() const;
+ int minorVersion() const;
+
+ QString toString() const;
+
+protected:
+ bool parseLine(const QString &line, int number);
+
+private:
+ Q_DECLARE_PRIVATE(QHttpResponseHeader)
+ friend class QHttpPrivate;
+};
+
+#endif // QT_NO_HTTP
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QHTTP_H
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index c9a41176d6..104a21f591 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -53,7 +53,6 @@
#include <qbuffer.h>
#include <qpair.h>
-#include <qhttp.h>
#include <qdebug.h>
#ifndef QT_NO_HTTP