Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions mslib/msui/wms_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
from mslib.utils.qt import Worker
from mslib.msui.multilayers import Multilayers, Layer
import mslib.utils.ogcwms as ogcwms
from mslib.utils.service_manager import WMSServiceManager
from mslib.utils.service_manager import WMSServiceManager, strip_request_params
from mslib.utils.time import parse_iso_datetime, parse_iso_duration
from mslib.utils.auth import save_password_to_keyring, get_auth_from_url_and_name
from mslib.utils.config import modify_config_file
Expand Down Expand Up @@ -988,11 +988,8 @@ def get_capabilities(self, level=None):

def on_success(request):
self.cpdlg.setValue(5)
# url shortener url translated
url = request.url

url = url.replace("?service=WMS", "").replace("&service=WMS", "") \
.replace("?request=GetCapabilities", "").replace("&request=GetCapabilities", "")
# url shortener url translated, service specific parameters are kept
url = strip_request_params(request.url)
logging.debug("requesting capabilities from %s", url)
self.initialise_wms(url, None, level=level)

Expand Down
42 changes: 40 additions & 2 deletions mslib/utils/service_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,44 @@
See the License for the specific language governing permissions and
limitations under the License.
"""
import urllib.parse

from slugify import slugify

# query parameters which describe a single request instead of the service itself
OGC_REQUEST_PARAMS = ("service", "request")
Comment thread
JanEisermann marked this conversation as resolved.
Outdated


def strip_request_params(url):
"""Remove the OGC request parameters (service, request) from an url.

All other query parameters are kept in their original order, so the result
can be used as base url for further requests to the same service.
"""
scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(url)
kept = [(key, value) for key, value in urllib.parse.parse_qsl(query)
if key.lower() not in OGC_REQUEST_PARAMS]
return urllib.parse.urlunparse(
(scheme, netloc, path, params, urllib.parse.urlencode(kept), fragment))


def service_cache_key(url):
"""Build the cache key of a WMS service from its full url.

In contrast to using only the base url, the query parameters are part of
the key. Services which differ solely in their parameters, e.g.
"https://example.com/wms?dataset=a", therefore get separate cache entries.

The parameters of the GetCapabilities request itself are dropped and the
remaining ones are sorted, so that the very same service is found again no
matter how the request was spelled. Scheme and host are lower cased because
they are case insensitive, the rest of the url is not.
"""
scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(strip_request_params(url))
query = urllib.parse.urlencode(sorted(urllib.parse.parse_qsl(query)))
normalised = urllib.parse.urlunparse(
(scheme.lower(), netloc.lower(), path, params, query, fragment))
return slugify(normalised, lowercase=False)
Comment thread
JanEisermann marked this conversation as resolved.
Outdated


class WMSServiceManager:
Expand All @@ -44,7 +82,7 @@ def clear_cache(self):
self._cache.clear()

def get_service(self, url):
return self._cache.get(url)
return self._cache.get(service_cache_key(url))

def cache_service(self, url, wms):
self._cache[url] = wms
self._cache[service_cache_key(url)] = wms
Loading