def invoke(url): if isinstance(url, str): try: url.decode('utf8') except UnicodeDecodeError: raise Http400BadRequest request = local.request response = local.response path, qlist = httputils.split_url(url) if path[:1] == ['static'] and len(path) > 1: return get_static_file(path[1:]) if path[:2] == ['pony', 'static'] and len(path) > 2: return get_static_file(path[2:], pony_static_dir, 30*60) qdict = dict(qlist) routes = routing.get_routes(path, qdict, request.method, request.host, request.port) if routes: pass elif request.method in ('GET', 'HEAD'): i = url.find('?') if i == -1: p, q = url, '' else: p, q = url[:i], url[i:] if p.endswith('/'): url2 = p[:-1] + q else: url2 = p + '/' + q path2, qlist = httputils.split_url(url2) routes = routing.get_routes(path2, qdict, request.method, request.host, request.port) if not routes: return get_static_file(path) script_name = request.environ.get('SCRIPT_NAME', '') url2 = script_name + url2 or '/' if url2 != script_name + url: raise HttpRedirect(url2) else: routes = routing.get_routes(path, qdict, 'GET', request.host, request.port) if routes: raise Http405MethodNotAllowed raise Http404NotFound route, args, kwargs = routes[0] if route.redirect: for alternative in route.func.routes: if not alternative.redirect: new_url = make_url(route.func, *args, **kwargs) status = '301 Moved Permanently' if isinstance(route.redirect, basestring): status = route.redirect elif isinstance(route.redirect, (int, long)) and 300 <= route.redirect < 400: status = str(route.redirect) raise HttpRedirect(new_url, status) response.headers.update(route.headers) names, argsname, keyargsname, defaults, converters = route.func.argspec params = request.params params.update(izip(names, args)) params.update(kwargs) middlewared_func = middleware.decorator_wrap(normalize_result_decorator(route.func)) result = middlewared_func(*args, **kwargs) headers = response.headers headers.setdefault('Expires', '0') max_age = headers.pop('Max-Age', '2') cache_control = headers.get('Cache-Control') if not cache_control: headers['Cache-Control'] = 'max-age=%s' % max_age headers.setdefault('Vary', 'Cookie') return result
def __init__(route, func, url, method, host, port, redirect, headers): url_cache.clear() route.func = func module = func.__module__ route.system = module.startswith( 'pony.') and not module.startswith('pony.examples.') argspec = getattr(func, 'argspec', None) if argspec is None: argspec = func.argspec = route.getargspec(func) func.dummy_func = route.create_dummy_func(func) if url is not None: route.url = url elif argspec[1] is not None: raise TypeError('Not supported: *%s' % argspec[1]) elif argspec[2] is not None: raise TypeError('Not supported: **%s' % argspec[2]) else: url = func.__name__ if argspec[0]: url = '?'.join((url, '&'.join('=$'.join((argname, argname)) for argname in argspec[0]))) route.url = url if method is not None and method not in ('HEAD', 'GET', 'POST', 'PUT', 'DELETE'): raise TypeError('Invalid HTTP method: %r' % method) route.method = method if host is not None: if not isinstance(host, basestring): raise TypeError('Host must be string') if ':' in host: if port is not None: raise TypeError('Duplicate port specification') host, port = host.split(':') route.host = host route.port = int(port) if port else None route.path, route.qlist = split_url(url, strict_parsing=True) route.redirect = redirect route.headers = dict([(name.replace('_', '-').title(), value) for name, value in headers.items()]) route.args = set() route.kwargs = set() route.parsed_path = [] route.star = False for component in route.path: if route.star: raise TypeError("'$*' must be last element in url path") elif component != '$*': route.parsed_path.append(route.parse_component(component)) else: route.star = True route.parsed_query = [] for name, value in route.qlist: if value == '$*': raise TypeError("'$*' does not allowed in query part of url") is_param, x = route.parse_component(value) route.parsed_query.append((name, is_param, x)) route.check() route.register()
def remove(x, method=None, host=None, port=None): if isinstance(x, basestring): path, qlist = split_url(x, strict_parsing=True) qdict = dict(qlist) with registry_lock: for route, _, _ in get_routes(path, qdict, method, host, port): _remove(route) elif hasattr(x, 'routes'): assert host is None and port is None with registry_lock: for route in list(x.routes): _remove(route) else: raise ValueError('This object is not bound to url: %r' % x)
def __init__(route, func, url, method, host, port, redirect, headers): url_cache.clear() route.func = func module = func.__module__ route.system = module.startswith('pony.') and not module.startswith('pony.examples.') argspec = getattr(func, 'argspec', None) if argspec is None: argspec = func.argspec = route.getargspec(func) func.dummy_func = route.create_dummy_func(func) if url is not None: route.url = url elif argspec[1] is not None: raise TypeError('Not supported: *%s' % argspec[1]) elif argspec[2] is not None: raise TypeError('Not supported: **%s' % argspec[2]) else: url = func.__name__ if argspec[0]: url = '?'.join((url, '&'.join('=$'.join((argname, argname)) for argname in argspec[0]))) route.url = url if method is not None and method not in ('HEAD', 'GET', 'POST', 'PUT', 'DELETE'): raise TypeError('Invalid HTTP method: %r' % method) route.method = method if host is not None: if not isinstance(host, basestring): raise TypeError('Host must be string') if ':' in host: if port is not None: raise TypeError('Duplicate port specification') host, port = host.split(':') route.host = host route.port = int(port) if port else None route.path, route.qlist = split_url(url, strict_parsing=True) route.redirect = redirect route.headers = dict([ (name.replace('_', '-').title(), value) for name, value in headers.items() ]) route.args = set() route.kwargs = set() route.parsed_path = [] route.star = False for component in route.path: if route.star: raise TypeError("'$*' must be last element in url path") elif component != '$*': route.parsed_path.append(route.parse_component(component)) else: route.star = True route.parsed_query = [] for name, value in route.qlist: if value == '$*': raise TypeError("'$*' does not allowed in query part of url") is_param, x = route.parse_component(value) route.parsed_query.append((name, is_param, x)) route.check() route.register()
def invoke(url): if isinstance(url, str): try: url.decode('utf8') except UnicodeDecodeError: raise Http400BadRequest request = local.request response = local.response path, qlist = httputils.split_url(url) if path[:1] == ['static'] and len(path) > 1: return get_static_file(path[1:]) if path[:2] == ['pony', 'static'] and len(path) > 2: return get_static_file(path[2:], pony_static_dir, 30 * 60) qdict = dict(qlist) routes = routing.get_routes(path, qdict, request.method, request.host, request.port) if routes: pass elif request.method in ('GET', 'HEAD'): i = url.find('?') if i == -1: p, q = url, '' else: p, q = url[:i], url[i:] if p.endswith('/'): url2 = p[:-1] + q else: url2 = p + '/' + q path2, qlist = httputils.split_url(url2) routes = routing.get_routes(path2, qdict, request.method, request.host, request.port) if not routes: return get_static_file(path) script_name = request.environ.get('SCRIPT_NAME', '') url2 = script_name + url2 or '/' if url2 != script_name + url: raise HttpRedirect(url2) else: routes = routing.get_routes(path, qdict, 'GET', request.host, request.port) if routes: raise Http405MethodNotAllowed raise Http404NotFound route, args, kwargs = routes[0] if route.redirect: for alternative in route.func.routes: if not alternative.redirect: new_url = make_url(route.func, *args, **kwargs) status = '301 Moved Permanently' if isinstance(route.redirect, basestring): status = route.redirect elif isinstance(route.redirect, (int, long)) and 300 <= route.redirect < 400: status = str(route.redirect) raise HttpRedirect(new_url, status) response.headers.update(route.headers) names, argsname, keyargsname, defaults, converters = route.func.argspec params = request.params params.update(izip(names, args)) params.update(kwargs) middlewared_func = middleware.decorator_wrap( normalize_result_decorator(route.func)) result = middlewared_func(*args, **kwargs) headers = response.headers headers.setdefault('Expires', '0') max_age = headers.pop('Max-Age', '2') cache_control = headers.get('Cache-Control') if not cache_control: headers['Cache-Control'] = 'max-age=%s' % max_age headers.setdefault('Vary', 'Cookie') return result