Merge pull request #5573 from boundlessgeo/BD-2238-auth-thread-safe

[tests] Add XYX slippy map to test QGIS server + multi-threading
This commit is contained in:
Alessandro Pasotti 2017-11-09 18:08:38 +01:00 committed by GitHub
commit 9168161e1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 13 deletions

View File

@ -704,12 +704,6 @@ Rebuild trusted certificate authorities cache
%End
QMutex *mutex();
%Docstring
Return pointer to mutex
:rtype: QMutex
%End

View File

@ -627,9 +627,6 @@ class CORE_EXPORT QgsAuthManager : public QObject
#endif
//! Return pointer to mutex
QMutex *mutex() { return mMutex; }
/**
* Error message getter
* \note not available in Python bindings

View File

@ -6,6 +6,11 @@ This script launches a QGIS Server listening on port 8081 or on the port
specified on the environment variable QGIS_SERVER_PORT.
QGIS_SERVER_HOST (defaults to 127.0.0.1)
A XYZ map service is also available for multithreading testing:
?MAP=/path/to/projects.qgs&SERVICE=XYZ&X=1&Y=0&Z=1&LAYERS=world
For testing purposes, HTTP Basic can be enabled by setting the following
environment variables:
@ -49,10 +54,14 @@ os.environ['QT_HASH_SEED'] = '1'
import sys
import signal
import ssl
import math
import urllib.parse
from http.server import BaseHTTPRequestHandler, HTTPServer
from qgis.core import QgsApplication
from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse
from socketserver import ThreadingMixIn
import threading
from qgis.core import QgsApplication, QgsCoordinateTransform, QgsCoordinateReferenceSystem
from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse, QgsServerFilter
QGIS_SERVER_PORT = int(os.environ.get('QGIS_SERVER_PORT', '8081'))
QGIS_SERVER_HOST = os.environ.get('QGIS_SERVER_HOST', '127.0.0.1')
@ -77,7 +86,6 @@ qgs_server = QgsServer()
if os.environ.get('QGIS_SERVER_HTTP_BASIC_AUTH') is not None:
from qgis.server import QgsServerFilter
import base64
class HTTPBasicFilter(QgsServerFilter):
@ -100,6 +108,42 @@ if os.environ.get('QGIS_SERVER_HTTP_BASIC_AUTH') is not None:
qgs_server.serverInterface().registerFilter(filter)
def num2deg(xtile, ytile, zoom):
"""This returns the NW-corner of the square. Use the function with xtile+1 and/or ytile+1
to get the other corners. With xtile+0.5 & ytile+0.5 it will return the center of the tile."""
n = 2.0 ** zoom
lon_deg = xtile / n * 360.0 - 180.0
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
lat_deg = math.degrees(lat_rad)
return (lat_deg, lon_deg)
class XYZFilter(QgsServerFilter):
"""XYZ server, example: ?MAP=/path/to/projects.qgs&SERVICE=XYZ&X=1&Y=0&Z=1&LAYERS=world"""
def requestReady(self):
handler = self.serverInterface().requestHandler()
if handler.parameter('SERVICE') == 'XYZ':
x = int(handler.parameter('X'))
y = int(handler.parameter('Y'))
z = int(handler.parameter('Z'))
# NW corner
lat_deg, lon_deg = num2deg(x, y, z)
# SE corner
lat_deg2, lon_deg2 = num2deg(x + 1, y + 1, z)
handler.setParameter('SERVICE', 'WMS')
handler.setParameter('REQUEST', 'GetMap')
handler.setParameter('VERSION', '1.3.0')
handler.setParameter('SRS', 'EPSG:4326')
handler.setParameter('HEIGHT', '256')
handler.setParameter('WIDTH', '256')
handler.setParameter('BBOX', "{},{},{},{}".format(lat_deg2, lon_deg, lat_deg, lon_deg2))
xyzfilter = XYZFilter(qgs_server.serverInterface())
qgs_server.serverInterface().registerFilter(xyzfilter)
class Handler(BaseHTTPRequestHandler):
def do_GET(self, post_body=None):
@ -128,8 +172,13 @@ class Handler(BaseHTTPRequestHandler):
return self.do_GET(post_body)
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
pass
if __name__ == '__main__':
server = HTTPServer((QGIS_SERVER_HOST, QGIS_SERVER_PORT), Handler)
server = ThreadedHTTPServer((QGIS_SERVER_HOST, QGIS_SERVER_PORT), Handler)
if https:
server.socket = ssl.wrap_socket(server.socket,
certfile=QGIS_SERVER_PKI_CERTIFICATE,