Example #1
0
    def test_render(self):
        req = self.mock(WMSMapRequest)
        ex_handler = self.mock(ExceptionHandler)

        req_ex = RequestError("the exception message", request=req)
        self.expect(req.exception_handler).result(ex_handler)
        self.expect(ex_handler.render(req_ex))

        self.replay()
        req_ex.render()
Example #2
0
    def test_exception(self):
        self.req.set("exceptions", "inimage")
        self.req.set("transparent", "true")

        req = WMSMapRequest(self.req)
        req_ex = RequestError("the exception message", request=req)

        response = req_ex.render()
        assert response.content_type == "image/png"
        data = StringIO(response.data)
        assert is_png(data)
        img = Image.open(data)
        assert img.size == (150, 100)
Example #3
0
    def test_exception(self):
        self.req["exceptions"] = "blank"
        req = WMSMapRequest(self.req)
        req_ex = RequestError("the exception message", request=req)

        response = req_ex.render()
        assert response.content_type == "image/png"
        data = StringIO(response.data)
        assert is_png(data)
        img = Image.open(data)
        assert img.size == (150, 100)
        eq_(img.getpixel((0, 0)), 0)  # pallete image
        eq_(img.getpalette()[0:3], [255, 255, 255])
Example #4
0
    def test_exception_w_transparent(self):
        self.req.set("exceptions", "inimage")
        self.req.set("transparent", "true")

        req = WMSMapRequest(self.req)
        req_ex = RequestError("the exception message", request=req)

        response = req_ex.render()
        assert response.content_type == "image/png"
        data = StringIO(response.data)
        assert is_png(data)
        img = Image.open(data)
        assert img.size == (150, 100)
        eq_(sorted([x for x in img.histogram() if x > 25]), [377, 14623])
        img = img.convert("RGBA")
        eq_(img.getpixel((0, 0))[3], 0)
Example #5
0
    def test_exception_w_transparent(self):
        self.req.set("exceptions", "blank")
        self.req.set("transparent", "true")

        req = WMSMapRequest(self.req)
        req_ex = RequestError("the exception message", request=req)

        response = req_ex.render()
        assert response.content_type == "image/png"
        data = StringIO(response.data)
        assert is_png(data)
        img = Image.open(data)
        assert img.size == (150, 100)
        assert img.mode == "P"
        img = img.convert("RGBA")
        eq_(img.getpixel((0, 0))[3], 0)
Example #6
0
    def test_render(self):
        req = self.mock(WMSMapRequest)
        req_ex = RequestError("the exception message", request=req)
        ex_handler = WMS100ExceptionHandler()
        self.expect(req.exception_handler).result(ex_handler)

        self.replay()
        response = req_ex.render()

        assert response.content_type == "text/xml"
        expected_resp = """
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<WMTException version="1.0.0">
the exception message
</WMTException>
"""
        assert expected_resp.strip() == response.data
Example #7
0
    def check_map_request(self, request):
        if self.max_output_pixels and \
            (request.params.size[0] * request.params.size[1]) > self.max_output_pixels:
            request.prevent_image_exception = True
            raise RequestError("image size too large", request=request)

        self.validate_layers(request)
        request.validate_format(self.image_formats)
        request.validate_srs(self.srs)
Example #8
0
    def test_render(self):
        req = self.mock(WMSMapRequest)
        req_ex = RequestError("the exception message", request=req)
        ex_handler = WMS110ExceptionHandler()
        self.expect(req.exception_handler).result(ex_handler)

        self.replay()
        response = req_ex.render()
        assert response.content_type == "application/vnd.ogc.se_xml"
        expected_resp = """
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE ServiceExceptionReport SYSTEM "http://schemas.opengis.net/wms/1.1.0/exception_1_1_0.dtd">
<ServiceExceptionReport version="1.1.0">
    <ServiceException>the exception message</ServiceException>
</ServiceExceptionReport>
"""
        assert expected_resp.strip() == response.data
        assert validate_with_dtd(response.data, "wms/1.1.0/exception_1_1_0.dtd")
