Skip to content
Permalink
Browse files
Merge pull request #45158 from dmarteau/fix-server-filter-streaming
[server] Allow better control of the response flow chain from server filters.
  • Loading branch information
elpaso committed Nov 3, 2021
2 parents 9134854 + bbb8e8f commit dc3e9ebad095cb84d0c1d011fbeabc0a4114ac52
@@ -44,29 +44,84 @@ and must be passed to QgsServerFilter instances.
Returns the :py:class:`QgsServerInterface` instance
%End

virtual void requestReady();
virtual void requestReady() /Deprecated/;
%Docstring
Method called when the :py:class:`QgsRequestHandler` is ready and populated with
parameters, just before entering the main switch for core services.

This method is considered as deprecated and :py:func:`onRequestReady` should
be used instead.

.. deprecated::
Will be removed in QGIS 4.0
%End

virtual void responseComplete();
virtual void responseComplete() /Deprecated/;
%Docstring
Method called when the :py:class:`QgsRequestHandler` processing has done and
the response is ready, just after the main switch for core services
and before final sending response.

This method is considered as deprecated and :py:func:`onResponseComplete` should
be used instead.

.. deprecated::
Will be removed in QGIS 4.0
%End

virtual void sendResponse() /Deprecated/;
%Docstring
Method called when the :py:class:`QgsRequestHandler` sends its data to FCGI stdout.
This normally occurs at the end of core services processing just after
the :py:func:`~QgsServerFilter.responseComplete` plugin hook. For streaming services (like WFS on
getFeature requests, :py:func:`~QgsServerFilter.sendResponse` might have been called several times
before the response is complete: in this particular case, :py:func:`~QgsServerFilter.sendResponse`
is called once for each feature before hitting :py:func:`~QgsServerFilter.responseComplete`

This method is considered as deprecated and :py:func:`onSendResponse` should
be used instead.

.. deprecated::
Will be removed in QGIS 4.0
%End

virtual bool onRequestReady();
%Docstring
Method called when the :py:class:`QgsRequestHandler` is ready and populated with
parameters, just before entering the main switch for core services.

:return: true if the call must propagate to the subsequent filters, false otherwise

.. versionadded:: 3.24
%End

virtual bool onResponseComplete();
%Docstring
Method called when the :py:class:`QgsRequestHandler` processing has done and
the response is ready, just after the main switch for core services
and before final sending response to FCGI stdout.

:return: true if the call must propagate to the subsequent filters, false otherwise

.. versionadded:: 3.24
%End

virtual void sendResponse();
virtual bool onSendResponse();
%Docstring
Method called when the :py:class:`QgsRequestHandler` sends its data to FCGI stdout.
This normally occurs at the end of core services processing just after
the :py:func:`~QgsServerFilter.responseComplete` plugin hook. For streaming services (like WFS on
getFeature requests, :py:func:`~QgsServerFilter.sendResponse` might have been called several times
before the response is complete: in this particular case, :py:func:`~QgsServerFilter.sendResponse`
is called once for each feature before hitting :py:func:`~QgsServerFilter.responseComplete`

:return: true if the call must propagate to the subsequent filters, false otherwise

.. versionadded:: 3.22
%End



};

typedef QMultiMap<int, QgsServerFilter *> QgsServerFiltersMap;
@@ -19,7 +19,6 @@

#include "qgsconfig.h"
#include "qgsfilterresponsedecorator.h"
#include "qgsserverexception.h"

QgsFilterResponseDecorator::QgsFilterResponseDecorator( QgsServerFiltersMap filters, QgsServerResponse &response )
: mFilters( filters )
@@ -33,32 +32,46 @@ void QgsFilterResponseDecorator::start()
QgsServerFiltersMap::const_iterator filtersIterator;
for ( filtersIterator = mFilters.constBegin(); filtersIterator != mFilters.constEnd(); ++filtersIterator )
{
filtersIterator.value()->requestReady();
if ( ! filtersIterator.value()->onRequestReady() )
{
// stop propagation
return;
}
}
#endif
}

void QgsFilterResponseDecorator::finish()
{

#ifdef HAVE_SERVER_PYTHON_PLUGINS
QgsServerFiltersMap::const_iterator filtersIterator;
for ( filtersIterator = mFilters.constBegin(); filtersIterator != mFilters.constEnd(); ++filtersIterator )
{
filtersIterator.value()->responseComplete();
if ( ! filtersIterator.value()->onResponseComplete() )
{
// stop propagation, 'finish' must be called on the wrapped
// response
break;
}
}
#endif
// Will call 'flush'
// Will call internal 'flush'
mResponse.finish();
}


