Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cheroot/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -1888,7 +1888,7 @@ def _serve_unservicable(self):
# We can't just raise an exception because that will kill this
# thread, and prevent 503 errors from being sent to future
# connections.
self.server.error_log(
self.error_log(
repr(ex),
level=logging.ERROR,
traceback=True,
Expand Down
55 changes: 54 additions & 1 deletion cheroot/test/test_server.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Tests for the HTTP server."""

import logging
import os
import pathlib
import queue
Expand All @@ -20,7 +21,12 @@
from pypytools.gc.custom import DefaultGc

from .._compat import IS_LINUX, IS_MACOS, IS_WINDOWS, SYS_PLATFORM, bton, ntob
from ..server import IS_UID_GID_RESOLVABLE, Gateway, HTTPServer
from ..server import (
_STOPPING_FOR_INTERRUPT,
IS_UID_GID_RESOLVABLE,
Gateway,
HTTPServer,
)
from ..testing import (
ANY_INTERFACE_IPV4,
ANY_INTERFACE_IPV6,
Expand Down Expand Up @@ -127,6 +133,53 @@ def test_stop_interrupts_serve():
assert not serve_thread.is_alive()


def test_serve_unservicable_logs_simple_response_errors(monkeypatch):
"""Check errors while sending 503 responses are logged by the server."""
error_log_calls = []

class BrokenRequest:
def __init__(self, server, conn):
self.server = server
self.conn = conn

def simple_response(self, status):
assert status == '503 Service Unavailable'
raise RuntimeError('response failed')

class FakeConnection:
linger = False

def __init__(self):
self.closed = False

def close(self):
self.closed = True

def error_log(msg='', level=20, traceback=False):
error_log_calls.append((msg, level, traceback))

httpserver = HTTPServer(
bind_addr=(ANY_INTERFACE_IPV4, EPHEMERAL_PORT),
gateway=Gateway,
)
httpserver.ready = True
httpserver.error_log = error_log

fake_conn = FakeConnection()
httpserver._unservicable_conns.put(fake_conn)
httpserver._unservicable_conns.put(_STOPPING_FOR_INTERRUPT)

monkeypatch.setattr('cheroot.server.HTTPRequest', BrokenRequest)

httpserver._serve_unservicable()

assert error_log_calls == [
("RuntimeError('response failed')", logging.ERROR, True),
]
assert fake_conn.linger
assert fake_conn.closed


@pytest.mark.parametrize(
'exc_cls',
(
Expand Down
Loading