Clarify header casing, query decoding, and response tuple rules

Commit 75d6630 · patx · 2026-10-15T20:38:39-04:00

Changeset
75d663079faf29c5c5126491796a4c6d113aa531
Parents
e981cc244367e01f3be26a593e54b59bea483db2

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/README.md b/README.md
index 7db17df..f912317 100644
--- a/README.md
+++ b/README.md
@@ -93,7 +93,7 @@ with pretty much every ASGI application you can think of.
 
 * `request.path` -> Path without the query string
 * `request.method` -> HTTP method
-* `request.headers` -> Decoded header dict; use lowercase keys
+* `request.headers` -> Decoded header dict; preserves header name casing supplied by the server
 * `request.scope` -> Original ASGI scope, including client, scheme, and middleware state
 * `request.query()` -> Cached dict of string keys and values. No `await`!
 * `await request.body()` -> Cached body raw bytes
@@ -106,6 +106,7 @@ async def search(request):
 ```
 
 Query parameters preserve blank values; repeated keys keep the last value.
+Invalid percent-encoded UTF-8 is replaced with `�`.
 JSON can be an object, array, or scalar. Validate inputs and convert types yourself.
 
 Authentication middleware can populate the scope for handlers to check.
@@ -116,6 +117,7 @@ signed, not encrypted. Wred doesn't supply a session property.
 
 Dicts and lists become `application/json` with HTTP 200. Bytes default to
 `application/octet-stream`. Custom responses use `(body, content_type, status[, headers])`.
+Tuple bodies must be bytes, dicts, or lists; dicts and lists always use `application/json`.
 Headers are string pairs; repeated `Set-Cookie` headers are supported.
 
 * `{'hello': 'world'}` -> JSON object, 200
@@ -152,7 +154,7 @@ Small files. Don't feed it a movie.
 ## Errors
 
 Exceptions propagate to your ASGI server or middleware. Malformed JSON raises
-`orjson.JSONDecodeError`, invalid UTF-8 query strings raise `UnicodeDecodeError`,
+`orjson.JSONDecodeError`, invalid raw UTF-8 query bytes raise `UnicodeDecodeError`,
 client disconnects during body reads raise `ConnectionError`, and unsupported
 response types raise `TypeError`. Wred does not turn exceptions into responses.