Skip to content

Commit 1fbb5b3

Browse files
author
patx
committed
Fix unicode redirect handling
1 parent 0184d2c commit 1fbb5b3

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

micropie.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import uuid
2020
from abc import ABC, abstractmethod
2121
from typing import Any, Awaitable, Callable, Dict, List, Optional, Tuple
22-
from urllib.parse import parse_qs
22+
from urllib.parse import parse_qs, urlsplit, urlunsplit, quote, quote_plus
2323

2424
try:
2525
import orjson as json # Use `orjson` if installed as it is faster
@@ -1044,18 +1044,31 @@ async def _send_websocket_close(
10441044
"reason": reason
10451045
})
10461046

1047-
def _redirect(self, location: str, extra_headers: list = None) -> Tuple[int, str, List[Tuple[str, str]]]:
1047+
def _encode_redirect_url(self, url: str) -> str:
1048+
"""
1049+
Make a URL safe to put in an HTTP Location header.
1050+
1051+
Key rule: Location must be ASCII/latin-1 -> percent-encode non-ASCII.
1052+
We percent-encode the PATH but we do NOT touch the query string.
1053+
"""
1054+
p = urlsplit(url)
1055+
safe_path = quote(p.path, safe="/%")
1056+
return urlunsplit((p.scheme, p.netloc, safe_path, p.query, p.fragment))
1057+
1058+
def _redirect(
1059+
self,
1060+
location: str,
1061+
extra_headers: list | None = None,
1062+
) -> Tuple[int, str, List[Tuple[str, str]]]:
10481063
"""
10491064
Generate an HTTP redirect response.
1050-
Args:
1051-
location: The URL to redirect to.
1052-
extra_headers: Optional list of tuples (header_name, header_value) to include in the response.
1053-
Returns:
1054-
A tuple containing the HTTP status code, the HTML body, and headers list.
10551065
"""
1056-
headers = [("Location", location)]
1066+
safe_location = self._encode_redirect_url(location)
1067+
1068+
headers = [("Location", safe_location)]
10571069
if extra_headers:
10581070
headers.extend(extra_headers)
1071+
10591072
return 302, "", headers
10601073

10611074
async def _render_template(self, name: str, **kwargs: Any) -> str:

0 commit comments

Comments
 (0)