示例#1
0
文件: web.py 项目: buhtigexa/Nerit
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
示例#2
0
 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()
示例#3
0
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)
示例#4
0
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)
示例#5
0
 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()
示例#6
0
文件: web.py 项目: buhtigexa/Nerit
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