You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Stallion users can now read cookies from requests and build validated
Set-Cookie response headers without pulling in a web framework. Cookie
signing (HMAC) stays in pyrois.
Request cookies are automatically parsed from Cookie headers and
available via request'.cookies.get("name") or .values(). ParseCookies
provides direct parsing for use outside the request lifecycle.
SetCookieBuilder constructs Set-Cookie headers with secure defaults
(Secure, HttpOnly, SameSite=Lax). It validates names (RFC 2616 token),
values (RFC 6265 cookie-octets), path and domain attributes (US-ASCII
0x20-0x7E, no semicolons), __Host-/__Secure- prefix rules (case-sensitive
per RFC 6265bis), and SameSite=None + Secure consistency, returning typed
errors on failure.
Headers.values() now yields Header val objects instead of (String, String)
tuples — a breaking change for code that destructures header values.
Design: #74
Closes #79
Stallion now provides built-in cookie support in two directions: reading cookies from requests and building `Set-Cookie` response headers.
4
+
5
+
Cookies are automatically parsed from `Cookie` request headers and available on the `Request` object. Use `request'.cookies.get("name")` to look up a cookie by name, or `request'.cookies.values()` to iterate over all parsed cookies:
6
+
7
+
```pony
8
+
fun ref on_request_complete(request': stallion.Request val,
9
+
responder: stallion.Responder)
10
+
=>
11
+
match request'.cookies.get("session")
12
+
| let token: String val =>
13
+
// Use the session token
14
+
end
15
+
```
16
+
17
+
For direct parsing outside the request lifecycle, `ParseCookies` accepts a raw `Cookie` header value string or a `Headers val` collection.
18
+
19
+
To build `Set-Cookie` response headers, use `SetCookieBuilder`. It defaults to `Secure`, `HttpOnly`, and `SameSite=Lax` — override explicitly when needed:
20
+
21
+
```pony
22
+
match stallion.SetCookieBuilder("session", token)
23
+
.with_path("/")
24
+
.with_max_age(3600)
25
+
.build()
26
+
| let sc: stallion.SetCookie val =>
27
+
// Add to response: .add_header("Set-Cookie", sc.header_value())
28
+
| let err: stallion.SetCookieBuildError =>
29
+
// Handle validation error
30
+
end
31
+
```
32
+
33
+
The builder validates cookie names (RFC 2616 token), values (RFC 6265 cookie-octets), and path/domain attributes (no CTLs or semicolons), enforces `__Host-` and `__Secure-` prefix rules, and checks `SameSite=None` + `Secure` consistency.
## Changed Headers.values() to yield Header val instead of tuples
38
+
39
+
`Headers.values()` now yields `Header val` objects instead of `(String, String)` tuples. Code that destructures header values needs to change from field access on tuples to field access on the `Header` class:
-`http_server_actor.pony` — Server actor trait (`HTTPServerActor`: extends `TCPConnectionActor` and `HTTPServerLifecycleEventReceiver`, provides `_connection()` default)
@@ -79,10 +80,20 @@ Follow the standard ponylang release notes conventions. Create individual `.md`
79
80
-`server_config.pony` — Server configuration (`ServerConfig` class with `max_requests_per_connection: (MaxRequestsPerConnection | None)`, `DefaultIdleTimeout` primitive)
Copy file name to clipboardExpand all lines: examples/README.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,10 @@ Each subdirectory is a self-contained Pony program demonstrating a different par
6
6
7
7
Greeting server that responds with "Hello, World!" by default, or "Hello, {name}!" when a `?name=X` query parameter is provided. Demonstrates the core API: a listener actor implements `lori.TCPListenerActor`, creates connection actors in `_on_accept`, and each connection actor uses `HTTPServerActor`, `HTTPServer`, `Request`, `Responder`, `ResponseBuilder`, and `ServerConfig`. Start here if you're new to the library.
8
8
9
+
## [cookies](cookies/)
10
+
11
+
Visit counter that reads the `visits` cookie from incoming requests, increments it, and sets it back via `Set-Cookie`. Demonstrates both `Request.cookies` for reading cookies parsed from request headers and `SetCookieBuilder` for building validated `Set-Cookie` response headers with secure defaults.
12
+
9
13
## [ssl](ssl/)
10
14
11
15
HTTPS server using SSL/TLS. Demonstrates creating an `SSLContext`, loading certificate and key files, and passing the context to connection actors via `_on_accept`. Actors use `HTTPServer.ssl` instead of `HTTPServer` to create an HTTPS connection.
0 commit comments