Skip to content

Commit 9168161

Browse files
authored
Merge pull request #5573 from boundlessgeo/BD-2238-auth-thread-safe
[tests] Add XYX slippy map to test QGIS server + multi-threading
2 parents d00efde + decbde2 commit 9168161

File tree

3 files changed

+53
-13
lines changed

3 files changed

+53
-13
lines changed

python/core/auth/qgsauthmanager.sip

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -704,12 +704,6 @@ Rebuild trusted certificate authorities cache
704704
%End
705705

706706

707-
QMutex *mutex();
708-
%Docstring
709-
Return pointer to mutex
710-
:rtype: QMutex
711-
%End
712-
713707

714708

715709

src/core/auth/qgsauthmanager.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,9 +627,6 @@ class CORE_EXPORT QgsAuthManager : public QObject
627627

628628
#endif
629629

630-
//! Return pointer to mutex
631-
QMutex *mutex() { return mMutex; }
632-
633630
/**
634631
* Error message getter
635632
* \note not available in Python bindings

tests/src/python/qgis_wrapped_server.py

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
specified on the environment variable QGIS_SERVER_PORT.
77
QGIS_SERVER_HOST (defaults to 127.0.0.1)
88
9+
A XYZ map service is also available for multithreading testing:
10+
11+
?MAP=/path/to/projects.qgs&SERVICE=XYZ&X=1&Y=0&Z=1&LAYERS=world
12+
13+
914
For testing purposes, HTTP Basic can be enabled by setting the following
1015
environment variables:
1116
@@ -49,10 +54,14 @@
4954
import sys
5055
import signal
5156
import ssl
57+
import math
5258
import urllib.parse
5359
from http.server import BaseHTTPRequestHandler, HTTPServer
54-
from qgis.core import QgsApplication
55-
from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse
60+
from socketserver import ThreadingMixIn
61+
import threading
62+
63+
from qgis.core import QgsApplication, QgsCoordinateTransform, QgsCoordinateReferenceSystem
64+
from qgis.server import QgsServer, QgsServerRequest, QgsBufferServerRequest, QgsBufferServerResponse, QgsServerFilter
5665

5766
QGIS_SERVER_PORT = int(os.environ.get('QGIS_SERVER_PORT', '8081'))
5867
QGIS_SERVER_HOST = os.environ.get('QGIS_SERVER_HOST', '127.0.0.1')
@@ -77,7 +86,6 @@
7786

7887

7988
if os.environ.get('QGIS_SERVER_HTTP_BASIC_AUTH') is not None:
80-
from qgis.server import QgsServerFilter
8189
import base64
8290

8391
class HTTPBasicFilter(QgsServerFilter):
@@ -100,6 +108,42 @@ def responseComplete(self):
100108
qgs_server.serverInterface().registerFilter(filter)
101109

102110

111+
def num2deg(xtile, ytile, zoom):
112+
"""This returns the NW-corner of the square. Use the function with xtile+1 and/or ytile+1
113+
to get the other corners. With xtile+0.5 & ytile+0.5 it will return the center of the tile."""
114+
n = 2.0 ** zoom
115+
lon_deg = xtile / n * 360.0 - 180.0
116+
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * ytile / n)))
117+
lat_deg = math.degrees(lat_rad)
118+
return (lat_deg, lon_deg)
119+
120+
121+
class XYZFilter(QgsServerFilter):
122+
"""XYZ server, example: ?MAP=/path/to/projects.qgs&SERVICE=XYZ&X=1&Y=0&Z=1&LAYERS=world"""
123+
124+
def requestReady(self):
125+
handler = self.serverInterface().requestHandler()
126+
if handler.parameter('SERVICE') == 'XYZ':
127+
x = int(handler.parameter('X'))
128+
y = int(handler.parameter('Y'))
129+
z = int(handler.parameter('Z'))
130+
# NW corner
131+
lat_deg, lon_deg = num2deg(x, y, z)
132+
# SE corner
133+
lat_deg2, lon_deg2 = num2deg(x + 1, y + 1, z)
134+
handler.setParameter('SERVICE', 'WMS')
135+
handler.setParameter('REQUEST', 'GetMap')
136+
handler.setParameter('VERSION', '1.3.0')
137+
handler.setParameter('SRS', 'EPSG:4326')
138+
handler.setParameter('HEIGHT', '256')
139+
handler.setParameter('WIDTH', '256')
140+
handler.setParameter('BBOX', "{},{},{},{}".format(lat_deg2, lon_deg, lat_deg, lon_deg2))
141+
142+
143+
xyzfilter = XYZFilter(qgs_server.serverInterface())
144+
qgs_server.serverInterface().registerFilter(xyzfilter)
145+
146+
103147
class Handler(BaseHTTPRequestHandler):
104148

105149
def do_GET(self, post_body=None):
@@ -128,8 +172,13 @@ def do_POST(self):
128172
return self.do_GET(post_body)
129173

130174

175+
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
176+
"""Handle requests in a separate thread."""
177+
pass
178+
179+
131180
if __name__ == '__main__':
132-
server = HTTPServer((QGIS_SERVER_HOST, QGIS_SERVER_PORT), Handler)
181+
server = ThreadedHTTPServer((QGIS_SERVER_HOST, QGIS_SERVER_PORT), Handler)
133182
if https:
134183
server.socket = ssl.wrap_socket(server.socket,
135184
certfile=QGIS_SERVER_PKI_CERTIFICATE,

0 commit comments

Comments
 (0)