mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-12 09:04:33 +02:00
Fix QxtFifo and move qxtweb modules in their respective folder
This commit is contained in:
960
thirdparty/qxt/qxtweb-standalone/web/qhttpheader.cpp
vendored
Normal file
960
thirdparty/qxt/qxtweb-standalone/web/qhttpheader.cpp
vendored
Normal file
@@ -0,0 +1,960 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, 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.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//#define QHTTP_DEBUG
|
||||
|
||||
#include "qhttpheader.h"
|
||||
#include <QtCore/QSet>
|
||||
|
||||
|
||||
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());
|
||||
}
|
||||
|
180
thirdparty/qxt/qxtweb-standalone/web/qhttpheader.h
vendored
Normal file
180
thirdparty/qxt/qxtweb-standalone/web/qhttpheader.h
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 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$
|
||||
** Commercial Usage
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, 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.
|
||||
**
|
||||
** If you have questions regarding the use of this file, please contact
|
||||
** Nokia at qt-info@nokia.com.
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTP_H
|
||||
#define QHTTP_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
#include <QScopedPointer>
|
||||
#include <qxtglobal.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 QXT_WEB_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 QXT_WEB_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 QXT_WEB_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)
|
||||
};
|
||||
|
||||
#endif // QT_NO_HTTP
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QHTTP_H
|
313
thirdparty/qxt/qxtweb-standalone/web/qxtabstracthttpconnector.cpp
vendored
Normal file
313
thirdparty/qxt/qxtweb-standalone/web/qxtabstracthttpconnector.cpp
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtAbstractHttpConnector
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtAbstractHttpConnector class is a base class for defining
|
||||
HTTP-based protocols for use with QxtHttpSessionManager
|
||||
|
||||
QxtHttpSessionManager does the work of managing sessions and state for the
|
||||
otherwise stateless HTTP protocol, but it relies on QxtAbstractHttpConnector
|
||||
subclasses to implement the protocol used to communicate with the web server.
|
||||
|
||||
Subclasses are responsible for accepting new connections (by implementing
|
||||
listen(const QHostAddress&, quint16) and invoking addConnection(QIODevice*)),
|
||||
for informing the session manager when request headers are available (by
|
||||
implementing canParseRequest(const QByteArray&)), for parsing the request
|
||||
headers (by implementing parseRequest(QByteArray&)), and for writing response
|
||||
headers (by implementing writeHeaders(QIODevice*, const QHttpResponseHeader&)).
|
||||
|
||||
\sa QxtHttpSessionManager
|
||||
*/
|
||||
|
||||
#include "qxthttpsessionmanager.h"
|
||||
#include "qxtwebcontent.h"
|
||||
#include <QReadWriteLock>
|
||||
#include <QHash>
|
||||
#include <QIODevice>
|
||||
#include <QByteArray>
|
||||
#include <QPointer>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtAbstractHttpConnectorPrivate : public QxtPrivate<QxtAbstractHttpConnector>
|
||||
{
|
||||
public:
|
||||
QxtHttpSessionManager* manager;
|
||||
QReadWriteLock bufferLock, requestLock;
|
||||
QHash<QIODevice*, QByteArray> buffers; // connection->buffer
|
||||
QHash<QIODevice*, QPointer<QxtWebContent> > contents; // connection->content
|
||||
QHash<quint32, QIODevice*> requests; // requestID->connection
|
||||
quint32 nextRequestID;
|
||||
|
||||
inline quint32 getNextRequestID(QIODevice* connection)
|
||||
{
|
||||
QWriteLocker locker(&requestLock);
|
||||
do
|
||||
{
|
||||
nextRequestID++;
|
||||
if (nextRequestID == 0xFFFFFFFF) nextRequestID = 1;
|
||||
}
|
||||
while (requests.contains(nextRequestID)); // yeah, right
|
||||
requests[nextRequestID] = connection;
|
||||
return nextRequestID;
|
||||
}
|
||||
|
||||
inline void doneWithBuffer(QIODevice* device)
|
||||
{
|
||||
QWriteLocker locker(&bufferLock);
|
||||
buffers.remove(device);
|
||||
contents.remove(device);
|
||||
}
|
||||
|
||||
inline void doneWithRequest(quint32 requestID)
|
||||
{
|
||||
QWriteLocker locker(&requestLock);
|
||||
requests.remove(requestID);
|
||||
}
|
||||
|
||||
inline QIODevice* getRequestConnection(quint32 requestID)
|
||||
{
|
||||
QReadLocker locker(&requestLock);
|
||||
return requests[requestID];
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtAbstractHttpConnector with the specified \a parent.
|
||||
*
|
||||
* Note that this is an abstract class and cannot be instantiated directly.
|
||||
*/
|
||||
QxtAbstractHttpConnector::QxtAbstractHttpConnector(QObject* parent) : QObject(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtAbstractHttpConnector);
|
||||
qxt_d().nextRequestID = 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtAbstractHttpConnector::setSessionManager(QxtHttpSessionManager* manager)
|
||||
{
|
||||
qxt_d().manager = manager;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the session manager into which the connector is installed.
|
||||
*
|
||||
* \sa QxtHttpSessionManager::setConnector()
|
||||
*/
|
||||
QxtHttpSessionManager* QxtAbstractHttpConnector::sessionManager() const
|
||||
{
|
||||
return qxt_d().manager;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* Returns the QIODevice associated with a \a requestID.
|
||||
*
|
||||
* The request ID is generated internally and used by the session manager.
|
||||
*/
|
||||
QIODevice* QxtAbstractHttpConnector::getRequestConnection(quint32 requestID)
|
||||
{
|
||||
return qxt_d().getRequestConnection(requestID);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Starts managing a new connection from \a device.
|
||||
*
|
||||
* This function should be invoked by a subclass to attach incoming connections
|
||||
* to the session manager.
|
||||
*/
|
||||
void QxtAbstractHttpConnector::addConnection(QIODevice* device)
|
||||
{
|
||||
if(!device) return;
|
||||
QWriteLocker locker(&qxt_d().bufferLock);
|
||||
qxt_d().buffers[device] = QByteArray();
|
||||
QObject::connect(device, SIGNAL(readyRead()), this, SLOT(incomingData()));
|
||||
QObject::connect(device, SIGNAL(aboutToClose()), this, SLOT(disconnected()));
|
||||
QObject::connect(device, SIGNAL(disconnected()), this, SLOT(disconnected()));
|
||||
QObject::connect(device, SIGNAL(destroyed()), this, SLOT(disconnected()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtAbstractHttpConnector::incomingData(QIODevice* device)
|
||||
{
|
||||
if (!device)
|
||||
{
|
||||
device = qobject_cast<QIODevice*>(sender());
|
||||
if (!device) return;
|
||||
}
|
||||
// Scope things so we don't block access during incomingRequest()
|
||||
QHttpRequestHeader header;
|
||||
QxtWebContent *content = 0;
|
||||
{
|
||||
// Fetch the incoming data block
|
||||
QByteArray block = device->readAll();
|
||||
// Check for a current content "device"
|
||||
QReadLocker locker(&qxt_d().bufferLock);
|
||||
content = qxt_d().contents[device];
|
||||
if(content && (content->wantAll() || content->bytesNeeded() > 0)){
|
||||
// This block (or part of it) belongs to content device
|
||||
qint64 needed = block.size();
|
||||
if(!content->wantAll() && needed > content->bytesNeeded())
|
||||
needed = content->bytesNeeded();
|
||||
content->write(block.constData(), needed);
|
||||
if(block.size() <= needed)
|
||||
return; // Used it all ...
|
||||
block.remove(0, needed);
|
||||
}
|
||||
// The data received represents a new request (or start thereof)
|
||||
qxt_d().contents[device] = content = NULL;
|
||||
QByteArray& buffer = qxt_d().buffers[device];
|
||||
buffer.append(block);
|
||||
if (!canParseRequest(buffer)) return;
|
||||
// Have received all of the headers so we can start processing
|
||||
header = parseRequest(buffer);
|
||||
QByteArray start;
|
||||
int len = header.hasContentLength() ? int(header.contentLength()) : -1;
|
||||
if(len > 0)
|
||||
{
|
||||
if(len <= buffer.size()){
|
||||
// This request is fully-received & excess is another request
|
||||
// Leave in buffer & we'll fake a following "readyRead()"
|
||||
start = buffer.left(len);
|
||||
buffer = buffer.mid(len);
|
||||
content = new QxtWebContent(start, this);
|
||||
if(buffer.size() > 0)
|
||||
QMetaObject::invokeMethod(this, "incomingData",
|
||||
Qt::QueuedConnection, Q_ARG(QIODevice*, device));
|
||||
}
|
||||
else{
|
||||
// This request isn't finished yet but may still have one to
|
||||
// follow it. Remember the content device so we can append to
|
||||
// it until we've got it all.
|
||||
start = buffer;
|
||||
buffer.clear();
|
||||
qxt_d().contents[device] = content =
|
||||
new QxtWebContent(len, start, this, device);
|
||||
}
|
||||
}
|
||||
else if (header.hasKey("connection") && header.value("connection").toLower() == "close")
|
||||
{
|
||||
// Not pipelining so we want to pass all remaining data to the
|
||||
// content device. Although 'len' will be -1, we're using an
|
||||
// explict value for clarity. This causes the content device
|
||||
// to indicate it wants all remaining data.
|
||||
start = buffer;
|
||||
buffer.clear();
|
||||
qxt_d().contents[device] = content =
|
||||
new QxtWebContent(-1, start, this, device);
|
||||
} // else no content
|
||||
//
|
||||
// NOTE: Buffer lock goes out of scope after this point
|
||||
}
|
||||
// Allocate request ID and process it
|
||||
quint32 requestID = qxt_d().getNextRequestID(device);
|
||||
sessionManager()->incomingRequest(requestID, header, content);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtAbstractHttpConnector::disconnected()
|
||||
{
|
||||
quint32 requestID=0;
|
||||
QIODevice* device = qobject_cast<QIODevice*>(sender());
|
||||
if (!device) return;
|
||||
|
||||
requestID = qxt_d().requests.key(device);
|
||||
qxt_d().doneWithRequest(requestID);
|
||||
qxt_d().doneWithBuffer(device);
|
||||
sessionManager()->disconnected(device);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the current local server port assigned during binding. This will
|
||||
* be 0 if the connector isn't currently bound or when a port number isn't
|
||||
* applicable to the connector in use.
|
||||
*
|
||||
* \sa listen()
|
||||
*/
|
||||
quint16 QxtAbstractHttpConnector::serverPort() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn virtual bool QxtAbstractHttpConnector::listen(const QHostAddress& interface, quint16 port)
|
||||
* Invoked by the session manager to indicate that the connector should listen
|
||||
* for incoming connections on the specified \a interface and \a port.
|
||||
*
|
||||
* If the interface is QHostAddress::Any, the server will listen on all
|
||||
* network interfaces.
|
||||
* If the port is explicitly set to 0, the underlying network subsystem will
|
||||
* assign a port in the dynamic range. In this case, the resulting port number
|
||||
* may be obtained using the serverPort() method.
|
||||
*
|
||||
* Returns true on success, or false if the server could not begin listening.
|
||||
*
|
||||
* \sa addConnection(), shutdown()
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual bool QxtAbstractHttpConnector::shutdown()
|
||||
* Invoked by the session manager to indicate that the connector should close
|
||||
* it's listener port and stop accepting new connections. A shutdown may be
|
||||
* followed by a new listen (to switch ports or handle a change in the
|
||||
* machine's IP address).
|
||||
*
|
||||
* Returns true on success, or false if the server wasn't listening.
|
||||
*
|
||||
* \sa listen()
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual bool QxtAbstractHttpConnector::canParseRequest(const QByteArray& buffer)
|
||||
* Returns true if a complete set of request headers can be extracted from the provided \a buffer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual QHttpRequestHeader QxtAbstractHttpConnector::parseRequest(QByteArray& buffer)
|
||||
* Extracts a set of request headers from the provided \a buffer.
|
||||
*
|
||||
* Subclasses implementing this function must be sure to remove the parsed data from the buffer.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual void QxtAbstractHttpConnector::writeHeaders(QIODevice* device, const QHttpResponseHeader& header)
|
||||
* Writes a the response \a header to the specified \a device.
|
||||
*/
|
150
thirdparty/qxt/qxtweb-standalone/web/qxtabstracthttpconnector.h
vendored
Normal file
150
thirdparty/qxt/qxtweb-standalone/web/qxtabstracthttpconnector.h
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTABSTRACTHTTPCONNECTOR_H
|
||||
#define QXTABSTRACTHTTPCONNECTOR_H
|
||||
|
||||
#include "qxtglobal.h"
|
||||
#include <QObject>
|
||||
#include <QHostAddress>
|
||||
#include "qhttpheader.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QIODevice)
|
||||
QT_FORWARD_DECLARE_CLASS(QTcpServer)
|
||||
class QxtHttpSessionManager;
|
||||
class QxtSslServer;
|
||||
|
||||
class QxtAbstractHttpConnectorPrivate;
|
||||
class QXT_WEB_EXPORT QxtAbstractHttpConnector : public QObject
|
||||
{
|
||||
friend class QxtHttpSessionManager;
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtAbstractHttpConnector(QObject* parent = 0);
|
||||
virtual bool listen(const QHostAddress& iface, quint16 port) = 0;
|
||||
virtual bool shutdown() = 0;
|
||||
virtual quint16 serverPort() const;
|
||||
|
||||
protected:
|
||||
QxtHttpSessionManager* sessionManager() const;
|
||||
|
||||
void addConnection(QIODevice* device);
|
||||
QIODevice* getRequestConnection(quint32 requestID);
|
||||
virtual bool canParseRequest(const QByteArray& buffer) = 0;
|
||||
virtual QHttpRequestHeader parseRequest(QByteArray& buffer) = 0;
|
||||
virtual void writeHeaders(QIODevice* device, const QHttpResponseHeader& header) = 0;
|
||||
|
||||
private Q_SLOTS:
|
||||
void incomingData(QIODevice* device = 0);
|
||||
void disconnected();
|
||||
|
||||
private:
|
||||
void setSessionManager(QxtHttpSessionManager* manager);
|
||||
QXT_DECLARE_PRIVATE(QxtAbstractHttpConnector)
|
||||
};
|
||||
|
||||
class QxtHttpServerConnectorPrivate;
|
||||
class QXT_WEB_EXPORT QxtHttpServerConnector : public QxtAbstractHttpConnector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtHttpServerConnector(QObject* parent = 0, QTcpServer* server = 0);
|
||||
virtual bool listen(const QHostAddress& iface, quint16 port = 80);
|
||||
virtual bool shutdown();
|
||||
virtual quint16 serverPort() const;
|
||||
|
||||
QTcpServer* tcpServer() const;
|
||||
|
||||
protected:
|
||||
virtual bool canParseRequest(const QByteArray& buffer);
|
||||
virtual QHttpRequestHeader parseRequest(QByteArray& buffer);
|
||||
virtual void writeHeaders(QIODevice* device, const QHttpResponseHeader& header);
|
||||
|
||||
private Q_SLOTS:
|
||||
void acceptConnection();
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtHttpServerConnector)
|
||||
};
|
||||
|
||||
#ifndef QT_NO_OPENSSL
|
||||
class QXT_WEB_EXPORT QxtHttpsServerConnector : public QxtHttpServerConnector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtHttpsServerConnector(QObject* parent = 0);
|
||||
virtual bool listen(const QHostAddress& iface, quint16 port = 443);
|
||||
|
||||
QxtSslServer* tcpServer() const;
|
||||
|
||||
protected Q_SLOTS:
|
||||
virtual void peerVerifyError(const QSslError &error);
|
||||
virtual void sslErrors(const QList<QSslError> &errors);
|
||||
};
|
||||
#endif
|
||||
|
||||
class QxtScgiServerConnectorPrivate;
|
||||
class QXT_WEB_EXPORT QxtScgiServerConnector : public QxtAbstractHttpConnector
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtScgiServerConnector(QObject* parent = 0);
|
||||
virtual bool listen(const QHostAddress& iface, quint16 port);
|
||||
virtual bool shutdown();
|
||||
virtual quint16 serverPort() const;
|
||||
|
||||
protected:
|
||||
virtual bool canParseRequest(const QByteArray& buffer);
|
||||
virtual QHttpRequestHeader parseRequest(QByteArray& buffer);
|
||||
virtual void writeHeaders(QIODevice* device, const QHttpResponseHeader& header);
|
||||
|
||||
private Q_SLOTS:
|
||||
void acceptConnection();
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtScgiServerConnector)
|
||||
};
|
||||
/* Commented out pending implementation
|
||||
|
||||
class QxtFcgiConnectorPrivate;
|
||||
class QXT_WEB_EXPORT QxtFcgiConnector : public QxtAbstractHttpConnector {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtFcgiConnector(QObject* parent = 0);
|
||||
virtual bool listen(const QHostAddress& iface, quint16 port);
|
||||
virtual bool shutdown();
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtFcgiConnector)
|
||||
};
|
||||
*/
|
||||
|
||||
#endif // QXTABSTRACTHTTPCONNECTOR_H
|
129
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebservice.cpp
vendored
Normal file
129
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebservice.cpp
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtAbstractWebService
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtAbstractWebService class is a base interface for web services
|
||||
|
||||
QxtAbstractWebService provides a common interface for all web service classes.
|
||||
It uses an event-driven design instead of the more traditional request-response
|
||||
design used by many web scripting languages. When the user requests a web
|
||||
page, the service receives a pageRequestedEvent; after the service assembles
|
||||
the response, it must post a QxtWebPageEvent (or a subclass, such as
|
||||
QxtWebRedirectEvent or QxtWebErrorEvent).
|
||||
|
||||
Usually, an application providing web services will instantiate one
|
||||
QxtAbstractWebService object for each session, but this is not a requirement.
|
||||
For services that do not require session management, such as those that serve
|
||||
only static content, the session factory may return the same pointer for
|
||||
every invocation, or it may use some more exotic scheme.
|
||||
|
||||
When using one service object per session, each service's data members are
|
||||
independent and may be used to track state across requests. A service object
|
||||
shared among multiple sessions will retain state across requests as well but
|
||||
it must implement its own mechanism for separating non-shared data.
|
||||
|
||||
The QxtWeb architecture is not multithreaded; that is, QxtAbstractWebService
|
||||
does not automatically spawn a process for every session. However,
|
||||
QxtAbstractWebSessionManager performs thread-safe event dispatching, so
|
||||
subclasses of QxtAbstractWebService are free to create threads themselves.
|
||||
|
||||
A web service object may delete itself (see QObject::deleteLater()) to end
|
||||
the associated session.
|
||||
|
||||
\sa QxtAbstractWebSessionManager::ServiceFactory
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* The current architecture only allows for two behaviors: creating a new session
|
||||
* for every connection without a session cookie, or not using sessions at all.
|
||||
* This needs to be fixed by adding a function to the session manager to explicitly
|
||||
* create a new session.
|
||||
*/
|
||||
|
||||
#include "qxtabstractwebservice.h"
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtAbstractWebServicePrivate : public QxtPrivate<QxtAbstractWebService>
|
||||
{
|
||||
public:
|
||||
QXT_DECLARE_PUBLIC(QxtAbstractWebService)
|
||||
QxtAbstractWebServicePrivate() {}
|
||||
|
||||
QxtAbstractWebSessionManager* manager;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtAbstractWebService with the specified \a parent and session \a manager.
|
||||
*
|
||||
* Often, the session manager will also be the parent, but this is not a requirement.
|
||||
*
|
||||
* Note that this is an abstract class and cannot be instantiated directly.
|
||||
*/
|
||||
QxtAbstractWebService::QxtAbstractWebService(QxtAbstractWebSessionManager* manager, QObject* parent) : QObject(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtAbstractWebService);
|
||||
qxt_d().manager = manager;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the session manager associated with the web service.
|
||||
*/
|
||||
QxtAbstractWebSessionManager* QxtAbstractWebService::sessionManager() const
|
||||
{
|
||||
return qxt_d().manager;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn void QxtAbstractWebService::postEvent(QxtWebEvent* event)
|
||||
* Posts an \a event to a web browser that has made a request to the service.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual void QxtAbstractWebService::pageRequestedEvent(QxtWebRequestEvent* event)
|
||||
* This event handler must be reimplemented in subclasses to receive page
|
||||
* request events. The supplied \a event object is owned by the session
|
||||
* manager and remains valid until a corresponding response has been
|
||||
* processed. It must never be deleted by a service handler.
|
||||
*
|
||||
* Every page request event received MUST be responded to with a QxtWebPageEvent
|
||||
* or a QxtWebPageEvent subclass. This response does not have to be posted
|
||||
* during the execution of this function, to support asynchronous design, but
|
||||
* failure to post an event will cause the web browser making the request to
|
||||
* wait until it times out and leak memory from pending event objects.
|
||||
*
|
||||
* \sa QxtWebRequestEvent
|
||||
*/
|
59
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebservice.h
vendored
Normal file
59
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebservice.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTABSTRACTWEBSERVICE_H
|
||||
#define QXTABSTRACTWEBSERVICE_H
|
||||
|
||||
#include <QObject>
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
class QxtWebEvent;
|
||||
class QxtWebRequestEvent;
|
||||
|
||||
class QxtAbstractWebServicePrivate;
|
||||
class QXT_WEB_EXPORT QxtAbstractWebService : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QxtAbstractWebService(QxtAbstractWebSessionManager* manager, QObject* parent = 0);
|
||||
|
||||
QxtAbstractWebSessionManager* sessionManager() const;
|
||||
inline void postEvent(QxtWebEvent* event)
|
||||
{
|
||||
sessionManager()->postEvent(event);
|
||||
}
|
||||
virtual void pageRequestedEvent(QxtWebRequestEvent* event) = 0;
|
||||
// virtual void functionInvokedEvent(QxtWebRequestEvent* event) = 0; // todo: implement
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtAbstractWebService)
|
||||
};
|
||||
|
||||
#endif // QXTABSTRACTWEBSERVICE_H
|
237
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebsessionmanager.cpp
vendored
Normal file
237
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebsessionmanager.cpp
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtAbstractWebSessionManager
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtAbstractWebSessionManager class is a base class for QxtWeb session managers
|
||||
|
||||
QxtAbstractWebSessionManager is the base class for all QxtWeb session managers.
|
||||
|
||||
Session managers are responsible for managing connections between web browsers
|
||||
and web services, for creating sessions and their corresponding service objects,
|
||||
and for managing and dispatching events between browsers and services.
|
||||
|
||||
Note that the session manager is not responsible for destroying service objects.
|
||||
A service object that wishes to end its corresponding session may destroy itself
|
||||
(see QObject::deleteLater()) and QxtAbstractWebSessionManager will automatically
|
||||
clean up its internal session tracking data.
|
||||
|
||||
\sa QxtAbstractWebService
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \typedef QxtAbstractWebSessionManager::ServiceFactory
|
||||
* \brief Pointer to a function that generates QxtAbstractWebService objects
|
||||
*
|
||||
* \bold TYPEDEF: The ServiceFactory type represents a pointer to a function that takes two
|
||||
* parameters -- a QxtAbstractWebSessionManager* pointer and an int session ID.
|
||||
* The function must return a QxtAbstractWebService* pointer.
|
||||
*
|
||||
* Usually, an application providing web services will instantiate one
|
||||
* QxtAbstractWebService object for each session. For services that do not
|
||||
* require session management, such as those that serve only static pages, a
|
||||
* single service object may be shared for all requests, or it may use some
|
||||
* more exotic scheme. See QxtAbstractWebService for more details.
|
||||
*/
|
||||
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
#include "qxtabstractwebsessionmanager_p.h"
|
||||
#include "qxtabstractwebservice.h"
|
||||
#include "qxtmetaobject.h"
|
||||
#include <QtDebug>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
QxtAbstractWebSessionManagerPrivate::QxtAbstractWebSessionManagerPrivate() : factory(0), maxID(1)
|
||||
{
|
||||
// initializers only
|
||||
}
|
||||
|
||||
void QxtAbstractWebSessionManagerPrivate::sessionDestroyed(int sessionID)
|
||||
{
|
||||
if (sessions.contains(sessionID))
|
||||
{
|
||||
freeList.enqueue(sessionID);
|
||||
sessions.remove(sessionID);
|
||||
qxt_p().sessionDestroyed(sessionID);
|
||||
}
|
||||
}
|
||||
|
||||
int QxtAbstractWebSessionManagerPrivate::getNextID()
|
||||
{
|
||||
if (freeList.empty())
|
||||
{
|
||||
int next = maxID;
|
||||
maxID++;
|
||||
return next;
|
||||
}
|
||||
return freeList.dequeue();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtAbstractWebSessionManager with the specified \a parent.
|
||||
*
|
||||
* Note that this is an abstract class and cannot be instantiated directly.
|
||||
*/
|
||||
QxtAbstractWebSessionManager::QxtAbstractWebSessionManager(QObject* parent) : QObject(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtAbstractWebSessionManager);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the service \a factory for the session manager.
|
||||
*
|
||||
* The service factory is invoked every time the session manager creates a new
|
||||
* session. Usually, an application providing web services will instantiate one
|
||||
* QxtAbstractWebService object for each session. For services that do not
|
||||
* require separate sessions, such as those that serve only static pages, the
|
||||
* factory may return a pointer to the same object for multiple requests.
|
||||
*
|
||||
* \sa QxtAbstractWebSessionManager::ServiceFactory
|
||||
*/
|
||||
void QxtAbstractWebSessionManager::setServiceFactory(ServiceFactory* factory)
|
||||
{
|
||||
qxt_d().factory = factory;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the service factory in use by the session manager.
|
||||
*
|
||||
* \sa setServiceFactory()
|
||||
*/
|
||||
QxtAbstractWebSessionManager::ServiceFactory* QxtAbstractWebSessionManager::serviceFactory() const
|
||||
{
|
||||
return qxt_d().factory;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the service object corresponding to the provided \a sessionID.
|
||||
*/
|
||||
QxtAbstractWebService* QxtAbstractWebSessionManager::session(int sessionID) const
|
||||
{
|
||||
if (qxt_d().sessions.contains(sessionID))
|
||||
return qxt_d().sessions[sessionID];
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new session and returns its session ID.
|
||||
*
|
||||
* This function uses the serviceFactory() to request an instance of the web service.
|
||||
* \sa serviceFactory()
|
||||
*/
|
||||
int QxtAbstractWebSessionManager::createService()
|
||||
{
|
||||
int sessionID = qxt_d().getNextID();
|
||||
if (!qxt_d().factory) return sessionID;
|
||||
|
||||
QxtAbstractWebService* service = serviceFactory()(this, sessionID);
|
||||
qxt_d().sessions[sessionID] = service;
|
||||
// Using QxtBoundFunction to bind the sessionID to the slot invocation
|
||||
QxtMetaObject::connect(service, SIGNAL(destroyed()), QxtMetaObject::bind(&qxt_d(), SLOT(sessionDestroyed(int)), Q_ARG(int, sessionID)), Qt::QueuedConnection);
|
||||
return sessionID; // you can always get the service with this
|
||||
}
|
||||
|
||||
/*!
|
||||
* Notification that a service has been destroyed. The \a sessionID contains
|
||||
* the session ID# which has already been deallocated.
|
||||
*
|
||||
* Derived classes should reimplement this method to perform any housekeeping
|
||||
* chores needed when a service is removed (such as expiring session cookies).
|
||||
*
|
||||
* This default implementation does nothing at all.
|
||||
*/
|
||||
void QxtAbstractWebSessionManager::sessionDestroyed(int)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
* \fn virtual bool QxtAbstractWebSessionManager::start()
|
||||
* Starts the session manager.
|
||||
*
|
||||
* Session managers should not create sessions before start() is invoked.
|
||||
* Subclasses are encouraged to refrain from accepting connections until the
|
||||
* session manager is started.
|
||||
*
|
||||
* Returns true if the session was successfully started and false otherwise.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual bool QxtAbstractWebSessionManager::shutdown()
|
||||
* Stops the session manager.
|
||||
*
|
||||
* This method stops listening for new connections. Any active connections
|
||||
* remain viable. It is permissible to start() the session again after a
|
||||
* successful shutdown (to change ports for example).
|
||||
*
|
||||
* Returns true if the session was active (successfully shut down) and false
|
||||
* otherwise. This may be connected to an application's aboutToQuit() signal
|
||||
* but doing so is not likely to allow any currently processing requests to
|
||||
* complete.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual void QxtAbstractWebSessionManager::postEvent(QxtWebEvent* event)
|
||||
* Adds the \a event to the event queue for its associated session.
|
||||
*
|
||||
* Since different protocols may require different event processing behavior,
|
||||
* there is no default implementation in QxtAbstractWebSessionManager. Subclasses
|
||||
* are responsible for maintaining event queues and deciding when and where to
|
||||
* dispatch events.
|
||||
*
|
||||
* Depending on the subclass's implementation posted events may not be dispatched
|
||||
* for some time, and is is possible that an event may never be dispatched if
|
||||
* the session is terminated before the event is handled.
|
||||
*
|
||||
* \sa QxtWebEvent
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \fn virtual void QxtAbstractWebSessionManager::processEvents()
|
||||
* Processes pending events for all sessions.
|
||||
*
|
||||
* Since different protocols may require different event processing behavior,
|
||||
* there is no default implementation in QxtAbstractWebSessionManager. Subclasses
|
||||
* are responsible for maintaining event queues and deciding when and where to
|
||||
* dispatch events.
|
||||
*
|
||||
* processEvents() is not required to dispatch all events immediately. In
|
||||
* particular, some events may require certain conditions to be met before
|
||||
* they may be fully processed. (For example, because HTTP cookies are sent
|
||||
* as response headers, QxtHttpServerConnector may not dispatch a
|
||||
* QxtWebStoreCookieEvent until a QxtWebPageEvent for the same session is
|
||||
* available.) Unprocessed events may remain in the event queue.
|
||||
*
|
||||
* \sa QxtWebEvent
|
||||
*/
|
70
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebsessionmanager.h
vendored
Normal file
70
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebsessionmanager.h
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTABSTRACTWEBSESSIONMANAGER_H
|
||||
#define QXTABSTRACTWEBSESSIONMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <qxtglobal.h>
|
||||
class QxtAbstractWebService;
|
||||
class QxtWebEvent;
|
||||
|
||||
class QxtAbstractWebSessionManagerPrivate;
|
||||
class QXT_WEB_EXPORT QxtAbstractWebSessionManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
typedef QxtAbstractWebService* ServiceFactory(QxtAbstractWebSessionManager*, int);
|
||||
|
||||
QxtAbstractWebSessionManager(QObject* parent = 0);
|
||||
|
||||
virtual bool start() = 0;
|
||||
virtual void postEvent(QxtWebEvent* event) = 0;
|
||||
void setServiceFactory(ServiceFactory* factory);
|
||||
ServiceFactory* serviceFactory() const;
|
||||
|
||||
QxtAbstractWebService* session(int sessionID) const;
|
||||
|
||||
public Q_SLOTS:
|
||||
virtual bool shutdown() = 0;
|
||||
|
||||
protected:
|
||||
int createService();
|
||||
virtual void sessionDestroyed(int sessionID);
|
||||
|
||||
protected Q_SLOTS:
|
||||
virtual void processEvents() = 0;
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtAbstractWebSessionManager)
|
||||
};
|
||||
|
||||
#endif // QXTABSTRACTWEBSESSIONMANAGER_H
|
61
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebsessionmanager_p.h
vendored
Normal file
61
thirdparty/qxt/qxtweb-standalone/web/qxtabstractwebsessionmanager_p.h
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTABSTRACTWEBSESSIONMANAGER_P_H
|
||||
#define QXTABSTRACTWEBSESSIONMANAGER_P_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
#include <QHash>
|
||||
#include <QQueue>
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtAbstractWebSessionManagerPrivate : public QObject, public QxtPrivate<QxtAbstractWebSessionManager>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtAbstractWebSessionManagerPrivate();
|
||||
QXT_DECLARE_PUBLIC(QxtAbstractWebSessionManager)
|
||||
|
||||
QxtAbstractWebSessionManager::ServiceFactory* factory;
|
||||
QHash<int, QxtAbstractWebService*> sessions;
|
||||
QQueue<int> freeList;
|
||||
int maxID;
|
||||
|
||||
int getNextID();
|
||||
|
||||
public Q_SLOTS:
|
||||
void sessionDestroyed(int sessionID);
|
||||
};
|
||||
#endif // QXT_DOXYGEN_RUN
|
||||
|
||||
#endif // QXTABSTRACTWEBSESSIONMANAGER_P_H
|
162
thirdparty/qxt/qxtweb-standalone/web/qxthtmltemplate.cpp
vendored
Normal file
162
thirdparty/qxt/qxtweb-standalone/web/qxthtmltemplate.cpp
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtHtmlTemplate
|
||||
\inmodule QxtWeb
|
||||
\brief The QxtHtmlTemplate class provides a basic HTML template engine
|
||||
|
||||
open a file containing html code and php style variables.
|
||||
use the square bracket operators to assign content for a variable
|
||||
|
||||
\code
|
||||
QxtHtmlTemplate index;
|
||||
if(!index.open)
|
||||
return 404;
|
||||
index["content"]="hello world";
|
||||
echo()<<index.render();
|
||||
\endcode
|
||||
the realatet html code would look like:
|
||||
\code
|
||||
<html>
|
||||
<head>
|
||||
<title>Test Page</title>
|
||||
</head>
|
||||
<?=content?>
|
||||
</html>
|
||||
\endcode
|
||||
|
||||
funny storry: whe are using this class to make our documentation (eat your own dogfood, you know ;).
|
||||
but when we where parsing exactly this file you read right now the first time, QxtHtmlTemplate got stuck in an infinite loop. guess why. becouse of that example above :D
|
||||
So be warned: when you assign content to a variable that contains the variable name itself, render() will never return.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QxtHtmlTemplate::open(const QString& filename)
|
||||
Opens \a filename. Returns \c true on success and \c false on failure.
|
||||
Note that it will also return false for an empty html file.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QString QxtHtmlTemplate::render() const
|
||||
Uses the variables you set and renders the opened file.
|
||||
returns an empty string on failure.
|
||||
Does NOT take care of not assigned variables, they will remain in the returned string
|
||||
*/
|
||||
|
||||
#include "qxthtmltemplate.h"
|
||||
#include <QFile>
|
||||
#include <QStringList>
|
||||
|
||||
/*!
|
||||
Constructs a new QxtHtmlTemplate.
|
||||
*/
|
||||
QxtHtmlTemplate::QxtHtmlTemplate() : QMap<QString, QString>()
|
||||
{}
|
||||
|
||||
/*!
|
||||
Loads data \a d.
|
||||
*/
|
||||
void QxtHtmlTemplate::load(const QString& d)
|
||||
{
|
||||
data = d;
|
||||
}
|
||||
|
||||
bool QxtHtmlTemplate::open(const QString& filename)
|
||||
{
|
||||
QFile f(filename);
|
||||
f.open(QIODevice::ReadOnly);
|
||||
data = QString::fromLocal8Bit(f.readAll());
|
||||
f.close();
|
||||
if (data.isEmpty())
|
||||
{
|
||||
qWarning("QxtHtmlTemplate::open(\"%s\") empty or nonexistent", qPrintable(filename));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString QxtHtmlTemplate::render() const
|
||||
{
|
||||
///try to preserve indention by parsing char by char and saving the last non-space character
|
||||
|
||||
|
||||
QString output = data;
|
||||
int lastnewline = 0;
|
||||
|
||||
|
||||
for (int i = 0;i < output.count();i++)
|
||||
{
|
||||
if (output.at(i) == '\n')
|
||||
{
|
||||
lastnewline = i;
|
||||
}
|
||||
|
||||
if (output.at(i) == '<' && output.at(i + 1) == '?' && output.at(i + 2) == '=')
|
||||
{
|
||||
int j = i + 3;
|
||||
QString var;
|
||||
|
||||
for (int jj = j;jj < output.count();jj++)
|
||||
{
|
||||
if (output.at(jj) == '?' && output.at(jj + 1) == '>')
|
||||
{
|
||||
j = jj;
|
||||
break;
|
||||
}
|
||||
var += output.at(jj);
|
||||
}
|
||||
|
||||
|
||||
if (j == i)
|
||||
{
|
||||
qWarning("QxtHtmlTemplate::render() unterminated <?= ");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!contains(var))
|
||||
{
|
||||
qWarning("QxtHtmlTemplate::render() unused variable \"%s\"", qPrintable(var));
|
||||
continue;
|
||||
}
|
||||
output.replace(i, j - i + 2, QString(value(var)).replace('\n', '\n' + QString(i - lastnewline - 1, QChar(' '))));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
54
thirdparty/qxt/qxtweb-standalone/web/qxthtmltemplate.h
vendored
Normal file
54
thirdparty/qxt/qxtweb-standalone/web/qxthtmltemplate.h
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTHTMLTEMPLATE_H
|
||||
#define QXTHTMLTEMPLATE_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
#include <qxtglobal.h>
|
||||
|
||||
class QXT_WEB_EXPORT QxtHtmlTemplate : public QMap<QString, QString>
|
||||
{
|
||||
public:
|
||||
QxtHtmlTemplate();
|
||||
bool open(const QString& filename);
|
||||
void load(const QString& data);
|
||||
|
||||
QString render() const;
|
||||
|
||||
private:
|
||||
QString data;
|
||||
};
|
||||
|
||||
#endif // QXTHTMLTEMPLATE_H
|
||||
|
243
thirdparty/qxt/qxtweb-standalone/web/qxthttpserverconnector.cpp
vendored
Normal file
243
thirdparty/qxt/qxtweb-standalone/web/qxthttpserverconnector.cpp
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtHttpServerConnector
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtHttpServerConnector class provides a built-in HTTP server for QxtHttpSessionManager
|
||||
|
||||
QxtHttpSessionManager does the work of managing sessions and state for the
|
||||
otherwise stateless HTTP protocol, but it relies on QxtAbstractHttpConnector
|
||||
subclasses to implement the protocol used to communicate with the web server.
|
||||
|
||||
QxtHttpServerConnector implements a complete HTTP server internally and does
|
||||
not require an external web server to function. However, it provides very
|
||||
little control over the behavior of the web server and may not suitable for
|
||||
high traffic scenarios or virtual hosting configurations.
|
||||
|
||||
\sa QxtHttpSessionManager
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtHttpsServerConnector
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtHttpsServerConnector class provides a built-in HTTPS server for QxtHttpSessionManager
|
||||
|
||||
QxtHttpSessionManager does the work of managing sessions and state for the
|
||||
otherwise stateless HTTP protocol, but it relies on QxtAbstractHttpConnector
|
||||
subclasses to implement the protocol used to communicate with the web server.
|
||||
|
||||
QxtHttpsServerConnector is a convenience subclass of QxtHttpServerConnector
|
||||
that adds HTTPS handling to the internal web server by delegating the
|
||||
incoming connection handling to QxtSslServer.
|
||||
|
||||
QxtHttpsServerConnector is only available if Qt was compiled with OpenSSL support.
|
||||
|
||||
\sa QxtHttpSessionManager
|
||||
\sa QxtHttpServerConnector
|
||||
\sa QxtSslServer
|
||||
*/
|
||||
|
||||
#include "qxthttpsessionmanager.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include "qxtsslserver.h"
|
||||
#include <QTcpServer>
|
||||
#include <QHash>
|
||||
#include <QTcpSocket>
|
||||
#include <QString>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtHttpServerConnectorPrivate : public QxtPrivate<QxtHttpServerConnector>
|
||||
{
|
||||
public:
|
||||
QTcpServer* server;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtHttpServerConnector with the given \a parent and \a server.
|
||||
*
|
||||
* You may pass a QTcpServer subclass to the \a server parameter to enable customized behaviors, for
|
||||
* instance to use QSslSocket like QxtHttpsServerConnector does. Pass 0 (the default) to \a server
|
||||
* to allow QxtHttpServerConnector to create its own QTcpServer.
|
||||
*/
|
||||
QxtHttpServerConnector::QxtHttpServerConnector(QObject* parent, QTcpServer* server) : QxtAbstractHttpConnector(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtHttpServerConnector);
|
||||
if(server)
|
||||
qxt_d().server = server;
|
||||
else
|
||||
qxt_d().server = new QTcpServer(this);
|
||||
QObject::connect(qxt_d().server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtHttpServerConnector::listen(const QHostAddress& iface, quint16 port)
|
||||
{
|
||||
return qxt_d().server->listen(iface, port);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtHttpServerConnector::shutdown()
|
||||
{
|
||||
if(qxt_d().server->isListening()){
|
||||
qxt_d().server->close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
quint16 QxtHttpServerConnector::serverPort() const
|
||||
{
|
||||
return qxt_d().server->serverPort();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the QTcpServer used by this QxtHttpServerConnector. Use this pointer
|
||||
* to adjust the maxPendingConnections or QNetworkProxy properties of the
|
||||
* server.
|
||||
*/
|
||||
QTcpServer* QxtHttpServerConnector::tcpServer() const
|
||||
{
|
||||
return qxt_d().server;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpServerConnector::acceptConnection()
|
||||
{
|
||||
QTcpSocket* socket = qxt_d().server->nextPendingConnection();
|
||||
addConnection(socket);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtHttpServerConnector::canParseRequest(const QByteArray& buffer)
|
||||
{
|
||||
if (buffer.indexOf("\r\n\r\n") >= 0) return true; // 1.0+
|
||||
if (buffer.indexOf("\r\n") >= 0 && buffer.indexOf("HTTP/") == -1) return true; // 0.9
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
QHttpRequestHeader QxtHttpServerConnector::parseRequest(QByteArray& buffer)
|
||||
{
|
||||
int pos = buffer.indexOf("\r\n\r\n"), endpos = pos + 3;
|
||||
if (pos == -1)
|
||||
{
|
||||
pos = buffer.indexOf("\r\n"); // 0.9
|
||||
endpos = pos + 1;
|
||||
}
|
||||
|
||||
QHttpRequestHeader header(QString::fromUtf8(buffer.left(endpos)));
|
||||
QByteArray firstLine = buffer.left(buffer.indexOf('\r'));
|
||||
if (firstLine.indexOf("HTTP/") == -1)
|
||||
{
|
||||
header.setRequest(header.method(), header.path(), 0, 9);
|
||||
}
|
||||
buffer.remove(0, endpos + 1);
|
||||
return header;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtHttpServerConnector::writeHeaders(QIODevice* device, const QHttpResponseHeader& header)
|
||||
{
|
||||
if (header.majorVersion() == 0) return; // 0.9 doesn't have headers
|
||||
device->write(header.toString().toUtf8());
|
||||
}
|
||||
|
||||
#ifndef QT_NO_OPENSSL
|
||||
/*!
|
||||
* Creates a QxtHttpsServerConnector with the given \a parent.
|
||||
*/
|
||||
QxtHttpsServerConnector::QxtHttpsServerConnector(QObject* parent)
|
||||
: QxtHttpServerConnector(parent, new QxtSslServer)
|
||||
{
|
||||
// initializers only
|
||||
// Reparent the SSL server
|
||||
tcpServer()->setParent(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtHttpsServerConnector::listen(const QHostAddress& iface, quint16 port)
|
||||
{
|
||||
return QxtHttpServerConnector::listen(iface, port);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the QxtSslServer used by this QxtHttpsServerConnector. Use this
|
||||
* pointer to adjust the maxPendingConnections or QNetworkProxy properties of the
|
||||
* server or the SSL properties assigned to incoming connections.
|
||||
*/
|
||||
QxtSslServer* QxtHttpsServerConnector::tcpServer() const
|
||||
{
|
||||
return static_cast<QxtSslServer*>(QxtHttpServerConnector::tcpServer());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Handles peer verification errors during SSL negotiation. This method may
|
||||
* be overridden to tear-down the connection.
|
||||
*/
|
||||
void QxtHttpsServerConnector::peerVerifyError(const QSslError &error)
|
||||
{
|
||||
qWarning() << "QxtHttpsServerConnector::peerVerifyError(): " << error.errorString();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Handles errors with SSL negotiation. This method may be overridden to
|
||||
* examine the errors and take appropriate action. The default behavior
|
||||
* is to terminate the connection (ie: ignoreSslErrors() is NOT called).
|
||||
*/
|
||||
void QxtHttpsServerConnector::sslErrors(const QList<QSslError> &errors)
|
||||
{
|
||||
for(int i = 0; i < errors.size(); ++i)
|
||||
qWarning() << "QxtHttpsServerConnector::sslErrors(): " << errors.at(i).errorString();
|
||||
}
|
||||
#endif /* QT_NO_OPENSSL */
|
775
thirdparty/qxt/qxtweb-standalone/web/qxthttpsessionmanager.cpp
vendored
Normal file
775
thirdparty/qxt/qxtweb-standalone/web/qxthttpsessionmanager.cpp
vendored
Normal file
@@ -0,0 +1,775 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtHttpSessionManager
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtHttpSessionManager class provides a session manager for HTTP-based protocols
|
||||
|
||||
QxtHttpSessionManager is a QxtWeb session manager that adds session management
|
||||
support to the normally stateless HTTP model.
|
||||
|
||||
In addition to session management, QxtHttpSessionManager also supports a
|
||||
static service, which can serve content that does not require session management,
|
||||
such as static web pages. The static service is also used to respond to HTTP/0.9
|
||||
clients that do not support cookies and HTTP/1.0 and HTTP/1.1 clients that are
|
||||
rejecting cookies. If no static service is provided, these clients will only
|
||||
see an "Internal Configuration Error", so it is recommended to supply a static
|
||||
service, even one that only returns a more useful error message.
|
||||
|
||||
QxtHttpSessionManager attempts to be thread-safe in accepting connections and
|
||||
posting events. It is reentrant for all other functionality.
|
||||
|
||||
\sa class QxtAbstractWebService
|
||||
*/
|
||||
|
||||
#include "qxthttpsessionmanager.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include "qxtwebcontent.h"
|
||||
#include "qxtabstractwebservice.h"
|
||||
#include <qxtboundfunction.h>
|
||||
#include <QMutex>
|
||||
#include <QList>
|
||||
#include <QUuid>
|
||||
#include <QIODevice>
|
||||
#include <QByteArray>
|
||||
#include <QPair>
|
||||
#include <QMetaObject>
|
||||
#include <QThread>
|
||||
#include <qxtmetaobject.h>
|
||||
#include <QTcpSocket>
|
||||
#ifndef QT_NO_OPENSSL
|
||||
#include <QSslSocket>
|
||||
#endif
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtHttpSessionManagerPrivate : public QxtPrivate<QxtHttpSessionManager>
|
||||
{
|
||||
public:
|
||||
struct ConnectionState
|
||||
{
|
||||
QxtBoundFunction *onBytesWritten, *onReadyRead, *onAboutToClose;
|
||||
bool readyRead;
|
||||
bool finishedTransfer;
|
||||
bool keepAlive;
|
||||
bool streaming;
|
||||
int httpMajorVersion;
|
||||
int httpMinorVersion;
|
||||
int sessionID;
|
||||
|
||||
void clearHandlers() {
|
||||
delete onBytesWritten;
|
||||
delete onReadyRead;
|
||||
delete onAboutToClose;
|
||||
onBytesWritten = onReadyRead = onAboutToClose = 0;
|
||||
}
|
||||
};
|
||||
|
||||
QxtHttpSessionManagerPrivate() : iface(QHostAddress::Any), port(80), sessionCookieName("sessionID"), connector(0), staticService(0), autoCreateSession(true),
|
||||
eventLock(QMutex::Recursive), sessionLock(QMutex::Recursive) {}
|
||||
QXT_DECLARE_PUBLIC(QxtHttpSessionManager)
|
||||
|
||||
QHostAddress iface;
|
||||
quint16 port;
|
||||
QByteArray sessionCookieName;
|
||||
QxtAbstractHttpConnector* connector;
|
||||
QxtAbstractWebService* staticService;
|
||||
bool autoCreateSession;
|
||||
|
||||
QMutex eventLock;
|
||||
QList<QxtWebEvent*> eventQueue;
|
||||
QHash<QPair<int,int>, QxtWebRequestEvent*> pendingRequests;
|
||||
|
||||
QMutex sessionLock;
|
||||
QHash<QUuid, int> sessionKeys; // sessionKey->sessionID
|
||||
QHash<QIODevice*, ConnectionState> connectionState; // connection->state
|
||||
|
||||
Qt::HANDLE mainThread;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs a new QxtHttpSessionManager with the specified \a parent.
|
||||
*/
|
||||
QxtHttpSessionManager::QxtHttpSessionManager(QObject* parent) : QxtAbstractWebSessionManager(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtHttpSessionManager);
|
||||
qxt_d().mainThread = QThread::currentThreadId();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the interface on which the session manager will listen for incoming connections.
|
||||
* \sa setListenInterface()
|
||||
*/
|
||||
QHostAddress QxtHttpSessionManager::listenInterface() const
|
||||
{
|
||||
return qxt_d().iface;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the interface \a iface on which the session manager will listen for incoming
|
||||
* connections.
|
||||
*
|
||||
* The default value is QHostAddress::Any, which will cause the session manager
|
||||
* to listen on all network interfaces.
|
||||
*
|
||||
* \sa QxtAbstractHttpConnector::listen()
|
||||
*/
|
||||
void QxtHttpSessionManager::setListenInterface(const QHostAddress& iface)
|
||||
{
|
||||
qxt_d().iface = iface;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the port on which the session manager is expected to listen for
|
||||
* incoming connections. This is always whatever value was supplied in the
|
||||
* last setPort() and not neccessarily the port number actually being
|
||||
* used.
|
||||
* \sa setPort(), serverPort()
|
||||
*/
|
||||
quint16 QxtHttpSessionManager::port() const
|
||||
{
|
||||
return qxt_d().port;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a port on which the session manager should listen for incoming
|
||||
* connections.
|
||||
*
|
||||
* The default value is to listen on port 80. This is an acceptable value when
|
||||
* using QxtHttpServerConnector, but it is not likely to be desirable for other
|
||||
* connectors. You may also use 0 to allow the network layer to dynamically
|
||||
* assign a port number. In this case, the serverPort() method will
|
||||
* return the actual port assigned once the session has been successfully
|
||||
* started.
|
||||
*
|
||||
* \note Setting the port number after the session has been started will
|
||||
* have no effect unless it is shutdown and started again.
|
||||
*
|
||||
* \sa port(), serverPort()
|
||||
*/
|
||||
void QxtHttpSessionManager::setPort(quint16 port)
|
||||
{
|
||||
qxt_d().port = port;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the port on which the session manager is listening for incoming
|
||||
* connections. This will be 0 if the session manager has not been started
|
||||
* or was shutdown.
|
||||
* \sa setInterface(), setPort()
|
||||
*/
|
||||
quint16 QxtHttpSessionManager::serverPort() const
|
||||
{
|
||||
if(qxt_d().connector)
|
||||
return connector()->serverPort();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtHttpSessionManager::start()
|
||||
{
|
||||
Q_ASSERT(qxt_d().connector);
|
||||
return connector()->listen(listenInterface(), port());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtHttpSessionManager::shutdown()
|
||||
{
|
||||
Q_ASSERT(qxt_d().connector);
|
||||
return connector()->shutdown();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the name of the HTTP cookie used to track sessions in the web browser.
|
||||
* \sa setSessionCookieName()
|
||||
*/
|
||||
QByteArray QxtHttpSessionManager::sessionCookieName() const
|
||||
{
|
||||
return qxt_d().sessionCookieName;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a name of the HTTP cookie used to track sessions in the web
|
||||
* browser.
|
||||
*
|
||||
* The default value is "sessionID".
|
||||
*
|
||||
* \sa sessionCookieName()
|
||||
*/
|
||||
void QxtHttpSessionManager::setSessionCookieName(const QByteArray& name)
|
||||
{
|
||||
qxt_d().sessionCookieName = name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a connector used to manage connections to web browsers.
|
||||
*
|
||||
* \sa connector()
|
||||
*/
|
||||
void QxtHttpSessionManager::setConnector(QxtAbstractHttpConnector* connector)
|
||||
{
|
||||
connector->setSessionManager(this);
|
||||
qxt_d().connector = connector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a connector used to manage connections to web browsers.
|
||||
*
|
||||
* This overload is provided for convenience and can construct the predefined
|
||||
* connectors provided with Qxt.
|
||||
*
|
||||
* \sa connector()
|
||||
*/
|
||||
void QxtHttpSessionManager::setConnector(Connector connector)
|
||||
{
|
||||
if (connector == HttpServer)
|
||||
setConnector(new QxtHttpServerConnector(this));
|
||||
else if (connector == Scgi)
|
||||
setConnector(new QxtScgiServerConnector(this));
|
||||
/* commented out pending implementation
|
||||
|
||||
else if(connector == Fcgi)
|
||||
setConnector(new QxtFcgiConnector(this));
|
||||
*/
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the connector used to manage connections to web browsers.
|
||||
* \sa setConnector()
|
||||
*/
|
||||
QxtAbstractHttpConnector* QxtHttpSessionManager::connector() const
|
||||
{
|
||||
return qxt_d().connector;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns \c true if sessions are automatically created for every connection
|
||||
* that does not already have a session cookie associated with it; otherwise
|
||||
* returns \c false.
|
||||
* \sa setAutoCreateSession()
|
||||
*/
|
||||
bool QxtHttpSessionManager::autoCreateSession() const
|
||||
{
|
||||
return qxt_d().autoCreateSession;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets \a enabled whether sessions are automatically created for every connection
|
||||
* that does not already have a session cookie associated with it.
|
||||
*
|
||||
* Sessions are only created for clients that support HTTP cookies. HTTP/0.9
|
||||
* clients will never generate a session.
|
||||
*
|
||||
* \sa autoCreateSession()
|
||||
*/
|
||||
void QxtHttpSessionManager::setAutoCreateSession(bool enable)
|
||||
{
|
||||
qxt_d().autoCreateSession = enable;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the QxtAbstractWebService that is used to respond to requests from
|
||||
* connections that are not associated with a session.
|
||||
*
|
||||
* \sa setStaticContentService()
|
||||
*/
|
||||
QxtAbstractWebService* QxtHttpSessionManager::staticContentService() const
|
||||
{
|
||||
return qxt_d().staticService;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a service that is used to respond to requests from
|
||||
* connections that are not associated with a session.
|
||||
*
|
||||
* If no static content service is set, connections that are not associated
|
||||
* with a session will receive an "Internal Configuration Error".
|
||||
*
|
||||
* \sa staticContentService()
|
||||
*/
|
||||
void QxtHttpSessionManager::setStaticContentService(QxtAbstractWebService* service)
|
||||
{
|
||||
qxt_d().staticService = service;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtHttpSessionManager::postEvent(QxtWebEvent* h)
|
||||
{
|
||||
qxt_d().eventLock.lock();
|
||||
qxt_d().eventQueue.append(h);
|
||||
qxt_d().eventLock.unlock();
|
||||
// if(h->type() == QxtWebEvent::Page)
|
||||
QMetaObject::invokeMethod(this, "processEvents", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
/*!
|
||||
* This method removes the session cookie value corresponding to a deleted
|
||||
* service.
|
||||
*/
|
||||
void QxtHttpSessionManager::sessionDestroyed(int sessionID)
|
||||
{
|
||||
QMutexLocker locker(&qxt_d().sessionLock);
|
||||
QUuid key = qxt_d().sessionKeys.key(sessionID);
|
||||
// qDebug() << Q_FUNC_INFO << "sessionID" << sessionID << "key" << key;
|
||||
if(!key.isNull())
|
||||
qxt_d().sessionKeys.remove(key);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Creates a new session and sends the session key to the web browser.
|
||||
*
|
||||
* Subclasses may override this function to perform custom session initialization,
|
||||
* but they must call the base class implementation in order to update the internal
|
||||
* session database and fetch a new session ID.
|
||||
*/
|
||||
int QxtHttpSessionManager::newSession()
|
||||
{
|
||||
QMutexLocker locker(&qxt_d().sessionLock);
|
||||
int sessionID = createService();
|
||||
QUuid key;
|
||||
do
|
||||
{
|
||||
key = QUuid::createUuid();
|
||||
}
|
||||
while (qxt_d().sessionKeys.contains(key));
|
||||
qxt_d().sessionKeys[key] = sessionID;
|
||||
postEvent(new QxtWebStoreCookieEvent(sessionID, qxt_d().sessionCookieName, key.toString()));
|
||||
return sessionID;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Handles incoming HTTP requests and dispatches them to the appropriate service.
|
||||
*
|
||||
* The \a requestID is an opaque value generated by the connector.
|
||||
*
|
||||
* Subclasses may override this function to perform preprocessing on each
|
||||
* request, but they must call the base class implementation in order to
|
||||
* generate and dispatch the appropriate events.
|
||||
*
|
||||
* To facilitate use with multi-threaded applications, the event will remain
|
||||
* valid until a response is posted.
|
||||
*/
|
||||
void QxtHttpSessionManager::incomingRequest(quint32 requestID, const QHttpRequestHeader& header, QxtWebContent* content)
|
||||
{
|
||||
QMultiHash<QString, QString> cookies;
|
||||
foreach(const QString& cookie, header.allValues("cookie")) // QHttpHeader is case-insensitive, thankfully
|
||||
{
|
||||
foreach(const QString& kv, cookie.split("; "))
|
||||
{
|
||||
int pos = kv.indexOf('=');
|
||||
if (pos == -1) continue;
|
||||
cookies.insert(kv.left(pos), kv.mid(pos + 1));
|
||||
}
|
||||
}
|
||||
|
||||
int sessionID;
|
||||
QString sessionCookie = cookies.value(qxt_d().sessionCookieName);
|
||||
|
||||
qxt_d().sessionLock.lock();
|
||||
if (qxt_d().sessionKeys.contains(sessionCookie))
|
||||
{
|
||||
sessionID = qxt_d().sessionKeys[sessionCookie];
|
||||
if(!sessionID && header.majorVersion() > 0 && qxt_d().autoCreateSession)
|
||||
sessionID = newSession();
|
||||
}
|
||||
else if (header.majorVersion() > 0 && qxt_d().autoCreateSession)
|
||||
{
|
||||
sessionID = newSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
sessionID = 0;
|
||||
}
|
||||
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
state.sessionID = sessionID;
|
||||
state.httpMajorVersion = header.majorVersion();
|
||||
state.httpMinorVersion = header.minorVersion();
|
||||
if (state.httpMajorVersion == 0 || (state.httpMajorVersion == 1 && state.httpMinorVersion == 0) || header.value("connection").toLower() == "close")
|
||||
state.keepAlive = false;
|
||||
else
|
||||
state.keepAlive = true;
|
||||
qxt_d().sessionLock.unlock();
|
||||
|
||||
QxtWebRequestEvent* event = new QxtWebRequestEvent(sessionID, requestID, QUrl::fromEncoded(header.path().toUtf8()));
|
||||
qxt_d().eventLock.lock();
|
||||
qxt_d().pendingRequests.insert(QPair<int,int>(sessionID, requestID), event);
|
||||
qxt_d().eventLock.unlock();
|
||||
QTcpSocket* socket = qobject_cast<QTcpSocket*>(device);
|
||||
if (socket)
|
||||
{
|
||||
event->remoteAddress = socket->peerAddress();
|
||||
#ifndef QT_NO_OPENSSL
|
||||
QSslSocket* sslSocket = qobject_cast<QSslSocket*>(socket);
|
||||
if(sslSocket) {
|
||||
event->isSecure = true;
|
||||
event->clientCertificate = sslSocket->peerCertificate();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
event->method = header.method();
|
||||
event->cookies = cookies;
|
||||
event->url.setScheme("http");
|
||||
if (event->url.host().isEmpty())
|
||||
event->url.setHost(header.value("host"));
|
||||
if (event->url.port() == -1)
|
||||
event->url.setPort(port());
|
||||
event->contentType = header.contentType();
|
||||
event->content = content;
|
||||
typedef QPair<QString, QString> StringPair;
|
||||
foreach(const StringPair& line, header.values())
|
||||
{
|
||||
if (line.first.toLower() == "cookie") continue;
|
||||
event->headers.insert(line.first, line.second);
|
||||
}
|
||||
event->headers.insert("X-Request-Protocol", "HTTP/" + QString::number(state.httpMajorVersion) + '.' + QString::number(state.httpMinorVersion));
|
||||
if (sessionID && session(sessionID))
|
||||
{
|
||||
QxtAbstractWebService *service = session(sessionID);
|
||||
if(content)
|
||||
content->setParent(service); // Set content ownership to the service
|
||||
service->pageRequestedEvent(event);
|
||||
}
|
||||
else if (qxt_d().staticService)
|
||||
{
|
||||
qxt_d().staticService->pageRequestedEvent(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
postEvent(new QxtWebErrorEvent(0, requestID, 500, "Internal Configuration Error"));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::disconnected(QIODevice* device)
|
||||
{
|
||||
QMutexLocker locker(&qxt_d().sessionLock);
|
||||
if (qxt_d().connectionState.contains(device)) {
|
||||
qxt_d().connectionState[device].clearHandlers();
|
||||
}
|
||||
qxt_d().connectionState.remove(device);
|
||||
device->deleteLater();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtHttpSessionManager::processEvents()
|
||||
{
|
||||
if (QThread::currentThreadId() != qxt_d().mainThread)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "processEvents", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
QxtHttpSessionManagerPrivate& d = qxt_d();
|
||||
QMutexLocker locker(&d.eventLock);
|
||||
if (!d.eventQueue.count()) return;
|
||||
|
||||
int ct = d.eventQueue.count(), sessionID = 0, requestID = 0, pagePos = -1;
|
||||
QxtWebRedirectEvent* re = 0;
|
||||
QxtWebPageEvent* pe = 0;
|
||||
for (int i = 0; i < ct; i++)
|
||||
{
|
||||
if (d.eventQueue[i]->type() != QxtWebEvent::Page && d.eventQueue[i]->type() != QxtWebEvent::Redirect) continue;
|
||||
pagePos = i;
|
||||
sessionID = d.eventQueue[i]->sessionID;
|
||||
if (d.eventQueue[pagePos]->type() == QxtWebEvent::Redirect)
|
||||
{
|
||||
re = static_cast<QxtWebRedirectEvent*>(d.eventQueue[pagePos]);
|
||||
}
|
||||
pe = static_cast<QxtWebPageEvent*>(d.eventQueue[pagePos]);
|
||||
requestID = pe->requestID;
|
||||
break;
|
||||
}
|
||||
if (pagePos == -1) return; // no pages to send yet
|
||||
|
||||
QHttpResponseHeader header;
|
||||
QList<int> removeIDs;
|
||||
QxtWebEvent* e = 0;
|
||||
for (int i = 0; i < pagePos; i++)
|
||||
{
|
||||
if (d.eventQueue[i]->sessionID != sessionID) continue;
|
||||
e = d.eventQueue[i];
|
||||
if (e->type() == QxtWebEvent::StoreCookie)
|
||||
{
|
||||
QxtWebStoreCookieEvent* ce = static_cast<QxtWebStoreCookieEvent*>(e);
|
||||
QString cookie = ce->name + '=' + ce->data;
|
||||
if (!ce->path.isEmpty())
|
||||
cookie += "; path=" + ce->path;
|
||||
if (ce->expiration.isValid())
|
||||
{
|
||||
cookie += "; max-age=" + QString::number(QDateTime::currentDateTime().secsTo(ce->expiration))
|
||||
+ "; expires=" + ce->expiration.toUTC().toString("ddd, dd-MMM-YYYY hh:mm:ss GMT");
|
||||
}
|
||||
header.addValue("set-cookie", cookie);
|
||||
removeIDs.push_front(i);
|
||||
}
|
||||
else if (e->type() == QxtWebEvent::RemoveCookie)
|
||||
{
|
||||
QxtWebRemoveCookieEvent* ce = static_cast<QxtWebRemoveCookieEvent*>(e);
|
||||
QString path;
|
||||
if(!ce->path.isEmpty()) path = "path=" + ce->path + "; ";
|
||||
header.addValue("set-cookie", ce->name + "=; "+path+"max-age=0; expires=" + QDateTime(QDate(1970, 1, 1)).toString("ddd, dd-MMM-YYYY hh:mm:ss GMT"));
|
||||
removeIDs.push_front(i);
|
||||
}
|
||||
}
|
||||
removeIDs.push_front(pagePos);
|
||||
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
QxtWebContent* content = qobject_cast<QxtWebContent*>(device);
|
||||
// TODO: This should only be invoked when pipelining occurs
|
||||
// In theory it shouldn't cause any problems as POST is specced to not be pipelined
|
||||
if (content) content->ignoreRemainingContent();
|
||||
QHash<QPair<int,int>,QxtWebRequestEvent*>::iterator iPending =
|
||||
qxt_d().pendingRequests.find(QPair<int,int>(sessionID, requestID));
|
||||
if(iPending != qxt_d().pendingRequests.end()){
|
||||
delete *iPending;
|
||||
qxt_d().pendingRequests.erase(iPending);
|
||||
}
|
||||
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[connector()->getRequestConnection(requestID)];
|
||||
QIODevice* source;
|
||||
header.setStatusLine(pe->status, pe->statusMessage, state.httpMajorVersion, state.httpMinorVersion);
|
||||
|
||||
if (re)
|
||||
{
|
||||
header.setValue("location", re->destination);
|
||||
}
|
||||
|
||||
// Set custom header values
|
||||
for (QMultiHash<QString, QString>::iterator it = pe->headers.begin(); it != pe->headers.end(); ++it)
|
||||
{
|
||||
header.setValue(it.key(), it.value());
|
||||
}
|
||||
|
||||
header.setContentType(pe->contentType);
|
||||
if (state.httpMajorVersion == 0 || (state.httpMajorVersion == 1 && state.httpMinorVersion == 0))
|
||||
pe->chunked = false;
|
||||
|
||||
source = pe->dataSource;
|
||||
state.finishedTransfer = false;
|
||||
bool emptyContent = !source->bytesAvailable() && !pe->streaming;
|
||||
state.readyRead = source->bytesAvailable();
|
||||
state.streaming = pe->streaming;
|
||||
|
||||
if (emptyContent)
|
||||
{
|
||||
header.setValue("connection", "close");
|
||||
connector()->writeHeaders(device, header);
|
||||
closeConnection(requestID);
|
||||
}
|
||||
else
|
||||
{
|
||||
pe->dataSource = 0; // so that it isn't destroyed when the event is deleted
|
||||
state.clearHandlers(); // disconnect old handlers
|
||||
|
||||
if (!pe->chunked)
|
||||
{
|
||||
state.keepAlive = false;
|
||||
state.onBytesWritten = QxtMetaObject::bind(this, SLOT(sendNextBlock(int, QObject*)), Q_ARG(int, requestID), Q_ARG(QObject*, source));
|
||||
state.onReadyRead = QxtMetaObject::bind(this, SLOT(blockReadyRead(int, QObject*)), Q_ARG(int, requestID), Q_ARG(QObject*, source));
|
||||
state.onAboutToClose = QxtMetaObject::bind(this, SLOT(closeConnection(int)), Q_ARG(int, requestID));
|
||||
}
|
||||
else
|
||||
{
|
||||
header.setValue("transfer-encoding", "chunked");
|
||||
state.onBytesWritten = QxtMetaObject::bind(this, SLOT(sendNextChunk(int, QObject*)), Q_ARG(int, requestID), Q_ARG(QObject*, source));
|
||||
state.onReadyRead = QxtMetaObject::bind(this, SLOT(chunkReadyRead(int, QObject*)), Q_ARG(int, requestID), Q_ARG(QObject*, source));
|
||||
state.onAboutToClose = QxtMetaObject::bind(this, SLOT(sendEmptyChunk(int, QObject*)), Q_ARG(int, requestID), Q_ARG(QObject*, source));
|
||||
}
|
||||
QxtMetaObject::connect(device, SIGNAL(bytesWritten(qint64)), state.onBytesWritten, Qt::QueuedConnection);
|
||||
QxtMetaObject::connect(source, SIGNAL(readyRead()), state.onReadyRead, Qt::QueuedConnection);
|
||||
QxtMetaObject::connect(source, SIGNAL(aboutToClose()), state.onAboutToClose, Qt::QueuedConnection);
|
||||
QObject::connect(device, SIGNAL(destroyed()), source, SLOT(deleteLater()));
|
||||
|
||||
if (state.keepAlive)
|
||||
{
|
||||
header.setValue("connection", "keep-alive");
|
||||
}
|
||||
else
|
||||
{
|
||||
header.setValue("connection", "close");
|
||||
}
|
||||
connector()->writeHeaders(device, header);
|
||||
if (state.readyRead)
|
||||
{
|
||||
if (pe->chunked)
|
||||
sendNextChunk(requestID, source);
|
||||
else
|
||||
sendNextBlock(requestID, source);
|
||||
}
|
||||
}
|
||||
|
||||
foreach(int id, removeIDs)
|
||||
{
|
||||
delete d.eventQueue.takeAt(id);
|
||||
}
|
||||
|
||||
if (d.eventQueue.count())
|
||||
QMetaObject::invokeMethod(this, "processEvents", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::chunkReadyRead(int requestID, QObject* dataSourceObject)
|
||||
{
|
||||
QIODevice* dataSource = static_cast<QIODevice*>(dataSourceObject);
|
||||
if (!dataSource->bytesAvailable()) return;
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if (!device->bytesToWrite() || qxt_d().connectionState[device].readyRead == false)
|
||||
{
|
||||
qxt_d().connectionState[device].readyRead = true;
|
||||
sendNextChunk(requestID, dataSourceObject);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::sendNextChunk(int requestID, QObject* dataSourceObject)
|
||||
{
|
||||
QIODevice* dataSource = static_cast<QIODevice*>(dataSourceObject);
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
if (state.finishedTransfer)
|
||||
{
|
||||
// This is just the last block written; we're done with it
|
||||
return;
|
||||
}
|
||||
if (!dataSource->bytesAvailable())
|
||||
{
|
||||
state.readyRead = false;
|
||||
return;
|
||||
}
|
||||
QByteArray chunk = dataSource->read(32768); // this is a good chunk size
|
||||
if (chunk.size())
|
||||
{
|
||||
QByteArray data = QString::number(chunk.size(), 16).toUtf8() + "\r\n" + chunk + "\r\n";
|
||||
device->write(data);
|
||||
}
|
||||
state.readyRead = false;
|
||||
if (!state.streaming && !dataSource->bytesAvailable())
|
||||
QMetaObject::invokeMethod(this, "sendEmptyChunk", Q_ARG(int, requestID), Q_ARG(QObject*, dataSource));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::sendEmptyChunk(int requestID, QObject* dataSource)
|
||||
{
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if (!qxt_d().connectionState.contains(device)) return; // in case a disconnect signal and a bytesWritten signal get fired in the wrong order
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
if (state.finishedTransfer) return;
|
||||
state.finishedTransfer = true;
|
||||
device->write("0\r\n\r\n");
|
||||
dataSource->deleteLater();
|
||||
if (state.keepAlive)
|
||||
{
|
||||
delete state.onBytesWritten;
|
||||
state.onBytesWritten = 0;
|
||||
connector()->incomingData(device);
|
||||
}
|
||||
else
|
||||
{
|
||||
closeConnection(requestID);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::closeConnection(int requestID)
|
||||
{
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
state.finishedTransfer = true;
|
||||
QTcpSocket* socket = qobject_cast<QTcpSocket*>(device);
|
||||
if (socket)
|
||||
socket->disconnectFromHost();
|
||||
else
|
||||
device->close();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::blockReadyRead(int requestID, QObject* dataSourceObject)
|
||||
{
|
||||
QIODevice* dataSource = static_cast<QIODevice*>(dataSourceObject);
|
||||
if (!dataSource->bytesAvailable()) return;
|
||||
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if (!device->bytesToWrite() || qxt_d().connectionState[device].readyRead == false)
|
||||
{
|
||||
qxt_d().connectionState[device].readyRead = true;
|
||||
sendNextBlock(requestID, dataSourceObject);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtHttpSessionManager::sendNextBlock(int requestID, QObject* dataSourceObject)
|
||||
{
|
||||
QIODevice* dataSource = static_cast<QIODevice*>(dataSourceObject);
|
||||
QIODevice* device = connector()->getRequestConnection(requestID);
|
||||
if (!qxt_d().connectionState.contains(device)) return; // in case a disconnect signal and a bytesWritten signal get fired in the wrong order
|
||||
QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[device];
|
||||
if (state.finishedTransfer) return;
|
||||
if (!dataSource->bytesAvailable())
|
||||
{
|
||||
state.readyRead = false;
|
||||
return;
|
||||
}
|
||||
QByteArray chunk = dataSource->read(32768); // empirically determined to be a good chunk size
|
||||
device->write(chunk);
|
||||
state.readyRead = false;
|
||||
if (!state.streaming && !dataSource->bytesAvailable())
|
||||
{
|
||||
closeConnection(requestID);
|
||||
dataSource->deleteLater();
|
||||
state.clearHandlers();
|
||||
}
|
||||
}
|
105
thirdparty/qxt/qxtweb-standalone/web/qxthttpsessionmanager.h
vendored
Normal file
105
thirdparty/qxt/qxtweb-standalone/web/qxthttpsessionmanager.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTHTTPSESSIONMANAGER_H
|
||||
#define QXTHTTPSESSIONMANAGER_H
|
||||
|
||||
#include "qxtabstractwebsessionmanager.h"
|
||||
#include "qxtabstracthttpconnector.h"
|
||||
#include <QHostAddress>
|
||||
#include "qhttpheader.h"
|
||||
|
||||
class QxtWebEvent;
|
||||
class QxtWebContent;
|
||||
|
||||
class QxtHttpSessionManagerPrivate;
|
||||
class QXT_WEB_EXPORT QxtHttpSessionManager : public QxtAbstractWebSessionManager
|
||||
{
|
||||
friend class QxtAbstractHttpConnector;
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QHostAddress listenInterface READ listenInterface WRITE setListenInterface)
|
||||
Q_PROPERTY(QByteArray sessionCookieName READ sessionCookieName WRITE setSessionCookieName)
|
||||
Q_PROPERTY(quint16 port READ port WRITE setPort)
|
||||
Q_PROPERTY(quint16 serverPort READ serverPort)
|
||||
Q_PROPERTY(bool autoCreateSession READ autoCreateSession WRITE setAutoCreateSession)
|
||||
public:
|
||||
enum Connector { HttpServer, Scgi, Fcgi };
|
||||
|
||||
QxtHttpSessionManager(QObject* parent = 0);
|
||||
|
||||
virtual void postEvent(QxtWebEvent*);
|
||||
|
||||
QHostAddress listenInterface() const;
|
||||
void setListenInterface(const QHostAddress& iface);
|
||||
|
||||
quint16 port() const;
|
||||
void setPort(quint16 port);
|
||||
|
||||
quint16 serverPort() const;
|
||||
|
||||
QByteArray sessionCookieName() const;
|
||||
void setSessionCookieName(const QByteArray& name);
|
||||
|
||||
bool autoCreateSession() const;
|
||||
void setAutoCreateSession(bool enable);
|
||||
|
||||
QxtAbstractWebService* staticContentService() const;
|
||||
void setStaticContentService(QxtAbstractWebService* service);
|
||||
|
||||
void setConnector(QxtAbstractHttpConnector* connector);
|
||||
void setConnector(Connector connector);
|
||||
QxtAbstractHttpConnector* connector() const;
|
||||
|
||||
virtual bool start();
|
||||
virtual bool shutdown();
|
||||
|
||||
protected:
|
||||
virtual void sessionDestroyed(int sessionID);
|
||||
virtual int newSession();
|
||||
virtual void incomingRequest(quint32 requestID, const QHttpRequestHeader& header, QxtWebContent* device);
|
||||
|
||||
protected Q_SLOTS:
|
||||
virtual void processEvents();
|
||||
|
||||
private Q_SLOTS:
|
||||
void closeConnection(int requestID);
|
||||
void chunkReadyRead(int requestID, QObject* dataSource);
|
||||
void sendNextChunk(int requestID, QObject* dataSource);
|
||||
void sendEmptyChunk(int requestID, QObject* dataSource);
|
||||
void blockReadyRead(int requestID, QObject* dataSource);
|
||||
void sendNextBlock(int requestID, QObject* dataSource);
|
||||
|
||||
private:
|
||||
void disconnected(QIODevice* device);
|
||||
QXT_DECLARE_PRIVATE(QxtHttpSessionManager)
|
||||
};
|
||||
|
||||
#endif
|
217
thirdparty/qxt/qxtweb-standalone/web/qxtscgiserverconnector.cpp
vendored
Normal file
217
thirdparty/qxt/qxtweb-standalone/web/qxtscgiserverconnector.cpp
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtScgiServerConnector
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtScgiServerConnector class provides an SCGI connector for QxtHttpSessionManager
|
||||
|
||||
|
||||
QxtScgiServerConnector implements the SCGI protocoll supported by almost all modern web servers.
|
||||
|
||||
|
||||
|
||||
\sa QxtHttpSessionManager
|
||||
*/
|
||||
#include "qxthttpsessionmanager.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include <QTcpServer>
|
||||
#include <QHash>
|
||||
#include <QTcpSocket>
|
||||
#include <QString>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtScgiServerConnectorPrivate : public QxtPrivate<QxtScgiServerConnector>
|
||||
{
|
||||
public:
|
||||
QTcpServer* server;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Creates a QxtHttpServerConnector with the given \a parent.
|
||||
*/
|
||||
QxtScgiServerConnector::QxtScgiServerConnector(QObject* parent) : QxtAbstractHttpConnector(parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtScgiServerConnector);
|
||||
qxt_d().server = new QTcpServer(this);
|
||||
QObject::connect(qxt_d().server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtScgiServerConnector::listen(const QHostAddress& iface, quint16 port)
|
||||
{
|
||||
return qxt_d().server->listen(iface, port);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtScgiServerConnector::shutdown()
|
||||
{
|
||||
if(qxt_d().server->isListening()){
|
||||
qxt_d().server->close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
quint16 QxtScgiServerConnector::serverPort() const
|
||||
{
|
||||
return qxt_d().server->serverPort();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtScgiServerConnector::acceptConnection()
|
||||
{
|
||||
QTcpSocket* socket = qxt_d().server->nextPendingConnection();
|
||||
addConnection(socket);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
bool QxtScgiServerConnector::canParseRequest(const QByteArray& buffer)
|
||||
{
|
||||
if (buffer.size() < 10)
|
||||
return false;
|
||||
QString expectedsize;
|
||||
for (int i = 0;i < 10;i++)
|
||||
{
|
||||
if (buffer.at(i) == ':')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
expectedsize += buffer.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (expectedsize.isEmpty())
|
||||
{
|
||||
//protocoll error
|
||||
return false;
|
||||
}
|
||||
|
||||
return (buffer.size() > expectedsize.toInt());
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
QHttpRequestHeader QxtScgiServerConnector::parseRequest(QByteArray& buffer)
|
||||
{
|
||||
QString expectedsize_s;
|
||||
for (int i = 0;i < 20;i++)
|
||||
{
|
||||
if (buffer.at(i) == ':')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
expectedsize_s += buffer.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (expectedsize_s.isEmpty())
|
||||
{
|
||||
//protocoll error
|
||||
return QHttpRequestHeader();
|
||||
}
|
||||
|
||||
|
||||
buffer = buffer.right(buffer.size() - (expectedsize_s.count() + 1));
|
||||
|
||||
|
||||
QHttpRequestHeader request_m;
|
||||
|
||||
QByteArray name;
|
||||
int i = 0;
|
||||
while ((i = buffer.indexOf('\0')) > -1)
|
||||
{
|
||||
if (name.isEmpty())
|
||||
{
|
||||
name = buffer.left(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
request_m.setValue(QString::fromLatin1(name).toLower(), QString::fromLatin1(buffer.left(i)));
|
||||
name = "";
|
||||
}
|
||||
buffer = buffer.mid(i + 1);
|
||||
}
|
||||
|
||||
|
||||
request_m.setRequest(request_m.value("request_method"), request_m.value("request_uri"), 1, 0);
|
||||
|
||||
|
||||
foreach(const QString& key, request_m.keys())
|
||||
{
|
||||
if (key.startsWith(QString("http_")))
|
||||
{
|
||||
request_m.setValue(key.right(key.size() - 5), request_m.value(key));
|
||||
}
|
||||
}
|
||||
|
||||
request_m.setValue("Connection", "close");
|
||||
|
||||
|
||||
buffer.chop(1);
|
||||
|
||||
|
||||
return request_m;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtScgiServerConnector::writeHeaders(QIODevice* device, const QHttpResponseHeader& response_m)
|
||||
{
|
||||
|
||||
device->write(("Status:" + QString::number(response_m.statusCode()) + ' ' + response_m.reasonPhrase() + "\r\n").toLatin1());
|
||||
|
||||
foreach(const QString& key, response_m.keys())
|
||||
{
|
||||
device->write((key + ':' + response_m.value(key) + "\r\n").toLatin1());
|
||||
}
|
||||
device->write("\r\n");
|
||||
}
|
77
thirdparty/qxt/qxtweb-standalone/web/qxtwebcgiservice_p.h
vendored
Normal file
77
thirdparty/qxt/qxtweb-standalone/web/qxtwebcgiservice_p.h
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBCGISERVICE_P_H
|
||||
#define QXTWEBCGISERVICE_P_H
|
||||
|
||||
#include "qxtwebcgiservice.h"
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
#include <QPair>
|
||||
#include <QTimer>
|
||||
#include <QSignalMapper>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
QT_FORWARD_DECLARE_CLASS(QProcess)
|
||||
class QxtWebContent;
|
||||
|
||||
struct QxtCgiRequestInfo
|
||||
{
|
||||
QxtCgiRequestInfo();
|
||||
QxtCgiRequestInfo(QxtWebRequestEvent* req);
|
||||
int sessionID, requestID;
|
||||
QHash<QString, QString> headers;
|
||||
bool eventSent, terminateSent;
|
||||
QTimer* timeout;
|
||||
};
|
||||
|
||||
class QxtWebCgiServicePrivate : public QObject, public QxtPrivate<QxtWebCgiService>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QXT_DECLARE_PUBLIC(QxtWebCgiService)
|
||||
|
||||
QHash<QProcess*, QxtCgiRequestInfo> requests;
|
||||
QHash<QxtWebContent*, QProcess*> processes;
|
||||
QString binary;
|
||||
int timeout;
|
||||
bool timeoutOverride;
|
||||
QSignalMapper timeoutMapper;
|
||||
|
||||
public Q_SLOTS:
|
||||
void browserReadyRead(QObject* o_content = 0);
|
||||
void processReadyRead();
|
||||
void processFinished();
|
||||
void terminateProcess(QObject* o_process);
|
||||
};
|
||||
#endif // QXT_DOXYGEN_RUN
|
||||
|
||||
#endif // QXTWEBSERVICEDIRECTORY_P_H
|
286
thirdparty/qxt/qxtweb-standalone/web/qxtwebcontent.cpp
vendored
Normal file
286
thirdparty/qxt/qxtweb-standalone/web/qxtwebcontent.cpp
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtWebContent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebContent class provides an I/O device for data sent by the web browser
|
||||
|
||||
QxtWebContent is a QxtFifo subclass that encapsulates data sent from the web
|
||||
browser, for instance in a POST or PUT request.
|
||||
|
||||
In order to avoid delays while reading content sent from the client, and to
|
||||
insulate multiple pipelined requests on the same connection from each other,
|
||||
QxtWeb uses QxtWebContent as an abstraction for streaming data.
|
||||
|
||||
\sa QxtAbstractWebService
|
||||
*/
|
||||
|
||||
#include "qxtwebcontent.h"
|
||||
#include <string.h>
|
||||
#include <QUrl>
|
||||
#include <QCoreApplication>
|
||||
#include <QThread>
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <QUrlQuery>
|
||||
#endif
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtWebContentPrivate : public QxtPrivate<QxtWebContent>
|
||||
{
|
||||
public:
|
||||
QxtWebContentPrivate() : bytesNeeded(0), ignoreRemaining(false) {}
|
||||
QXT_DECLARE_PUBLIC(QxtWebContent)
|
||||
|
||||
void init(int contentLength, QIODevice* device)
|
||||
{
|
||||
if (contentLength < 0)
|
||||
bytesNeeded = -1;
|
||||
else{
|
||||
bytesNeeded = contentLength - qxt_p().bytesAvailable();
|
||||
Q_ASSERT(bytesNeeded >= 0);
|
||||
}
|
||||
if(device){
|
||||
// Connect a disconnected signal if it has one
|
||||
if(device->metaObject()->indexOfSignal(QMetaObject::normalizedSignature(SIGNAL(disconnected()))) >= 0){
|
||||
QObject::connect(device, SIGNAL(disconnected()), &qxt_p(), SLOT(sourceDisconnect()), Qt::QueuedConnection);
|
||||
}
|
||||
// Likewise, connect an error signal if it has one
|
||||
if(device->metaObject()->indexOfSignal(QMetaObject::normalizedSignature(SIGNAL(error(QAbstractSocket::SocketError)))) >= 0){
|
||||
QObject::connect(device, SIGNAL(error(QAbstractSocket::SocketError)), &qxt_p(), SLOT(errorReceived(QAbstractSocket::SocketError)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qint64 bytesNeeded;
|
||||
bool ignoreRemaining;
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebContent object with the specified \a parent.
|
||||
*
|
||||
* The content provided by this constructor is the data contained in \a prime,
|
||||
* followed by whatever data is subsequently written to this object from the
|
||||
* source device up to the specified \a contentLength. Note that the provided
|
||||
* \a sourceDevice is used solely to detect socket errors and does not specify
|
||||
* parentage. This variation is ReadWrite to permit incoming data but should
|
||||
* never be written to by the service handler.
|
||||
*
|
||||
*/
|
||||
QxtWebContent::QxtWebContent(int contentLength, const QByteArray& prime,
|
||||
QObject *parent, QIODevice* sourceDevice) : QxtFifo(prime, parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtWebContent);
|
||||
qxt_d().init(contentLength, sourceDevice);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebContent object with the specified \a parent.
|
||||
*
|
||||
* The content provided by this constructor is exactly the data contained in
|
||||
* \a content. This variation is ReadOnly.
|
||||
*/
|
||||
QxtWebContent::QxtWebContent(const QByteArray& content, QObject* parent)
|
||||
: QxtFifo(content, parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtWebContent);
|
||||
qxt_d().init(content.size(), 0);
|
||||
setOpenMode(ReadOnly);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
qint64 QxtWebContent::readData(char* data, qint64 maxSize)
|
||||
{
|
||||
int result = QxtFifo::readData(data, maxSize);
|
||||
if(bytesAvailable() == 0 && bytesNeeded() == 0)
|
||||
QMetaObject::invokeMethod(this, "aboutToClose", Qt::QueuedConnection);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns \bold true if the total content size is unknown and
|
||||
* \bold false otherwise.
|
||||
*/
|
||||
bool QxtWebContent::wantAll() const
|
||||
{
|
||||
return (qxt_d().bytesNeeded == -1);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the total number of bytes of content expected. This will be \bold -1
|
||||
* if the total content size is unknown. This total includes both unread
|
||||
* data and that which has not been received yet. To obtain the number of
|
||||
* bytes available for reading, use bytesAvailable().
|
||||
* \sa bytesNeeded(), wantAll()
|
||||
*/
|
||||
qint64 QxtWebContent::unreadBytes() const
|
||||
{
|
||||
if(wantAll())
|
||||
return -1;
|
||||
return bytesAvailable() + bytesNeeded();
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the number of bytes of content that have not yet been written
|
||||
* from the source device. This will be \bold -1 if the total content size is
|
||||
* unknown and \bold zero once all data has been received from the source (the
|
||||
* readChannelFinished() signal will be emitted when that occurs).
|
||||
*/
|
||||
qint64 QxtWebContent::bytesNeeded() const
|
||||
{
|
||||
return qxt_d().bytesNeeded;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
qint64 QxtWebContent::writeData(const char *data, qint64 maxSize)
|
||||
{
|
||||
if(!(openMode() & WriteOnly)){
|
||||
qWarning("QxtWebContent(): size=%lld but read-only", maxSize);
|
||||
return -1; // Not accepting writes
|
||||
}
|
||||
if(maxSize > 0) {
|
||||
// This must match the QxtFifo implementation for consistency
|
||||
if(maxSize > INT_MAX) maxSize = INT_MAX; // qint64 could easily exceed QAtomicInt, so let's play it safe
|
||||
if(qxt_d().bytesNeeded >= 0){
|
||||
if(maxSize > qxt_d().bytesNeeded){
|
||||
qWarning("QxtWebContent(): size=%lld needed %lld", maxSize,
|
||||
qxt_d().bytesNeeded);
|
||||
maxSize = qxt_d().bytesNeeded;
|
||||
}
|
||||
qxt_d().bytesNeeded -= maxSize;
|
||||
Q_ASSERT(qxt_d().bytesNeeded >= 0);
|
||||
}
|
||||
if(qxt_d().ignoreRemaining)
|
||||
return maxSize;
|
||||
return QxtFifo::writeData(data, maxSize);
|
||||
}
|
||||
// Error
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
void QxtWebContent::errorReceived(QAbstractSocket::SocketError)
|
||||
{
|
||||
QIODevice *device = qobject_cast<QIODevice*>(sender());
|
||||
if(device)
|
||||
setErrorString(device->errorString());
|
||||
}
|
||||
|
||||
/*!
|
||||
* Blocks until all of the streaming data has been read from the browser.
|
||||
*
|
||||
* Note that this method effectively runs a tight event loop. Although it
|
||||
* will not block a thread's other activities, it may result in high CPU
|
||||
* consumption and cause performance problems. It is suggested that you
|
||||
* avoid use of this method and try to implement services using the
|
||||
* readChannelFinished() signal instead.
|
||||
*/
|
||||
void QxtWebContent::waitForAllContent()
|
||||
{
|
||||
while(qxt_d().bytesNeeded != 0 && !qxt_d().ignoreRemaining){
|
||||
// Still need data ... yield processing
|
||||
if(QCoreApplication::hasPendingEvents())
|
||||
QCoreApplication::processEvents();
|
||||
if(this->thread() != QThread::currentThread())
|
||||
QThread::yieldCurrentThread();
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Discards any data not yet read.
|
||||
*
|
||||
* After invoking this function, any further data received from the browser
|
||||
* is silently discarded.
|
||||
*/
|
||||
void QxtWebContent::ignoreRemainingContent()
|
||||
{
|
||||
if (qxt_d().bytesNeeded == 0) return;
|
||||
if(!qxt_d().ignoreRemaining){
|
||||
qxt_d().ignoreRemaining = true;
|
||||
qxt_d().bytesNeeded = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* This slot handles a disconnect notice from a source I/O device to handle
|
||||
* cases where the source size is unknown. The internal state is adjusted
|
||||
* ensuring a reader will unblock in waitForAllContent(). If unread
|
||||
* data is present, a readyRead() signal will be emitted.
|
||||
* The readChannelFinished() signal is emitted regardless.
|
||||
*/
|
||||
void QxtWebContent::sourceDisconnect()
|
||||
{
|
||||
if (qxt_d().bytesNeeded == 0) return;
|
||||
if(!qxt_d().ignoreRemaining){
|
||||
qxt_d().ignoreRemaining = true;
|
||||
qxt_d().bytesNeeded = 0;
|
||||
if(bytesAvailable() != 0)
|
||||
QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, "readChannelFinished", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
typedef QPair<QString, QString> QxtQueryItem;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Parses URL-encoded form data
|
||||
*
|
||||
* Extracts the key/value pairs from \bold application/x-www-form-urlencoded
|
||||
* \a data, such as the query string from the URL or the form data from a
|
||||
* POST request.
|
||||
*/
|
||||
QHash<QString, QString> QxtWebContent::parseUrlEncodedQuery(const QString& data)
|
||||
{
|
||||
QHash<QString, QString> rv;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
|
||||
QUrl post("/?" + data);
|
||||
#else
|
||||
QUrlQuery post("/?" + data);
|
||||
#endif
|
||||
foreach(const QxtQueryItem& item, post.queryItems())
|
||||
{
|
||||
rv.insertMulti(item.first, item.second);
|
||||
}
|
||||
return rv;
|
||||
}
|
72
thirdparty/qxt/qxtweb-standalone/web/qxtwebcontent.h
vendored
Normal file
72
thirdparty/qxt/qxtweb-standalone/web/qxtwebcontent.h
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBCONTENT_H
|
||||
#define QXTWEBCONTENT_H
|
||||
|
||||
#include <QAbstractSocket>
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
#include <qxtglobal.h>
|
||||
#include <qxtfifo.h>
|
||||
|
||||
class QxtWebContentPrivate;
|
||||
class QXT_WEB_EXPORT QxtWebContent : public QxtFifo
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QxtWebContent(int contentLength, const QByteArray& start, QObject *parent,
|
||||
QIODevice* sourceDevice);
|
||||
explicit QxtWebContent(const QByteArray& content, QObject* parent = 0);
|
||||
static QHash<QString, QString> parseUrlEncodedQuery(const QString& data);
|
||||
|
||||
bool wantAll() const;
|
||||
qint64 bytesNeeded() const;
|
||||
qint64 unreadBytes() const;
|
||||
|
||||
void waitForAllContent();
|
||||
|
||||
public Q_SLOTS:
|
||||
void ignoreRemainingContent();
|
||||
|
||||
protected:
|
||||
virtual qint64 readData(char* data, qint64 maxSize);
|
||||
virtual qint64 writeData(const char* data, qint64 maxSize);
|
||||
|
||||
private Q_SLOTS:
|
||||
void sourceDisconnect();
|
||||
void errorReceived(QAbstractSocket::SocketError);
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtWebContent)
|
||||
};
|
||||
|
||||
#endif // QXTWEBCONTENT_H
|
459
thirdparty/qxt/qxtweb-standalone/web/qxtwebevent.cpp
vendored
Normal file
459
thirdparty/qxt/qxtweb-standalone/web/qxtwebevent.cpp
vendored
Normal file
@@ -0,0 +1,459 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#include "qxtwebevent.h"
|
||||
#include "qxtwebcontent.h"
|
||||
#include <QBuffer>
|
||||
|
||||
/*!
|
||||
\class QxtWebEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebEvent class is a base class of all QxtWeb event types
|
||||
|
||||
QxtWebEvent is the base class for all QxtWeb event classes. Event objects
|
||||
contain event parameters.
|
||||
|
||||
The base QxtWebEvent class contains the type of the event and a session ID for
|
||||
the session it relates to. Subclasses of QxtWebEvent contain additional
|
||||
parameters describing the particular event.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QxtWebEvent::EventType
|
||||
|
||||
\value None Not an event.
|
||||
\value Request A request event.
|
||||
\value FileUpload A file upload event.
|
||||
\value Page A page event.
|
||||
\value StoreCookie A store cookie event.
|
||||
\value RemoveCookie A remove cookie event.
|
||||
\value Redirect A redirect event.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebEvent of the specified \a type for the specified \a sessionID.
|
||||
*/
|
||||
QxtWebEvent::QxtWebEvent(EventType type, int sessionID)
|
||||
: sessionID(sessionID), m_type(type) {}
|
||||
|
||||
/*!
|
||||
* Destroys the event.
|
||||
*/
|
||||
QxtWebEvent::~QxtWebEvent() {}
|
||||
|
||||
/*!
|
||||
* \fn EventType QxtWebEvent::type() const
|
||||
* Returns the event type.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebEvent::sessionID
|
||||
* Contains the ID of the session the event is related to.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebRequestEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebRequestEvent class describes a request from a web browser
|
||||
|
||||
The QxtWebRequestEvent class contains information about a request from a web
|
||||
browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebRequestEvent for the specified \a sessionID, \a requestID and \a url.
|
||||
*/
|
||||
QxtWebRequestEvent::QxtWebRequestEvent(int _sessionID, int _requestID, const QUrl& _url)
|
||||
: QxtWebEvent(QxtWebEvent::Request, _sessionID), requestID(_requestID), url(_url), originalUrl(_url), isSecure(false) {}
|
||||
|
||||
/*!
|
||||
* Destroys the event and any content that may still be associated with it.
|
||||
*/
|
||||
QxtWebRequestEvent::~QxtWebRequestEvent()
|
||||
{
|
||||
if (content) delete content;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::requestID
|
||||
* Contains an opaque value generated by the session manager. This request ID
|
||||
* must be included in the QxtWebPageEvent or QxtWebPageEvent subclass that
|
||||
* is the response to the request.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::url
|
||||
* Contains the request URL, possibly after rewriting by intermediate services
|
||||
* such as QxtWebServiceDirectory.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::originalUrl
|
||||
* Contains the request URL exactly as it was sent from the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::contentType
|
||||
* Contains the MIME type of the request body, if present.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::content
|
||||
* Contains the content of the request body, if present.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::isSecure
|
||||
* If the request was sent over an encrypted channel, such as HTTPS, isSecure will be
|
||||
* set to \a true and clientCertificate will be set. Otherwise, isSecure will be set
|
||||
* to \a false.
|
||||
*
|
||||
* \sa clientCertificate, remoteAddress
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::remoteAddress
|
||||
* This variable will contain the address of the client as a QHostAddress.
|
||||
* In IPv6 dual-stack systems (generally only Linux), this may be a IPv4
|
||||
* mapped address.
|
||||
*
|
||||
* \warning This variable was originally declared as a QString value in
|
||||
* prior releases, albeit undocumented until now.
|
||||
*
|
||||
* \sa isSecure, clientCertificate
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::clientCertificate
|
||||
* If the request was sent over an encrypted channel, such as HTTPS, clientCertificate
|
||||
* will contain the certificate presented by the requesting client, if any.
|
||||
*
|
||||
* This member variable is not available if Qt was not compiled with SSL support.
|
||||
*
|
||||
* \sa isSecure, remoteAddress
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::cookies
|
||||
* Contains all of the cookies sent by the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRequestEvent::headers
|
||||
* Contains all of the headers sent by the web browser.
|
||||
*
|
||||
* Note that use of these values may not be portable across session managers.
|
||||
*/
|
||||
|
||||
/*
|
||||
QxtWebFileUploadEvent::QxtWebFileUploadEvent(int sessionID)
|
||||
: QxtWebEvent(QxtWebEvent::FileUpload, sessionID) {}
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebErrorEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebErrorEvent class describes an error condition to be sent to a web browser
|
||||
|
||||
The QxtWebErrorEvent class contains information about an error that will be
|
||||
sent to a web browser.
|
||||
|
||||
QxtWebErrorEvent is a QxtWebPageEvent, so the \a dataSource may be replaced
|
||||
with a custom error page. If you choose to do this, be sure to delete the
|
||||
original data source automatically generated by the constructor first.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebErrorEvent for the specified \a sessionID and \a requestID,
|
||||
* with the provided \a statusCode and \a statusMessage.
|
||||
*
|
||||
* The requestID is an opaque value generated by the session manager; services
|
||||
* will receive this value via QxtWebRequestEvent and must use it in every
|
||||
* event that responds to that request.
|
||||
*/
|
||||
QxtWebErrorEvent::QxtWebErrorEvent(int sessionID, int requestID, int statusCode, QByteArray statusMessage)
|
||||
: QxtWebPageEvent(sessionID, requestID, "<html><body><h1>" + statusMessage + "</h1></body></html>\r\n")
|
||||
{
|
||||
status = statusCode;
|
||||
QxtWebPageEvent::statusMessage = statusMessage;
|
||||
}
|
||||
|
||||
/*!
|
||||
\class QxtWebPageEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebPageEvent class describes a web page or other content to be sent to a web browser
|
||||
|
||||
The QxtWebPageEvent class contains information about a web page or other similar
|
||||
content that will be sent to a web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebPageEvent for the specified \a sessionID and \a requestID that will
|
||||
* use the data from \a source as the content to be sent to the web browser.
|
||||
*
|
||||
* The requestID is an opaque value generated by the session manager; services
|
||||
* will receive this value via QxtWebRequestEvent and must use it in every
|
||||
* event that responds to that request.
|
||||
*
|
||||
* QxtWeb takes ownership of the source and will delete it when the response
|
||||
* is completed.
|
||||
*/
|
||||
QxtWebPageEvent::QxtWebPageEvent(int sessionID, int requestID, QIODevice* source)
|
||||
: QxtWebEvent(QxtWebEvent::Page, sessionID), dataSource(source), chunked(true), streaming(true), requestID(requestID),
|
||||
status(200), statusMessage("OK"), contentType("text/html") {}
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebPageEvent for the specified \a sessionID and \a requestID that will
|
||||
* use \a source as the content to be sent to the web browser.
|
||||
*
|
||||
* The requestID is an opaque value generated by the session manager; services
|
||||
* will receive this value via QxtWebRequestEvent and must use it in every
|
||||
* event that responds to that request.
|
||||
*/
|
||||
QxtWebPageEvent::QxtWebPageEvent(int sessionID, int requestID, QByteArray source)
|
||||
: QxtWebEvent(QxtWebEvent::Page, sessionID), chunked(false), streaming(false), requestID(requestID),
|
||||
status(200), statusMessage("OK"), contentType("text/html")
|
||||
{
|
||||
QBuffer* buffer = new QBuffer;
|
||||
buffer->setData(source);
|
||||
buffer->open(QIODevice::ReadOnly);
|
||||
dataSource = buffer;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
*/
|
||||
QxtWebPageEvent::QxtWebPageEvent(QxtWebEvent::EventType typeOverride, int sessionID, int requestID, QByteArray source)
|
||||
: QxtWebEvent(typeOverride, sessionID), chunked(false), streaming(false), requestID(requestID),
|
||||
status(200), statusMessage("OK"), contentType("text/html")
|
||||
{
|
||||
QBuffer* buffer = new QBuffer;
|
||||
buffer->setData(source);
|
||||
buffer->open(QIODevice::ReadOnly);
|
||||
dataSource = buffer;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Destroys the event and any data source attached to it.
|
||||
*/
|
||||
QxtWebPageEvent::~QxtWebPageEvent()
|
||||
{
|
||||
if (!dataSource.isNull()) dataSource->deleteLater();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::dataSource
|
||||
* Data will be read from this device and relayed to the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::chunked
|
||||
* If true, and if the web browser supports "chunked" encoding, the content
|
||||
* will be sent using "chunked" encoding. If false, or if the browser does not
|
||||
* support this encoding (for instance, HTTP/0.9 and HTTP/1.0 user agents),
|
||||
* HTTP keep-alive will be disabled.
|
||||
*
|
||||
* The default value is true when using the QIODevice* constructor and false
|
||||
* when using the QByteArray constructor.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::streaming
|
||||
* If true, the data source is considered to be a source of streaming data.
|
||||
* The QIODevice must emit the readyRead() signal when data is available and
|
||||
* must emit aboutToClose() after all data has been transferred. (This can
|
||||
* be accomplished by invoking QIODevice::close() on it after all data is
|
||||
* determined to have been transferred.)
|
||||
*
|
||||
* The default value is true when using the QIODevice* constructor and false
|
||||
* when using the QByteArray constructor. If using a QIODevice that does not
|
||||
* produce streaming data, such as QFile, this \a must be set to false to
|
||||
* ensure correct behavior.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::requestID
|
||||
* Contains the opaque requestID provided by QxtWebRequestEvent.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::status
|
||||
* Contains the HTTP status code that will be sent with the response.
|
||||
*
|
||||
* The default value is 200 ("OK").
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::statusMessage
|
||||
* Contains the human-readable message associated with the HTTP status code
|
||||
* that will be sent with the response.
|
||||
*
|
||||
* The default value is "OK".
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::contentType
|
||||
* Contains the MIME type of the content being sent to the web browser.
|
||||
*
|
||||
* The default value is "text/html".
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebPageEvent::headers
|
||||
* Contains custom headers to be sent to the web browser.
|
||||
*
|
||||
* It is empty by default.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebStoreCookieEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebStoreCookieEvent class describes a cookie to be sent to a web browser
|
||||
|
||||
The QxtWebStoreCookieEvent class instructs the session manager to store
|
||||
a cookie on the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebStoreCookieEvent for the specified \a sessionID that will
|
||||
* store a cookie with the specified \a name and \a data on the web browser.
|
||||
*
|
||||
* If an \a expiration date is supplied, it will be passed to the browser along
|
||||
* with the cookie. The browser will delete the cookie automatically after
|
||||
* the specified date. If an expiration date is not supplied, the cookie will
|
||||
* expire when the browser is closed.
|
||||
*
|
||||
* The cookie will be assigned a path of / by default. You may change this
|
||||
* using the \a path member.
|
||||
*/
|
||||
QxtWebStoreCookieEvent::QxtWebStoreCookieEvent(int sessionID, QString name, QString data, QDateTime expiration)
|
||||
: QxtWebEvent(QxtWebEvent::StoreCookie, sessionID), name(name), data(data), expiration(expiration), path("/") {}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebStoreCookieEvent::name
|
||||
* Contains the name of the cookie to be stored.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebStoreCookieEvent::data
|
||||
* Contains the content of the cookie to be stored.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebStoreCookieEvent::expiration
|
||||
* Contains the expiration date of the cookie to be stored. If null, the
|
||||
* cookie will expire when the web browser is closed.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebStoreCookieEvent::path
|
||||
* Contains the path of the cookie to be stored.
|
||||
*
|
||||
* The default value is "/". Set the path to an empty QString to send
|
||||
* the cookie with no path specifier.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebRemoveCookieEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebRemoveCookieEvent class describes a cookie to be deleted from a web browser
|
||||
|
||||
The QxtWebStoreCookieEvent class instructs the session manager to remove
|
||||
a cookie stored on the web browser.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebRemoveCookieEvent for the specified \a sessionID that
|
||||
* removed the cookie with \a name from the web browser.
|
||||
*
|
||||
* The cookie's path is / by default. You may change this using the \a path member.
|
||||
*/
|
||||
QxtWebRemoveCookieEvent::QxtWebRemoveCookieEvent(int sessionID, QString name)
|
||||
: QxtWebEvent(QxtWebEvent::RemoveCookie, sessionID), name(name) {}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRemoveCookieEvent::name
|
||||
* Contains the name of the cookie to be removed.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \variable QxtWebStoreCookieEvent::path
|
||||
* Contains the path of the cookie to be removed.
|
||||
*
|
||||
* The default value is "/". Set the path to an empty QString to send
|
||||
* the cookie with no path specifier.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class QxtWebRedirectEvent
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebRedirectEvent class describes a redirect event to be sent to a web browser
|
||||
|
||||
The QxtWebRedirectEvent class instructs the web browser to load a page found at
|
||||
another location.
|
||||
|
||||
The default status code, 302, indicates that the requested page was found at
|
||||
a different location. Other useful status codes are 301, which indicates
|
||||
that the web browser should always use the new URL in place of the old one,
|
||||
and (in HTTP/1.1) 307, which indicates that the web browser should reissue
|
||||
the same request (including POST data) to the new URL.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebRedirectEvent for the specified \a sessionID and \a requestID that
|
||||
* instructs the browser to move to the specified \a destination URL with \a statusCode.
|
||||
*/
|
||||
QxtWebRedirectEvent::QxtWebRedirectEvent(int sessionID, int requestID, const QString& destination, int statusCode)
|
||||
: QxtWebPageEvent(QxtWebEvent::Redirect, sessionID, requestID, QString("Redirect: <a href='%1'>%1</a>").arg(destination).toUtf8()), destination(destination)
|
||||
{
|
||||
QxtWebPageEvent::status = statusCode;
|
||||
QxtWebPageEvent::statusMessage = ("Redirect to " + destination).toUtf8();
|
||||
}
|
||||
|
||||
/*!
|
||||
* \variable QxtWebRedirectEvent::destination
|
||||
* Contains the new location (absolute or relative) to which the browser
|
||||
* should redirect.
|
||||
*/
|
169
thirdparty/qxt/qxtweb-standalone/web/qxtwebevent.h
vendored
Normal file
169
thirdparty/qxt/qxtweb-standalone/web/qxtwebevent.h
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBEVENT_H
|
||||
#define QXTWEBEVENT_H
|
||||
|
||||
#include <qxtglobal.h>
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
#include <QStringList>
|
||||
#include <QPointer>
|
||||
#include <QUrl>
|
||||
#include <QMultiHash>
|
||||
#include <QDateTime>
|
||||
#include <QHostAddress>
|
||||
#ifndef QT_NO_OPENSSL
|
||||
#include <QSslCertificate>
|
||||
#endif
|
||||
QT_FORWARD_DECLARE_CLASS(QIODevice)
|
||||
class QxtWebContent;
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebEvent
|
||||
{
|
||||
public:
|
||||
enum EventType
|
||||
{
|
||||
None = 0,
|
||||
Request,
|
||||
FileUpload,
|
||||
Page,
|
||||
StoreCookie,
|
||||
RemoveCookie,
|
||||
Redirect
|
||||
};
|
||||
|
||||
QxtWebEvent(EventType type, int sessionID);
|
||||
virtual ~QxtWebEvent();
|
||||
|
||||
inline EventType type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
const int sessionID;
|
||||
|
||||
private:
|
||||
EventType m_type;
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebRequestEvent : public QxtWebEvent
|
||||
{
|
||||
public:
|
||||
QxtWebRequestEvent(int sessionID, int requestID, const QUrl& url);
|
||||
virtual ~QxtWebRequestEvent();
|
||||
|
||||
const int requestID;
|
||||
|
||||
QUrl url;
|
||||
const QUrl originalUrl;
|
||||
QString contentType;
|
||||
QPointer<QxtWebContent> content;
|
||||
QString method;
|
||||
QHostAddress remoteAddress;
|
||||
bool isSecure;
|
||||
#ifndef QT_NO_OPENSSL
|
||||
QSslCertificate clientCertificate;
|
||||
#endif
|
||||
|
||||
QMultiHash<QString, QString> cookies;
|
||||
QMultiHash<QString, QString> headers;
|
||||
};
|
||||
|
||||
/* TODO: refactor and implement
|
||||
class QXT_WEB_EXPORT QxtWebFileUploadEvent : public QxtWebEvent {
|
||||
public:
|
||||
QxtWebFileUploadEvent(int sessionID);
|
||||
|
||||
QString filename;
|
||||
int contentLength;
|
||||
QIODevice* content;
|
||||
};
|
||||
*/
|
||||
|
||||
class QxtWebRedirectEvent;
|
||||
class QXT_WEB_EXPORT QxtWebPageEvent : public QxtWebEvent
|
||||
{
|
||||
public:
|
||||
QxtWebPageEvent(int sessionID, int requestID, QIODevice* source = 0);
|
||||
QxtWebPageEvent(int sessionID, int requestID, QByteArray source); // creates a QBuffer
|
||||
virtual ~QxtWebPageEvent();
|
||||
|
||||
QPointer<QIODevice> dataSource; // data is read from this device and written to the client
|
||||
bool chunked;
|
||||
bool streaming;
|
||||
|
||||
const int requestID;
|
||||
int status;
|
||||
QByteArray statusMessage;
|
||||
QByteArray contentType;
|
||||
|
||||
QMultiHash<QString, QString> headers;
|
||||
|
||||
private:
|
||||
friend class QxtWebRedirectEvent;
|
||||
QxtWebPageEvent(QxtWebEvent::EventType typeOverride, int sessionID, int requestID, QByteArray source);
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebErrorEvent : public QxtWebPageEvent
|
||||
{
|
||||
public:
|
||||
QxtWebErrorEvent(int sessionID, int requestID, int status, QByteArray statusMessage);
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebStoreCookieEvent : public QxtWebEvent
|
||||
{
|
||||
public:
|
||||
QxtWebStoreCookieEvent(int sessionID, QString name, QString data, QDateTime expiration = QDateTime());
|
||||
|
||||
QString name;
|
||||
QString data;
|
||||
QDateTime expiration;
|
||||
QString path;
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebRemoveCookieEvent : public QxtWebEvent
|
||||
{
|
||||
public:
|
||||
QxtWebRemoveCookieEvent(int sessionID, QString name);
|
||||
|
||||
QString name;
|
||||
QString path;
|
||||
};
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebRedirectEvent : public QxtWebPageEvent
|
||||
{
|
||||
public:
|
||||
QxtWebRedirectEvent(int sessionID, int requestID, const QString& destination, int statusCode = 302);
|
||||
|
||||
QString destination;
|
||||
};
|
||||
|
||||
#endif // QXTWEBEVENT_H
|
245
thirdparty/qxt/qxtweb-standalone/web/qxtwebservicedirectory.cpp
vendored
Normal file
245
thirdparty/qxt/qxtweb-standalone/web/qxtwebservicedirectory.cpp
vendored
Normal file
@@ -0,0 +1,245 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
/*!
|
||||
\class QxtWebServiceDirectory
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebServiceDirectory class provides Path-based web service dispatcher
|
||||
|
||||
QxtWebServiceDirectory allows multiple services to be associated with a single
|
||||
session. Selection between services is determined by the first path component
|
||||
in the URL. For example, the URL "/site/request?param=true" would relay the
|
||||
URL "/request?param=true" to the service named "site".
|
||||
|
||||
This class can be used recursively to declare a hierarchy of services. For
|
||||
example:
|
||||
\code
|
||||
QxtWebServiceDirectory* top = new QxtWebServiceDirectory(sm, sm);
|
||||
QxtWebServiceDirectory* service1 = new QxtWebServiceDirectory(sm, top);
|
||||
QxtWebServiceDirectory* service2 = new QxtWebServiceDirectory(sm, top);
|
||||
QxtWebServiceDirectory* service1a = new QxtWebServiceDirectory(sm, service1);
|
||||
QxtWebServiceDirectory* service1b = new QxtWebServiceDirectory(sm, service1);
|
||||
top->addService("1", service1);
|
||||
top->addService("2", service2);
|
||||
service1->addService("a", service1a);
|
||||
service1->addService("b", service1b);
|
||||
\endcode
|
||||
This accepts the URLs "/1/a/", "/1/b/", and "/2/".
|
||||
*/
|
||||
|
||||
#include "qxtwebservicedirectory.h"
|
||||
#include "qxtwebservicedirectory_p.h"
|
||||
#include "qxtwebevent.h"
|
||||
#include <QUrl>
|
||||
#include <QtDebug>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
QxtWebServiceDirectoryPrivate::QxtWebServiceDirectoryPrivate() : QObject(0)
|
||||
{
|
||||
// initializers only
|
||||
}
|
||||
|
||||
void QxtWebServiceDirectoryPrivate::serviceDestroyed()
|
||||
{
|
||||
QxtAbstractWebService* service = qobject_cast<QxtAbstractWebService*>(sender());
|
||||
if (!service) return; // this shouldn't happen
|
||||
QString path;
|
||||
while (!(path = services.key(service)).isNull())
|
||||
{
|
||||
services.remove(path);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Constructs a QxtWebServiceDirectory object with the specified session manager \a sm and \a parent.
|
||||
*
|
||||
* Often, the session manager will also be the parent, but this is not a requirement.
|
||||
*/
|
||||
QxtWebServiceDirectory::QxtWebServiceDirectory(QxtAbstractWebSessionManager* sm, QObject* parent) : QxtAbstractWebService(sm, parent)
|
||||
{
|
||||
QXT_INIT_PRIVATE(QxtWebServiceDirectory);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Adds a \a service to the directory at the given \a path.
|
||||
* \sa removeService(), service()
|
||||
*/
|
||||
void QxtWebServiceDirectory::addService(const QString& path, QxtAbstractWebService* service)
|
||||
{
|
||||
if (qxt_d().services.contains(path))
|
||||
{
|
||||
qWarning() << "QxtWebServiceDirectory::addService:" << path << "already registered";
|
||||
}
|
||||
|
||||
qxt_d().services[path] = service;
|
||||
if (qxt_d().defaultRedirect.isEmpty())
|
||||
setDefaultRedirect(path);
|
||||
connect(service, SIGNAL(destroyed()), &qxt_d(), SLOT(serviceDestroyed()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Removes the service at the given \a path.
|
||||
*
|
||||
* Note that the service object is not destroyed.
|
||||
*/
|
||||
void QxtWebServiceDirectory::removeService(const QString& path)
|
||||
{
|
||||
if (!qxt_d().services.contains(path))
|
||||
{
|
||||
qWarning() << "QxtWebServiceDirectory::removeService:" << path << "not registered";
|
||||
}
|
||||
else
|
||||
{
|
||||
qxt_d().services.remove(path);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the service at the given \a path.
|
||||
*/
|
||||
QxtAbstractWebService* QxtWebServiceDirectory::service(const QString& path) const
|
||||
{
|
||||
if (!qxt_d().services.contains(path))
|
||||
return 0;
|
||||
return qxt_d().services[path];
|
||||
}
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* Returns the first path segment from the URL in the \a event object.
|
||||
* (i.e. "a" from "/a/b/c") This also removes the path segment from the
|
||||
* event object. (in the previous example, the event's URL is now "/b/c")
|
||||
*/
|
||||
static QString extractPathLevel(QxtWebRequestEvent* event)
|
||||
{
|
||||
QString path = event->url.path();
|
||||
int pos = path.indexOf("/", 1); // the path always starts with /
|
||||
if (pos == -1)
|
||||
event->url.setPath(""); // cue to redirect to /service/
|
||||
else
|
||||
event->url.setPath(path.mid(pos));
|
||||
return path.mid(1, pos - 1);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \reimp
|
||||
*/
|
||||
void QxtWebServiceDirectory::pageRequestedEvent(QxtWebRequestEvent* event)
|
||||
{
|
||||
QString path = extractPathLevel(event);
|
||||
if (path.isEmpty())
|
||||
{
|
||||
indexRequested(event);
|
||||
}
|
||||
else if (!qxt_d().services.contains(path))
|
||||
{
|
||||
unknownServiceRequested(event, path);
|
||||
}
|
||||
else if (event->url.path().isEmpty())
|
||||
{
|
||||
postEvent(new QxtWebRedirectEvent(event->sessionID, event->requestID, path + '/', 307));
|
||||
}
|
||||
else
|
||||
{
|
||||
qxt_d().services[path]->pageRequestedEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* \reimp unimplemented
|
||||
*/
|
||||
/*
|
||||
void QxtWebServiceDirectory::functionInvokedEvent(QxtWebRequestEvent* event) {
|
||||
QString path = extractPathLevel(event);
|
||||
if(path == "") {
|
||||
indexRequested(event);
|
||||
} else if(!qxt_d().services.contains(path)) {
|
||||
unknownServiceRequested(event, path);
|
||||
} else {
|
||||
qxt_d().services[path]->functionInvokedEvent(event);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*!
|
||||
* This \a event handler is called whenever the URL requests a service with \a name that has
|
||||
* not been added to the directory.
|
||||
*
|
||||
* The default implementation returns a 404 "Service not known" error.
|
||||
* Subclasses may reimplement this event handler to customize this behavior.
|
||||
*/
|
||||
void QxtWebServiceDirectory::unknownServiceRequested(QxtWebRequestEvent* event, const QString& name)
|
||||
{
|
||||
postEvent(new QxtWebErrorEvent(event->sessionID, event->requestID, 404, ("Service "" + QString(name).replace('<', "<") + "" not known").toUtf8()));
|
||||
}
|
||||
|
||||
/*!
|
||||
* This \a event handler is called whenever the URL does not contain a path, that
|
||||
* is, the URL is "/" or empty.
|
||||
*
|
||||
* The default implementation redirects to the service specified by
|
||||
* setDefaultRedirect(), or invokes unknownServiceRequested() if no default
|
||||
* redirect has been set.
|
||||
*/
|
||||
void QxtWebServiceDirectory::indexRequested(QxtWebRequestEvent* event)
|
||||
{
|
||||
if (defaultRedirect().isEmpty())
|
||||
{
|
||||
unknownServiceRequested(event, "/");
|
||||
}
|
||||
else
|
||||
{
|
||||
postEvent(new QxtWebRedirectEvent(event->sessionID, event->requestID, defaultRedirect() + '/', 307));
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Returns the path that will be used by default by the indexRequested event.
|
||||
* \sa indexRequested(), setDefaultRedirect()
|
||||
*/
|
||||
QString QxtWebServiceDirectory::defaultRedirect() const
|
||||
{
|
||||
return qxt_d().defaultRedirect;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Sets the \a path that will be used by default by the indexRequested event.
|
||||
* \sa indexRequested(), defaultRedirect()
|
||||
*/
|
||||
void QxtWebServiceDirectory::setDefaultRedirect(const QString& path)
|
||||
{
|
||||
if (!qxt_d().services.contains(path))
|
||||
qWarning() << "QxtWebServiceDirectory::setDefaultRedirect:" << path << "not registered";
|
||||
qxt_d().defaultRedirect = path;
|
||||
}
|
65
thirdparty/qxt/qxtweb-standalone/web/qxtwebservicedirectory.h
vendored
Normal file
65
thirdparty/qxt/qxtweb-standalone/web/qxtwebservicedirectory.h
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBSERVICEDIRECTORY_H
|
||||
#define QXTWEBSERVICEDIRECTORY_H
|
||||
|
||||
#include <qxtabstractwebservice.h>
|
||||
#include <QString>
|
||||
class QxtAbstractWebSessionManager;
|
||||
class QxtWebEvent;
|
||||
|
||||
class QxtWebServiceDirectoryPrivate;
|
||||
class QXT_WEB_EXPORT QxtWebServiceDirectory : public QxtAbstractWebService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QxtWebServiceDirectory(QxtAbstractWebSessionManager* sm, QObject* parent = 0);
|
||||
|
||||
void addService(const QString& path, QxtAbstractWebService* service);
|
||||
void removeService(const QString& path);
|
||||
QxtAbstractWebService* service(const QString& path) const;
|
||||
|
||||
virtual void pageRequestedEvent(QxtWebRequestEvent* event);
|
||||
// virtual void functionInvokedEvent(QxtWebRequestEvent* event);
|
||||
|
||||
QString defaultRedirect() const;
|
||||
void setDefaultRedirect(const QString& path);
|
||||
|
||||
protected:
|
||||
virtual void unknownServiceRequested(QxtWebRequestEvent* event, const QString& name);
|
||||
virtual void indexRequested(QxtWebRequestEvent* event);
|
||||
|
||||
private:
|
||||
QXT_DECLARE_PRIVATE(QxtWebServiceDirectory)
|
||||
};
|
||||
|
||||
#endif // QXTWEBSERVICEDIRECTORY_H
|
55
thirdparty/qxt/qxtweb-standalone/web/qxtwebservicedirectory_p.h
vendored
Normal file
55
thirdparty/qxt/qxtweb-standalone/web/qxtwebservicedirectory_p.h
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBSERVICEDIRECTORY_P_H
|
||||
#define QXTWEBSERVICEDIRECTORY_P_H
|
||||
|
||||
#include "qxtwebservicedirectory.h"
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
|
||||
#ifndef QXT_DOXYGEN_RUN
|
||||
class QxtWebServiceDirectoryPrivate : public QObject, public QxtPrivate<QxtWebServiceDirectory>
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QXT_DECLARE_PUBLIC(QxtWebServiceDirectory)
|
||||
QxtWebServiceDirectoryPrivate();
|
||||
|
||||
QHash<QString, QxtAbstractWebService*> services;
|
||||
QString defaultRedirect;
|
||||
|
||||
public Q_SLOTS:
|
||||
void serviceDestroyed();
|
||||
};
|
||||
#endif // QXT_DOXYGEN_RUN
|
||||
|
||||
#endif // QXTWEBSERVICEDIRECTORY_P_H
|
232
thirdparty/qxt/qxtweb-standalone/web/qxtwebslotservice.cpp
vendored
Normal file
232
thirdparty/qxt/qxtweb-standalone/web/qxtwebslotservice.cpp
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/*!
|
||||
\class QxtWebSlotService
|
||||
|
||||
\inmodule QxtWeb
|
||||
|
||||
\brief The QxtWebSlotService class provides a Slot based webservice
|
||||
|
||||
A WebService that resolves the first part of the path to a slot name and passes the rest as arguments.
|
||||
|
||||
\code
|
||||
class MyService : public QxtWebSlotService
|
||||
{
|
||||
// Q_OBJECT
|
||||
public slots:
|
||||
void hello(QxtWebRequestEvent* event, QString a)
|
||||
{
|
||||
postEvent(new QxtWebPageEvent(event->sessionID, event->requestID, "<h1>"+a.toUtf8()+"</h1>));
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
|
||||
|
||||
/hello/foo<br>
|
||||
will output<br>
|
||||
<h1>Foo</h1><br>
|
||||
|
||||
|
||||
\sa QxtAbstractWebService
|
||||
*/
|
||||
|
||||
#include "qxtwebslotservice.h"
|
||||
#include "qxtwebevent.h"
|
||||
|
||||
/*!
|
||||
Constructs a new QxtWebSlotService with \a sm and \a parent.
|
||||
*/
|
||||
QxtWebSlotService::QxtWebSlotService(QxtAbstractWebSessionManager* sm, QObject* parent): QxtAbstractWebService(sm, parent)
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the current absolute url of this service depending on the request \a event.
|
||||
*/
|
||||
QUrl QxtWebSlotService::self(QxtWebRequestEvent* event)
|
||||
|
||||
{
|
||||
QStringList u = event->url.path().split('/');
|
||||
QStringList o = event->originalUrl.path().split('/');
|
||||
u.removeFirst();
|
||||
o.removeFirst();
|
||||
for (int i = 0;i < u.count();i++)
|
||||
o.removeLast();
|
||||
|
||||
|
||||
QString r = "/";
|
||||
foreach(const QString& d, o)
|
||||
{
|
||||
r += d + '/';
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QxtWebSlotService::pageRequestedEvent(QxtWebRequestEvent* event)
|
||||
{
|
||||
QList<QString> args = event->url.path().split('/');
|
||||
args.removeFirst();
|
||||
if (args.at(args.count() - 1).isEmpty())
|
||||
args.removeLast();
|
||||
|
||||
|
||||
///--------------find action ------------------
|
||||
QByteArray action = "index";
|
||||
if (args.count())
|
||||
{
|
||||
action = args.at(0).toUtf8();
|
||||
if (action.trimmed().isEmpty())
|
||||
action = "index";
|
||||
args.removeFirst();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ok = false;
|
||||
if (args.count() > 7)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3)),
|
||||
Q_ARG(QString, args.at(4)),
|
||||
Q_ARG(QString, args.at(5)),
|
||||
Q_ARG(QString, args.at(6)),
|
||||
Q_ARG(QString, args.at(7))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 6)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3)),
|
||||
Q_ARG(QString, args.at(4)),
|
||||
Q_ARG(QString, args.at(5)),
|
||||
Q_ARG(QString, args.at(6))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 5)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3)),
|
||||
Q_ARG(QString, args.at(4)),
|
||||
Q_ARG(QString, args.at(5))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 4)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3)),
|
||||
Q_ARG(QString, args.at(4))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 3)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2)),
|
||||
Q_ARG(QString, args.at(3))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 2)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1)),
|
||||
Q_ARG(QString, args.at(2))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 1)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0)),
|
||||
Q_ARG(QString, args.at(1))
|
||||
);
|
||||
}
|
||||
else if (args.count() > 0)
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event),
|
||||
Q_ARG(QString, args.at(0))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = QMetaObject::invokeMethod(this, action,
|
||||
Q_ARG(QxtWebRequestEvent*, event)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
QByteArray err = "<h1>Can not find slot</h1> <pre>Class " + QByteArray(metaObject()->className()) + "\r{\npublic slots:\r void " + action.replace('<', "<") + " ( QxtWebRequestEvent* event, ";
|
||||
for (int i = 0;i < args.count();i++)
|
||||
err += "QString arg" + QByteArray::number(i) + ", ";
|
||||
err.chop(2);
|
||||
|
||||
err += " ); \r};\r</pre> ";
|
||||
|
||||
postEvent(new QxtWebErrorEvent(event->sessionID, event->requestID, 404, err));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QxtWebSlotService::functionInvokedEvent(QxtWebRequestEvent* event)
|
||||
{
|
||||
postEvent(new QxtWebErrorEvent(event->sessionID, event->requestID, 500, "<h1>Not supported</h1>"));
|
||||
}
|
51
thirdparty/qxt/qxtweb-standalone/web/qxtwebslotservice.h
vendored
Normal file
51
thirdparty/qxt/qxtweb-standalone/web/qxtwebslotservice.h
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
/****************************************************************************
|
||||
** Copyright (c) 2006 - 2011, the LibQxt project.
|
||||
** See the Qxt AUTHORS file for a list of authors and copyright holders.
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** * Neither the name of the LibQxt project nor the
|
||||
** names of its contributors may be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
** DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
||||
** DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**
|
||||
** <http://libqxt.org> <foundation@libqxt.org>
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef QXTWEBSLOTSERVICE_H
|
||||
#define QXTWEBSLOTSERVICE_H
|
||||
|
||||
#include "qxtabstractwebservice.h"
|
||||
#include <QUrl>
|
||||
|
||||
class QXT_WEB_EXPORT QxtWebSlotService : public QxtAbstractWebService
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QxtWebSlotService(QxtAbstractWebSessionManager* sm, QObject* parent = 0);
|
||||
|
||||
protected:
|
||||
QUrl self(QxtWebRequestEvent* event);
|
||||
|
||||
virtual void pageRequestedEvent(QxtWebRequestEvent* event);
|
||||
virtual void functionInvokedEvent(QxtWebRequestEvent* event);
|
||||
};
|
||||
|
||||
#endif // QXTWEBSLOTSERVICE_H
|
Reference in New Issue
Block a user