Тем не менее, для очень скромного личного проекта я реализовал свой собственный класс, производный от http.server.BaseHTTPRequestHandler, в котором я переопределил метод do_GET. Все работало правильно, пока я не обновил версию Python до 3.12: кажется, эта версия также внесла некоторые изменения в модуль ssl, поэтому мне пришлось немного реорганизовать код.
В этом отношении это сжатое содержимое файла main.py:
Код: Выделить всё
# ...here are import statements and other functions...
class RequestHandler(BaseHTTPRequestHandler):
# ...here the other methods are defined...
def do_GET(self):
resobj = self._manage_get_request()
self.send_response(resobj.status_code)
self._send_headers(resobj.headers)
self._send_body(resobj.body)
def main():
print('Running http server...')
address = (_HTTP_SERV_ADDR, _HTTP_SERV_PORT)
httpd = HTTPServer(address, RequestHandler)
if not _DEBUG_ENABLED:
print('Enabling TLS protocol...')
context = _ssl.SSLContext(_ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile=_CERTIFICATE_FILE_PATH,
keyfile=_KEY_FILE_PATH)
httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
print(f'Server is listening ({httpd.server_address[0]}:{httpd.server_port})...')
try:
httpd.serve_forever()
except KeyboardInterrupt:
pass
print('Shutting down http server...')
httpd.server_close()
Не мог бы кто-нибудь из вас предоставить мне что-нибудь подскажет, что проверить, чтобы лучше понять, что происходит и почему?
Дополнительная информация по реализации
Хотя send_response уже определен в BaseHTTPRequestHandler, остальные методы, вызываемые в do_GET, определены в моей реализации. В частности:
- — это своего рода оператор if для правильного управления запросом с учетом параметров, предоставленных через запрос; он возвращает пользовательский объект Response с кодом, заголовками и телом
Код: Выделить всё
_manage_get_request - по сути является оболочкой метода send_header родительского класса
Код: Выделить всё
_send_headers - просто записывает тело ответа в буфер сокета.
Код: Выделить всё
_send_body
После того как я задал этот вопрос, я попробовал несколько изменений в коде, но на самом деле ни одно из них не решило проблему.
Итак, я решил реализовать скромный декоратор для отслеживания стека вызовов функций. С помощью этого небольшого инструмента я заметил, что код висит внутри метода get_request класса TCPServer, где принимается новое TCP-соединение:
Код: Выделить всё
[...]
----- Calling BaseServer.service_actions on 2025-01-05 15:59:15.092364 -----
BaseServer.service_actions execution ended after 0:00:00.000015
----- Calling BaseServer._handle_request_noblock on 2025-01-05 15:59:15.282698 -----
----- Calling TCPServer.get_request on 2025-01-05 15:59:15.282869 -----
Код: Выделить всё
class TimeoutException(BaseException):
pass
def alarm_handler(signum, frame):
print('Timeout reached!')
raise TimeoutException
def get_request(self):
# Overwrite method of TCPServer class...
_signal.signal(_signal.SIGALRM, alarm_handler)
_signal.alarm(30)
try:
result = self.socket.accept()
_signal.alarm(0)
return result
except TimeoutException as e:
_signal.alarm(0)
raise OSError from e # OSError is already managed by caller...
Тем не менее, может ли кто-нибудь из вас объяснить, каковы возможные причины этой проблемы и как ее решить? Рассматриваемое приложение работает внутри образа Docker, полученного из ubuntu:latest.
Подробнее здесь: https://stackoverflow.com/questions/793 ... n-https-is
Мобильная версия