diff --git a/python/server/qgsserverfilter.sip b/python/server/qgsserverfilter.sip index 61b5104add3..dc81979f79c 100644 --- a/python/server/qgsserverfilter.sip +++ b/python/server/qgsserverfilter.sip @@ -48,8 +48,17 @@ public: * parameters, just before entering the main switch for core services.*/ virtual void requestReady(); /** Method called when the QgsRequestHandler processing has done and - * the response is ready, just after the main switch for core services. + * the response is ready, just after the main switch for core services + * and before final sending response to FCGI stdout. */ - virtual void responseReady(); + virtual void responseComplete(); + /** Method called when the QgsRequestHandler sends its data to FCGI stdout. + * This normally occours 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() + */ + virtual void sendResponse(); }; diff --git a/src/mapserver/qgis_map_serv.cpp b/src/mapserver/qgis_map_serv.cpp index 0490c2c352c..18145eb5049 100644 --- a/src/mapserver/qgis_map_serv.cpp +++ b/src/mapserver/qgis_map_serv.cpp @@ -370,6 +370,14 @@ int main( int argc, char * argv[] ) { filtersIterator.value()->requestReady(); } + + //Pass the filters to the requestHandler, this is needed for the following reasons: + // 1. allow core services to access plugin filters and implement thir own plugin hooks + // 2. allow requestHandler to call Response + + //TODO: implement this in the requestHandler ctor (far easier if we will get rid of + // MAPSERVER_HAVE_PYTHON_PLUGINS + theRequestHandler->setPluginFilters( pluginFilters ); #endif // Copy the parameters map @@ -431,15 +439,12 @@ int main( int argc, char * argv[] ) } // end if not exception raised #ifdef MAPSERVER_HAVE_PYTHON_PLUGINS - // Call responseReady plugin filters in reverse order - filtersIterator = pluginFilters.constEnd(); - while ( filtersIterator != pluginFilters.constBegin() ) + // Iterate filters and call their responseComplete() method + for ( filtersIterator = pluginFilters.constBegin(); filtersIterator != pluginFilters.constEnd(); ++filtersIterator ) { - --filtersIterator; - filtersIterator.value()->responseReady(); + filtersIterator.value()->responseComplete(); } #endif - theRequestHandler->sendResponse(); if ( logLevel < 1 ) diff --git a/src/mapserver/qgshttprequesthandler.cpp b/src/mapserver/qgshttprequesthandler.cpp index f62974f2973..86e342f2694 100644 --- a/src/mapserver/qgshttprequesthandler.cpp +++ b/src/mapserver/qgshttprequesthandler.cpp @@ -63,7 +63,7 @@ void QgsHttpRequestHandler::setHttpResponse( QByteArray *ba, const QString &form bool QgsHttpRequestHandler::responseReady() const { - return mHeaders.count() || ( mBody.size() && mInfoFormat.length() ); + return mHeaders.count() || mBody.size(); } bool QgsHttpRequestHandler::exceptionRaised() const @@ -132,6 +132,7 @@ void QgsHttpRequestHandler::sendHeaders() printf( "\n" ); } printf( "\n" ); + mHeaders.clear(); mHeadersSent = TRUE; } @@ -139,21 +140,37 @@ void QgsHttpRequestHandler::sendBody() const { size_t result = fwrite( (void*)mBody.data(), mBody.size(), 1, FCGI_stdout ); #ifdef QGISDEBUG - QgsDebugMsg( QString( "Sent %1 blocks of %2 bytes" ).arg( result, mBody.size() ) ); + QgsDebugMsg( QString( "Sent %1 blocks of %2 bytes" ).arg( result ).arg( mBody.size() ) ); #else Q_UNUSED( result ); #endif } +#ifdef MAPSERVER_HAVE_PYTHON_PLUGINS +void QgsHttpRequestHandler::setPluginFilters( QgsServerFiltersMap pluginFilters ) +{ + mPluginFilters = pluginFilters; +} +#endif + void QgsHttpRequestHandler::sendResponse() { QgsDebugMsg( QString( "Sending HTTP response" ) ); if ( ! responseReady() ) { - QgsDebugMsg( QString( "Trying to send out an empty reponse" ) ); + QgsDebugMsg( QString( "Trying to send out an invalid response" ) ); return; } - if ( ! mHeadersSent ) +#ifdef MAPSERVER_HAVE_PYTHON_PLUGINS + // Plugin hook + // Iterate filters and call their sendResponse() method + QgsServerFiltersMap::const_iterator filtersIterator; + for ( filtersIterator = mPluginFilters.constBegin(); filtersIterator != mPluginFilters.constEnd(); ++filtersIterator ) + { + filtersIterator.value()->sendResponse(); + } +#endif + if (! headersSent() ) { sendHeaders(); } diff --git a/src/mapserver/qgshttprequesthandler.h b/src/mapserver/qgshttprequesthandler.h index 67836097065..87207a4f81f 100644 --- a/src/mapserver/qgshttprequesthandler.h +++ b/src/mapserver/qgshttprequesthandler.h @@ -55,10 +55,12 @@ class QgsHttpRequestHandler: public QgsRequestHandler virtual void setInfoFormat( const QString &format ); virtual bool responseReady() const; virtual bool exceptionRaised() const; - virtual void setParameter( const QString &key, const QString &value ); - virtual QString parameter( const QString &key ) const; - virtual int removeParameter( const QString &key ); - + virtual void setParameter(const QString &key, const QString &value); + virtual QString parameter(const QString &key) const; + virtual int removeParameter(const QString &key); +#ifdef MAPSERVER_HAVE_PYTHON_PLUGINS + virtual void setPluginFilters( QgsServerFiltersMap pluginFilters ); +#endif protected: virtual void sendHeaders( ); virtual void sendBody( ) const; diff --git a/src/mapserver/qgsrequesthandler.h b/src/mapserver/qgsrequesthandler.h index 8af597c54b6..3c00a8b3cc2 100644 --- a/src/mapserver/qgsrequesthandler.h +++ b/src/mapserver/qgsrequesthandler.h @@ -22,10 +22,17 @@ #ifndef QGSREQUESTHANDLER_H #define QGSREQUESTHANDLER_H +//Needed for MAPSERVER_HAVE_PYTHON_PLUGINS +#include "qgsconfig.h" + #include #include #include +#ifdef MAPSERVER_HAVE_PYTHON_PLUGINS +#include "qgsserverfilter.h" +#endif + class QDomDocument; class QImage; class QgsMapServiceException; @@ -64,6 +71,8 @@ class QgsRequestHandler virtual void clearBody( ) = 0; virtual QByteArray* body( ) { return &mBody; } virtual void setInfoFormat( const QString &format ) = 0; + /**Check if the response headers or the response body are not empty*/ + virtual bool responseReady() const = 0; /**Send out HTTP headers and flush output buffer*/ virtual void sendResponse( ) = 0; /**Pointer to last raised exception*/ @@ -76,22 +85,24 @@ class QgsRequestHandler /**Return a request parameter*/ virtual QString parameter( const QString &key ) const = 0; /**Return the response body*/ - virtual QByteArray* body( ) { return &mBody; } /**Return the requested format string*/ QString format() const { return mFormat; } /**Return the mime type for the response*/ QString infoFormat() const { return mInfoFormat; } /**Return true if the HTTP headers were already sent to the client*/ bool headersSent() { return mHeadersSent; } - QString infoFormat() const { return mInfoFormat; } - - protected: - +#ifdef MAPSERVER_HAVE_PYTHON_PLUGINS + /**Allow core services to call plugin hooks through sendResponse() */ + virtual void setPluginFilters( QgsServerFiltersMap pluginFilters ) = 0; +#endif +protected: virtual void sendHeaders( ) = 0; virtual void sendBody( ) const = 0; +#ifdef MAPSERVER_HAVE_PYTHON_PLUGINS + QgsServerFiltersMap mPluginFilters; +#endif QByteArray mBody; // The response payload /**This is set by the parseInput methods of the subclasses (parameter FORMAT, e.g. 'FORMAT=PNG')*/ - QByteArray mBody; // The response payload QString mFormat; QString mFormatString; //format string as it is passed in the request (with base) bool mHeadersSent; diff --git a/src/mapserver/qgsserverfilter.cpp b/src/mapserver/qgsserverfilter.cpp index de604379eea..a18a384fd63 100644 --- a/src/mapserver/qgsserverfilter.cpp +++ b/src/mapserver/qgsserverfilter.cpp @@ -42,8 +42,13 @@ void QgsServerFilter::requestReady() QgsDebugMsg( "QgsServerFilter plugin default requestReady called"); } -void QgsServerFilter::responseReady() +void QgsServerFilter::responseComplete() { - QgsDebugMsg( "QgsServerFilter plugin default responseReady called"); + QgsDebugMsg( "QgsServerFilter plugin default responseComplete called"); } + +void QgsServerFilter::sendResponse() +{ + QgsDebugMsg( "QgsServerFilter plugin default sendResponse called"); +} diff --git a/src/mapserver/qgsserverfilter.h b/src/mapserver/qgsserverfilter.h index ebe28ff509d..5e8af3aeae5 100644 --- a/src/mapserver/qgsserverfilter.h +++ b/src/mapserver/qgsserverfilter.h @@ -41,7 +41,8 @@ public: virtual ~QgsServerFilter(); QgsServerInterface* serverInterface( ) { return mServerInterface; } virtual void requestReady(); - virtual void responseReady(); + virtual void responseComplete(); + virtual void sendResponse(); private: