[server] Python plugins API cleanup part 1

This is the first step to a cleaner and consitent API
for server plugin.

It also adds some new tests for the base request and
response classes
This commit is contained in:
Alessandro Pasotti 2017-04-30 12:59:20 +02:00
parent fe7d49a053
commit b7d6c1e59e
24 changed files with 610 additions and 90 deletions

View File

@ -0,0 +1,55 @@
/************************************************************************
* This file has been generated automatically from *
* *
* ../src/server/qgsbufferserverrequest.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsBufferServerRequest : QgsServerRequest
{
%Docstring
QgsBufferServerRequest
Class defining request with data
%End
%TypeHeaderCode
#include "qgsbufferserverrequest.h"
%End
public:
QgsBufferServerRequest( const QString &url, Method method = GetMethod, QByteArray *data = 0 );
%Docstring
Constructor
\param url the url string
\param method the request method
%End
QgsBufferServerRequest( const QUrl &url, Method method = GetMethod, QByteArray *data = 0 );
%Docstring
Constructor
\param url QUrl
\param method the request method
%End
~QgsBufferServerRequest();
virtual QByteArray data() const;
%Docstring
:rtype: QByteArray
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* ../src/server/qgsbufferserverrequest.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -0,0 +1,153 @@
/************************************************************************
* This file has been generated automatically from *
* *
* ../src/server/qgsbufferserverresponse.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsBufferServerResponse: QgsServerResponse
{
%Docstring
Class defining buffered response
%End
%TypeHeaderCode
#include "qgsbufferserverresponse.h"
%End
public:
QgsBufferServerResponse();
~QgsBufferServerResponse();
virtual void setHeader( const QString &key, const QString &value );
%Docstring
Set Header entry
Add Header entry to the response
Note that it is usually an error to set Header after data have been sent through the wire
%End
virtual void removeHeader( const QString &key );
%Docstring
Clear header
Undo a previous 'setHeader' call
%End
virtual QString header( const QString &key ) const;
%Docstring
Return the header value
:rtype: str
%End
virtual QMap<QString, QString> headers() const;
%Docstring
Return all the headers
:rtype: QMap<str, QString>
%End
virtual bool headersSent() const;
%Docstring
Return true if the headers have alredy been sent
:rtype: bool
%End
virtual void setStatusCode( int code );
%Docstring
Set the http status code
\param code HTTP status code value
%End
virtual int statusCode( ) const;
%Docstring
Return the http status code
:rtype: int
%End
virtual void sendError( int code, const QString &message );
%Docstring
Send error
This method delegates error handling at the server level. This is different
from calling setReturnCode() which let you return a specific response body.
Calling sendError() will end the transaction and any attempt to write data
or set headers will be an error.
\param code HHTP return code value
\param message An informative error message
%End
virtual QIODevice *io();
%Docstring
Return the underlying QIODevice
:rtype: QIODevice
%End
virtual void finish();
%Docstring
Finish the response, ending the transaction
%End
virtual void flush();
%Docstring
Flushes the current output buffer to the network
'flush()' may be called multiple times. For HTTP transactions
headers will be written on the first call to 'flush()'.
%End
virtual void clear();
%Docstring
Reset all headers and content for this response
%End
virtual QByteArray data() const;
%Docstring
Get the data written so far
This is implementation dependent: some implementations may not
give access to the underlying and return an empty array.
Note that each call to 'flush' may empty the buffer and in case
of streaming process you may get partial content
:rtype: QByteArray
%End
virtual void truncate();
%Docstring
Truncate data
Clear internal buffer
%End
QByteArray body() const;
%Docstring
Return body
:rtype: QByteArray
%End
private:
QgsBufferServerResponse(const QgsBufferServerResponse &) ;
};
/************************************************************************
* This file has been generated automatically from *
* *
* ../src/server/qgsbufferserverresponse.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -29,20 +29,29 @@ class QgsRequestHandler /Abstract/
/** Allow plugins to return a QgsServerException*/
void setServiceException( const QgsServerException &ex );
/** Set an HTTP header*/
void setHeader( const QString &name, const QString &value );
//! Set an HTTP response header
void setResponseHeader( const QString &name, const QString &value );
//! Retrieve header value
QString header( const QString &name ) const;
//! Remove an HTTP response header
void removeResponseHeader( const QString &name );
//! Return the list of all header keys
QList<QString> headerKeys() const;
//! Retrieve response header value
QString responseHeader( const QString &name ) const;
/** Remove an HTTP header*/
void removeHeader( const QString &name );
//! Return the response headers
QMap<QString, QString> responseHeaders() const;
/** Delete all HTTP headers*/
void clear();
//! Set an HTTP request header
void setRequestHeader( const QString &name, const QString &value );
//! Remove an HTTP request header
void removeRequestHeader( const QString &name );
//! Retrieve request header value
QString requestHeader( const QString &name ) const;
//! Return the Request headers
QMap<QString, QString> requestHeaders() const;
/** Append the bytestream to response body*/
void appendBody( const QByteArray &body );
@ -62,6 +71,9 @@ class QgsRequestHandler /Abstract/
/** Clear response buffer */
void clearBody();
//! Clears the response body and headers
void clear();
/** Return body data */
QByteArray body() const;

