Skip to content

Commit 8a2b6b1

Browse files
Merge pull request #17 from CreatCodeBuild/dev
~
2 parents e845e15 + d412bc9 commit 8a2b6b1

File tree

2 files changed

+100
-98
lines changed

2 files changed

+100
-98
lines changed

hyper2web/router.py

Lines changed: 89 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,89 @@
1-
import os
2-
3-
from .abstract import AbstractRouter
4-
from .http import HTTP, Stream
5-
6-
7-
class Router(AbstractRouter):
8-
"""User should never construct Router"""
9-
10-
# todo: I may want to change the constructor
11-
def __init__(self, default_get):
12-
self._routes = {
13-
'GET': {},
14-
'POST': {}
15-
}
16-
self.default_get = default_get
17-
18-
def register(self, method: str, route: str, handler):
19-
assert method in ['GET', 'POST'] # 这只是目前为了测试而加的限制
20-
self._routes[method][route] = handler
21-
22-
def find_match(self, path: str):
23-
"""
24-
'user/{userId}' should match 'user/abc'
25-
userId = abc
26-
return a tuple (matched, parameters)
27-
matched is the route which matches the incoming path
28-
parameters is a dict of parameters and their values
29-
"""
30-
# todo: now the problem is how to implement it
31-
# todo: pattern matching should be independent from :method,
32-
# todo: but the current implementation doesn't support it. Should improve it later.
33-
for routes_of_this_method in self._routes.values():
34-
for route in routes_of_this_method:
35-
matched, parameters = self._match(route, path)
36-
# this function returns the first match, not the best match
37-
if matched:
38-
return route, parameters
39-
return None, None
40-
41-
@classmethod
42-
def _match(cls, route, path):
43-
# '/something/xxx/' to 'something/xxx'. Get rid of '/' at the left and the right end of a string
44-
route = route.lstrip('/').rstrip('/').split('/')
45-
path = path.lstrip('/').rstrip('/').split('/')
46-
print(route, path)
47-
if len(route) != len(path):
48-
return False, None
49-
else:
50-
# todo: implement it
51-
parameters = {}
52-
for r, p in zip(route, path):
53-
if r == p == '':
54-
return True, None
55-
if r[0] == '{' and r[-1] == '}':
56-
parameters[r[1:-1]] = p
57-
elif r != p:
58-
return False, None
59-
print('out of for loop')
60-
return True, parameters
61-
62-
# async
63-
async def handle_route(self, http: HTTP, stream: Stream):
64-
print('app.App.handle_route')
65-
66-
path = stream.headers[':path']
67-
method = stream.headers[':method']
68-
69-
route, parameters = self.find_match(path)
70-
71-
# 如果没有任何匹配,就默认为静态文件读取
72-
if route is None:
73-
if method == 'GET':
74-
print('GET')
75-
handler = self.default_get
76-
else:
77-
handler = None
78-
else:
79-
handler = self._routes[method].get(route, None)
80-
81-
if handler is not None:
82-
print('handle')
83-
print(handler)
84-
await handler(http, stream, parameters)
85-
else:
86-
# maybe raise an error?
87-
raise Exception(path, 'is not a valid request path')
1+
import os
2+
3+
from .abstract import AbstractRouter
4+
from .http import HTTP, Stream
5+
6+
7+
class Router(AbstractRouter):
8+
"""User should never construct Router"""
9+
10+
# todo: I may want to change the constructor
11+
def __init__(self, default_get):
12+
self._routes = {
13+
'GET': {},
14+
'POST': {}
15+
}
16+
self.default_get = default_get
17+
18+
def register(self, method: str, route: str, handler):
19+
assert method in ['GET', 'POST'] # 这只是目前为了测试而加的限制
20+
self._routes[method][route] = handler
21+
22+
def find_match(self, path: str):
23+
"""
24+
'user/{userId}' should match 'user/abc'
25+
userId = abc
26+
return a tuple (matched, parameters)
27+
matched is the route which matches the incoming path
28+
parameters is a dict of parameters and their values
29+
"""
30+
# todo: now the problem is how to implement it
31+
# todo: pattern matching should be independent from :method,
32+
# todo: but the current implementation doesn't support it. Should improve it later.
33+
for routes_of_this_method in self._routes.values():
34+
for route in routes_of_this_method:
35+
matched, parameters = self._match(route, path)
36+
# this function returns the first match, not the best match
37+
if matched:
38+
return route, parameters
39+
return None, None
40+
41+
@classmethod
42+
def _match(cls, route, path):
43+
# '/something/xxx/' to 'something/xxx'. Get rid of '/' at the left and the right end of a string
44+
route = route.lstrip('/').rstrip('/').split('/')
45+
path = path.lstrip('/').rstrip('/').split('/')
46+
print(route, path)
47+
if len(route) != len(path):
48+
return False, None
49+
else:
50+
# todo: optimize the logic
51+
parameters = {}
52+
for r, p in zip(route, path):
53+
if r == p == '':
54+
return True, None
55+
if r == '' and r != p:
56+
return False, None
57+
if r[0] == '{' and r[-1] == '}':
58+
parameters[r[1:-1]] = p
59+
elif r != p:
60+
return False, None
61+
print('out of for loop')
62+
return True, parameters
63+
64+
# async
65+
async def handle_route(self, http: HTTP, stream: Stream):
66+
print('app.App.handle_route')
67+
68+
path = stream.headers[':path']
69+
method = stream.headers[':method']
70+
71+
route, parameters = self.find_match(path)
72+
73+
# 如果没有任何匹配,就默认为静态文件读取
74+
if route is None:
75+
if method == 'GET':
76+
print('GET')
77+
handler = self.default_get
78+
else:
79+
handler = None
80+
else:
81+
handler = self._routes[method].get(route, None)
82+
83+
if handler is not None:
84+
print('handle')
85+
print(handler)
86+
await handler(http, stream, parameters)
87+
else:
88+
# maybe raise an error?
89+
raise Exception(path, 'is not a valid request path')

setup.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
from setuptools import setup
2-
3-
setup(
4-
name="hyper2web",
5-
version="0.0.0",
6-
description="Super Fast H2 Backend Framework for Progressive Web App",
7-
url="https://github.com/CreatCodeBuild/hyper2web",
8-
author="CreatCodeBuild@github.com",
9-
package=['hyper2web'],
10-
install_requires=['h2', 'curio']
11-
)
1+
from setuptools import setup
2+
3+
setup(
4+
name="hyper2web",
5+
version="0.0.0",
6+
description="Super Fast H2 Backend Framework for Progressive Web App",
7+
url="https://github.com/CreatCodeBuild/hyper2web",
8+
author="CreatCodeBuild@github.com",
9+
package=['hyper2web'],
10+
install_requires=['h2', 'curio']
11+
)

0 commit comments

Comments
 (0)