http.py 859 B

1234567891011121314151617
  1. """HTTP response helpers."""
  2. from urllib.parse import quote
  3. def build_content_disposition(filename: str, disposition: str = "attachment") -> str:
  4. """Build an RFC 6266-compliant Content-Disposition header value.
  5. Starlette/uvicorn encodes response headers as latin-1, so any non-ASCII
  6. character in a raw `filename="..."` parameter raises UnicodeEncodeError.
  7. The fix is RFC 5987's `filename*=UTF-8''<percent-encoded>` form alongside
  8. a stripped ASCII fallback in the legacy `filename="..."` parameter — every
  9. modern browser prefers the `*` form when present.
  10. """
  11. ascii_fallback = filename.encode("ascii", "ignore").decode("ascii").strip(" ._-") or "download"
  12. ascii_fallback = ascii_fallback.replace('"', "").replace("\\", "")
  13. return f"{disposition}; filename=\"{ascii_fallback}\"; filename*=UTF-8''{quote(filename)}"