fix: keep server.py under the 750-line guard after auth-reject close
Move the close-on-reject decision into api.auth.check_auth_or_close so the added lines land outside server.py, restoring it to 749 lines. Trim the inline comment to a one-line docstring on the helper, per review feedback. The rejected-write connection-close test now patches api.auth.check_auth (the dependency the helper calls) instead of server.check_auth.
This commit is contained in:
1 parent
11f6b31d12
commit
6a8011f983
3 files changed
+12
-8
No files matched your search
@@ -1207,6 +1207,14 @@ def check_auth(handler, parsed) -> bool:
|
||||
return False
|
||||
|
||||
|
||||
def check_auth_or_close(handler, parsed) -> bool:
|
||||
"""Check auth; close the connection when rejected so an unread body can't poison HTTP/1.1 reuse."""
|
||||
if not check_auth(handler, parsed):
|
||||
handler.close_connection = True
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def _is_loopback(addr: str) -> bool:
|
||||
"""Return True if *addr* is a loopback address (127.x.x.x, ::1, or ::ffff:127.x.x.x)."""
|
||||
import ipaddress as _ipaddress
|
||||
|
||||
@@ -100,7 +100,7 @@ from urllib.parse import urlparse
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
from api.request_logging import emit_request_log
|
||||
from api.auth import check_auth, reset_trusted_auth_request_state
|
||||
from api.auth import check_auth, check_auth_or_close, reset_trusted_auth_request_state
|
||||
from api.config import HOST, PORT, STATE_DIR, SESSION_DIR, DEFAULT_WORKSPACE
|
||||
from api.helpers import (
|
||||
j,
|
||||
@@ -404,12 +404,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
_is_csp_report_post = (
|
||||
parsed.path == "/api/csp-report" and self.command == "POST"
|
||||
)
|
||||
if not _is_csp_report_post and not check_auth(self, parsed):
|
||||
# Authentication can reject an unsafe request before its body is
|
||||
# consumed. Reusing that HTTP/1.1 connection would make the
|
||||
# unread body prefix the next request line.
|
||||
self.close_connection = True
|
||||
return
|
||||
if not _is_csp_report_post and not check_auth_or_close(self, parsed): return
|
||||
result = route_func(self, parsed)
|
||||
if result is False:
|
||||
return j(self, {'error': 'not found'}, status=404)
|
||||
|
||||
@@ -10,6 +10,7 @@ from typing import Any, cast
|
||||
|
||||
|
||||
def test_auth_rejected_write_closes_connection(monkeypatch):
|
||||
import api.auth as auth
|
||||
import server
|
||||
|
||||
handler = SimpleNamespace(
|
||||
@@ -20,7 +21,7 @@ def test_auth_rejected_write_closes_connection(monkeypatch):
|
||||
monkeypatch.setattr(server, "reset_trusted_auth_request_state", lambda _handler: None)
|
||||
monkeypatch.setattr(server, "get_profile_cookie", lambda _handler: None)
|
||||
monkeypatch.setattr(server, "clear_request_profile", lambda: None)
|
||||
monkeypatch.setattr(server, "check_auth", lambda _handler, _parsed: False)
|
||||
monkeypatch.setattr(auth, "check_auth", lambda _handler, _parsed: False)
|
||||
|
||||
def route_must_not_run(_handler, _parsed):
|
||||
raise AssertionError("route ran after auth rejection")
|
||||
|
||||
Reference in new issue
Block a user