/
handler.py
136 lines (98 loc) · 3.68 KB
/
handler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
from httptools import HttpRequestParser, HttpResponseParser
from .protocol import BaseProtocol
from abc import abstractmethod
from typing import Union, Type
from .types import URL
from .exceptions import StatusRequest, UnknownRequest
import re
PARSERS_CLASSES = Union[Type[HttpRequestParser], Type[HttpResponseParser]]
class BaseHandler:
def __init__(self, parser_cls: PARSERS_CLASSES):
self.parser = parser_cls(self)
self.is_done = False
@abstractmethod
def on_message_begin(self):
pass
def on_status(self, status: bytes):
pass
def on_url(self, url: bytes):
pass
@abstractmethod
def on_header(self, name: bytes, value: bytes):
pass
@abstractmethod
def on_headers_complete(self):
pass
@abstractmethod
def on_body(self, body: bytes):
pass
def on_message_complete(self):
self.is_done = True
@abstractmethod
def on_chunk_header(self):
pass
@abstractmethod
def on_chunk_complete(self):
pass
def feed(self, data: bytes):
self.parser.feed_data(data)
class RequestHandler(BaseHandler):
def __init__(self, protocol: BaseProtocol):
super().__init__(HttpRequestParser)
self.protocol = protocol
self.buffer = bytes()
def on_message_begin(self):
self.protocol.on_request_message_begin()
def on_url(self, url: bytes):
self.protocol.request.url = URL(url)
self.protocol.request.method = self.parser.get_method().decode()
path = self.protocol.request.url.path
method = self.protocol.request.method
search_pattern = self.protocol.SEARCH_PATH
search_methods = self.protocol.SEARCH_METHODS
status_pattern = self.protocol.STATUS_PATH
status_methods = self.protocol.STATUS_METHODS
if re.match(search_pattern, path) and method in search_methods:
pass
elif re.match(status_pattern, path) and method in status_methods:
raise StatusRequest
else:
raise UnknownRequest
self.protocol.on_request_url_and_method()
def on_header(self, name: bytes, value: bytes):
self.protocol.on_request_header(name.decode(), value.decode())
def on_headers_complete(self):
self.protocol.on_request_headers_complete()
def on_body(self, body: bytes):
self.protocol.on_request_body(body)
def on_message_complete(self):
self.protocol.on_request_message_complete()
super().on_message_complete()
def on_chunk_header(self):
self.protocol.on_request_chunk_header()
def on_chunk_complete(self):
self.protocol.on_request_chunk_complete()
def feed(self, data: bytes):
self.buffer += data
super().feed(data)
class ResponseHandler(BaseHandler):
def __init__(self, protocol: BaseProtocol):
super().__init__(HttpResponseParser)
self.protocol = protocol
def on_message_begin(self):
self.protocol.on_response_message_begin()
def on_status(self, status: bytes):
self.protocol.on_response_status(self.parser.get_status_code())
def on_header(self, name: bytes, value: bytes):
self.protocol.on_response_header(name.decode(), value.decode())
def on_headers_complete(self):
self.protocol.on_response_headers_complete()
def on_body(self, body: bytes):
self.protocol.on_response_body(body)
def on_message_complete(self):
self.protocol.on_response_message_complete()
super().on_message_complete()
def on_chunk_header(self):
self.protocol.on_response_chunk_header()
def on_chunk_complete(self):
self.protocol.on_response_chunk_complete()