120 lines
4.8 KiB
Python
120 lines
4.8 KiB
Python
import logging
|
|
|
|
from urlparse import urlparse
|
|
|
|
from mandaye.filters.default import MandayeFilter
|
|
from mandaye.response import _502
|
|
|
|
# TODO: add an external url mapping
|
|
|
|
class Dispatcher(object):
|
|
""" The dispatcher is the main class of Mandaye
|
|
It allows you to launch the right filter on the reqest and the response
|
|
"""
|
|
|
|
def __init__(self, target_url, mapping=None):
|
|
""" target_url: the full url of your destination
|
|
"""
|
|
self.target = urlparse(target_url)
|
|
self.env = None
|
|
self.mapping = mapping
|
|
|
|
def init(self, env):
|
|
self.env = env
|
|
self.env['target'] = self.target
|
|
self.filter = MandayeFilter(self.env, self.target)
|
|
path = self.env['PATH_INFO']
|
|
if self.mapping and \
|
|
self.mapping.has_key(path) and \
|
|
self.mapping[path].has_key('method') and \
|
|
self.mapping[path]['method'] == self.env['REQUEST_METHOD']:
|
|
self.req_mapping = self.mapping[path]
|
|
else:
|
|
self.req_mapping = None
|
|
|
|
def _call_dispatcher_hook(self, hookname, *args):
|
|
if not self.req_mapping:
|
|
return None
|
|
hook = self.req_mapping.get(hookname)
|
|
if hook and hook.has_key('dispatcher_method'):
|
|
try:
|
|
method = getattr(self, hook['dispatcher_method'])
|
|
except AttributeError:
|
|
logging.warning('%s: Invalid dispatcher method for hook %s' % \
|
|
(self.env['PATH_INFO'], hookname))
|
|
else:
|
|
values = hook.get('values')
|
|
if not values:
|
|
values = dict()
|
|
return method(values, *args)
|
|
return None
|
|
|
|
def get_target_url(self):
|
|
""" Return the destination url
|
|
"""
|
|
# Disable reverse proxy if we have a static response
|
|
if self.req_mapping and self.req_mapping.has_key('response'):
|
|
return None
|
|
# TODO: manage redirect here
|
|
url = self.target.geturl() + self.env['PATH_INFO']
|
|
if self.env['QUERY_STRING']:
|
|
return url + "?" + self.env['QUERY_STRING']
|
|
else:
|
|
return url
|
|
|
|
def get_response(self, request):
|
|
""" Called if you have a response hook for this request
|
|
"""
|
|
response = self._call_dispatcher_hook('response', request)
|
|
if not response:
|
|
return _500("The response dispatcher hook failed for URL %s" %\
|
|
self.env["PATH_INFO"])
|
|
return response
|
|
|
|
def mod_request(self, request):
|
|
""" Modify the request
|
|
request: MandayeRequest object with cookies and headers
|
|
Return the request object """
|
|
# Loading defaults filters
|
|
request.headers = self.filter.request_headers(request.headers)
|
|
request.cookies = self.filter.request_cookies(request.cookies)
|
|
request.msg = self.filter.request_msg(request.msg)
|
|
# Loading specific filters
|
|
if self.req_mapping and self.req_mapping.has_key('on_request_filters'):
|
|
for filter in self.req_mapping['on_request_filters']:
|
|
if filter['type'] == "data":
|
|
request.msg = filter['filter'](request.msg, self.env)
|
|
elif filter['type'] == "cookies":
|
|
request.cookies = filter['filter'](request.cookies, self.env)
|
|
elif filter['type'] == "headers":
|
|
request.headers = filter['filter'](request.headers, self.env)
|
|
# Calling hook function
|
|
new_request = self._call_dispatcher_hook('on_request_hook', request)
|
|
if new_request:
|
|
return new_request
|
|
return request
|
|
|
|
def mod_response(self, request, response):
|
|
""" Modify the response
|
|
request: the Mandaye request
|
|
response: MandayeResponse object with cookies, headers and HTML
|
|
you can modify the cookies and the HTTP headers """
|
|
# Loading defaults filters
|
|
response.headers = self.filter.response_headers(response.headers)
|
|
response.cookies = self.filter.response_cookies(response.cookies)
|
|
response.msg = self.filter.response_msg(response.msg)
|
|
# Loading specific filters
|
|
if self.req_mapping and self.req_mapping.has_key('on_response_filters'):
|
|
for filter in self.req_mapping['on_response_filters']:
|
|
if filter['type'] == "data":
|
|
response.msg = filter['filter'](response.msg, self.env)
|
|
elif filter['type'] == "cookies":
|
|
response.cookies = filter['filter'](response.cookies, self.env)
|
|
elif filter['type'] == "headers":
|
|
response.headers = filter['filter'](response.headers, self.env)
|
|
new_response = self._call_dispatcher_hook('on_response_hook', request, response)
|
|
if new_response:
|
|
return new_response
|
|
return response
|
|
|