Skip to content

Commit 163c31b

Browse files
committed
Remove WSGI layer entirely
Delete WSGIHandler, WSGIRequest, and the plain.wsgi entry point. Remove dead WSGI helpers (base_environ, default_environ, create, WSGIErrorsWrapper, headers_to_wsgi_environ, unquote_to_wsgi_str). Rename server/http/wsgi.py to server/http/response.py. Server now loads BaseHandler directly.
1 parent bed765f commit 163c31b

File tree

17 files changed

+27
-495
lines changed

17 files changed

+27
-495
lines changed

plain/plain/cli/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def server(
120120
max_requests: int,
121121
pidfile: str | None,
122122
) -> None:
123-
"""Production-ready WSGI server"""
123+
"""Production-ready HTTP server"""
124124
from plain.runtime import settings
125125

126126
# Show settings loaded from environment

plain/plain/http/__init__.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
Request,
1919
RequestHeaders,
2020
UnreadablePostError,
21-
headers_to_wsgi_environ,
2221
)
2322
from .response import (
2423
BadHeaderError,
@@ -64,6 +63,4 @@
6463
"TooManyFieldsSentError400",
6564
"TooManyFilesSentError400",
6665
"RequestDataTooBigError400",
67-
# WSGI helpers (used by test client)
68-
"headers_to_wsgi_environ",
6966
]

plain/plain/http/request.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ def close(self) -> None:
466466
# File-like and iterator interface.
467467
#
468468
# Expects self._stream to be set to an appropriate source of bytes by
469-
# a corresponding request subclass (e.g. WSGIRequest).
469+
# a corresponding request creator (e.g. server or test client).
470470
# Also when request data has already been read by request.json_data,
471471
# request.form_data, or request.body, self._stream points to a BytesIO
472472
# instance containing that data.
@@ -525,26 +525,6 @@ def __getitem__(self, key: str) -> str:
525525
return super().__getitem__(key.replace("_", "-"))
526526

527527

528-
# WSGI environ conversion helpers (used by test client and WSGIRequest)
529-
_WSGI_UNPREFIXED_HEADERS = {"CONTENT_TYPE", "CONTENT_LENGTH"}
530-
531-
532-
def headers_to_wsgi_environ(headers: dict[str, str]) -> dict[str, str]:
533-
"""Convert standard HTTP header names to WSGI environ keys.
534-
535-
Example: {"Content-Type": "text/html"} -> {"CONTENT_TYPE": "text/html"}
536-
{"Accept": "text/html"} -> {"HTTP_ACCEPT": "text/html"}
537-
"""
538-
result: dict[str, str] = {}
539-
for name, value in headers.items():
540-
key = name.replace("-", "_").upper()
541-
if key in _WSGI_UNPREFIXED_HEADERS:
542-
result[key] = value
543-
else:
544-
result[f"HTTP_{key}"] = value
545-
return result
546-
547-
548528
class QueryDict(MultiValueDict):
549529
"""
550530
A specialized MultiValueDict which represents a query string.

plain/plain/http/response.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ def make_bytes(self, value: str | bytes) -> bytes:
305305
# Handle non-string types.
306306
return str(value).encode(self.charset)
307307

308-
# The WSGI server must call this method upon completion of the request.
308+
# The server must call this method upon completion of the request.
309309
# See http://blog.dscpl.com.au/2012/10/obligations-for-calling-close-on.html
310310
def close(self) -> None:
311311
for closer in self._resource_closers:

plain/plain/internal/handlers/base.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,10 @@ def get_response(self, request: Request) -> ResponseBase:
8282
url_attributes.URL_SCHEME: request.scheme,
8383
}
8484

85-
# Add full URL if we can build it (requires proper WSGI environment)
85+
# Add full URL if we can build it
8686
try:
8787
span_attributes[url_attributes.URL_FULL] = request.build_absolute_uri()
88-
except KeyError:
89-
# Missing required WSGI environment variables (e.g. in tests)
88+
except (KeyError, AttributeError):
9089
pass
9190

9291
# Add query string if present

plain/plain/internal/handlers/wsgi.py

Lines changed: 0 additions & 225 deletions
This file was deleted.

plain/plain/packages/registry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def populate(
5858
return
5959

6060
# populate() might be called by two threads in parallel on servers
61-
# that create threads before initializing the WSGI callable.
61+
# that create threads before initializing the request handler.
6262
with self._lock:
6363
if self.ready:
6464
return

plain/plain/server/app.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ def __init__(self, cfg: Config) -> None:
2626
def load(self) -> Any:
2727
"""Load the request handler."""
2828
import plain.runtime
29-
from plain.internal.handlers.wsgi import WSGIHandler
29+
from plain.internal.handlers.base import BaseHandler
3030

3131
plain.runtime.setup()
32-
return WSGIHandler()
32+
handler = BaseHandler()
33+
handler.load_middleware()
34+
return handler
3335

3436
def handler(self) -> Any:
3537
"""Get the request handler."""

plain/plain/server/http/message.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ def parse_headers(
160160
# X-Forwarded-For: 2001:db8::ha:cc:ed
161161
# X_Forwarded_For: 127.0.0.1,::1
162162
# HTTP_X_FORWARDED_FOR = 2001:db8::ha:cc:ed,127.0.0.1,::1
163-
# Only modify after fixing *ALL* header transformations; network to wsgi env
163+
# Only modify after fixing *ALL* header transformations
164164
if "_" in name:
165165
if name in forwarder_headers or "*" in forwarder_headers:
166166
# This forwarder may override our environment

0 commit comments

Comments
 (0)