This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
mandaye/mandaye/dispatchers/default.py

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