Example #9
0
 def validate_styles(self):
     if 'styles' in self.params:
         styles = self.params['styles']
         if not set(styles.split(',')).issubset(
                 set(['default', '', 'inspire_common:DEFAULT'])):
             raise RequestError('unsupported styles: ' +
                                self.params['styles'],
                                code='StyleNotDefined',
                                request=self)
Example #10
0
 def authorized_demo(self, environ):
     if 'mapproxy.authorize' in environ:
         result = environ['mapproxy.authorize']('demo', [], environ=environ)
         if result['authorized'] == 'unauthenticated':
             raise RequestError('unauthorized', status=401)
         if result['authorized'] == 'full':
             return True
         return False
     return True
Example #11
0
 def check_request_dimensions(self, tile_layer, request):
     # check that unknown dimension for this layer are set to default
     if request.dimensions:
         for dimension, value in iteritems(request.dimensions):
             dimension = dimension.lower()
             if dimension not in tile_layer.dimensions and value != 'default':
                 raise RequestError('unknown dimension: ' + str(dimension),
                                    code='InvalidParameterValue',
                                    request=request)
Example #12
0
 def layer(self, tile_request):
     if self.use_dimension_layers:
         internal_layer = self._internal_dimension_layer(tile_request)
     else:
         internal_layer = self._internal_layer(tile_request)
     if internal_layer is None:
         raise RequestError('unknown layer: ' + tile_request.layer,
                            request=tile_request)
     return internal_layer
Example #13
0
 def authorized_tile_layers(self, env):
     if 'mapproxy.authorize' in env:
         result = env['mapproxy.authorize']('tms', [l for l in self.layers],
                                            environ=env)
         if result['authorized'] == 'unauthenticated':
             raise RequestError('unauthorized', status=401)
         if result['authorized'] == 'full':
             return self.layers
         if result['authorized'] == 'none':
             raise RequestError('forbidden', status=403)
         allowed_layers = odict()
         for layer in self.layers.itervalues():
             if result['layers'].get(layer.name, {}).get('tile',
                                                         False) == True:
                 allowed_layers[layer.name] = layer
         return allowed_layers
     else:
         return self.layers
Example #14
0
    def test_render(self):
        req = self.mock(WMSMapRequest)
        req_ex = RequestError('the exception message', request=req)
        ex_handler = WMS110ExceptionHandler()
        self.expect(req.exception_handler).result(ex_handler)

        self.replay()
        response = req_ex.render()
        assert response.content_type == 'application/vnd.ogc.se_xml'
        expected_resp = b"""
<?xml version="1.0"?>
<!DOCTYPE ServiceExceptionReport SYSTEM "http://schemas.opengis.net/wms/1.1.0/exception_1_1_0.dtd">
<ServiceExceptionReport version="1.1.0">
    <ServiceException>the exception message</ServiceException>
</ServiceExceptionReport>
"""
        assert expected_resp.strip() == response.data
        assert validate_with_dtd(response.data, 'wms/1.1.0/exception_1_1_0.dtd')
Example #15
0
    def _render_layer(self, layer):
        try:
            layer_img = layer.get_map(self.query)
            if layer_img is not None:
                layer_img.opacity = layer.opacity

            return layer, layer_img
        except SourceError:
            raise
        except MapBBOXError:
            raise RequestError('Request too large or invalid BBOX.', request=self.request)
        except MapError as e:
            raise RequestError('Invalid request: %s' % e.args[0], request=self.request)
        except TransformationError:
            raise RequestError('Could not transform BBOX: Invalid result.',
                request=self.request)
        except BlankImage:
            return layer, None
