コード例 #1
0
ファイル: mapserverproxy.py プロジェクト: vicb/c2cgeoportal
def proxy(request):

    user = request.user
    external = bool(request.params.get("EXTERNAL", None))

    # params hold the parameters we're going to send to MapServer
    params = dict(request.params)

    # reset possible value of role_id and user_id
    if 'role_id' in params:
        del params['role_id']
    if 'user_id' in params:
        del params['user_id']
    if user:
        # We have a user logged in. We need to set group_id and
        # possible layer_name in the params. We set layer_name
        # when either QUERY_PARAMS or LAYERS is set in the
        # WMS params, i.e. for GetMap and GetFeatureInfo
        # requests. For GetLegendGraphic requests we don't
        # send layer_name, but MapServer shouldn't use the DATA
        # string for GetLegendGraphic.

        params['role_id'] = user.parent_role.id if external else user.role.id

        # In some application we want to display the features owned by a user
        # than we need his id.
        if not external:
            params['user_id'] = user.id

    # don't allows direct variable substitution
    for k in params.keys():
        if k[:2].capitalize() == 'S_':
            log.warning("Direct substitution not allowed (%s=%s)." %
                        (k, params[k]))
            del params[k]

    mss = get_functionality('mapserver_substitution',
                            request.registry.settings, request)
    if mss:
        for s in mss:
            index = s.find('=')
            if index > 0:
                attribute = 's_' + s[:index]
                value = s[index + 1:]
                if attribute in params:
                    params[attribute] += "," + value
                else:
                    params[attribute] = value
            else:
                log.warning("Mapserver Substitution '%s' does not "
                            "respect pattern: <attribute>=<value>" % s)

    # get method
    method = request.method

    # we want the browser to cache GetLegendGraphic requests, so
    # we need to know if the current request is a GetLegendGraphic
    # request
    is_glg = False

    # name of the JSON callback (value for the "callback" query string param
    # in the request). None if request has no "callback" param in the query
    # string
    callback = None

    if method == "GET":
        _params = dict(
            (k.lower(), unicode(v).lower()) for k, v in params.iteritems())

        # For GET requests, params are added only if the REQUEST
        # parameter is actually provided.
        if 'request' not in _params:
            params = {}  # pragma: no cover
        else:
            # WMS GetLegendGraphic request?
            is_glg = ('service' not in _params or _params['service'] == u'wms') and \
                _params['request'] == u'getlegendgraphic'

        callback = params.get('callback')

    # get query string
    params_encoded = {}
    for k, v in params.iteritems():
        if k == 'callback':
            continue
        params_encoded[k] = unicode(v).encode('utf-8')
    query_string = urllib.urlencode(params_encoded)

    # get URL
    _url = request.registry.settings['external_mapserv_url'] \
        if external \
        else request.registry.settings['mapserv_url']
    _url += '?' + query_string
    log.info("Querying mapserver proxy at URL: %s." % _url)

    # get body
    body = None
    if method in ("POST", "PUT"):
        body = request.body

    # forward request to target (without Host Header)
    http = httplib2.Http()
    h = dict(request.headers)
    if urlparse(_url).hostname != 'localhost':
        h.pop('Host')
    # mapserver don't need the cookie, and sometimes it failed with it.
    if 'Cookie' in h:
        h.pop('Cookie')
    try:
        resp, content = http.request(_url, method=method, body=body, headers=h)
    except:  # pragma: no cover
        log.error("Error '%s' while getting the URL: %s." %
                  (sys.exc_info()[0], _url))
        if method == "POST":
            log.error("--- With body ---")
            log.error(body)
        return HTTPBadGateway("See logs for details")  # pragma: no cover

    if resp.status != 200:
        log.error("\nError\n '%s'\n in response from URL:\n %s\n "
                  "with query:\n %s" %
                  (resp.reason, _url, body))  # pragma: no cover
        return HTTPInternalServerError(
            "See logs for details")  # pragma: no cover

    # check for allowed content types
    if "content-type" not in resp:
        return HTTPNotAcceptable()  # pragma: no cover

    if method == "POST" and is_get_feature(request.body):
        content = limit_featurecollection(content, limit=200)

    content_type = None
    if callback:
        content_type = "application/javascript"
        # escape single quotes in the JavaScript string
        content = unicode(content.decode('utf8'))
        content = content.replace(u"'", ur"\'")
        content = u"%s('%s');" % (callback, u' '.join(content.splitlines()))
    else:
        content_type = resp["content-type"]

    headers = {"Content-Type": content_type}

    if is_glg:
        # 30min expiration for GetLegendGraphic
        headers.update({"Cache-Control": "public, max-age=1800"})

    return Response(content, status=resp.status, headers=headers)
