Commit 9d66fc4b authored by Tatsuhiro Tsujikawa's avatar Tatsuhiro Tsujikawa

python: wrap socket in overridden process_request.

parent e2083055
...@@ -1235,7 +1235,7 @@ try: ...@@ -1235,7 +1235,7 @@ try:
def send_cb(self, session, data): def send_cb(self, session, data):
return self.sslsock.send(data) return self.request.send(data)
def read_cb(self, session, stream_id, length, read_ctrl, source): def read_cb(self, session, stream_id, length, read_ctrl, source):
data = source.read(length) data = source.read(length)
...@@ -1277,65 +1277,54 @@ try: ...@@ -1277,65 +1277,54 @@ try:
def handle(self): def handle(self):
self.request.setsockopt(socket.IPPROTO_TCP, self.request.setsockopt(socket.IPPROTO_TCP,
socket.TCP_NODELAY, True) socket.TCP_NODELAY, True)
# TODO We need to call handshake manually because 3.3.0b2 try:
# crashes if do_handshake_on_connect=True self.request.do_handshake()
self.sslsock = self.server.ctx.wrap_socket(\ self.request.setblocking(False)
self.request,
server_side=True, version = npn_get_version(self.request.selected_npn_protocol())
do_handshake_on_connect=False) if version == 0:
return
self.sslsock.setblocking(False)
self.ssctrl = SessionCtrl()
while True: self.session = Session(\
try: SERVER, version,
self.sslsock.do_handshake() send_cb=self.send_cb,
break on_ctrl_recv_cb=self.on_ctrl_recv_cb,
except ssl.SSLWantReadError as e: on_data_chunk_recv_cb=self.on_data_chunk_recv_cb,
select.select([self.sslsock], [], []) on_stream_close_cb=self.on_stream_close_cb,
except ssl.SSLWantWriteError as e: on_request_recv_cb=self.on_request_recv_cb)
select.select([], [self.sslsock], [])
self.session.submit_settings(\
version = npn_get_version(self.sslsock.selected_npn_protocol()) FLAG_SETTINGS_NONE,
if version == 0: [(SETTINGS_MAX_CONCURRENT_STREAMS, ID_FLAG_SETTINGS_NONE,
return 100)]
)
self.ssctrl = SessionCtrl()
self.session = Session(\ while self.session.want_read() or self.session.want_write():
SERVER, version, want_read = want_write = False
send_cb=self.send_cb, try:
on_ctrl_recv_cb=self.on_ctrl_recv_cb, data = self.request.recv(4096)
on_data_chunk_recv_cb=self.on_data_chunk_recv_cb, if data:
on_stream_close_cb=self.on_stream_close_cb, self.session.recv(data)
on_request_recv_cb=self.on_request_recv_cb) else:
break
self.session.submit_settings(\ except ssl.SSLWantReadError:
FLAG_SETTINGS_NONE, want_read = True
[(SETTINGS_MAX_CONCURRENT_STREAMS, ID_FLAG_SETTINGS_NONE, 100)] except ssl.SSLWantWriteError:
) want_write = True
try:
while self.session.want_read() or self.session.want_write(): self.session.send()
want_read = want_write = False except ssl.SSLWantReadError:
try: want_read = True
data = self.sslsock.recv(4096) except ssl.SSLWantWriteError:
if data: want_write = True
self.session.recv(data)
else: if want_read or want_write:
break select.select([self.request] if want_read else [],
except ssl.SSLWantReadError: [self.request] if want_write else [],
want_read = True [])
except ssl.SSLWantWriteError: finally:
want_write = True self.request.setblocking(True)
try:
self.session.send()
except ssl.SSLWantReadError:
want_read = True
except ssl.SSLWantWriteError:
want_write = True
if want_read or want_write:
select.select([self.sslsock] if want_read else [],
[self.sslsock] if want_write else [],
[])
# The following methods and attributes are copied from # The following methods and attributes are copied from
# Lib/http/server.py of cpython source code # Lib/http/server.py of cpython source code
...@@ -1463,6 +1452,18 @@ try: ...@@ -1463,6 +1452,18 @@ try:
server_thread.daemon = daemon server_thread.daemon = daemon
server_thread.start() server_thread.start()
def process_request(self, request, client_address):
# ThreadingMixIn.process_request() dispatches request and
# client_address to separate thread. To cleanly shutdown
# SSL/TLS wrapped socket, we wrap socket here.
# SSL/TLS handshake is postponed to each thread.
request = self.ctx.wrap_socket(\
request, server_side=True, do_handshake_on_connect=False)
socketserver.ThreadingMixIn.process_request(self,
request, client_address)
except ImportError: except ImportError:
# No server for 2.x because they lack TLS NPN. # No server for 2.x because they lack TLS NPN.
pass pass
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment