Skip to content

Commit 786b95b

Browse files
committed
Rename request.meta to request.environ, add request.query_string
1 parent 22f241a commit 786b95b

File tree

6 files changed

+47
-38
lines changed

6 files changed

+47
-38
lines changed

plain/plain/http/multipartparser.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,16 @@ class MultiPartParser:
6363

6464
def __init__(
6565
self,
66-
meta: dict[str, Any],
66+
environ: dict[str, Any],
6767
input_data: Any,
6868
upload_handlers: list[FileUploadHandler],
6969
encoding: str | None = None,
7070
):
7171
"""
7272
Initialize the MultiPartParser object.
7373
74-
:meta:
75-
The standard ``meta`` dictionary in Plain request objects.
74+
:environ:
75+
The WSGI environ dictionary from the request.
7676
:input_data:
7777
The raw post data, as a file-like object.
7878
:upload_handlers:
@@ -82,7 +82,7 @@ def __init__(
8282
The encoding with which to treat the incoming data.
8383
"""
8484
# Content-Type should contain multipart and the boundary information.
85-
content_type = meta.get("CONTENT_TYPE", "")
85+
content_type = environ.get("CONTENT_TYPE", "")
8686
if not content_type.startswith("multipart/"):
8787
raise MultiPartParserError(f"Invalid Content-Type: {content_type}")
8888