コード例 #2
0
ファイル: mapserverproxy.py プロジェクト: vicb/c2cgeoportal
def proxy(request):

    user = request.user
    external = bool(request.params.get("EXTERNAL", None))

    # params hold the parameters we're going to send to MapServer
    params = dict(request.params)

    # reset possible value of role_id and user_id
    if "role_id" in params:
        del params["role_id"]
    if "user_id" in params:
        del params["user_id"]
    if user:
        # We have a user logged in. We need to set group_id and
        # possible layer_name in the params. We set layer_name
        # when either QUERY_PARAMS or LAYERS is set in the
        # WMS params, i.e. for GetMap and GetFeatureInfo
        # requests. For GetLegendGraphic requests we don't
        # send layer_name, but MapServer shouldn't use the DATA
        # string for GetLegendGraphic.

        params["role_id"] = user.parent_role.id if external else user.role.id

        # In some application we want to display the features owned by a user
        # than we need his id.
        if not external:
            params["user_id"] = user.id

    # don't allows direct variable substitution
    for k in params.keys():
        if k[:2].capitalize() == "S_":
            log.warning("Direct substitution not allowed (%s=%s)." % (k, params[k]))
            del params[k]

    mss = get_functionality("mapserver_substitution", request.registry.settings, request)
    if mss:
        for s in mss:
            index = s.find("=")
            if index > 0:
                attribute = "s_" + s[:index]
                value = s[index + 1 :]
                if attribute in params:
                    params[attribute] += "," + value
                else:
                    params[attribute] = value
            else:
                log.warning("Mapserver Substitution '%s' does not " "respect pattern: <attribute>=<value>" % s)

    # get method
    method = request.method

    # we want the browser to cache GetLegendGraphic requests, so
    # we need to know if the current request is a GetLegendGraphic
    # request
    is_glg = False

    # name of the JSON callback (value for the "callback" query string param
    # in the request). None if request has no "callback" param in the query
    # string
    callback = None

    if method == "GET":
        _params = dict((k.lower(), unicode(v).lower()) for k, v in params.iteritems())

        # For GET requests, params are added only if the REQUEST
        # parameter is actually provided.
        if "request" not in _params:
            params = {}  # pragma: no cover
        else:
            # WMS GetLegendGraphic request?
            is_glg = ("service" not in _params or _params["service"] == u"wms") and _params[
                "request"
            ] == u"getlegendgraphic"

        callback = params.get("callback")

    # get query string
    params_encoded = {}
    for k, v in params.iteritems():
        if k == "callback":
            continue
        params_encoded[k] = unicode(v).encode("utf-8")
    query_string = urllib.urlencode(params_encoded)

    # get URL
    _url = request.registry.settings["external_mapserv_url"] if external else request.registry.settings["mapserv_url"]
    _url += "?" + query_string
    log.info("Querying mapserver proxy at URL: %s." % _url)

    # get body
    body = None
    if method in ("POST", "PUT"):
        body = request.body

    # forward request to target (without Host Header)
    http = httplib2.Http()
    h = dict(request.headers)
    if urlparse(_url).hostname != "localhost":
        h.pop("Host")
    # mapserver don't need the cookie, and sometimes it failed with it.
    if "Cookie" in h:
        h.pop("Cookie")
    try:
        resp, content = http.request(_url, method=method, body=body, headers=h)
    except:  # pragma: no cover
        log.error("Error '%s' while getting the URL: %s." % (sys.exc_info()[0], _url))
        if method == "POST":
            log.error("--- With body ---")
            log.error(body)
        return HTTPBadGateway("See logs for details")  # pragma: no cover

    if resp.status != 200:
        log.error(
            "\nError\n '%s'\n in response from URL:\n %s\n " "with query:\n %s" % (resp.reason, _url, body)
        )  # pragma: no cover
        return HTTPInternalServerError("See logs for details")  # pragma: no cover

    # check for allowed content types
    if "content-type" not in resp:
        return HTTPNotAcceptable()  # pragma: no cover

    if method == "POST" and is_get_feature(request.body):
        content = limit_featurecollection(content, limit=200)

    content_type = None
    if callback:
        content_type = "application/javascript"
        # escape single quotes in the JavaScript string
        content = unicode(content.decode("utf8"))
        content = content.replace(u"'", ur"\'")
        content = u"%s('%s');" % (callback, u" ".join(content.splitlines()))
    else:
        content_type = resp["content-type"]

    headers = {"Content-Type": content_type}

    if is_glg:
        # 30min expiration for GetLegendGraphic
        headers.update({"Cache-Control": "public, max-age=1800"})

    return Response(content, status=resp.status, headers=headers)