Example #16
0
 def _render_raise_exceptions(self, async_pool, render_layers,
                              layer_merger):
     # call _render_layer, raise all exceptions
     try:
         for layer, layer_img in async_pool.imap(self._render_layer,
                                                 render_layers):
             if layer_img is not None:
                 layer_merger.add(layer_img, layer=layer)
     except SourceError, ex:
         raise RequestError(ex.args[0], request=self.request)
Example #17
0
def wmts_request(req, validate=True):
    req_type = _parse_request_type(req)

    req_class = request_mapping.get(req_type, None)
    if req_class is None:
        # use map request to get an exception handler for the requested version
        dummy_req = request_mapping['tile'](param=req.args, url=req.base_url,
                                            validate=False)
        raise RequestError("unknown WMTS request type '%s'" % req_type, request=dummy_req)
    return req_class(param=req.args, url=req.base_url, validate=True, http=req)
Example #18
0
 def authorize_tile_layer(self, tile_layer, request):
     if 'mapproxy.authorize' in request.http.environ:
         query_extent = tile_layer.grid.srs.srs_code, tile_layer.tile_bbox(request)
         result = request.http.environ['mapproxy.authorize']('wmts', [tile_layer.name],
             query_extent=query_extent, environ=request.http.environ)
         if result['authorized'] == 'unauthenticated':
             raise RequestError('unauthorized', status=401)
         if result['authorized'] == 'full':
             return
         if result['authorized'] == 'partial':
             if result['layers'].get(tile_layer.name, {}).get('tile', False) == True:
                 limited_to = result['layers'][tile_layer.name].get('limited_to')
                 if not limited_to:
                     limited_to = result.get('limited_to')
                 if limited_to:
                     return load_limited_to(limited_to)
                 else:
                     return None
         raise RequestError('forbidden', status=403)
Example #19
0
 def layer(self, tile_request):
     if self.use_dimension_layers:
         internal_layer = self._internal_dimension_layer(tile_request)
     else:
         internal_layer = self._internal_layer(tile_request)
     if internal_layer is None:
         raise RequestError('unknown layer: ' + tile_request.layer,
                            request=tile_request)
     self.authorize_tile_layer(internal_layer.name,
                               tile_request.http.environ)
     return internal_layer
Example #20
0
    def check_request(self, request, info_formats=None):
        request.make_request()
        if request.layer not in self.layers:
            raise RequestError('unknown layer: ' + str(request.layer),
                code='InvalidParameterValue', request=request)
        if request.tilematrixset not in self.layers[request.layer]:
            raise RequestError('unknown tilematrixset: ' + str(request.tilematrixset),
                code='InvalidParameterValue', request=request)

        if info_formats is not None:
            if '/' in request.infoformat:  # mimetype
                if request.infoformat not in self.info_formats.values():
                    raise RequestError('unknown infoformat: ' + str(request.infoformat),
                        code='InvalidParameterValue', request=request)
            else: # RESTful suffix
                if request.infoformat not in self.info_formats:
                    raise RequestError('unknown infoformat: ' + str(request.infoformat),
                        code='InvalidParameterValue', request=request)
                # set mimetype as infoformat
                request.infoformat = self.info_formats[request.infoformat]
Example #21
0
 def authorized_tile_layers(self, env):
     if 'mapproxy.authorize' in env:
         result = env['mapproxy.authorize']('wmts',
                                            [l for l in self.layers],
                                            query_extent=None,
                                            environ=env)
         if result['authorized'] == 'unauthenticated':
             raise RequestError('unauthorized', status=401)
         if result['authorized'] == 'full':
             return self.layers.values()
         if result['authorized'] == 'none':
             raise RequestError('forbidden', status=403)
         allowed_layers = []
         for layer in itervalues(self.layers):
             if result['layers'].get(layer.name, {}).get('tile',
                                                         False) == True:
                 allowed_layers.append(layer)
         return allowed_layers
     else:
         return self.layers.values()
