X-Git-Url: https://code.kerkeslager.com/?a=blobdiff_plain;f=src%2Ffwx%2F__init__.py;h=e0abb7523994c58847b1ee6501fcbb6299aacae4;hb=add99327a18a300ff26d64759921fc0f6847a07b;hp=411c07761b02dd177e1919a665b35ccd6ead9cc1;hpb=1b9f0c47a6e4ef0d19c652d6476923f6e437b28c;p=fwx diff --git a/src/fwx/__init__.py b/src/fwx/__init__.py index 411c077..e0abb75 100644 --- a/src/fwx/__init__.py +++ b/src/fwx/__init__.py @@ -8,6 +8,7 @@ _Request = collections.namedtuple( ( 'env', 'GET', + 'POST', 'accept', 'accept_encoding', 'accept_language', @@ -24,7 +25,10 @@ _Request = collections.namedtuple( ) class Request(_Request): - def __new__(cls, env): + def __new__(cls, method, path, env=None): + if env is None: + env = {} + errors = [] accept = env.get('HTTP_ACCEPT') @@ -32,8 +36,6 @@ class Request(_Request): accept_language = env.get('HTTP_ACCEPT_LANGUAGE') content = env.get('CONTENT', '') content_type = env.get('CONTENT_TYPE') - method = env.get('REQUEST_METHOD') - path = env.get('PATH_INFO') query = env.get('QUERY_STRING') user_agent = env.get('HTTP_USER_AGENT') @@ -53,20 +55,39 @@ class Request(_Request): except: cookie = http.cookies.SimpleCookie() - try: GET = urllib.parse.parse_qs(query) except: GET = {} errors.append('Unable to parse GET parameters from query string "{}"'.format(query)) + if method == 'POST': + try: + if content_type == 'application/x-www-form-urlencoded': + POST = urllib.parse.parse_qs(content) + else: + POST = {} + errors.append('Unable to parse POST parameters from content string "{}"'.format(content)) + + except: + POST = {} + errors.append('Unable to parse POST parameters from content string "{}"'.format(content)) + + else: + POST = {} + if method == 'GET': parameters = GET + elif method == 'POST': + parameters = POST + else: + parameters = None result = super().__new__( cls, env=env, GET=GET, + POST=POST, accept=accept, accept_encoding=accept_encoding, accept_language=accept_language, @@ -81,9 +102,18 @@ class Request(_Request): user_agent=user_agent, ) - result.subpath = path + if path.startswith('/'): + result.subpath = path[1:] + else: + result.subpath = path + return result +def _get_request_from_env(env): + method = env.get('REQUEST_METHOD') + path = env.get('PATH_INFO') + return Request(method, path, env) + _Response = collections.namedtuple( 'Response', ( @@ -191,6 +221,38 @@ class RedirectResponse(_RedirectResponse): def content(self): return (b'',) +def default_file_not_found_handler(request): + return TextResponse( + 'Path "{}" with query "{}" not found'.format(request.path, request.query), + status=404, + ) + +def route_on_subpath(**kwargs): + routes = kwargs.pop('routes') + file_not_found_handler = kwargs.pop( + 'file_not_found_handler', + default_file_not_found_handler, + ) + + if routes is None: + raise Exception('Keyword argument "routes" is required') + + if len(kwargs) > 0: + raise Exception('Unexpected keyword argument') + + def wrapped(request): + split_subpath = request.subpath.split('/', 1) + subpath = split_subpath[0] + + if len(split_subpath) == 2: + request.subpath = split_subpath[1] + else: + request.subpath = '' + + return routes.get(subpath, file_not_found_handler)(request) + + return wrapped + REQUEST_METHODS = ( 'GET', 'HEAD', @@ -258,7 +320,7 @@ def _get_content(response): def App(handler): def app(env, start_fn): - response = handler(Request(env)) + response = handler(_get_request_from_env(env)) start_fn(_get_status(response), _get_headers(response)) return _get_content(response)