plain 0.65.0__py3-none-any.whl → 0.65.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- plain/CHANGELOG.md +11 -0
- plain/http/request.py +5 -6
- plain/internal/handlers/base.py +5 -1
- {plain-0.65.0.dist-info → plain-0.65.1.dist-info}/METADATA +1 -1
- {plain-0.65.0.dist-info → plain-0.65.1.dist-info}/RECORD +8 -8
- {plain-0.65.0.dist-info → plain-0.65.1.dist-info}/WHEEL +0 -0
- {plain-0.65.0.dist-info → plain-0.65.1.dist-info}/entry_points.txt +0 -0
- {plain-0.65.0.dist-info → plain-0.65.1.dist-info}/licenses/LICENSE +0 -0
plain/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# plain changelog
|
2
2
|
|
3
|
+
## [0.65.1](https://github.com/dropseed/plain/releases/plain@0.65.1) (2025-09-22)
|
4
|
+
|
5
|
+
### What's changed
|
6
|
+
|
7
|
+
- Fixed DisallowedHost exception handling in request span attributes to prevent telemetry errors ([bcc0005](https://github.com/dropseed/plain/commit/bcc000575b))
|
8
|
+
- Removed cached property optimization for scheme/host to improve request processing reliability ([3a52690](https://github.com/dropseed/plain/commit/3a52690d47))
|
9
|
+
|
10
|
+
### Upgrade instructions
|
11
|
+
|
12
|
+
- No changes required
|
13
|
+
|
3
14
|
## [0.65.0](https://github.com/dropseed/plain/releases/plain@0.65.0) (2025-09-22)
|
4
15
|
|
5
16
|
### What's changed
|
plain/http/request.py
CHANGED
@@ -220,6 +220,8 @@ class HttpRequest:
|
|
220
220
|
location = str(location)
|
221
221
|
bits = urlsplit(location)
|
222
222
|
if not (bits.scheme and bits.netloc):
|
223
|
+
current_scheme_host = f"{self.scheme}://{self.get_host()}"
|
224
|
+
|
223
225
|
# Handle the simple, most common case. If the location is absolute
|
224
226
|
# and a scheme or host (netloc) isn't provided, skip an expensive
|
225
227
|
# urljoin() as long as no path segments are '.' or '..'.
|
@@ -233,17 +235,14 @@ class HttpRequest:
|
|
233
235
|
# If location starts with '//' but has no netloc, reuse the
|
234
236
|
# schema and netloc from the current request. Strip the double
|
235
237
|
# slashes and continue as if it wasn't specified.
|
236
|
-
location =
|
238
|
+
location = current_scheme_host + location.removeprefix("//")
|
237
239
|
else:
|
238
240
|
# Join the constructed URL with the provided location, which
|
239
241
|
# allows the provided location to apply query strings to the
|
240
242
|
# base path.
|
241
|
-
location = urljoin(
|
242
|
-
return iri_to_uri(location)
|
243
|
+
location = urljoin(current_scheme_host + self.path, location)
|
243
244
|
|
244
|
-
|
245
|
-
def _current_scheme_host(self):
|
246
|
-
return f"{self.scheme}://{self.get_host()}"
|
245
|
+
return iri_to_uri(location)
|
247
246
|
|
248
247
|
def _get_scheme(self):
|
249
248
|
"""
|
plain/internal/handlers/base.py
CHANGED
@@ -4,7 +4,7 @@ import types
|
|
4
4
|
from opentelemetry import baggage, trace
|
5
5
|
from opentelemetry.semconv.attributes import http_attributes, url_attributes
|
6
6
|
|
7
|
-
from plain.exceptions import ImproperlyConfigured
|
7
|
+
from plain.exceptions import DisallowedHost, ImproperlyConfigured
|
8
8
|
from plain.logs.utils import log_response
|
9
9
|
from plain.runtime import settings
|
10
10
|
from plain.urls import get_resolver
|
@@ -78,6 +78,10 @@ class BaseHandler:
|
|
78
78
|
except KeyError:
|
79
79
|
# Missing required WSGI environment variables (e.g. in tests)
|
80
80
|
pass
|
81
|
+
except DisallowedHost:
|
82
|
+
# Invalid host header - skip URL_FULL for telemetry but let the
|
83
|
+
# exception be handled normally by middleware for proper 400 response
|
84
|
+
pass
|
81
85
|
|
82
86
|
# Add query string if present
|
83
87
|
if query_string := request.meta.get("QUERY_STRING"):
|
@@ -1,5 +1,5 @@
|
|
1
1
|
plain/AGENTS.md,sha256=5XMGBpJgbCNIpp60DPXB7bpAtFk8FAzqiZke95T965o,1038
|
2
|
-
plain/CHANGELOG.md,sha256=
|
2
|
+
plain/CHANGELOG.md,sha256=NlQC7IqcrH9tiUMqkCgyG6Pn7xQiaDUE3Xtfn6g4nIc,15292
|
3
3
|
plain/README.md,sha256=5BJyKhf0TDanWVbOQyZ3zsi5Lov9xk-LlJYCDWofM6Y,4078
|
4
4
|
plain/__main__.py,sha256=GK39854Lc_LO_JP8DzY9Y2MIQ4cQEl7SXFJy244-lC8,110
|
5
5
|
plain/debug.py,sha256=XdjnXcbPGsi0J2SpHGaLthhYU5AjhBlkHdemaP4sbYY,758
|
@@ -59,7 +59,7 @@ plain/http/__init__.py,sha256=PfmXBIq7onLO_bbOrVdj5rJeHxqJMYqrIobVKupUzUA,1003
|
|
59
59
|
plain/http/cookie.py,sha256=THd7nOl-2ugeBPKgOhbD87aM2oxUbNH8HWrarUn0fpM,1955
|
60
60
|
plain/http/hosts.py,sha256=GbvFzle2VgPC2ehtXW8MM_1XD9gKuv7h-8HTOX3RiJA,4567
|
61
61
|
plain/http/multipartparser.py,sha256=Z1dFJNAd8N5RHUuF67jh1jBfZOFepORsre_3ee6CgOQ,27266
|
62
|
-
plain/http/request.py,sha256=
|
62
|
+
plain/http/request.py,sha256=6kimxbIZMK2ckx366fQHDzrNTf6H8ih6YJ4y9yx2aAI,24623
|
63
63
|
plain/http/response.py,sha256=FM3otFkKEEkAaV_pVB3JUSMhMk7x_zf5JcDWKhOKviM,23223
|
64
64
|
plain/internal/__init__.py,sha256=fVBaYLCXEQc-7riHMSlw3vMTTuF7-0Bj2I8aGzv0o0w,171
|
65
65
|
plain/internal/files/__init__.py,sha256=VctFgox4Q1AWF3klPaoCC5GIw5KeLafYjY5JmN8mAVw,63
|
@@ -71,7 +71,7 @@ plain/internal/files/uploadedfile.py,sha256=JRB7T3quQjg-1y3l1ASPxywtSQZhaeMc45uF
|
|
71
71
|
plain/internal/files/uploadhandler.py,sha256=63_QUwAwfq3bevw79i0S7zt2EB2UBoO7MaauvezaVMY,7198
|
72
72
|
plain/internal/files/utils.py,sha256=xN4HTJXDRdcoNyrL1dFd528MBwodRlHZM8DGTD_oBIg,2646
|
73
73
|
plain/internal/handlers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
74
|
-
plain/internal/handlers/base.py,sha256=
|
74
|
+
plain/internal/handlers/base.py,sha256=rrPq-LqMOsDUP2IQ-d_FUNq8fZfYqbLVMYOeqrftoXQ,6228
|
75
75
|
plain/internal/handlers/exception.py,sha256=TbPYtgZ7ITJahUKhQWkptHK28Lb4zh_nOviNctC2EYs,4815
|
76
76
|
plain/internal/handlers/wsgi.py,sha256=dgPT29t_F9llB-c5RYU3SHxGuZNaZ83xRjOfuOmtOl8,8209
|
77
77
|
plain/internal/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -161,8 +161,8 @@ plain/views/forms.py,sha256=ESZOXuo6IeYixp1RZvPb94KplkowRiwO2eGJCM6zJI0,2400
|
|
161
161
|
plain/views/objects.py,sha256=v3Vgvdoc1s0QW6JNWWrO5XXy9zF7vgwndgxX1eOSQoE,4999
|
162
162
|
plain/views/redirect.py,sha256=Xpb3cB7nZYvKgkNqcAxf9Jwm2SWcQ0u2xz4oO5M3vP8,1909
|
163
163
|
plain/views/templates.py,sha256=oAlebEyfES0rzBhfyEJzFmgLkpkbleA6Eip-8zDp-yk,1863
|
164
|
-
plain-0.65.
|
165
|
-
plain-0.65.
|
166
|
-
plain-0.65.
|
167
|
-
plain-0.65.
|
168
|
-
plain-0.65.
|
164
|
+
plain-0.65.1.dist-info/METADATA,sha256=MnXWc7Ncpu8r1geVUL6uiAorVD_1aJ0CJ5KcUs4jkQI,4488
|
165
|
+
plain-0.65.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
166
|
+
plain-0.65.1.dist-info/entry_points.txt,sha256=iGx7EijzXy87htbSv90RhtAcjhSTH_kvE8aeRCn1TRA,129
|
167
|
+
plain-0.65.1.dist-info/licenses/LICENSE,sha256=m0D5O7QoH9l5Vz_rrX_9r-C8d9UNr_ciK6Qwac7o6yo,3175
|
168
|
+
plain-0.65.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|