コード例 #3
0
    def _proxy(self, _url, params, use_cache, method, body, headers):
        # name of the JSON callback (value for the "callback" query string param
        # in the self.request). None if self.request has no "callback" param in the query
        # string
        callback = params.get('callback')

        # get query string
        params_encoded = {}
        for k, v in params.iteritems():
            if k == 'callback':
                continue
            params_encoded[k] = unicode(v).encode('utf-8')
        query_string = urllib.urlencode(params_encoded)

        _url += '?' + query_string
        log.info("Querying mapserver proxy at URL: %s." % _url)

        # forward self.request to target (without Host Header)
        http = httplib2.Http()
        headers = dict(headers)
        if urlparse(_url).hostname != 'localhost':  # pragma: no cover
            headers.pop('Host')
        # mapserver don't need the cookie, and sometimes it failed with it.
        if 'Cookie' in headers:  # pragma: no cover
            headers.pop('Cookie')
        try:
            resp, content = http.request(
                _url, method=method, body=body, headers=headers
            )
        except:  # pragma: no cover
            log.error(
                "Error '%s' while getting the URL: %s." %
                (sys.exc_info()[0], _url))
            if method == "POST":
                log.error("--- With body ---")
                log.error(body)
            return HTTPBadGateway("See logs for details")  # pragma: no cover

        if resp.status != 200:
            log.error("\nError\n '%s'\n in response from URL:\n %s\n "
                      "with query:\n %s" %
                      (resp.reason, _url, body))  # pragma: no cover
            return HTTPInternalServerError(
                "See logs for details")  # pragma: no cover

        # check for allowed content types
        if "content-type" not in resp:
            return HTTPNotAcceptable()  # pragma: no cover

        if method == "POST" and is_get_feature(body) and \
                self.settings.get('enable_limit_featurecollection', True):
            content = limit_featurecollection(
                content,
                limit=self.settings.get('maxfeatures', 200)
            )

        content_type = None
        if callback:
            content_type = "application/javascript"
            # escape single quotes in the JavaScript string
            content = unicode(content.decode('utf8'))
            content = content.replace(u"'", ur"\'")
            content = u"%s('%s');" % (callback, u' '.join(content.splitlines()))
        else:
            content_type = resp["content-type"]

        headers = {"Content-Type": content_type}
        response = Response(content, status=resp.status, headers=headers)

        if use_cache:
            response.cache_control.public = True
            response.cache_control.max_age = self.request.registry.settings["default_max_age"]
        else:
            response.cache_control.no_cache = True

        return response
コード例 #4
0
    def _proxy(self, _url, params, use_cache, method, body, headers):
        # name of the JSON callback (value for the "callback" query string param
        # in the self.request). None if self.request has no "callback" param in the query
        # string
        callback = params.get('callback')

        # get query string
        params_encoded = {}
        for k, v in params.iteritems():
            if k == 'callback':
                continue
            params_encoded[k] = unicode(v).encode('utf-8')
        query_string = urllib.urlencode(params_encoded)

        _url += '?' + query_string
        log.info("Querying mapserver proxy at URL: %s." % _url)

        # forward self.request to target (without Host Header)
        http = httplib2.Http()
        headers = dict(headers)
        if urlparse(_url).hostname != 'localhost':  # pragma: no cover
            headers.pop('Host')
        # mapserver don't need the cookie, and sometimes it failed with it.
        if 'Cookie' in headers:  # pragma: no cover
            headers.pop('Cookie')
        try:
            resp, content = http.request(_url,
                                         method=method,
                                         body=body,
                                         headers=headers)
        except:  # pragma: no cover
            log.error("Error '%s' while getting the URL: %s." %
                      (sys.exc_info()[0], _url))
            if method == "POST":
                log.error("--- With body ---")
                log.error(body)
            return HTTPBadGateway("See logs for details")  # pragma: no cover

        if resp.status != 200:
            log.error("\nError\n '%s'\n in response from URL:\n %s\n "
                      "with query:\n %s" %
                      (resp.reason, _url, body))  # pragma: no cover
            return HTTPInternalServerError(
                "See logs for details")  # pragma: no cover

        # check for allowed content types
        if "content-type" not in resp:
            return HTTPNotAcceptable()  # pragma: no cover

        if method == "POST" and is_get_feature(body) and \
                self.settings.get('enable_limit_featurecollection', True):
            content = limit_featurecollection(content,
                                              limit=self.settings.get(
                                                  'maxfeatures', 200))

        content_type = None
        if callback:
            content_type = "application/javascript"
            # escape single quotes in the JavaScript string
            content = unicode(content.decode('utf8'))
            content = content.replace(u"'", ur"\'")
            content = u"%s('%s');" % (callback, u' '.join(
                content.splitlines()))
        else:
            content_type = resp["content-type"]

        headers = {"Content-Type": content_type}
        response = Response(content, status=resp.status, headers=headers)

        if use_cache:
            response.cache_control.public = True
            response.cache_control.max_age = self.request.registry.settings[
                "default_max_age"]
        else:
            response.cache_control.no_cache = True

        return response
コード例 #5
0
 def test_is_get_feature_not(self):
     from c2cgeoportal.lib.wfsparsing import is_get_feature
     assert not is_get_feature('<is_not>foo</is_not>')
コード例 #6
0
 def test_is_get_feature(self):
     from c2cgeoportal.lib.wfsparsing import is_get_feature
     from c2cgeoportal.tests.xmlstr import getfeature
     assert is_get_feature(getfeature)
コード例 #7
0
 def test_is_get_feature_not(self):
     from c2cgeoportal.lib.wfsparsing import is_get_feature
     assert not is_get_feature('<is_not>foo</is_not>')
コード例 #8
0
 def test_is_get_feature(self):
     from c2cgeoportal.lib.wfsparsing import is_get_feature
     from c2cgeoportal.tests.xmlstr import getfeature
     assert is_get_feature(getfeature)