Example #22
0
    def test_render(self):
        req = self.mock(WMSMapRequest)
        req_ex = RequestError('the exception message', request=req)
        ex_handler = WMS130ExceptionHandler()
        self.expect(req.exception_handler).result(ex_handler)

        self.replay()
        response = req_ex.render()
        assert response.content_type == 'text/xml; charset=utf-8'
        expected_resp = b"""
<?xml version="1.0"?>
<ServiceExceptionReport version="1.3.0"
  xmlns="http://www.opengis.net/ogc"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/ogc
http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd">
    <ServiceException>the exception message</ServiceException>
</ServiceExceptionReport>
"""
        assert expected_resp.strip() == response.data
        assert validate_with_xsd(response.data, 'wms/1.3.0/exceptions_1_3_0.xsd')
Example #23
0
    def test_render_w_code(self):
        req = self.mock(WMSMapRequest)
        req_ex = RequestError("the exception message", code="InvalidFormat", request=req)
        ex_handler = WMS130ExceptionHandler()
        self.expect(req.exception_handler).result(ex_handler)

        self.replay()
        response = req_ex.render()
        assert response.content_type == "text/xml; charset=utf-8"
        expected_resp = """
<?xml version='1.0' encoding="UTF-8"?>
<ServiceExceptionReport version="1.3.0"
  xmlns="http://www.opengis.net/ogc"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/ogc
http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd">
    <ServiceException code="InvalidFormat">the exception message</ServiceException>
</ServiceExceptionReport>
"""
        assert expected_resp.strip() == response.data
        assert validate_with_xsd(response.data, "wms/1.3.0/exceptions_1_3_0.xsd")
Example #24
0
    def render(self, tile_request, use_profiles=False):
        if tile_request.format != self.format:
            raise RequestError(
                'invalid format (%s). this tile set only supports (%s)' %
                (tile_request.format, self.format),
                request=tile_request,
                code='InvalidParameterValue')

        tile_coord = self._internal_tile_coord(tile_request,
                                               use_profiles=use_profiles)
        try:
            with self.tile_manager.session():
                tile = self.tile_manager.load_tile_coord(tile_coord,
                                                         with_metadata=True)
            if tile.source is None:
                return self.empty_response()

            format = None if self._mixed_format else tile_request.format
            return TileResponse(tile, format=format)
        except SourceError, e:
            raise RequestError(e.args[0], request=tile_request, internal=True)
Example #25
0
 def authorized_capability_layers(self, env):
     if 'mapproxy.authorize' in env:
         result = env['mapproxy.authorize']('wms.capabilities',
                                            self.layers.keys(),
                                            environ=env)
         if result['authorized'] == 'unauthenticated':
             raise RequestError('unauthorized', status=401)
         if result['authorized'] == 'full':
             return self.root_layer
         if result['authorized'] == 'partial':
             limited_to = result.get('limited_to')
             if limited_to:
                 coverage = load_limited_to(limited_to)
             else:
                 coverage = None
             return FilteredRootLayer(self.root_layer,
                                      result['layers'],
                                      coverage=coverage)
         raise RequestError('forbidden', status=403)
     else:
         return self.root_layer
Example #26
0
    def _internal_tile_coord(self, tile_request, use_profiles=False):
        tile_coord = self.grid.internal_tile_coord(tile_request.tile, use_profiles)
        if tile_coord is None:
            raise RequestError('The requested tile is outside the bounding box'
                               ' of the tile map.', request=tile_request,
                               code='TileOutOfRange')
        if tile_request.origin == 'nw' and self.grid.origin not in ('ul', 'nw'):
            tile_coord = self.grid.flip_tile_coord(tile_coord)
        elif tile_request.origin == 'sw' and self.grid.origin not in ('ll', 'sw', None):
            tile_coord = self.grid.flip_tile_coord(tile_coord)

        return tile_coord
Example #27
0
    def validate_param(self):
        missing_param = []
        for param in self.expected_param:
            if self.non_strict and param in self.non_strict_params:
                continue
            if param not in self.params:
                missing_param.append(param)

        if missing_param:
            if 'format' in missing_param:
                self.params['format'] = 'image/png'
            raise RequestError('missing parameters ' + str(missing_param),
                               request=self)
