1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-07-31 19:30:21 +02:00

Fix QxtFifo and move qxtweb modules in their respective folder

This commit is contained in:
Uwe L. Korn
2013-04-09 10:35:08 +02:00
parent fd60cf4a5b
commit bf2067c414
70 changed files with 75 additions and 1547 deletions

View File

@@ -241,7 +241,7 @@ ENDIF( WIN32 )
#TODO: support external qxt
set(QXTWEB_FOUND TRUE)
set(QXTWEB_LIBRARIES qxtweb-standalone)
set(QXTWEB_INCLUDE_DIRS ${THIRDPARTY_DIR}/qxt/qxtweb-standalone/qxtweb ${CMAKE_CURRENT_BINARY_DIR})
set(QXTWEB_INCLUDE_DIRS ${THIRDPARTY_DIR}/qxt/qxtweb-standalone/web ${THIRDPARTY_DIR}/qxt/qxtweb-standalone/network ${THIRDPARTY_DIR}/qxt/qxtweb-standalone/core ${CMAKE_CURRENT_BINARY_DIR})
### libportfwd
set(LIBPORTFWD_INCLUDE_DIR ${THIRDPARTY_DIR}/libportfwd/include)

View File

@@ -7,16 +7,18 @@ ENDIF( ${CMAKE_VERSION} VERSION_GREATER 2.8.3 )
setup_qt()
SET(qxtweb "qxtweb")
SET( qxtcore "core" )
SET( qxtnet "network" )
SET( qxtweb "web" )
ADD_DEFINITIONS(-Wall -O2 -DNDEBUG)
IF(NOT WIN32)
ADD_DEFINITIONS(-fPIC)
ADD_DEFINITIONS( -Wall -O2 -DNDEBUG )
IF( NOT WIN32 )
ADD_DEFINITIONS( -fPIC )
ENDIF()
ADD_DEFINITIONS( -DBUILD_QXT_CORE -DBUILD_QXT_WEB )
INCLUDE_DIRECTORIES( ${qxtweb} )
INCLUDE_DIRECTORIES( ${qxtweb} ${qxtcore} ${qxtnet} )
macro(create_qxtweb_fancy_header simpleHeader fancyHeader)
file(WRITE ${CMAKE_BINARY_DIR}/QxtWeb/${fancyHeader} "#include \"${simpleHeader}\"" )
@@ -41,24 +43,23 @@ SET( sources
${qxtweb}/qxtwebcontent.cpp
${qxtweb}/qxtwebevent.cpp
${qxtweb}/qxtwebservicedirectory.cpp
${qxtweb}/qxtwebslotservice.cpp
${qxtweb}/qxtwebcgiservice.cpp
${qxtweb}/qhttpheader.cpp
${qxtweb}/qxtwebslotservice.cpp
# Ripped bits of QxtCore:
${qxtweb}/qxtmetaobject.cpp
${qxtweb}/qxtnull.cpp
${qxtweb}/qxtfifo.cpp
${qxtcore}/qxtmetaobject.cpp
${qxtcore}/qxtnull.cpp
${qxtcore}/qxtfifo.cpp
# QxtNetwork
${qxtweb}/qxtsslserver.cpp
${qxtnet}/qxtsslserver.cpp
# automoc hack
${qxtweb}/qxtboundfunction.h
${qxtcore}/qxtboundfunction.h
)
ADD_LIBRARY(qxtweb-standalone STATIC
ADD_LIBRARY( qxtweb-standalone STATIC
${mocstuff}
${headers}
${sources}
@@ -69,6 +70,6 @@ target_link_libraries( qxtweb-standalone
${QT_LIBRARIES}
)
qt5_use_modules(qxtweb-standalone Network)
qt5_use_modules( qxtweb-standalone Network )
set_target_properties(qxtweb-standalone PROPERTIES AUTOMOC TRUE)
set_target_properties( qxtweb-standalone PROPERTIES AUTOMOC TRUE )

View File

@@ -137,17 +137,14 @@ QxtFifo::QxtFifo(const QByteArray &prime, QObject *parent) : QIODevice(parent)
QXT_INIT_PRIVATE(QxtFifo);
setOpenMode(QIODevice::ReadWrite);
// Since we're being constructed, access to the internals is safe
QxtFifoNode *head;
int available;
QxtFifoNode* node;
#if QT_VERSION >= 0x50000
head = qxt_d().head.load();
available = qxt_d().available.load();
node = qxt_d().head.load();
#else
head = qxt_d().head;
available = qxt_d().available;
node = qxt_d().head;
#endif
node->content = prime;
qxt_d().available.QXT_ADD( prime.size() );
}
/*!

View File

@@ -51,8 +51,6 @@
#define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE
#define QXT_STATIC
#if !defined(QXT_STATIC) && !defined(QXT_DOXYGEN_RUN)
# if defined(BUILD_QXT_CORE)
# define QXT_CORE_EXPORT Q_DECL_EXPORT

View File

@@ -1,27 +1,33 @@
/****************************************************************************
**
** Copyright (C) Qxt Foundation. Some rights reserved.
**
** This file is part of the QxtCore module of the Qxt library.
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the Common Public License, version 1.0, as published
** by IBM, and/or under the terms of the GNU Lesser General Public License,
** version 2.1, as published by the Free Software Foundation.
**
** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
** FITNESS FOR A PARTICULAR PURPOSE.
**
** You should have received a copy of the CPL and the LGPL along with this
** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
** included with the source distribution for more information.
** If you did not receive a copy of the licenses, contact the Qxt Foundation.
**
** <http://libqxt.org> <foundation@libqxt.org>
**
****************************************************************************/
** 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 QXTMETATYPE_H
#define QXTMETATYPE_H
@@ -32,13 +38,19 @@
#include <QtDebug>
#include <qxtglobal.h>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
#define qxtcreate create
#else
#define qxtcreate construct
#endif
template <typename T>
class /*QXT_CORE_EXPORT*/ QxtMetaType
{
public:
static inline T* construct(const T* copy = 0)
{
return QMetaType::construct(qMetaTypeId<T>(), reinterpret_cast<const void*>(copy));
return QMetaType::qxtcreate(qMetaTypeId<T>(), reinterpret_cast<const void*>(copy));
}
static inline void destroy(T* data)
@@ -111,11 +123,7 @@ public:
inline void* qxtConstructByName(const char* typeName, const void* copy = 0)
{
#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 )
return QMetaType::create(QMetaType::type(typeName), copy);
#else
return QMetaType::construct(QMetaType::type(typeName), copy);
#endif
return QMetaType::qxtcreate(QMetaType::type(typeName), copy);
}
inline void qxtDestroyByName(const char* typeName, void* data)

View File

@@ -39,7 +39,7 @@
#include <QSslSocket>
class QxtSslServerPrivate;
class QxtSslServer : public QTcpServer
class QXT_NETWORK_EXPORT QxtSslServer : public QTcpServer
{
Q_OBJECT
public:

View File

@@ -1,2 +0,0 @@
#include "qxtabstracthttpconnector.h"

View File

@@ -1,2 +0,0 @@
#include "qxtabstractwebservice.h"

View File

@@ -1,2 +0,0 @@
#include "qxtabstractwebsessionmanager.h"

View File

@@ -1,2 +0,0 @@
#include "qxthtmltemplate.h"

View File

@@ -1 +0,0 @@
#include "qxtabstracthttpconnector.h"

View File

@@ -1,2 +0,0 @@
#include "qxthttpsessionmanager.h"

View File

@@ -1,2 +0,0 @@
#include "qxtmail.h"

View File

@@ -1 +0,0 @@
#include "qxtabstracthttpconnector.h"

View File

@@ -1,2 +0,0 @@
#include "qxtsendmail.h"

View File

@@ -1 +0,0 @@
#include "qxtweb.h"

View File

@@ -1 +0,0 @@
#include "qxtwebcgiservice.h"

View File

@@ -1,2 +0,0 @@
#include "qxtwebcontent.h"

View File

@@ -1,2 +0,0 @@
#include "qxtwebevent.h"

View File

@@ -1,2 +0,0 @@
#include "qxtwebevent.h"

View File

@@ -1 +0,0 @@
#include "qxtwebevent.h"

View File

@@ -1,2 +0,0 @@
#include "qxtwebevent.h"

View File

@@ -1,2 +0,0 @@
#include "qxtwebevent.h"

View File

@@ -1 +0,0 @@
#include "qxtwebevent.h"

View File

@@ -1,2 +0,0 @@
#include "qxtwebevent.h"

View File

@@ -1,2 +0,0 @@
#include "qxtwebservicedirectory.h"

View File

@@ -1,2 +0,0 @@
#include "qxtwebslotservice.h"

View File

@@ -1 +0,0 @@
#include "qxtwebevent.h"

View File

@@ -1,251 +0,0 @@
/****************************************************************************
** 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 "qxtglobal.h"
/*!
\headerfile <QxtGlobal>
\title Global Qxt Declarations
\inmodule QxtCore
\brief The <QxtGlobal> header provides basic declarations and
is included by all other Qxt headers.
*/
/*!
\macro QXT_VERSION
\relates <QxtGlobal>
This macro expands a numeric value of the form 0xMMNNPP (MM =
major, NN = minor, PP = patch) that specifies Qxt's version
number. For example, if you compile your application against Qxt
0.4.0, the QXT_VERSION macro will expand to 0x000400.
You can use QXT_VERSION to use the latest Qt features where
available. For example:
\code
#if QXT_VERSION >= 0x000400
qxtTabWidget->setTabMovementMode(QxtTabWidget::InPlaceMovement);
#endif
\endcode
\sa QXT_VERSION_STR, qxtVersion()
*/
/*!
\macro QXT_VERSION_STR
\relates <QxtGlobal>
This macro expands to a string that specifies Qxt's version number
(for example, "0.4.0"). This is the version against which the
application is compiled.
\sa qxtVersion(), QXT_VERSION
*/
/*!
\relates <QxtGlobal>
Returns the version number of Qxt at run-time as a string (for
example, "0.4.0"). This may be a different version than the
version the application was compiled against.
\sa QXT_VERSION_STR
*/
const char * qxtVersion()
{
return QXT_VERSION_STR;
}
/*!
\headerfile <QxtPimpl>
\title The Qxt private implementation
\inmodule QxtCore
\brief The <QxtPimpl> header provides tools for hiding
details of a class.
Application code generally doesn't have to be concerned about hiding its
implementation details, but when writing library code it is important to
maintain a constant interface, both source and binary. Maintaining a constant
source interface is easy enough, but keeping the binary interface constant
means moving implementation details into a private class. The PIMPL, or
d-pointer, idiom is a common method of implementing this separation. QxtPimpl
offers a convenient way to connect the public and private sides of your class.
\section1 Getting Started
Before you declare the public class, you need to make a forward declaration
of the private class. The private class must have the same name as the public
class, followed by the word Private. For example, a class named MyTest would
declare the private class with:
\code
class MyTestPrivate;
\endcode
\section1 The Public Class
Generally, you shouldn't keep any data members in the public class without a
good reason. Functions that are part of the public interface should be declared
in the public class, and functions that need to be available to subclasses (for
calling or overriding) should be in the protected section of the public class.
To connect the private class to the public class, include the
QXT_DECLARE_PRIVATE macro in the private section of the public class. In the
example above, the private class is connected as follows:
\code
private:
QXT_DECLARE_PRIVATE(MyTest)
\endcode
Additionally, you must include the QXT_INIT_PRIVATE macro in the public class's
constructor. Continuing with the MyTest example, your constructor might look
like this:
\code
MyTest::MyTest() {
// initialization
QXT_INIT_PRIVATE(MyTest);
}
\endcode
\section1 The Private Class
As mentioned above, data members should usually be kept in the private class.
This allows the memory layout of the private class to change without breaking
binary compatibility for the public class. Functions that exist only as
implementation details, or functions that need access to private data members,
should be implemented here.
To define the private class, inherit from the template QxtPrivate class, and
include the QXT_DECLARE_PUBLIC macro in its public section. The template
parameter should be the name of the public class. For example:
\code
class MyTestPrivate : public QxtPrivate<MyTest> {
public:
MyTestPrivate();
QXT_DECLARE_PUBLIC(MyTest)
};
\endcode
\section1 Accessing Private Members
Use the qxt_d() function (actually a function-like object) from functions in
the public class to access the private class. Similarly, functions in the
private class can invoke functions in the public class by using the qxt_p()
function (this one's actually a function).
For example, assume that MyTest has methods named getFoobar and doBaz(),
and MyTestPrivate has a member named foobar and a method named doQuux().
The code might resemble this example:
\code
int MyTest::getFoobar() {
return qxt_d().foobar;
}
void MyTestPrivate::doQuux() {
qxt_p().doBaz(foobar);
}
\endcode
*/
/*!
* \macro QXT_DECLARE_PRIVATE(PUB)
* \relates <QxtPimpl>
* Declares that a public class has a related private class.
*
* This shuold be put in the private section of the public class. The
* parameter \a PUB must be the name of the public class.
*/
/*!
* \macro QXT_DECLARE_PUBLIC(PUB)
* \relates <QxtPimpl>
* Declares that a private class has a related public class named \a PUB.
*
* This may be put anywhere in the declaration of the private class. The parameter is the name of the public class.
*/
/*!
* \macro QXT_INIT_PRIVATE(PUB)
* \relates <QxtPimpl>
* Initializes resources owned by the private class.
*
* This should be called from the public class's constructor,
* before qxt_d() is used for the first time. The parameter \a PUB must be
* the name of the public class.
*/
/*!
* \macro QXT_D(PUB)
* \relates <QxtPimpl>
* Returns a reference in the current scope named "d" to the private class
* associated with the public class \a PUB.
*
* This function is only available in a class using QXT_DECLARE_PRIVATE().
*/
/*!
* \macro QXT_P(PUB)
* \relates <QxtPimpl>
* Creates a reference in the current scope named "q" to the public class
* named \a PUB.
*
* This macro only works in a class using QXT_DECLARE_PUBLIC().
*/
/*!
* \fn QxtPrivate<PUB>& PUB::qxt_d()
* \relates <QxtPimpl>
* Returns a reference to the private class.
*
* This function is only available in a class using \a QXT_DECLARE_PRIVATE.
*/
/*!
* \fn const QxtPrivate<PUB>& PUB::qxt_d() const
* \relates <QxtPimpl>
* Returns a const reference to the private class.
*
* This function is only available in a class using \a QXT_DECLARE_PRIVATE.
* This overload will be automatically used in const functions.
*/
/*!
* \fn PUB& QxtPrivate::qxt_p()
* \relates <QxtPimpl>
* Returns a reference to the public class.
*
* This function is only available in a class using QXT_DECLARE_PUBLIC().
*/
/*!
* \fn const PUB& QxtPrivate::qxt_p() const
* \relates <QxtPimpl>
* Returns a const reference to the public class.
*
* This function is only available in a class using QXT_DECLARE_PUBLIC().
* This overload will be automatically used in const functions.
*/

View File

@@ -1,46 +0,0 @@
#ifndef QXTWEB_H_INCLUDED
/****************************************************************************
** 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>
*****************************************************************************/
#define QXTWEB_H_INCLUDED
#include "qxtabstracthttpconnector.h"
#include "qxtabstractwebservice.h"
#include "qxtabstractwebsessionmanager.h"
#include "qxthtmltemplate.h"
#include "qxthttpsessionmanager.h"
#include "qxtwebcgiservice.h"
#include "qxtwebcontent.h"
#include "qxtwebevent.h"
#include "qxtwebjsonrpcservice.h"
#include "qxtwebservicedirectory.h"
#include "qxtwebslotservice.h"
#endif // QXTWEB_H_INCLUDED

View File

@@ -1,445 +0,0 @@
/****************************************************************************
** 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 QxtWebCgiService
\inmodule QxtWeb
\brief The QxtWebCgiService class provides a CGI/1.1 gateway for QxtWeb
TODO: write docs
TODO: implement timeout
*/
#include "qxtwebcgiservice.h"
#include "qxtwebcgiservice_p.h"
#include "qxtwebevent.h"
#include "qxtwebcontent.h"
#include <QMap>
#include <QFile>
#include <QProcess>
#include <QtDebug>
QxtCgiRequestInfo::QxtCgiRequestInfo() : sessionID(0), requestID(0), eventSent(false), terminateSent(false) {}
QxtCgiRequestInfo::QxtCgiRequestInfo(QxtWebRequestEvent* req) : sessionID(req->sessionID), requestID(req->requestID), eventSent(false), terminateSent(false) {}
/*!
* Constructs a QxtWebCgiService object with the specified session \a manager and \a parent.
* This service will invoke the specified \a binary to handle incoming requests.
*
* Often, the session manager will also be the parent, but this is not a requirement.
*/
QxtWebCgiService::QxtWebCgiService(const QString& binary, QxtAbstractWebSessionManager* manager, QObject* parent) : QxtAbstractWebService(manager, parent)
{
QXT_INIT_PRIVATE(QxtWebCgiService);
qxt_d().binary = binary;
QObject::connect(&qxt_d().timeoutMapper, SIGNAL(mapped(QObject*)), &qxt_d(), SLOT(terminateProcess(QObject*)));
}
/*!
* Returns the path to the CGI script that will be executed to handle requests.
*
* \sa setBinary()
*/
QString QxtWebCgiService::binary() const
{
return qxt_d().binary;
}
/*!
* Sets the path to the CGI script \a bin that will be executed to handle requests.
*
* \sa binary()
*/
void QxtWebCgiService::setBinary(const QString& bin)
{
if (!QFile::exists(bin) || !(QFile::permissions(bin) & (QFile::ExeUser | QFile::ExeGroup | QFile::ExeOther)))
{
qWarning() << "QxtWebCgiService::setBinary: " + bin + " does not appear to be executable.";
}
qxt_d().binary = bin;
}
/*!
* Returns the maximum time a CGI script may execute, in milliseconds.
*
* The default value is 0, which indicates that CGI scripts will not be terminated
* due to long running times.
*
* \sa setTimeout()
*/
int QxtWebCgiService::timeout() const
{
return qxt_d().timeout;
}
/*!
* Sets the maximum \a time a CGI script may execute, in milliseconds.
*
* The timer is started when the script is launched. After the timeout elapses once,
* the script will be asked to stop, as QProcess::terminate(). (That is, the script
* will receive WM_CLOSE on Windows or SIGTERM on UNIX.) If the process has still
* failed to terminate after another timeout, it will be forcibly terminated, as
* QProcess::kill(). (That is, the script will receive TerminateProcess on Windows
* or SIGKILL on UNIX.)
*
* Set the timeout to 0 to disable this behavior; scripts will not be terminated
* due to excessive run time. This is the default behavior.
*
* CAUTION: Keep in mind that the timeout applies to the real running time of the
* script, not processor time used. A script that initiates a lengthy download
* may be interrupted while transferring data to the web browser. To avoid this
* behavior, see the timeoutOverride property to allow the script to request
* an extended timeout, or use a different QxtAbstractWebService object for
* serving streaming content or large files.
*
*
* \sa timeout(), timeoutOverride(), setTimeoutOverride(), QProcess::terminate(), QProcess::kill()
*/
void QxtWebCgiService::setTimeout(int time)
{
qxt_d().timeout = time;
}
/*!
* Returns whether or not to allow scripts to override the timeout.
*
* \sa setTimeoutOverride(), setTimeout()
*/
bool QxtWebCgiService::timeoutOverride() const
{
return qxt_d().timeoutOverride;
}
/*!
* Sets whether or not to allow scripts to override the timeout.
* Scripts are allowed to override if \a enable is \c true.
*
* As an extension to the CGI/1.1 gateway specification, a CGI script may
* output a "X-QxtWeb-Timeout" header to change the termination timeout
* on a per-script basis. Only enable this option if you trust the scripts
* being executed.
*
* \sa timeoutOverride(), setTimeout()
*/
void QxtWebCgiService::setTimeoutOverride(bool enable)
{
qxt_d().timeoutOverride = enable;
}
/*!
* \reimp
*/
void QxtWebCgiService::pageRequestedEvent(QxtWebRequestEvent* event)
{
// Create the process object and initialize connections
QProcess* process = new QProcess(this);
qxt_d().requests[process] = QxtCgiRequestInfo(event);
qxt_d().processes[event->content] = process;
QxtCgiRequestInfo& requestInfo = qxt_d().requests[process];
QObject::connect(process, SIGNAL(readyRead()), &qxt_d(), SLOT(processReadyRead()));
QObject::connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), &qxt_d(), SLOT(processFinished()));
QObject::connect(process, SIGNAL(error(QProcess::ProcessError)), &qxt_d(), SLOT(processFinished()));
requestInfo.timeout = new QTimer(process);
qxt_d().timeoutMapper.setMapping(requestInfo.timeout, process);
QObject::connect(requestInfo.timeout, SIGNAL(timeout()), &qxt_d().timeoutMapper, SLOT(map()));
// Initialize the system environment
QStringList s_env = process->systemEnvironment();
QMap<QString, QString> env;
foreach(const QString& entry, s_env)
{
int pos = entry.indexOf('=');
env[entry.left(pos)] = entry.mid(pos + 1);
}
// Populate CGI/1.1 environment variables
env["SERVER_SOFTWARE"] = QString("QxtWeb/" QXT_VERSION_STR);
env["SERVER_NAME"] = event->url.host();
env["GATEWAY_INTERFACE"] = "CGI/1.1";
if (event->headers.contains("X-Request-Protocol"))
env["SERVER_PROTOCOL"] = event->headers.value("X-Request-Protocol");
else
env.remove("SERVER_PROTOCOL");
if (event->url.port() != -1)
env["SERVER_PORT"] = QString::number(event->url.port());
else
env.remove("SERVER_PORT");
env["REQUEST_METHOD"] = event->method;
env["PATH_INFO"] = event->url.path();
env["PATH_TRANSLATED"] = event->url.path(); // CGI/1.1 says we should resolve this, but we have no logical interpretation
env["SCRIPT_NAME"] = event->originalUrl.path().remove(QRegExp(QRegExp::escape(event->url.path()) + '$'));
env["SCRIPT_FILENAME"] = qxt_d().binary; // CGI/1.1 doesn't define this but PHP demands it
env.remove("REMOTE_HOST");
env["REMOTE_ADDR"] = event->remoteAddress.toString();
// TODO: If we ever support HTTP authentication, we should use these
env.remove("AUTH_TYPE");
env.remove("REMOTE_USER");
env.remove("REMOTE_IDENT");
if (event->contentType.isEmpty())
{
env.remove("CONTENT_TYPE");
env.remove("CONTENT_LENGTH");
}
else
{
env["CONTENT_TYPE"] = event->contentType;
env["CONTENT_LENGTH"] = QString::number(event->content->unreadBytes());
}
#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 )
env["QUERY_STRING"] = event->url.query();
#else
env["QUERY_STRING"] = event->url.encodedQuery();
#endif
// Populate HTTP header environment variables
QMultiHash<QString, QString>::const_iterator iter = event->headers.constBegin();
while (iter != event->headers.constEnd())
{
QString key = "HTTP_" + iter.key().toUpper().replace('-', '_');
if (key != "HTTP_CONTENT_TYPE" && key != "HTTP_CONTENT_LENGTH")
env[key] = iter.value();
iter++;
}
// Populate HTTP_COOKIE parameter
iter = event->cookies.constBegin();
QString cookies;
while (iter != event->cookies.constEnd())
{
if (!cookies.isEmpty())
cookies += "; ";
cookies += iter.key() + '=' + iter.value();
iter++;
}
if (!cookies.isEmpty())
env["HTTP_COOKIE"] = cookies;
// Load environment into process space
QStringList p_env;
QMap<QString, QString>::iterator env_iter = env.begin();
while (env_iter != env.end())
{
p_env << env_iter.key() + '=' + env_iter.value();
env_iter++;
}
process->setEnvironment(p_env);
// Launch process
#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 )
if (event->url.hasQuery() && event->url.query().contains('='))
#else
if (event->url.hasQuery() && event->url.encodedQuery().contains('='))
#endif
{
// CGI/1.1 spec says to pass the query on the command line if there's no embedded = sign
#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 )
process->start(qxt_d().binary + ' ' + event->url.query(), QIODevice::ReadWrite);
#else
process->start(qxt_d().binary + ' ' + event->url.encodedQuery(), QIODevice::ReadWrite);
#endif
}
else
{
process->start(qxt_d().binary, QIODevice::ReadWrite);
}
// Start the timeout
if(qxt_d().timeout > 0)
{
requestInfo.timeout->start(qxt_d().timeout);
}
// Transmit POST data
if (event->content)
{
QObject::connect(event->content, SIGNAL(readyRead()), &qxt_d(), SLOT(browserReadyRead()));
qxt_d().browserReadyRead(event->content);
}
}
/*!
* \internal
*/
void QxtWebCgiServicePrivate::browserReadyRead(QObject* o_content)
{
if (!o_content) o_content = sender();
QxtWebContent* content = static_cast<QxtWebContent*>(o_content); // this is a private class, no worries about type safety
// Read POST data and copy it to the process
QByteArray data = content->readAll();
if (!data.isEmpty())
processes[content]->write(data);
// If no POST data remains unsent, clean up
if (!content->unreadBytes() && processes.contains(content))
{
processes[content]->closeWriteChannel();
processes.remove(content);
}
}
/*!
* \internal
*/
void QxtWebCgiServicePrivate::processReadyRead()
{
QProcess* process = static_cast<QProcess*>(sender());
QxtCgiRequestInfo& request = requests[process];
QByteArray line;
while (process->canReadLine())
{
// Read in a CGI/1.1 header line
line = process->readLine().replace(QByteArray("\r"), ""); //krazy:exclude=doublequote_chars
if (line == "\n")
{
// An otherwise-empty line indicates the end of CGI/1.1 headers and the start of content
QObject::disconnect(process, SIGNAL(readyRead()), this, 0);
QxtWebPageEvent* event = 0;
int code = 200;
if (request.headers.contains("status"))
{
// CGI/1.1 defines a "Status:" header that dictates the HTTP response code
code = request.headers["status"].left(3).toInt();
if (code >= 300 && code < 400) // redirect
{
event = new QxtWebRedirectEvent(request.sessionID, request.requestID, request.headers["location"], code);
}
}
// If a previous header (currently just status) hasn't created an event, create a normal page event here
if (!event)
{
event = new QxtWebPageEvent(request.sessionID, request.requestID, process);
event->status = code;
}
// Add other response headers passed from CGI (currently only Content-Type is supported)
if (request.headers.contains("content-type"))
event->contentType = request.headers["content-type"].toUtf8();
// TODO: QxtWeb doesn't support transmitting arbitrary HTTP headers right now, but it may be desirable
// for applications that know what kind of server frontend they're using to allow scripts to send
// protocol-specific headers.
// Post the event
qxt_p().postEvent(event);
request.eventSent = true;
return;
}
else
{
// Since we haven't reached the end of headers yet, parse a header
int pos = line.indexOf(": ");
QByteArray hdrName = line.left(pos).toLower();
QByteArray hdrValue = line.mid(pos + 2).replace(QByteArray("\n"), ""); //krazy:exclude=doublequote_chars
if (hdrName == "set-cookie")
{
// Parse a new cookie and post an event to send it to the client
QList<QByteArray> cookies = hdrValue.split(',');
foreach(const QByteArray& cookie, cookies)
{
int equals = cookie.indexOf("=");
int semi = cookie.indexOf(";");
QByteArray cookieName = cookie.left(equals);
int age = cookie.toLower().indexOf("max-age=", semi);
int secs = -1;
if (age >= 0)
secs = cookie.mid(age + 8, cookie.indexOf(";", age) - age - 8).toInt();
if (secs == 0)
{
qxt_p().postEvent(new QxtWebRemoveCookieEvent(request.sessionID, cookieName));
}
else
{
QByteArray cookieValue = cookie.mid(equals + 1, semi - equals - 1);
QDateTime cookieExpires;
if (secs != -1)
cookieExpires = QDateTime::currentDateTime().addSecs(secs);
qxt_p().postEvent(new QxtWebStoreCookieEvent(request.sessionID, cookieName, cookieValue, cookieExpires));
}
}
}
else if(hdrName == "x-qxtweb-timeout")
{
if(timeoutOverride)
request.timeout->setInterval(hdrValue.toInt());
}
else
{
// Store other headers for later inspection
request.headers[hdrName] = hdrValue;
}
}
}
}
/*!
* \internal
*/
void QxtWebCgiServicePrivate::processFinished()
{
QProcess* process = static_cast<QProcess*>(sender());
QxtCgiRequestInfo& request = requests[process];
if (!request.eventSent)
{
// If no event was posted, issue an internal error
qxt_p().postEvent(new QxtWebErrorEvent(request.sessionID, request.requestID, 500, "Internal Server Error"));
}
// Clean up data structures
process->close();
QxtWebContent* key = processes.key(process);
if (key) processes.remove(key);
timeoutMapper.removeMappings(request.timeout);
requests.remove(process);
}
/*!
* \internal
*/
void QxtWebCgiServicePrivate::terminateProcess(QObject* o_process)
{
QProcess* process = static_cast<QProcess*>(o_process);
QxtCgiRequestInfo& request = requests[process];
if(request.terminateSent)
{
// kill with fire
process->kill();
}
else
{
// kill nicely
process->terminate();
request.terminateSent = true;
}
}

View File

@@ -1,64 +0,0 @@
/****************************************************************************
** 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_H
#define QXTWEBCGISERVICE_H
#include <QObject>
#include <qxtglobal.h>
#include "qxtabstractwebsessionmanager.h"
#include "qxtabstractwebservice.h"
class QxtWebEvent;
class QxtWebRequestEvent;
class QxtWebCgiServicePrivate;
class QXT_WEB_EXPORT QxtWebCgiService : public QxtAbstractWebService
{
Q_OBJECT
public:
QxtWebCgiService(const QString& binary, QxtAbstractWebSessionManager* manager, QObject* parent = 0);
QString binary() const;
void setBinary(const QString& bin);
int timeout() const;
void setTimeout(int time);
bool timeoutOverride() const;
void setTimeoutOverride(bool enable);
virtual void pageRequestedEvent(QxtWebRequestEvent* event);
private:
QXT_DECLARE_PRIVATE(QxtWebCgiService)
};
#endif // QXTWEBCGISERVICE_H

View File

@@ -1,512 +0,0 @@
/****************************************************************************
** 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 QxtWebJsonRPCService
\inmodule QxtWeb
\brief The QxtWebJsonRPCService class provides a Slot based webservice that responds to JSONRPC
See http://json-rpc.org for details on the protocol
To create a Webservice, simply subclass QxtWebJsonRPCService. All slots are exposed as jsonrpc method
\code
class MyService : public QxtWebJsonRPCService
{
Q_OBJECT
public slots:
int add(int a, int b
{
return a +b;
}
}
\endcode
\code
curl -d '{"method":"add", "id":1, "params": [9,2] }' localhost:1339
{"error":null,"id":1,"result":11}
\endcode
\sa QxtAbstractWebService
*/
#include "qxtwebjsonrpcservice_p.h"
#include "qxtwebevent.h"
#include "qxtwebcontent.h"
#include "qxtjson.h"
#include <QtCore/QMetaMethod>
#include <QtCore/QMetaType>
#include <QtCore/QGenericReturnArgument>
#include <QtCore/QGenericArgument>
QxtWebJsonRPCService::Private::Private(QxtWebJsonRPCService *that)
: QObject()
, p(that)
, invokable(0)
{
}
void QxtWebJsonRPCService::Private::initTables(QObject *in)
{
invokable = in;
const QMetaObject *po = invokable->metaObject();
for (int i = po->methodOffset(); i < po->methodCount(); i++) {
QxtWebJsonRPCService::Private::Method method;
QMetaMethod mo = po->method (i);
#if QT_VERSION >= 0x50000
method.name = QByteArray(mo.methodSignature()).split('(').at(0);
#else
method.name = QByteArray(mo.signature()).split('(').at(0);
#endif
method.meta = mo;
method.argCount = mo.parameterTypes ().count();
method.returns = QByteArray(mo.typeName()).count();
methods.insert(method.name + QByteArray::number(method.argCount), method);
}
}
void QxtWebJsonRPCService::Private::readFinished()
{
QxtWebContent *c = qobject_cast<QxtWebContent *>(sender());
handle(c);
}
void QxtWebJsonRPCService::Private::handle(QxtWebContent *c)
{
QxtWebRequestEvent *event = content.take(c);
currentRequest = 0;
c->ignoreRemainingContent();
QString data = QString::fromUtf8(c->readAll());
QVariantMap var = QxtJSON::parse(data).toMap();
if (var.isEmpty()) {
QByteArray resp = "{\"result\": null, \"error\": \"invalid json data\", \"id\": 0}\r\n";
QxtWebPageEvent *err = new QxtWebPageEvent(event->sessionID, event->requestID, resp);
err->status = 500;
p->postEvent(err);
return;
}
QVariant rid = var.value("id");
QString action = var.value("method").toString();
QVariant argsE = var.value("params");
handle(event, rid, action, argsE);
}
void QxtWebJsonRPCService::Private::handle(QxtWebRequestEvent *event, QVariant rid, QString action, QVariant argsE)
{
QVariantMap argsM;
QVariantList args;
if (argsE.type() == QVariant::Map) {
argsM = argsE.toMap();
args = argsM.values();
} else {
args = argsE.toList();
}
if (!invokable)
initTables(p);
if (!methods.contains(action.toUtf8() + QByteArray::number(args.count()))) {
QVariantMap res;
res.insert("result", QVariant());
res.insert("error", "no such method or incorrect number of arguments");
res.insert("id", rid);
QxtWebPageEvent *err = new QxtWebPageEvent(event->sessionID, event->requestID,
QxtJSON::stringify(res).toUtf8() + "\r\n");
p->postEvent(err);
return;
}
Method method = methods.value(action.toUtf8() + QByteArray::number(args.count()));
if (argsE.type() == QVariant::Map) {
args.clear();
foreach (const QString &pname, method.meta.parameterNames ()) {
args.append(argsM.value(pname));
}
}
QList<QGenericArgument> vargs;
foreach (const QVariant &ar, args) {
vargs.append(QGenericArgument(ar.typeName(), ar.data()));
}
QVariant returnValue;
currentRequest = event;
currentRequestId = rid;
requestCanceled = false;
bool ok = false;
if (method.returns) {
QVariant retA(QVariant::nameToType(method.meta.typeName()));
QGenericReturnArgument ret(retA.typeName(), retA.data());
if (args.count() > 8)
{
ok = method.meta.invoke(invokable,
ret,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4)),
(vargs.at(5)),
(vargs.at(6)),
(vargs.at(7)),
(vargs.at(7))
);
}
if (args.count() > 7)
{
ok = method.meta.invoke(invokable,
ret,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4)),
(vargs.at(5)),
(vargs.at(6)),
(vargs.at(7))
);
}
else if (args.count() > 6)
{
ok = method.meta.invoke(invokable,
ret,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4)),
(vargs.at(5)),
(vargs.at(6))
);
}
else if (args.count() > 5)
{
ok = method.meta.invoke(invokable,
ret,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4)),
(vargs.at(5))
);
}
else if (args.count() > 4)
{
ok = method.meta.invoke(invokable,
ret,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4))
);
}
else if (args.count() > 3)
{
ok = method.meta.invoke(invokable,
ret,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3))
);
}
else if (args.count() > 2)
{
ok = method.meta.invoke(invokable,
ret,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2))
);
}
else if (args.count() > 1)
{
ok = method.meta.invoke(invokable,
ret,
(vargs.at(0)),
(vargs.at(1))
);
}
else if (args.count() > 0)
{
ok = method.meta.invoke(invokable,
ret,
(vargs.at(0))
);
}
else
{
ok = method.meta.invoke(invokable,
ret
);
}
returnValue = retA;
// the pass through QGenericReturnArgument didn't make it non null.
returnValue.data_ptr().is_null = 0;
} else {
if (args.count() > 8)
{
ok = method.meta.invoke(invokable,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4)),
(vargs.at(5)),
(vargs.at(6)),
(vargs.at(7)),
(vargs.at(7))
);
}
if (args.count() > 7)
{
ok = method.meta.invoke(invokable,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4)),
(vargs.at(5)),
(vargs.at(6)),
(vargs.at(7))
);
}
else if (args.count() > 6)
{
ok = method.meta.invoke(invokable,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4)),
(vargs.at(5)),
(vargs.at(6))
);
}
else if (args.count() > 5)
{
ok = method.meta.invoke(invokable,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4)),
(vargs.at(5))
);
}
else if (args.count() > 4)
{
ok = method.meta.invoke(invokable,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3)),
(vargs.at(4))
);
}
else if (args.count() > 3)
{
ok = method.meta.invoke(invokable,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2)),
(vargs.at(3))
);
}
else if (args.count() > 2)
{
ok = method.meta.invoke(invokable,
(vargs.at(0)),
(vargs.at(1)),
(vargs.at(2))
);
}
else if (args.count() > 1)
{
ok = method.meta.invoke(invokable,
(vargs.at(0)),
(vargs.at(1))
);
}
else if (args.count() > 0)
{
ok = method.meta.invoke(invokable,
(vargs.at(0))
);
}
else
{
ok = method.meta.invoke(invokable
);
}
}
if (!ok) {
QVariantMap res;
res.insert("result", QVariant());
res.insert("error", "execution failure");
res.insert("id", rid);
QxtWebPageEvent *err = new QxtWebPageEvent(event->sessionID, event->requestID,
QxtJSON::stringify(res).toUtf8() + "\r\n");
p->postEvent(err);
return;
}
if (requestCanceled) {
return;
}
QVariantMap res;
res.insert("result", returnValue);
res.insert("error", QVariant());
res.insert("id", rid);
QxtWebPageEvent *err = new QxtWebPageEvent(event->sessionID, event->requestID,
QxtJSON::stringify(res).toUtf8() + "\r\n");
p->postEvent(err);
return;
}
/*!
Constructs a new QxtWebJsonRPCService with \a sm and \a parent.
*/
QxtWebJsonRPCService::QxtWebJsonRPCService(QxtAbstractWebSessionManager* sm, QObject* parent)
: QxtAbstractWebService(sm, parent)
, d(new Private(this))
{
}
QxtWebJsonRPCService::~QxtWebJsonRPCService()
{
delete d;
}
/*!
* respond to the current request with an error.
*
* The return value of the current slot is NOT used.
* Instead null is returned, adhering to the jsonrpc specificaiton.
*
* Calling this function from somewhere else then a handler slot is undefined behaviour.
*/
void QxtWebJsonRPCService::throwRPCError(QVariant error)
{
d->requestCanceled= true;
QxtWebRequestEvent *event = d->currentRequest;
QVariantMap res;
res.insert("result", QVariant());
res.insert("error", error);
res.insert("id", d->currentRequestId);
QxtWebPageEvent *err = new QxtWebPageEvent(event->sessionID, event->requestID,
QxtJSON::stringify(res).toUtf8() + "\r\n");
postEvent(err);
}
/*!
Returns the current absolute url of this service depending on the request \a event.
*/
QUrl QxtWebJsonRPCService::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 QxtWebJsonRPCService::pageRequestedEvent(QxtWebRequestEvent* event)
{
if (event->method == "GET") {
QVariantMap params;
QList<QPair<QByteArray, QByteArray> > enc = event->url.encodedQueryItems ();
for (int i = 0; i < enc.count(); i++) {
params.insert(
QUrl::fromPercentEncoding (enc.at(i).first),
QUrl::fromPercentEncoding (enc.at(i).second));
}
QString method = event->url.path().split('/').last();
d->handle(event, QVariant(), method, params);
return;
}
if (!event->content) {
QVariantMap res;
res.insert("result", QVariant());
res.insert("error", "missing POST data");
res.insert("id", QVariant());
QxtWebPageEvent *err = new QxtWebPageEvent(event->sessionID, event->requestID,
QxtJSON::stringify(res).toUtf8() + "\r\n");
err->status = 500;
postEvent(err);
return;
}
d->content.insert(event->content, event);
if (event->content->bytesNeeded() == 0) {
d->handle(event->content);
} else {
connect(event->content, SIGNAL(readChannelFinished()), d, SLOT(readFinished()));
}
}
/*!
\reimp
*/
void QxtWebJsonRPCService::functionInvokedEvent(QxtWebRequestEvent* event)
{
postEvent(new QxtWebErrorEvent(event->sessionID, event->requestID, 500, "<h1>Not supported</h1>"));
}