View File

@ -30,6 +30,9 @@ class QgsServerRequest
%End
public:
typedef QMap<QString, QString> Parameters;
typedef QMap<QString, QString> Headers;
enum Method
{
HeadMethod, PutMethod, GetMethod, PostMethod, DeleteMethod
@ -48,21 +51,55 @@ class QgsServerRequest
*/
QgsServerRequest( const QString &url, Method method );
/**
* Constructor
*
* @param url QUrl
* @param method the request method (default to GetMethod)
* \param url the url string
* \param method the request method
* \param headers
*/
QgsServerRequest( const QUrl &url, Method method = GetMethod );
QgsServerRequest( const QString &url, Method method = GetMethod, const QgsServerRequest::Headers &headers = QgsServerRequest::Headers( ) );
/**
* Constructor
*
* \param url QUrl
* \param method the request method
* \param headers
*/
QgsServerRequest( const QUrl &url, Method method = GetMethod, const QgsServerRequest::Headers &headers = QgsServerRequest::Headers( ) );
//! destructor
virtual ~QgsServerRequest();
/**
* @return the value of the header field for that request
* Return the header value
* @param name of the header
* @return the header value or an empty string
*/
virtual QString getHeader( const QString &name ) const;
QString header( const QString &name ) const;
/**
* Set an header
* @param name
* @param value
*/
void setHeader( const QString &name, const QString &value );
/**
* Return the header map
* @return the headers map
*/
QMap<QString, QString> headers( ) const;
/**
* Remove an header
* @param name
*/
void removeHeader( const QString &name );
/**
* @return the request url
@ -87,7 +124,7 @@ class QgsServerRequest
/**
* Get a parameter value
*/
QString getParameter( const QString &key ) const;
QString parameter( const QString& key ) const;
/**
* Remove a parameter

View File

@ -44,9 +44,8 @@ class QgsServerResponse
/**
* Clear header
* Undo a previous 'set_header' call
*/
virtual void clearHeader( const QString &key ) = 0;
virtual void removeHeader( const QString &key ) = 0;
/**
* Return the header value
@ -54,9 +53,9 @@ class QgsServerResponse
virtual QString header( const QString &key ) const = 0;
/**
* Return the list of all header keys
* Return the response headers
*/
virtual QList<QString> headerKeys() const = 0;
virtual QMap<QString, QString> headers() const = 0;
/**
* Return true if the headers have alredy been sent

View File

@ -30,6 +30,8 @@
%Include qgsserverrequest.sip
%Include qgsserverresponse.sip
%Include qgsbufferserverresponse.sip
%Include qgsbufferserverrequest.sip
%Include qgsserverexception.sip
%Include qgsservice.sip
%Include qgsservicemodule.sip

View File

@ -1,7 +1,7 @@
/***************************************************************************
qgsbufferserverrequest.h
Define response wrapper for storing responsea in buffer
Define response wrapper for storing request in buffer
-------------------
begin : 2017-01-03
copyright : (C) 2017 by David Marteau
@ -19,6 +19,7 @@
#ifndef QGSBUFFERSERVERREQUEST_H
#define QGSBUFFERSERVERREQUEST_H
#include "qgis_server.h"
#include "qgsserverrequest.h"
#include <QBuffer>
@ -30,7 +31,7 @@
* QgsBufferServerRequest
* Class defining request with data
*/
class QgsBufferServerRequest : public QgsServerRequest
class SERVER_EXPORT QgsBufferServerRequest : public QgsServerRequest
{
public:
@ -52,7 +53,7 @@ class QgsBufferServerRequest : public QgsServerRequest
~QgsBufferServerRequest();
virtual QByteArray data() const { return mData; }
virtual QByteArray data() const override { return mData; }
private:
QByteArray mData;

View File

@ -37,7 +37,7 @@ QgsBufferServerResponse::~QgsBufferServerResponse()
}
void QgsBufferServerResponse::clearHeader( const QString &key )
void QgsBufferServerResponse::removeHeader( const QString &key )
{
if ( !mHeadersSent )
mHeaders.remove( key );
@ -51,7 +51,7 @@ void QgsBufferServerResponse::setHeader( const QString &key, const QString &valu
void QgsBufferServerResponse::setStatusCode( int code )
{
mReturnCode = code;
mStatusCode = code;
}
QString QgsBufferServerResponse::header( const QString &key ) const
@ -59,11 +59,6 @@ QString QgsBufferServerResponse::header( const QString &key ) const
return mHeaders.value( key );
}
QList<QString> QgsBufferServerResponse::headerKeys() const
{
return mHeaders.keys();
}
bool QgsBufferServerResponse::headersSent() const
{
return mHeadersSent;

View File

@ -19,6 +19,8 @@
#ifndef QGSBUFFERSERVERRESPONSE_H
#define QGSBUFFERSERVERRESPONSE_H
#include "qgis_server.h"
#include "qgis.h"
#include "qgsserverresponse.h"
#include <QBuffer>
@ -30,39 +32,101 @@
* \class QgsBufferServerResponse
* Class defining buffered response
*/
class QgsBufferServerResponse: public QgsServerResponse
class SERVER_EXPORT QgsBufferServerResponse: public QgsServerResponse
{
public:
QgsBufferServerResponse();
~QgsBufferServerResponse();
/**
* Set Header entry
* Add Header entry to the response
* Note that it is usually an error to set Header after data have been sent through the wire
*/
void setHeader( const QString &key, const QString &value ) override;
void clearHeader( const QString &key ) override;
/**
* Clear header
* Undo a previous 'setHeader' call
*/
void removeHeader( const QString &key ) override;
/**
* Return the header value
*/
QString header( const QString &key ) const override;
QList<QString> headerKeys() const override;
/**
* Return all the headers
*/
QMap<QString, QString> headers() const override { return mHeaders; }
/**
* Return true if the headers have alredy been sent
*/
bool headersSent() const override;
/** Set the http status code
* \param code HTTP status code value
*/
void setStatusCode( int code ) override;
int statusCode( ) const override { return mReturnCode; }
/** Return the http status code
*/
int statusCode( ) const override { return mStatusCode; }
/**
* Send error
* This method delegates error handling at the server level. This is different
* from calling setReturnCode() which let you return a specific response body.
* Calling sendError() will end the transaction and any attempt to write data
* or set headers will be an error.
* \param code HHTP return code value
* \param message An informative error message
*/
void sendError( int code, const QString &message ) override;
/**
* Return the underlying QIODevice
*/
QIODevice *io() override;
/**
* Finish the response, ending the transaction
*/
void finish() override;
/**
* Flushes the current output buffer to the network
*
* 'flush()' may be called multiple times. For HTTP transactions
* headers will be written on the first call to 'flush()'.
*/
void flush() override;
/**
* Reset all headers and content for this response
*/
void clear() override;
/**
* Get the data written so far
*
* This is implementation dependent: some implementations may not
* give access to the underlying and return an empty array.
*
* Note that each call to 'flush' may empty the buffer and in case
* of streaming process you may get partial content
*/
QByteArray data() const override;
/**
* Truncate data
*
* Clear internal buffer
*/
void truncate() override;
/**
@ -70,19 +134,16 @@ class QgsBufferServerResponse: public QgsServerResponse
*/
QByteArray body() const { return mBody; }
/**
* Return header's map
*/
QMap<QString, QString> headers() const { return mHeaders; }
private:
QgsBufferServerResponse( const QgsBufferServerResponse & ) SIP_FORCE;
QMap<QString, QString> mHeaders;
QBuffer mBuffer;
QByteArray mBody;
bool mFinished = false;
bool mHeadersSent = false;
int mReturnCode = 200;
int mStatusCode = 200;
};
#endif

View File

@ -41,7 +41,7 @@ QgsFcgiServerResponse::~QgsFcgiServerResponse()
{
}
void QgsFcgiServerResponse::clearHeader( const QString &key )
void QgsFcgiServerResponse::removeHeader( const QString &key )
{
mHeaders.remove( key );
}
@ -56,11 +56,6 @@ QString QgsFcgiServerResponse::header( const QString &key ) const
return mHeaders.value( key );
}
QList<QString> QgsFcgiServerResponse::headerKeys() const
{
return mHeaders.keys();
}
bool QgsFcgiServerResponse::headersSent() const
{
return mHeadersSent;

View File

@ -38,11 +38,11 @@ class SERVER_EXPORT QgsFcgiServerResponse: public QgsServerResponse
void setHeader( const QString &key, const QString &value ) override;
void clearHeader( const QString &key ) override;
void removeHeader( const QString &key ) override;
QString header( const QString &key ) const override;
QList<QString> headerKeys() const override;
QMap<QString, QString> headers() const override { return mHeaders; }
bool headersSent() const override;

View File

@ -43,11 +43,11 @@ class QgsFilterResponseDecorator: public QgsServerResponse
void setHeader( const QString &key, const QString &value ) override { mResponse.setHeader( key, value ); }
void clearHeader( const QString &key ) override { mResponse.clearHeader( key ); }
void removeHeader( const QString &key ) override { mResponse.removeHeader( key ); }
QString header( const QString &key ) const override { return mResponse.header( key ); }
QList<QString> headerKeys() const override { return mResponse.headerKeys(); }
QMap<QString, QString> headers() const override { return mResponse.headers( ); }
bool headersSent() const override { return mResponse.headersSent(); }

View File

@ -54,7 +54,7 @@ bool QgsRequestHandler::exceptionRaised() const
return mExceptionRaised;
}
void QgsRequestHandler::setHeader( const QString &name, const QString &value )
void QgsRequestHandler::setResponseHeader( const QString &name, const QString &value )
{
mResponse.setHeader( name, value );
}
@ -64,21 +64,43 @@ void QgsRequestHandler::clear()
mResponse.clear();
}
void QgsRequestHandler::removeHeader( const QString &name )
void QgsRequestHandler::removeResponseHeader( const QString &name )
{
mResponse.clearHeader( name );
mResponse.removeHeader( name );
}
QString QgsRequestHandler::header( const QString &name ) const
QString QgsRequestHandler::responseHeader( const QString &name ) const
{
return mResponse.header( name );
}
QList<QString> QgsRequestHandler::headerKeys() const
QMap<QString, QString> QgsRequestHandler::responseHeaders() const
{
return mResponse.headerKeys();
return mResponse.headers( );
}
void QgsRequestHandler::setRequestHeader( const QString &name, const QString &value )
{
mRequest.setHeader( name, value );
}
void QgsRequestHandler::removeRequestHeader( const QString &name )
{
mRequest.removeHeader( name );
}
QString QgsRequestHandler::requestHeader( const QString &name ) const
{
return mRequest.header( name );
}
QMap<QString, QString> QgsRequestHandler::requestHeaders() const
{
return mRequest.headers( );
}
bool QgsRequestHandler::headersSent() const
{
return mResponse.headersSent();
@ -243,7 +265,7 @@ void QgsRequestHandler::setParameter( const QString &key, const QString &value )
QString QgsRequestHandler::parameter( const QString &key ) const
{
return mRequest.getParameter( key );
return mRequest.parameter( key );
}
void QgsRequestHandler::removeParameter( const QString &key )

View File

@ -64,17 +64,29 @@ class SERVER_EXPORT QgsRequestHandler
*/
void sendResponse();
//! Set an HTTP header
void setHeader( const QString &name, const QString &value );
//! Set an HTTP response header
void setResponseHeader( const QString &name, const QString &value );
//! Remove an HTTP header
void removeHeader( const QString &name );
//! Remove an HTTP response header
void removeResponseHeader( const QString &name );
//! Retrieve header value
QString header( const QString &name ) const;
//! Retrieve response header value
QString responseHeader( const QString &name ) const;
//! Return the list of all header keys
QList<QString> headerKeys() const;
//! Return the response headers
QMap<QString, QString> responseHeaders() const;
//! Set an HTTP request header
void setRequestHeader( const QString &name, const QString &value );
//! Remove an HTTP request header
void removeRequestHeader( const QString &name );
//! Retrieve request header value
QString requestHeader( const QString &name ) const;
//! Return the Request headers
QMap<QString, QString> requestHeaders() const;
//! Clears the response body and headers
void clear();

View File

@ -389,7 +389,7 @@ void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &res
QString outputFileName = parameterMap.value( QStringLiteral( "FILE_NAME" ) );
if ( !outputFileName.isEmpty() )
{
requestHandler.setHeader( QStringLiteral( "Content-Disposition" ), "attachment; filename=\"" + outputFileName + "\"" );
requestHandler.setResponseHeader( QStringLiteral( "Content-Disposition" ), "attachment; filename=\"" + outputFileName + "\"" );
}
// Lookup for service

View File

@ -28,26 +28,44 @@ QgsServerRequest::QgsServerRequest()
}
QgsServerRequest::QgsServerRequest( const QString &url, Method method )
QgsServerRequest::QgsServerRequest( const QString &url, Method method, const Headers &headers )
: mUrl( url )
, mMethod( method )
, mDecoded( false )
, mHeaders( headers )
{
}
QgsServerRequest::QgsServerRequest( const QUrl &url, Method method )
QgsServerRequest::QgsServerRequest( const QUrl &url, Method method, const Headers &headers )
: mUrl( url )
, mMethod( method )
, mDecoded( false )
, mHeaders( headers )
{
}
QString QgsServerRequest::getHeader( const QString &name ) const
QString QgsServerRequest::header( const QString &name ) const
{
Q_UNUSED( name );
return QString();
return mHeaders.value( name );
}
void QgsServerRequest::setHeader( const QString &name, const QString &value )
{
mHeaders.insert( name, value );
}
QMap<QString, QString> QgsServerRequest::headers( ) const
{
return mHeaders;
}
void QgsServerRequest::removeHeader( const QString &name )
{
mHeaders.remove( name );
}
QUrl QgsServerRequest::url() const
@ -89,7 +107,7 @@ void QgsServerRequest::setParameter( const QString &key, const QString &value )
mParams.insert( key, value );
}
QString QgsServerRequest::getParameter( const QString &key ) const
QString QgsServerRequest::parameter( const QString &key ) const
{
parameters();
return mParams.value( key );

View File

@ -39,6 +39,7 @@ class SERVER_EXPORT QgsServerRequest
public:
typedef QMap<QString, QString> Parameters;
typedef QMap<QString, QString> Headers;
/**
* HTTP Method (or equivalent) used for the request
@ -59,16 +60,18 @@ class SERVER_EXPORT QgsServerRequest
*
* \param url the url string
* \param method the request method
* \param headers
*/
QgsServerRequest( const QString &url, Method method = GetMethod );
QgsServerRequest( const QString &url, Method method = GetMethod, const Headers &headers = Headers( ) );
/**
* Constructor
*
* \param url QUrl
* \param method the request method
* \param headers
*/
QgsServerRequest( const QUrl &url, Method method = GetMethod );
QgsServerRequest( const QUrl &url, Method method = GetMethod, const Headers &headers = Headers( ) );
//! destructor
virtual ~QgsServerRequest() = default;
@ -97,13 +100,39 @@ class SERVER_EXPORT QgsServerRequest
/**
* Get a parameter value
*/
QString getParameter( const QString &key ) const;
QString parameter( const QString &key ) const;
/**
* Remove a parameter
*/
void removeParameter( const QString &key );
/**
* Return the header value
* @param name of the header
* @return the header value or an empty string
*/
QString header( const QString &name ) const;
/**
* Set an header
* @param name
* @param value
*/
void setHeader( const QString &name, const QString &value );
/**
* Return the header map
* @return the headers map
*/
QMap<QString, QString> headers( ) const;
/**
* Remove an header
* @param name
*/
void removeHeader( const QString &name );
/**
* Return post/put data
* Check for QByteArray::isNull() to check if data
@ -111,11 +140,6 @@ class SERVER_EXPORT QgsServerRequest
*/
virtual QByteArray data() const;
/**
* \returns the value of the header field for that request
*/
virtual QString getHeader( const QString &name ) const;
/**
* Set the request url
*/
@ -134,7 +158,8 @@ class SERVER_EXPORT QgsServerRequest
// Use QMap here because it will be faster for small
// number of elements
mutable bool mDecoded;
mutable QMap<QString, QString> mParams;
mutable Parameters mParams;
mutable Headers mHeaders;
};
#endif