@@ -104,7 +104,7 @@ def __init__(
104104
# Content-Length should contain the length of the body we are about
105105
# to receive.
106106
try:
107-
content_length = int(meta.get("CONTENT_LENGTH", 0))
107+
content_length = int(environ.get("CONTENT_LENGTH", 0))
108108
except (ValueError, TypeError):
109109
content_length = 0
110110

@@ -120,7 +120,7 @@ def __init__(
120120
possible_sizes = [x.chunk_size for x in upload_handlers if x.chunk_size]
121121
self._chunk_size = min([2**31 - 4] + possible_sizes)
122122

123-
self._meta = meta
123+
self._environ = environ
124124
self._encoding = encoding or settings.DEFAULT_CHARSET
125125
self._content_length = content_length
126126
self._upload_handlers = upload_handlers
@@ -163,7 +163,7 @@ def _parse(self) -> tuple[Any, MultiValueDict]:
163163
for handler in handlers:
164164
result = handler.handle_raw_input(
165165
self._input_data,
166-
self._meta,
166+
self._environ,
167167
self._content_length,
168168
self._boundary,
169169
encoding,

plain/plain/http/request.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class Request:
6565
content_params: dict[str, str] | None
6666
query_params: QueryDict
6767
cookies: dict[str, str]
68-
meta: dict[str, Any]
68+
environ: dict[str, Any]
6969
path: str
7070
path_info: str
7171
unique_id: str
@@ -103,7 +103,7 @@ def __deepcopy__(self, memo: dict[int, Any]) -> Request:
103103

104104
@cached_property
105105
def headers(self) -> RequestHeaders:
106-
return RequestHeaders(self.meta)
106+
return RequestHeaders(self.environ)
107107

108108
@cached_property
109109
def csp_nonce(self) -> str:
@@ -157,13 +157,15 @@ def host(self) -> str:
157157
property can safely return the host without any validation.
158158
"""
159159
# We try three options, in order of decreasing preference.
160-
if settings.HTTP_X_FORWARDED_HOST and ("HTTP_X_FORWARDED_HOST" in self.meta):
161-
host = self.meta["HTTP_X_FORWARDED_HOST"]
162-
elif "HTTP_HOST" in self.meta:
163-
host = self.meta["HTTP_HOST"]
160+
if settings.HTTP_X_FORWARDED_HOST and (
161+
xff_host := self.headers.get("X-Forwarded-Host")
162+
):
163+
host = xff_host
164+
elif http_host := self.headers.get("Host"):
165+
host = http_host
164166
else:
165167
# Reconstruct the host using the algorithm from PEP 333.
166-
host = self.meta["SERVER_NAME"]
168+
host = self.environ["SERVER_NAME"]
167169
server_port = self.port
168170
if server_port != ("443" if self.is_https() else "80"):
169171
host = f"{host}:{server_port}"
@@ -172,10 +174,12 @@ def host(self) -> str:
172174
@cached_property
173175
def port(self) -> str:
174176
"""Return the port number for the request as a string."""
175-
if settings.HTTP_X_FORWARDED_PORT and "HTTP_X_FORWARDED_PORT" in self.meta:
176-
port = self.meta["HTTP_X_FORWARDED_PORT"]
177+
if settings.HTTP_X_FORWARDED_PORT and (
178+
xff_port := self.headers.get("X-Forwarded-Port")
179+
):
180+
port = xff_port
177181
else:
178-
port = self.meta["SERVER_PORT"]
182+
port = self.environ["SERVER_PORT"]
179183
return str(port)
180184

181185
@cached_property
@@ -191,7 +195,12 @@ def client_ip(self) -> str:
191195
if settings.HTTP_X_FORWARDED_FOR:
192196
if xff := self.headers.get("X-Forwarded-For"):
193197
return xff.split(",")[0].strip()
194-
return self.meta["REMOTE_ADDR"]
198+
return self.environ["REMOTE_ADDR"]
199+
200+
@property
201+
def query_string(self) -> str:
202+
"""Return the raw query string from the request URL."""
203+
return self.environ.get("QUERY_STRING", "")
195204

196205
def get_full_path(self, force_append_slash: bool = False) -> str:
197206
"""
@@ -219,11 +228,10 @@ def escape_uri_path(path: str) -> str:
219228
# the entire path, not a path segment.
220229
return quote(path, safe="/:@&+$,-_.!~*'()")
221230

222-
query_string = self.meta.get("QUERY_STRING", "")
223231
return "{}{}{}".format(
224232
escape_uri_path(self.path),
225233
"/" if force_append_slash and not self.path.endswith("/") else "",
226-
("?" + (iri_to_uri(query_string) or "")) if query_string else "",
234+
("?" + (iri_to_uri(self.query_string) or "")) if self.query_string else "",
227235
)
228236

229237
def build_absolute_uri(self, location: str | None = None) -> str:
@@ -306,7 +314,7 @@ def body(self) -> bytes:
306314
# Limit the maximum request data size that will be handled in-memory.
307315
if (
308316
settings.DATA_UPLOAD_MAX_MEMORY_SIZE is not None
309-
and int(self.meta.get("CONTENT_LENGTH") or 0)
317+
and int(self.environ.get("CONTENT_LENGTH") or 0)
310318
> settings.DATA_UPLOAD_MAX_MEMORY_SIZE
311319
):
312320
raise RequestDataTooBig(
@@ -323,10 +331,12 @@ def body(self) -> bytes:
323331
return self._body
324332

325333
def _parse_file_upload(
326-
self, meta: dict[str, Any], post_data: IO[bytes]
334+
self, environ: dict[str, Any], post_data: IO[bytes]
327335
) -> tuple[Any, MultiValueDict]:
328336
"""Return a tuple of (data QueryDict, files MultiValueDict)."""
329-
parser = MultiPartParser(meta, post_data, self.upload_handlers, self.encoding)
337+
parser = MultiPartParser(
338+
environ, post_data, self.upload_handlers, self.encoding
339+
)
330340
return parser.parse()
331341

332342
@cached_property
@@ -341,7 +351,7 @@ def _multipart_data(self) -> tuple[QueryDict, MultiValueDict]:
341351
data = BytesIO(self._body)
342352
else:
343353
data = self
344-
return self._parse_file_upload(self.meta, data)
354+
return self._parse_file_upload(self.environ, data)
345355

346356
@cached_property
347357
def json_data(self) -> dict[str, Any]:

plain/plain/internal/files/uploadhandler.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def __init__(self, request: Request | None = None) -> None:
9797
def handle_raw_input(
9898
self,
9999
input_data: Any,
100-
meta: dict[str, Any],
100+
environ: dict[str, Any],
101101
content_length: int,
102102
boundary: bytes,
103103
encoding: str | None = None,
@@ -109,8 +109,8 @@ def handle_raw_input(
109109
110110
:input_data:
111111
An object that supports reading via .read().
112-
:meta:
113-
``request.meta``.
112+
:environ:
113+
``request.environ``.
114114
:content_length:
115115
The (integer) value of the Content-Length header from the
116116
client.
@@ -219,7 +219,7 @@ class MemoryFileUploadHandler(FileUploadHandler):
219219
def handle_raw_input(
220220
self,
221221
input_data: Any,
222-
meta: dict[str, Any],
222+
environ: dict[str, Any],
223223
content_length: int,
224224
boundary: bytes,
225225
encoding: str | None = None,

plain/plain/internal/handlers/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ def get_response(self, request: Request) -> ResponseBase:
8989
pass
9090

9191
# Add query string if present
92-
if query_string := request.meta.get("QUERY_STRING"):
93-
span_attributes[url_attributes.URL_QUERY] = query_string
92+
if request.query_string:
93+
span_attributes[url_attributes.URL_QUERY] = request.query_string
9494

9595
span_context = baggage.set_baggage("http.request.cookies", request.cookies)
9696
span_context = baggage.set_baggage(

plain/plain/internal/handlers/wsgi.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ def __init__(self, environ: dict[str, Any]) -> None:
8282
self.path = "{}/{}".format(
8383
script_name.rstrip("/"), path_info.replace("/", "", 1)
8484
)
85-
self.meta = environ
86-
self.meta["PATH_INFO"] = path_info
87-
self.meta["SCRIPT_NAME"] = script_name
85+
self.environ = environ
86+
self.environ["PATH_INFO"] = path_info
87+
self.environ["SCRIPT_NAME"] = script_name
8888
self.method = environ["REQUEST_METHOD"].upper()
8989

9090
# Set content_type, content_params, and encoding
@@ -109,8 +109,8 @@ def __init__(self, environ: dict[str, Any]) -> None:
109109
def __getstate__(self) -> dict[str, Any]:
110110
state = super().__getstate__()
111111
for attr in frozenset(["wsgi.errors", "wsgi.input"]):
112-
if attr in state["meta"]:
113-
del state["meta"][attr]
112+
if attr in state["environ"]:
113+
del state["environ"][attr]
114114
return state
115115

116116
def _get_scheme(self) -> str:

plain/plain/views/redirect.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ def get_redirect_url(self) -> str:
4242
else:
4343
raise ValueError("RedirectView requires either url or url_name to be set")
4444

45-
args = self.request.meta.get("QUERY_STRING", "")
46-
if args and self.preserve_query_params:
47-
url = f"{url}?{args}"
45+
if self.preserve_query_params and self.request.query_string:
46+
url = f"{url}?{self.request.query_string}"
4847
return url
4948

5049
def get(self) -> ResponseRedirect:

0 commit comments

Comments
 (0)