View File

@@ -1,56 +0,0 @@
/****************************************************************************
** 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 QXTWEBJSONRPCSERVICE_H
#define QXTWEBJSONRPCSERVICE_H
#include "qxtabstractwebservice.h"
#include <QUrl>
class QXT_WEB_EXPORT QxtWebJsonRPCService : public QxtAbstractWebService
{
Q_OBJECT
public:
explicit QxtWebJsonRPCService(QxtAbstractWebSessionManager* sm, QObject* parent = 0);
virtual ~QxtWebJsonRPCService();
protected:
void throwRPCError(QVariant error);
QUrl self(QxtWebRequestEvent* event);
virtual void pageRequestedEvent(QxtWebRequestEvent* event);
virtual void functionInvokedEvent(QxtWebRequestEvent* event);
private:
class Private;
Private *d;
};
#endif // QXTWEBJSONRPCSERVICE_H

View File

@@ -1,66 +0,0 @@
/****************************************************************************
** 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 "qxtwebjsonrpcservice.h"
#include "qxtwebcontent.h"
#include "qxtwebevent.h"
#include <QtCore/QMetaMethod>
class QxtWebJsonRPCService::Private : public QObject
{
Q_OBJECT
public:
Private(QxtWebJsonRPCService *that);
QMap<QxtWebContent *, QxtWebRequestEvent*> content;
QxtWebJsonRPCService *p;
void initTables(QObject *invokable);
bool tablesInitilized;
QObject *invokable;
struct Method
{
QMetaMethod meta;
QByteArray name;
bool returns;
int argCount;
};
QMap<QByteArray, Method> methods;
QxtWebRequestEvent *currentRequest;
QVariant currentRequestId;
bool requestCanceled;
public slots:
void readFinished();
void handle(QxtWebContent *);
void handle( QxtWebRequestEvent *event, QVariant id, QString method, QVariant args);
};

View File

@@ -42,11 +42,12 @@
#ifndef QHTTP_H
#define QHTTP_H
#include <QtCore/qobject.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qmap.h>
#include <QtCore/qpair.h>
#include <QtCore/qscopedpointer.h>
#include <QObject>
#include <QStringList>
#include <QMap>
#include <QPair>
#include <QScopedPointer>
#include <qxtglobal.h>
QT_BEGIN_HEADER
@@ -66,7 +67,7 @@ class QSslError;
class QHttpPrivate;
class QHttpHeaderPrivate;
class Q_NETWORK_EXPORT QHttpHeader
class QXT_WEB_EXPORT QHttpHeader
{
public:
QHttpHeader();
@@ -116,7 +117,7 @@ private:
};
class QHttpResponseHeaderPrivate;
class Q_NETWORK_EXPORT QHttpResponseHeader : public QHttpHeader
class QXT_WEB_EXPORT QHttpResponseHeader : public QHttpHeader
{
public:
QHttpResponseHeader();
@@ -144,7 +145,7 @@ private:
};
class QHttpRequestHeaderPrivate;
class Q_NETWORK_EXPORT QHttpRequestHeader : public QHttpHeader
class QXT_WEB_EXPORT QHttpRequestHeader : public QHttpHeader
{
public:
QHttpRequestHeader();

View File

@@ -52,7 +52,7 @@ QxtWeb uses QxtWebContent as an abstraction for streaming data.
#include <QCoreApplication>
#include <QThread>
#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 )
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QUrlQuery>
#endif
@@ -272,13 +272,13 @@ typedef QPair<QString, QString> QxtQueryItem;
*/
QHash<QString, QString> QxtWebContent::parseUrlEncodedQuery(const QString& data)
{
QUrl post("/?" + data);
QHash<QString, QString> rv;
#if QT_VERSION >= QT_VERSION_CHECK( 5, 0, 0 )
foreach(const QxtQueryItem& item, QUrlQuery( post ).queryItems())
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
QUrl post("/?" + data);
#else
foreach(const QxtQueryItem& item, post.queryItems())
QUrlQuery post("/?" + data);
#endif
foreach(const QxtQueryItem& item, post.queryItems())
{
rv.insertMulti(item.first, item.second);
}

View File

@@ -42,7 +42,7 @@ A WebService that resolves the first part of the path to a slot name and passes
\code
class MyService : public QxtWebSlotService
{
//Q_OBJECT
// Q_OBJECT
public slots:
void hello(QxtWebRequestEvent* event, QString a)
{