View File

@ -51,7 +51,7 @@ class SERVER_EXPORT QgsServerResponse
/**
* Set Header entry
* Add Header entry to the response
* Note that it is usually an error to set Header after writing data
* Note that it is usually an error to set Header after data have been sent through the wire
*/
virtual void setHeader( const QString &key, const QString &value ) = 0;
@ -59,7 +59,7 @@ class SERVER_EXPORT QgsServerResponse
* Clear header
* Undo a previous 'setHeader' call
*/
virtual void clearHeader( const QString &key ) = 0;
virtual void removeHeader( const QString &key ) = 0;
/**
* Return the header value
@ -67,9 +67,9 @@ class SERVER_EXPORT QgsServerResponse
virtual QString header( const QString &key ) const = 0;
/**
* Return the list of all header keys
* Return the header value
*/
virtual QList<QString> headerKeys() const = 0;
virtual QMap<QString, QString> headers( ) const = 0;
/**
* Return true if the headers have alredy been sent

View File

@ -100,7 +100,7 @@ namespace QgsWfs
}
else
{
QString typeNames = request.getParameter( QStringLiteral( "TYPENAME" ) );
QString typeNames = request.parameter( QStringLiteral( "TYPENAME" ) );
if ( !typeNames.isEmpty() )
{
QStringList typeNameSplit = typeNames.split( QStringLiteral( "," ) );

View File

@ -204,4 +204,6 @@ IF (WITH_SERVER)
ADD_PYTHON_TEST(PyQgsAuthManagerPKIPostgresTest test_authmanager_pki_postgres.py)
ADD_PYTHON_TEST(PyQgsServerServices test_qgsserver_services.py)
ADD_PYTHON_TEST(PyQgsServerModules test_qgsserver_modules.py)
ADD_PYTHON_TEST(PyQgsServerRequest test_qgsserver_request.py)
ADD_PYTHON_TEST(PyQgsServerResponse test_qgsserver_response.py)
ENDIF (WITH_SERVER)

View File

@ -94,8 +94,8 @@ if os.environ.get('QGIS_SERVER_HTTP_BASIC_AUTH') is not None:
return
# No auth ...
request.clear()
request.setHeader('Status', '401 Authorization required')
request.setHeader('WWW-Authenticate', 'Basic realm="QGIS Server"')
request.setResponseHeader('Status', '401 Authorization required')
request.setResponseHeader('WWW-Authenticate', 'Basic realm="QGIS Server"')
request.appendBody(b'<h1>Authorization required</h1>')
filter = HTTPBasicFilter(qgs_server.serverInterface())

View File

@ -121,7 +121,7 @@ class TestQgsServerPlugins(unittest.TestCase):
QgsMessageLog.logMessage("SimpleHelloFilter.responseComplete")
if params.get('SERVICE', '').upper() == 'SIMPLE':
request.clear()
request.setHeader('Content-type', 'text/plain')
request.setResponseHeader('Content-type', 'text/plain')
request.appendBody('Hello from SimpleServer!'.encode('utf-8'))
serverIface = self.server.serverInterface()
@ -178,7 +178,7 @@ class TestQgsServerPlugins(unittest.TestCase):
global headers2
request = self.serverInterface().requestHandler()
request.clearBody()
headers2 = {k: request.header(k) for k in request.headerKeys()}
headers2 = request.responseHeaders()
request.appendBody('new body, new life!'.encode('utf-8'))
filter1 = Filter1(serverIface)

View File

@ -0,0 +1,66 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsServerRequest.
From build dir, run: ctest -R PyQgsServerRequest -V
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
import unittest
__author__ = 'Alessandro Pasotti'
__date__ = '29/04/2017'
__copyright__ = 'Copyright 2017, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
from qgis.PyQt.QtCore import QUrl
from qgis.server import QgsServerRequest
class QgsServerRequestTest(unittest.TestCase):
def test_requestHeaders(self):
"""Test request headers"""
headers = {'header-key-1': 'header-value-1', 'header-key-2': 'header-value-2'}
request = QgsServerRequest('http://somesite.com/somepath', QgsServerRequest.GetMethod, headers)
for k, v in request.headers().items():
self.assertEqual(headers[k], v)
request.removeHeader('header-key-1')
self.assertEqual(request.headers(), {'header-key-2': 'header-value-2'})
request.setHeader('header-key-1', 'header-value-1')
for k, v in request.headers().items():
self.assertEqual(headers[k], v)
def test_requestParameters(self):
"""Test request parameters"""
request = QgsServerRequest('http://somesite.com/somepath?parm1=val1&parm2=val2', QgsServerRequest.GetMethod)
parameters = {'PARM1': 'val1', 'PARM2': 'val2'}
for k, v in request.parameters().items():
self.assertEqual(parameters[k], v)
request.removeParameter('PARM1')
self.assertEqual(request.parameters(), {'PARM2': 'val2'})
request.setHeader('PARM1', 'val1')
for k, v in request.headers().items():
self.assertEqual(parameters[k], v)
def test_requestUrl(self):
"""Test url"""
request = QgsServerRequest('http://somesite.com/somepath', QgsServerRequest.GetMethod)
self.assertEqual(request.url().toString(), 'http://somesite.com/somepath')
request.setUrl(QUrl('http://someother.com/someotherpath'))
self.assertEqual(request.url().toString(), 'http://someother.com/someotherpath')
def test_requestMethod(self):
request = QgsServerRequest('http://somesite.com/somepath', QgsServerRequest.GetMethod)
self.assertEqual(request.method(), QgsServerRequest.GetMethod)
request.setMethod(QgsServerRequest.PostMethod)
self.assertEqual(request.method(), QgsServerRequest.PostMethod)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsServerResponse.
From build dir, run: ctest -R PyQgsServerResponse -V
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
import unittest
__author__ = 'Alessandro Pasotti'
__date__ = '29/04/2017'
__copyright__ = 'Copyright 2017, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
from qgis.server import QgsBufferServerResponse
class QgsServerResponseTest(unittest.TestCase):
def test_responseHeaders(self):
"""Test response headers"""
headers = {'header-key-1': 'header-value-1', 'header-key-2': 'header-value-2'}
response = QgsBufferServerResponse()
for k, v in headers.items():
response.setHeader(k, v)
for k, v in response.headers().items():
self.assertEqual(headers[k], v)
response.removeHeader('header-key-1')
self.assertEqual(response.headers(), {'header-key-2': 'header-value-2'})
response.setHeader('header-key-1', 'header-value-1')
for k, v in response.headers().items():
self.assertEqual(headers[k], v)
def test_statusCode(self):
"""Test return status HTTP code"""
response = QgsBufferServerResponse()
response.setStatusCode(222)
self.assertEqual(response.statusCode(), 222)
def test_write(self):
"""Test that writing on the buffer sets the body"""
# Set as str
response = QgsBufferServerResponse()
response.write('Greetings from Essen Linux Hotel 2017 Hack Fest!')
self.assertEqual(bytes(response.body()), b'')
response.finish()
self.assertEqual(bytes(response.body()), b'Greetings from Essen Linux Hotel 2017 Hack Fest!')
self.assertEqual(response.headers(), {'Content-Length': '48'})
# Set as a byte array
response = QgsBufferServerResponse()
response.write(b'Greetings from Essen Linux Hotel 2017 Hack Fest!')
self.assertEqual(bytes(response.body()), b'')
response.finish()
self.assertEqual(bytes(response.body()), b'Greetings from Essen Linux Hotel 2017 Hack Fest!')
if __name__ == '__main__':
unittest.main()