mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-12 00:06:43 -04:00
[server] Python plugins API cleanup part 2
This part adds the headers as an optional argument to the request and start using the handleRequest(request, response) call in the python tests. Some additional tests are also added.
This commit is contained in:
parent
b7d6c1e59e
commit
2afcad279d
@ -21,7 +21,7 @@ class QgsBufferServerRequest : QgsServerRequest
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsBufferServerRequest( const QString &url, Method method = GetMethod, QByteArray *data = 0 );
|
||||
QgsBufferServerRequest( const QString &url, Method method = GetMethod, const QgsServerRequest::Headers &headers = QgsServerRequest::Headers( ), QByteArray *data = 0 );
|
||||
%Docstring
|
||||
Constructor
|
||||
|
||||
@ -29,7 +29,7 @@ class QgsBufferServerRequest : QgsServerRequest
|
||||
\param method the request method
|
||||
%End
|
||||
|
||||
QgsBufferServerRequest( const QUrl &url, Method method = GetMethod, QByteArray *data = 0 );
|
||||
QgsBufferServerRequest( const QUrl &url, Method method = GetMethod, const QgsServerRequest::Headers &headers = QgsServerRequest::Headers( ), QByteArray *data = 0 );
|
||||
%Docstring
|
||||
Constructor
|
||||
|
||||
@ -40,9 +40,6 @@ class QgsBufferServerRequest : QgsServerRequest
|
||||
~QgsBufferServerRequest();
|
||||
|
||||
virtual QByteArray data() const;
|
||||
%Docstring
|
||||
:rtype: QByteArray
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
|
@ -193,9 +193,10 @@ class QgsServer
|
||||
* \param urlstr QString containing the request url (simple quely string must be preceded by '?')
|
||||
* \param requestMethod QgsServerRequest::Method that indicates the method. Only "GET" or "POST" are supported.
|
||||
* \param data array of bytes containing post data
|
||||
* \param map of request headers
|
||||
* \returns the response headers and body QPair of QByteArray
|
||||
*/
|
||||
QPair<QByteArray, QByteArray> handleRequest( const QString &urlstr, const QgsServerRequest::Method requestMethod = QgsServerRequest::GetMethod, const char *data = 0 );
|
||||
QPair<QByteArray, QByteArray> handleRequest( const QString &urlstr, const QgsServerRequest::Method requestMethod = QgsServerRequest::GetMethod, const QgsServerRequest::Headers &headers = QgsServerRequest::Headers(), const char *data = nullptr );
|
||||
|
||||
/** Returns a pointer to the server interface */
|
||||
QgsServerInterface *serverInterface();
|
||||
|
@ -23,8 +23,8 @@
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
QgsBufferServerRequest::QgsBufferServerRequest( const QString &url, Method method, QByteArray *data )
|
||||
: QgsServerRequest( url, method )
|
||||
QgsBufferServerRequest::QgsBufferServerRequest( const QString &url, Method method, const QgsServerRequest::Headers &headers, QByteArray *data )
|
||||
: QgsServerRequest( url, method, headers )
|
||||
{
|
||||
if ( data )
|
||||
{
|
||||
@ -32,8 +32,8 @@ QgsBufferServerRequest::QgsBufferServerRequest( const QString &url, Method metho
|
||||
}
|
||||
}
|
||||
|
||||
QgsBufferServerRequest::QgsBufferServerRequest( const QUrl &url, Method method, QByteArray *data )
|
||||
: QgsServerRequest( url, method )
|
||||
QgsBufferServerRequest::QgsBufferServerRequest( const QUrl &url, Method method, const QgsServerRequest::Headers &headers, QByteArray *data )
|
||||
: QgsServerRequest( url, method, headers )
|
||||
{
|
||||
if ( data )
|
||||
{
|
||||
|
@ -41,7 +41,7 @@ class SERVER_EXPORT QgsBufferServerRequest : public QgsServerRequest
|
||||
* \param url the url string
|
||||
* \param method the request method
|
||||
*/
|
||||
QgsBufferServerRequest( const QString &url, Method method = GetMethod, QByteArray *data = nullptr );
|
||||
QgsBufferServerRequest( const QString &url, Method method = GetMethod, const QgsServerRequest::Headers &headers = QgsServerRequest::Headers( ), QByteArray *data = nullptr );
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -49,7 +49,7 @@ class SERVER_EXPORT QgsBufferServerRequest : public QgsServerRequest
|
||||
* \param url QUrl
|
||||
* \param method the request method
|
||||
*/
|
||||
QgsBufferServerRequest( const QUrl &url, Method method = GetMethod, QByteArray *data = nullptr );
|
||||
QgsBufferServerRequest( const QUrl &url, Method method = GetMethod, const QgsServerRequest::Headers &headers = QgsServerRequest::Headers( ), QByteArray *data = nullptr );
|
||||
|
||||
~QgsBufferServerRequest();
|
||||
|
||||
|
@ -427,7 +427,7 @@ void QgsServer::handleRequest( QgsServerRequest &request, QgsServerResponse &res
|
||||
}
|
||||
}
|
||||
|
||||
QPair<QByteArray, QByteArray> QgsServer::handleRequest( const QString &urlstr, const QgsServerRequest::Method requestMethod, const char *data )
|
||||
QPair<QByteArray, QByteArray> QgsServer::handleRequest( const QString &urlstr, const QgsServerRequest::Method requestMethod, const QgsServerRequest::Headers &headers, const char *data )
|
||||
{
|
||||
|
||||
QUrl url( urlstr );
|
||||
@ -446,7 +446,7 @@ QPair<QByteArray, QByteArray> QgsServer::handleRequest( const QString &urlstr, c
|
||||
throw QgsServerException( QStringLiteral( "Invalid method in handleRequest(): only GET or POST is supported" ) );
|
||||
}
|
||||
|
||||
QgsBufferServerRequest request( url, requestMethod, &ba );
|
||||
QgsBufferServerRequest request( url, requestMethod, headers, &ba );
|
||||
QgsBufferServerResponse response;
|
||||
|
||||
handleRequest( request, response );
|
||||
|
@ -81,9 +81,10 @@ class SERVER_EXPORT QgsServer
|
||||
* \param urlstr QString containing the request url (simple quely string must be preceded by '?')
|
||||
* \param requestMethod QgsServerRequest::Method that indicates the method. Only "GET" or "POST" are supported.
|
||||
* \param data array of bytes containing post data
|
||||
* \param map of request headers
|
||||
* \returns the response headers and body QPair of QByteArray
|
||||
*/
|
||||
QPair<QByteArray, QByteArray> handleRequest( const QString &urlstr, const QgsServerRequest::Method requestMethod = QgsServerRequest::GetMethod, const char *data = nullptr );
|
||||
QPair<QByteArray, QByteArray> handleRequest( const QString &urlstr, const QgsServerRequest::Method requestMethod = QgsServerRequest::GetMethod, const QgsServerRequest::Headers &headers = QgsServerRequest::Headers(), const char *data = nullptr );
|
||||
|
||||
//! Returns a pointer to the server interface
|
||||
QgsServerInterfaceImpl *serverInterface() { return sServerInterface; }
|
||||
|
@ -55,7 +55,7 @@ import ssl
|
||||
import urllib.parse
|
||||
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||||
from qgis.core import QgsApplication
|
||||
from qgis.server import QgsServer
|
||||
from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse
|
||||
|
||||
QGIS_SERVER_PORT = int(os.environ.get('QGIS_SERVER_PORT', '8081'))
|
||||
QGIS_SERVER_HOST = os.environ.get('QGIS_SERVER_HOST', '127.0.0.1')
|
||||
@ -86,17 +86,18 @@ if os.environ.get('QGIS_SERVER_HTTP_BASIC_AUTH') is not None:
|
||||
class HTTPBasicFilter(QgsServerFilter):
|
||||
|
||||
def responseComplete(self):
|
||||
request = self.serverInterface().requestHandler()
|
||||
if self.serverInterface().getEnv('HTTP_AUTHORIZATION'):
|
||||
username, password = base64.b64decode(self.serverInterface().getEnv('HTTP_AUTHORIZATION')[6:]).split(b':')
|
||||
handler = self.serverInterface().requestHandler()
|
||||
auth = self.serverInterface().requestHandler().requestHeader('HTTP_AUTHORIZATION')
|
||||
if auth:
|
||||
username, password = base64.b64decode(auth[6:]).split(b':')
|
||||
if (username.decode('utf-8') == os.environ.get('QGIS_SERVER_USERNAME', 'username') and
|
||||
password.decode('utf-8') == os.environ.get('QGIS_SERVER_PASSWORD', 'password')):
|
||||
return
|
||||
# No auth ...
|
||||
request.clear()
|
||||
request.setResponseHeader('Status', '401 Authorization required')
|
||||
request.setResponseHeader('WWW-Authenticate', 'Basic realm="QGIS Server"')
|
||||
request.appendBody(b'<h1>Authorization required</h1>')
|
||||
handler.clear()
|
||||
handler.setResponseHeader('Status', '401 Authorization required')
|
||||
handler.setResponseHeader('WWW-Authenticate', 'Basic realm="QGIS Server"')
|
||||
handler.appendBody(b'<h1>Authorization required</h1>')
|
||||
|
||||
filter = HTTPBasicFilter(qgs_server.serverInterface())
|
||||
qgs_server.serverInterface().registerFilter(filter)
|
||||
@ -104,12 +105,16 @@ if os.environ.get('QGIS_SERVER_HTTP_BASIC_AUTH') is not None:
|
||||
|
||||
class Handler(BaseHTTPRequestHandler):
|
||||
|
||||
def do_GET(self):
|
||||
def do_GET(self, post_body=None):
|
||||
# CGI vars:
|
||||
headers = {}
|
||||
for k, v in self.headers.items():
|
||||
qgs_server.putenv('HTTP_%s' % k.replace(' ', '-').replace('-', '_').replace(' ', '-').upper(), v)
|
||||
headers, body = qgs_server.handleRequest(self.path)
|
||||
headers_dict = dict(h.split(': ', 1) for h in headers.decode().split('\n') if h)
|
||||
headers['HTTP_%s' % k.replace(' ', '-').replace('-', '_').replace(' ', '-').upper()] = v
|
||||
request = QgsBufferServerRequest(self.path, (QgsServerRequest.PostMethod if post_body is not None else QgsServerRequest.GetMethod), headers, post_body)
|
||||
response = QgsBufferServerResponse()
|
||||
qgs_server.handleRequest(request, response)
|
||||
|
||||
headers_dict = response.headers()
|
||||
try:
|
||||
self.send_response(int(headers_dict['Status'].split(' ')[0]))
|
||||
except:
|
||||
@ -117,16 +122,13 @@ class Handler(BaseHTTPRequestHandler):
|
||||
for k, v in headers_dict.items():
|
||||
self.send_header(k, v)
|
||||
self.end_headers()
|
||||
self.wfile.write(body)
|
||||
self.wfile.write(response.body())
|
||||
return
|
||||
|
||||
def do_POST(self):
|
||||
content_len = int(self.headers.get('content-length', 0))
|
||||
post_body = self.rfile.read(content_len).decode()
|
||||
request = post_body[1:post_body.find(' ')]
|
||||
self.path = self.path + '&REQUEST_BODY=' + \
|
||||
post_body.replace('&', '') + '&REQUEST=' + request
|
||||
return self.do_GET()
|
||||
post_body = self.rfile.read(content_len)
|
||||
return self.do_GET(post_body)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -9,7 +9,7 @@ configuration to access an HTTP Basic protected endpoint.
|
||||
|
||||
|
||||
From build dir, run from test directory:
|
||||
LC_ALL=EN ctest -R PyQgsAuthManagerPasswordOWSTest -V
|
||||
LC_ALL=en_US.UTF-8 ctest -R PyQgsAuthManagerPasswordOWSTest -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
|
||||
|
@ -3,7 +3,7 @@
|
||||
Test the QgsFileDownloader class
|
||||
|
||||
Run test with:
|
||||
LC_ALL=EN ctest -V -R PyQgsFileDownloader
|
||||
LC_ALL=en_US.UTF-8 ctest -V -R PyQgsFileDownloader
|
||||
|
||||
.. 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
|
||||
|
@ -38,7 +38,7 @@ import urllib.error
|
||||
import email
|
||||
|
||||
from io import StringIO
|
||||
from qgis.server import QgsServer, QgsServerRequest
|
||||
from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse
|
||||
from qgis.core import QgsRenderChecker, QgsApplication
|
||||
from qgis.testing import unittest
|
||||
from qgis.PyQt.QtCore import QSize
|
||||
@ -198,6 +198,16 @@ class TestQgsServer(QgsServerTestBase):
|
||||
locals()["s%s" % i] = QgsServer()
|
||||
locals()["s%s" % i].handleRequest("")
|
||||
|
||||
def test_requestHandler(self):
|
||||
"""Test request handler"""
|
||||
headers = {'header-key-1': 'header-value-1', 'header-key-2': 'header-value-2'}
|
||||
request = QgsBufferServerRequest('http://somesite.com/somepath', QgsServerRequest.GetMethod, headers)
|
||||
response = QgsBufferServerResponse()
|
||||
self.server.handleRequest(request, response)
|
||||
self.assertEqual(bytes(response.body()), b'<ServerException>Project file error</ServerException>\n')
|
||||
self.assertEqual(response.headers(), {'Content-Length': '54', 'Content-Type': 'text/xml; charset=utf-8'})
|
||||
self.assertEqual(response.statusCode(), 500)
|
||||
|
||||
def test_api(self):
|
||||
"""Using an empty query string (returns an XML exception)
|
||||
we are going to test if headers and body are returned correctly"""
|
||||
|
@ -26,13 +26,10 @@ import urllib.request
|
||||
import urllib.parse
|
||||
import urllib.error
|
||||
|
||||
from qgis.core import QgsRenderChecker
|
||||
from qgis.testing import unittest
|
||||
from qgis.PyQt.QtCore import QSize
|
||||
|
||||
import osgeo.gdal # NOQA
|
||||
import tempfile
|
||||
import base64
|
||||
|
||||
from test_qgsserver import QgsServerTestBase
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user