void QgsFilterResponseDecorator::flush()
{
#ifdef HAVE_SERVER_PYTHON_PLUGINS
QgsServerFiltersMap::const_iterator filtersIterator;

for ( filtersIterator = mFilters.constBegin(); filtersIterator != mFilters.constEnd(); ++filtersIterator )
{
filtersIterator.value()->sendResponse();
if ( ! filtersIterator.value()->onSendResponse() )
{
// Stop propagation
return;
}
}
#endif
mResponse.flush();
@@ -19,6 +19,7 @@

#include "qgsserverfilter.h"
#include "qgslogger.h"
#include "qgis.h"

/**
* QgsServerFilter
@@ -42,8 +43,33 @@ void QgsServerFilter::responseComplete()
QgsDebugMsg( QStringLiteral( "QgsServerFilter plugin default responseComplete called" ) );
}


void QgsServerFilter::sendResponse()
{
QgsDebugMsg( QStringLiteral( "QgsServerFilter plugin default sendResponse called" ) );
}

bool QgsServerFilter::onRequestReady()
{
Q_NOWARN_DEPRECATED_PUSH
requestReady();
Q_NOWARN_DEPRECATED_POP
return true;
}

bool QgsServerFilter::onResponseComplete()
{
Q_NOWARN_DEPRECATED_PUSH
responseComplete();
Q_NOWARN_DEPRECATED_POP
return true;
}

bool QgsServerFilter::onSendResponse()
{
Q_NOWARN_DEPRECATED_PUSH
sendResponse();
Q_NOWARN_DEPRECATED_POP
return true;
}


@@ -59,16 +59,62 @@ class SERVER_EXPORT QgsServerFilter

/**
* Method called when the QgsRequestHandler is ready and populated with
* parameters, just before entering the main switch for core services.
*/
virtual void requestReady();
* parameters, just before entering the main switch for core services.
*
* This method is considered as deprecated and \see onRequestReady should
* be used instead.
*
* \deprecated Will be removed in QGIS 4.0
*/
Q_DECL_DEPRECATED virtual void requestReady() SIP_DEPRECATED;

/**
* Method called when the QgsRequestHandler processing has done and
* the response is ready, just after the main switch for core services
* and before final sending response.
*
* This method is considered as deprecated and \see onResponseComplete should
* be used instead.
*
* \deprecated Will be removed in QGIS 4.0
*/
Q_DECL_DEPRECATED virtual void responseComplete() SIP_DEPRECATED;

/**
* Method called when the QgsRequestHandler sends its data to FCGI stdout.
* This normally occurs at the end of core services processing just after
* the responseComplete() plugin hook. For streaming services (like WFS on
* getFeature requests, sendResponse() might have been called several times
* before the response is complete: in this particular case, sendResponse()
* is called once for each feature before hitting responseComplete()
*
* This method is considered as deprecated and \see onSendResponse should
* be used instead.
*
* \deprecated Will be removed in QGIS 4.0
*/
Q_DECL_DEPRECATED virtual void sendResponse() SIP_DEPRECATED;

/**
* Method called when the QgsRequestHandler is ready and populated with
* parameters, just before entering the main switch for core services.
*
* \return true if the call must propagate to the subsequent filters, false otherwise
*
* \since QGIS 3.24
*/
virtual bool onRequestReady();

/**
* Method called when the QgsRequestHandler processing has done and
* the response is ready, just after the main switch for core services
* and before final sending response to FCGI stdout.
*
* \return true if the call must propagate to the subsequent filters, false otherwise
*
* \since QGIS 3.24
*/
virtual void responseComplete();
virtual bool onResponseComplete();

/**
* Method called when the QgsRequestHandler sends its data to FCGI stdout.
@@ -77,11 +123,16 @@ class SERVER_EXPORT QgsServerFilter
* getFeature requests, sendResponse() might have been called several times
* before the response is complete: in this particular case, sendResponse()
* is called once for each feature before hitting responseComplete()
*
* \return true if the call must propagate to the subsequent filters, false otherwise
*
* \since QGIS 3.22
*/
virtual void sendResponse();
virtual bool onSendResponse();

private:


private:
QgsServerInterface *mServerInterface = nullptr;

};
Loading

0 comments on commit dc3e9eb

Please sign in to comment.