Как transpot в asyncio.Protocol задать timeout
Пишу на Asyncio SSL сервер с обработкой N одновременных запросов.
Если запрос корректный с body, то все отрабатывает как надо.
Если запрос намерено сгенерирован с ошибкой, то сервер ожидая приема данных при превышении N блокирует поступление новых запросов.
Как настроить транспорт, чтобы от отбивал по таймауту? Или посоветуйте как обрабатывать keep-alive.
Код сервера:
import asyncio
import ssl
import socket
import re
import threading
class EchoServerProtocol(asyncio.Protocol):
def __init__(self):
self.transport = None
self.datas = None
def connection_made(self, transport):
peername = transport.get_extra_info('peername')
print('Connection from {}'.format(peername))
self.transport = transport
self.datas = ""
def data_received(self, data):
message = data.decode()
print('Data received: {!r}'.format(message))
if "connection: keep-alive" in message.lower():
if re.findall(r'content-length: (\d+)', message.lower()):
self.datas += message
else:
self.datas += message
sem.acquire()
answer = f"HTTP/1.1 200 OK\r\n\r\n"
print('Send: {!r}'.format(answer))
self.transport.write(answer.encode())
print('Close the client socket')
self.transport.close()
sem.release()
async def main():
sem = threading.Semaphore(value=5)
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ssl_context.load_cert_chain(certfile="config/ca_self_signed.crt",
keyfile="config/ca_private.key")
ssl_context.check_hostname = False
socket.setdefaulttimeout(10)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_context.wrap_socket(sock=sock, server_side=False, do_handshake_on_connect=True, suppress_ragged_eofs=True, server_hostname='localhost')
ssl_context.check_hostname = False
loop = asyncio.get_running_loop()
server = await loop.create_server(lambda: EchoServerProtocol(),
host='localhost',
port=8888,
ssl=ssl_context,
)
async with server:
await server.serve_forever()
asyncio.run(main())
Запрос клиента:
session = requests.Session()
response = session.get('https://localhost:8888/',
headers={'Connection': 'keep-alive', 'Content-Length': '136'},
verify='config/ca_self_signed.crt')