Example #28
0
    def validate_format(self, image_formats):
        format = self.params['format']
        image_formats100 = [f.split('/', 1)[1].upper() for f in image_formats]

        if format in image_formats100:
            format = 'image/' + format.lower()
            self.params['format'] = format

        if format not in image_formats:
            format = self.params['format']
            self.params['format'] = 'image/png'
            raise RequestError('unsupported image format: ' + format,
                               code='InvalidFormat', request=self)
Example #29
0
 def filter_actual_layers(self, actual_layers, requested_layers, authorized_layers):
     if authorized_layers is not PERMIT_ALL_LAYERS:
         requested_layer_names = set(requested_layers)
         for layer_name in actual_layers.keys():
             if layer_name not in authorized_layers:
                 # check whether layer was requested explicit...
                 if layer_name in requested_layer_names:
                     raise RequestError('forbidden', status=403)
                 # or implicit (part of group layer)
                 else:
                     del actual_layers[layer_name]
             elif authorized_layers[layer_name] is not None:
                 limited_to = load_limited_to(authorized_layers[layer_name])
                 actual_layers[layer_name] = [LimitedLayer(lyr, limited_to) for lyr in actual_layers[layer_name]]
Example #30
0
    def wmts_request(req):
        if req.path.endswith(RESTFUL_CAPABILITIES_PATH):
            return WMTS100RestCapabilitiesRequest(req)

        match = tile_req_re.search(req.path)
        if not match:
            match = fi_req_re.search(req.path)
            if not match:
                raise RequestError('invalid request (%s)' % (req.path))

            req_vars = match.groupdict()
            return WMTS100RestFeatureInfoRequest(req, req_vars, fi_url_converter)
        req_vars = match.groupdict()
        return WMTS100RestTileRequest(req, req_vars, url_converter)
Example #31
0
    def checked_dimensions(self, tile_request):
        dimensions = {}

        for dimension, values in self.dimensions.iteritems():
            value = tile_request.dimensions.get(dimension)
            if value in values:
                dimensions[dimension] = value
            elif not value or value == 'default':
                dimensions[dimension] = values.default
            else:
                raise RequestError('invalid dimension value (%s=%s).'
                    % (dimension, value), request=tile_request,
                       code='InvalidParameterValue')
        return dimensions
Example #32
0
 def _render_raise_exceptions(self, async_pool, render_layers, layer_merger):
     # call _render_layer, raise all exceptions
     try:
         for layer_task in async_pool.imap(self._render_layer, render_layers,
                                           use_result_objects=True):
             if layer_task.exception is None:
                 layer, layer_img = layer_task.result
                 if layer_img is not None:
                     layer_merger.add(layer_img, layer.coverage)
             else:
                 ex = layer_task.exception
                 async_pool.shutdown(True)
                 reraise(ex)
     except SourceError as ex:
         raise RequestError(ex.args[0], request=self.request)
Example #33
0
    def legendgraphic(self, request):
        legends = []
        self.check_legend_request(request)
        layer = request.params.layer
        if not self.layers[layer].has_legend:
            raise RequestError('layer %s has no legend graphic' % layer, request=request)
        legend = self.layers[layer].legend(request)

        [legends.append(i) for i in legend if i is not None]
        result = concat_legends(legends)
        if 'format' in request.params:
            mimetype = request.params.format_mime_type
        else:
            mimetype = 'image/png'
        img_opts = self.image_formats[request.params.format_mime_type]
        return Response(result.as_buffer(img_opts), mimetype=mimetype)
