-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbasehandler.py
176 lines (141 loc) · 4.18 KB
/
basehandler.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
"""
Usage:
BaseServerHandler:
* self.socket -> the socket for listening
for default, it is a TCP socket with AF_INET(IPv4)
to change the type of the socket, override it
* user add_to_loop() to bind to a eventloop
when the socket is ready, the handle() method called
you have to override the handle() method
BaseRequestHandler:
self.request -> the request
"""
import socket
import logging
from eventloop import POLLNULL, POLLIN, POLLPRI, POLLOUT, POLLERR, \
POLLHUP, POLLNVAL, POLLRDNORM, POLLRDBAND, \
POLLWRBAND, POLLEXTEND, POLLATTRIB, POLLNLINK, POLLWRITE
class BaseServerHandler(object):
"""
have to overridden handle() manully
use:
* initial
* add_to_loop(event_loop)
start when called event_loop.run()
function:
construction: __init__ -> |server_bind(),server_active()
|setup()
call_back func: self.handle()
"""
address_family = socket.AF_INET
socket_type = socket.SOCK_STREAM
allow_reuse_address = True
reuqest_queue_size = 5
def __init__(self, server_addr, RequestHandlerClass, bind_and_active=True):
self.socket = socket.socket(self.address_family, self.socket_type)
self.socket.setblocking(False)
self.server_addr = server_addr
self._loop = None
self.RequestHandlerClass = RequestHandlerClass
if bind_and_active:
self.server_bind()
self.server_active()
self.setup()
def setup(self):
"""
may be overridden
add extra members
called in constructor
"""
pass
def add_to_loop(self, eventloop):
self._bind_eventloop(eventloop)
self._register_to_loop()
def _register_to_loop(self):
self._loop.add(self.socket, POLLIN)
self._loop.bind_handler(self.socket, self.handle)
def handle(self, events):
pass
def _bind_eventloop(self, eventloop):
self._loop = eventloop
def server_bind(self):
if self.allow_reuse_address:
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_addr)
self.server_addr = self.socket.getsockname()
def server_active(self):
# for TCP self.socket.listen(self.reuqest_queue_size)
# for UDP no need to listen
pass
def finish(self):
pass
def verify_request(self, request, addr):
"""
May be overridden
"""
return True
def handle_error(self, request, addr):
"""
May be overridden
"""
pass
def shutdown_request(self, request):
"""
May be overridden
"""
pass
class BaseRequestHandler(object):
def __init__(self, request, client_addr):
self.request = request
self.client_addr = client_addr
try:
self.handle()
finally:
self.finish()
def handle(self):
pass
def finish(self):
pass
def async_process(func):
def w(*args, **kw):
body = args[0]
body.verify_handle()
if not body.err:
f = func(*args, **kw)
else:
return
body.finish()
return f
return w
class BaseAsyncRequestHandler(object):
"""
BaseAsyncRequestHandler
handler for request that no need to reply immediately
reply when handle() called
handle(self,mode) have a parameter "mode" to handle different circumstance
"""
timeout = None
def __init__(self, request, client_addr):
self.request = request
self.connection = self.request
self.client_addr = client_addr
self.remote_server = None
self.err = False
self._setup()
self.setup()
def _setup(self):
if self.timeout is not None:
self.connection.settimeout(self.timeout)
def setup(self):
"""
may be overridden
to add extra members
called manully
"""
pass
def handle(self, mode):
pass
def verify_handle(self):
return True
def finish(self):
pass