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)
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)
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
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
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>')
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)