Example #34
0
    def make_tile_request(self):
        """
        Initialize tile request. Sets ``tile`` and ``layer`` and ``format``.
        :raise RequestError: if the format does not match the URL template``
        """
        match = self.tile_req_re.search(self.http.path)
        if not match:
            raise RequestError('invalid request (%s)' % (self.http.path),
                               request=self)

        req_vars = match.groupdict()

        self.layer = req_vars['Layer']
        self.tile = int(req_vars['TileCol']), int(req_vars['TileRow']), int(
            req_vars['TileMatrix'])
        self.format = req_vars.get('Format')
        self.tilematrixset = req_vars['TileMatrixSet']
Example #35
0
    def featureinfo(self, request):
        infos = []
        self.check_request(request, self.info_formats)

        tile_layer = self.layers[request.layer][request.tilematrixset]
        if not request.format:
            request.format = tile_layer.format

        bbox = tile_layer.grid.tile_bbox(request.tile)
        query = InfoQuery(
            bbox,
            tile_layer.grid.tile_size,
            tile_layer.grid.srs,
            request.pos,
            request.infoformat,
        )

        self.check_request_dimensions(tile_layer, request)

        coverage = self.authorize_tile_layer(tile_layer,
                                             request,
                                             featureinfo=True)

        if not tile_layer.info_sources:
            raise RequestError('layer %s not queryable' % str(request.layer),
                               code='OperationNotSupported',
                               request=request)

        if coverage and not coverage.contains(query.coord, query.srs):
            infos = []
        else:
            for source in tile_layer.info_sources:
                info = source.get_info(query)
                if info is None:
                    continue
                infos.append(info)

        mimetype = request.infoformat

        if not infos:
            return Response('', mimetype=mimetype)

        resp, _ = combine_docs(infos)

        return Response(resp, mimetype=mimetype)
Example #36
0
    def _init_request(self):
        """
        Initialize tile request. Sets ``tile`` and ``layer``.
        :raise RequestError: if the format is not ``/layer/z/x/y.format``
        """
        match = self.tile_req_re.search(self.http.path)
        if not match or match.group('begin') != self.req_prefix:
            raise RequestError('invalid request (%s)' % (self.http.path),
                               request=self)

        self.layer = match.group('layer')
        self.dimensions = tuple()
        if match.group('layer_spec') is not None:
            self.dimensions = (match.group('layer_spec'), )
        if not self.tile:
            self.tile = tuple([int(match.group(v)) for v in ['x', 'y', 'z']])
        if not self.format:
            self.format = match.group('format')
Example #37
0
def wms_request(req, validate=True, strict=True, versions=None):
    version = _parse_version(req)
    req_type = _parse_request_type(req)

    if versions and version not in versions:
        version_requests = None
    else:
        version_requests = request_mapping.get(version, None)

    if version_requests is None:
        negotiated_version = negotiate_version(version, supported_versions=versions)
        version_requests = request_mapping[negotiated_version]
    req_class = version_requests.get(req_type, None)
    if req_class is None:
        # use map request to get an exception handler for the requested version
        dummy_req = version_requests['map'](param=req.args, url=req.base_url,
                                            validate=False)
        raise RequestError("unknown WMS request type '%s'" % req_type, request=dummy_req)
    return req_class(param=req.args, url=req.base_url, validate=True,
                     non_strict=not strict, http=req)
Example #38
0
 def authorized_layers(self, feature, layers, env, query_extent):
     if 'mapproxy.authorize' in env:
         result = env['mapproxy.authorize']('wms.' + feature, layers[:],
             environ=env, query_extent=query_extent)
         if result['authorized'] == 'unauthenticated':
             raise RequestError('unauthorized', status=401)
         if result['authorized'] == 'full':
             return PERMIT_ALL_LAYERS, None
         layers = {}
         if result['authorized'] == 'partial':
             for layer_name, permissions in iteritems(result['layers']):
                 if permissions.get(feature, False) == True:
                     layers[layer_name] = permissions.get('limited_to')
         limited_to = result.get('limited_to')
         if limited_to:
             coverage = load_limited_to(limited_to)
         else:
             coverage = None
         return layers, coverage
     else:
         return PERMIT_ALL_LAYERS, None