mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
[SERVER] QgsRequestHandler now returns a QPair
Much simpler GUI with a single method for all cases. handleRequest now returns both headers and body in a QPair. Python binding returns a tuple of QByteArray.
This commit is contained in:
parent
86115435f5
commit
a9f2acc57e
@ -17,6 +17,48 @@
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
%MappedType QPair<QByteArray, QByteArray>
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <QPair>
|
||||
#include <QByteArray>
|
||||
%End
|
||||
|
||||
|
||||
%TypeCode
|
||||
// Convenience function for converting a QByteArray to a Python str object. (from QtCore/qbytearray.sip)
|
||||
static PyObject *QByteArrayToPyStr(QByteArray *ba)
|
||||
{
|
||||
char *data = ba->data();
|
||||
|
||||
if (data)
|
||||
// QByteArrays may have embedded '\0's so set the size explicitly.
|
||||
return SIPBytes_FromStringAndSize(data, ba->size());
|
||||
return SIPBytes_FromString("");
|
||||
}
|
||||
%End
|
||||
|
||||
|
||||
%ConvertFromTypeCode
|
||||
// Create the tuple.
|
||||
return Py_BuildValue((char *)"OO", QByteArrayToPyStr( &sipCpp->first ), QByteArrayToPyStr( &sipCpp->second ) );
|
||||
%End
|
||||
|
||||
%ConvertToTypeCode
|
||||
// Check the type if that is all that is required.
|
||||
if (sipIsErr == NULL)
|
||||
return (PyTuple_Size(sipPy) == 2);
|
||||
|
||||
QPair<QByteArray, QByteArray> *qp = new QPair<QByteArray, QByteArray>;
|
||||
|
||||
qp->first = SIPLong_AsLong(PyTuple_GET_ITEM(sipPy, 0));
|
||||
qp->second = SIPLong_AsLong(PyTuple_GET_ITEM(sipPy, 1));
|
||||
|
||||
*sipCppPtr = qp;
|
||||
|
||||
return sipGetState(sipTransferObj);
|
||||
%End
|
||||
};
|
||||
|
||||
class QgsServer
|
||||
{
|
||||
@ -31,21 +73,12 @@ class QgsServer
|
||||
//void init( int argc, char* argv[] );
|
||||
// init for python bindings:
|
||||
void init( );
|
||||
QByteArray handleRequest( const QString queryString = QString( ) );
|
||||
// TODO: if HAVE_SERVER_PYTHON
|
||||
QByteArray handleRequest( const QString queryString,
|
||||
const bool returnHeaders,
|
||||
const bool returnBody );
|
||||
QByteArray handleRequestGetBody( const QString queryString = QString( ) );
|
||||
QByteArray handleRequestGetHeaders( const QString queryString = QString( ) );
|
||||
//QgsServerContext& serverContext ( ) /KeepReference/;
|
||||
QPair<QByteArray, QByteArray> handleRequest( const QString queryString = QString( ) );
|
||||
%If (HAVE_SERVER_PYTHON_PLUGINS)
|
||||
QgsServerInterface* serverInterface( );
|
||||
// Needs %MethodCode
|
||||
//QMultiMap<int, QgsServerFilter*> pluginFilters( );
|
||||
%End
|
||||
|
||||
// The following is needed because otherwise SIP fails trying to create copy
|
||||
// The following is needed because otherwise SIP fails trying to create copy
|
||||
// ctor
|
||||
private:
|
||||
QgsServer( const QgsServer& );
|
||||
|
@ -218,21 +218,10 @@ void QgsHttpRequestHandler::sendResponse()
|
||||
clearBody();
|
||||
}
|
||||
|
||||
QByteArray QgsHttpRequestHandler::getResponse( const bool returnHeaders,
|
||||
const bool returnBody )
|
||||
QPair<QByteArray, QByteArray> QgsHttpRequestHandler::getResponse()
|
||||
{
|
||||
if ( ! returnHeaders )
|
||||
{
|
||||
return mResponseBody;
|
||||
}
|
||||
else if ( ! returnBody )
|
||||
{
|
||||
return mResponseHeader;
|
||||
}
|
||||
else
|
||||
{
|
||||
return mResponseHeader.append( mResponseBody );
|
||||
}
|
||||
QPair<QByteArray, QByteArray> response( mResponseHeader, mResponseBody );
|
||||
return response;
|
||||
}
|
||||
|
||||
QString QgsHttpRequestHandler::formatToMimeType( const QString& format ) const
|
||||
|
@ -63,12 +63,8 @@ class QgsHttpRequestHandler: public QgsRequestHandler
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
virtual void setPluginFilters( QgsServerFiltersMap pluginFilters ) override;
|
||||
#endif
|
||||
// TODO: if HAVE_SERVER_PYTHON
|
||||
QByteArray getResponseHeader( ) override { return mResponseHeader; }
|
||||
QByteArray getResponseBody( ) override { return mResponseBody; }
|
||||
/** Return the response if capture output is activated */
|
||||
QByteArray getResponse( const bool returnHeaders = TRUE,
|
||||
const bool returnBody = TRUE ) override;
|
||||
QPair<QByteArray, QByteArray> getResponse( ) override;
|
||||
|
||||
protected:
|
||||
virtual void sendHeaders( ) override;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QPair>
|
||||
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
#include "qgsserverfilter.h"
|
||||
@ -113,11 +114,7 @@ class QgsRequestHandler
|
||||
*/
|
||||
virtual void setPluginFilters( QgsServerFiltersMap pluginFilters ) = 0;
|
||||
#endif
|
||||
// TODO: if HAVE_SERVER_PYTHON
|
||||
virtual QByteArray getResponseHeader( ) = 0;
|
||||
virtual QByteArray getResponseBody( ) = 0;
|
||||
virtual QByteArray getResponse( const bool returnHeaders = TRUE,
|
||||
const bool returnBody = TRUE ) = 0;
|
||||
virtual QPair<QByteArray, QByteArray> getResponse( ) = 0;
|
||||
|
||||
protected:
|
||||
virtual void sendHeaders( ) = 0;
|
||||
|
@ -403,47 +403,14 @@ bool QgsServer::init( int & argc, char ** argv )
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the request
|
||||
*/
|
||||
QByteArray QgsServer::handleRequest( const QString queryString /*= QString( )*/ )
|
||||
{
|
||||
return handleRequest( queryString, TRUE, TRUE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles the request, returning only the body
|
||||
* @param queryString
|
||||
* @return response body if mCaptureOutput is set, empty QByteArray if not
|
||||
*/
|
||||
QByteArray QgsServer::handleRequestGetBody( const QString queryString /*= QString( )*/ )
|
||||
{
|
||||
return handleRequest( queryString, FALSE, TRUE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles the request, returning only the headers
|
||||
* @param queryString
|
||||
* @return response headers if mCaptureOutput is set, empty QByteArray if not
|
||||
*/
|
||||
QByteArray QgsServer::handleRequestGetHeaders( const QString queryString /*= QString( )*/ )
|
||||
{
|
||||
return handleRequest( queryString, TRUE, FALSE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles the request
|
||||
* @param queryString
|
||||
* @param returnBody
|
||||
* @param returnHeaders
|
||||
* @return response body and headers if mCaptureOutput is set and the
|
||||
* flags are set, empty QByteArray if not
|
||||
* @return response body and headers
|
||||
*/
|
||||
QByteArray QgsServer::handleRequest( const QString queryString ,
|
||||
bool returnHeaders,
|
||||
bool returnBody )
|
||||
QPair<QByteArray, QByteArray> QgsServer::handleRequest( const QString queryString /*= QString( )*/ )
|
||||
{
|
||||
|
||||
// Run init if handleRequest was called without previously initialising
|
||||
// the server
|
||||
if ( ! mInitialised )
|
||||
@ -603,6 +570,7 @@ QByteArray QgsServer::handleRequest( const QString queryString ,
|
||||
}
|
||||
// TODO: if HAVE_SERVER_PYTHON
|
||||
// Returns the response bytestream
|
||||
return theRequestHandler->getResponse( returnHeaders , returnBody );
|
||||
return theRequestHandler->getResponse( );
|
||||
|
||||
}
|
||||
|
||||
|
@ -61,36 +61,15 @@ class SERVER_EXPORT QgsServer
|
||||
/** Handles the request. The output is normally printed trough FCGI printf
|
||||
* by the request handler or, in case the server has been invoked from python
|
||||
* bindings, a flag is set that captures all the output headers and body, instead
|
||||
* of printing it returns the output as a QByteArray.
|
||||
* When calling handleRequest() from python bindings an additional argument
|
||||
* specify if we only want the headers or the body back, this is mainly useful
|
||||
* for testing purposes.
|
||||
* of printing it returns the output as a QPair of QByteArray.
|
||||
* The query string is normally read from environment
|
||||
* but can be also passed in args and in this case overrides the environment
|
||||
* variable
|
||||
*
|
||||
* @param queryString optional QString containing the query string
|
||||
* @return the response QByteArray if called from python bindings, empty otherwise
|
||||
* @return the response headers and body QPair of QByteArray if called from python bindings, empty otherwise
|
||||
*/
|
||||
QByteArray handleRequest( const QString queryString = QString( ) );
|
||||
QByteArray handleRequest( const QString queryString,
|
||||
const bool returnHeaders,
|
||||
const bool returnBody );
|
||||
/**
|
||||
* Handles the request and returns only the body
|
||||
*
|
||||
* @param queryString optional QString containing the query string
|
||||
* @return the response body QByteArray if called from python bindings, empty otherwise
|
||||
*/
|
||||
QByteArray handleRequestGetBody( const QString queryString = QString( ) );
|
||||
|
||||
/**
|
||||
* Handles the request and returns only the headers
|
||||
*
|
||||
* @param queryString optional QString containing the query string
|
||||
* @return the response headers QByteArray if called from python bindings, empty otherwise
|
||||
*/
|
||||
QByteArray handleRequestGetHeaders( const QString queryString = QString( ) );
|
||||
QPair<QByteArray, QByteArray> handleRequest( const QString queryString = QString( ) );
|
||||
|
||||
/** Returns a pointer to the server interface */
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
|
@ -53,17 +53,15 @@ class TestQgsServer(unittest.TestCase):
|
||||
"""Using an empty query string (returns an XML exception)
|
||||
we are going to test if headers and body are returned correctly"""
|
||||
# Test as a whole
|
||||
response = str(self.server.handleRequest())
|
||||
header, body = [str(_v) for _v in self.server.handleRequest()]
|
||||
response = header + body
|
||||
expected = 'Content-Length: 206\nContent-Type: text/xml; charset=utf-8\n\n<ServiceExceptionReport version="1.3.0" xmlns="http://www.opengis.net/ogc">\n <ServiceException code="Service configuration error">Service unknown or unsupported</ServiceException>\n</ServiceExceptionReport>\n'
|
||||
self.assertEqual(response, expected)
|
||||
# Test header
|
||||
response = str(self.server.handleRequestGetHeaders())
|
||||
expected = 'Content-Length: 206\nContent-Type: text/xml; charset=utf-8\n\n'
|
||||
self.assertEqual(response, expected)
|
||||
self.assertEqual(header, expected)
|
||||
# Test body
|
||||
response = str(self.server.handleRequestGetBody())
|
||||
expected = '<ServiceExceptionReport version="1.3.0" xmlns="http://www.opengis.net/ogc">\n <ServiceException code="Service configuration error">Service unknown or unsupported</ServiceException>\n</ServiceExceptionReport>\n'
|
||||
self.assertEqual(response, expected)
|
||||
self.assertEqual(body, expected)
|
||||
|
||||
def test_pluginfilters(self):
|
||||
"""Test python plugins filters"""
|
||||
@ -122,7 +120,8 @@ class TestQgsServer(unittest.TestCase):
|
||||
self.assertTrue(filter2 in serverIface.filters()[100])
|
||||
self.assertEqual(filter1, serverIface.filters()[101][0])
|
||||
self.assertEqual(filter2, serverIface.filters()[200][0])
|
||||
response = str(self.server.handleRequest('service=simple'))
|
||||
header, body = [str(_v) for _v in self.server.handleRequest('service=simple')]
|
||||
response = header + body
|
||||
expected = 'Content-type: text/plain\n\nHello from SimpleServer!Hello from Filter1!Hello from Filter2!'
|
||||
self.assertEqual(response, expected)
|
||||
|
||||
@ -133,7 +132,8 @@ class TestQgsServer(unittest.TestCase):
|
||||
self.assertTrue(filter2 in serverIface.filters()[100])
|
||||
self.assertEqual(filter1, serverIface.filters()[101][0])
|
||||
self.assertEqual(filter2, serverIface.filters()[200][0])
|
||||
response = str(self.server.handleRequest('service=simple'))
|
||||
header, body = [str(_v) for _v in self.server.handleRequest('service=simple')]
|
||||
response = header + body
|
||||
expected = 'Content-type: text/plain\n\nHello from SimpleServer!Hello from Filter1!Hello from Filter2!'
|
||||
self.assertEqual(response, expected)
|
||||
|
||||
@ -143,7 +143,8 @@ class TestQgsServer(unittest.TestCase):
|
||||
assert os.path.exists(project), "Project file not found: " + project
|
||||
|
||||
query_string = 'MAP=%s&SERVICE=WMS&VERSION=1.3&REQUEST=%s' % (urllib.quote(project), request)
|
||||
response = str(self.server.handleRequest(query_string))
|
||||
header, body = [str(_v) for _v in self.server.handleRequest(query_string)]
|
||||
response = header + body
|
||||
f = open(self.testdata_path + request.lower() + '.txt')
|
||||
expected = f.read()
|
||||
f.close()
|
||||
|
Loading…
x
Reference in New Issue
Block a user