Changes for version 0.002000 - 2026-06-26
- Split out of the PAGI distribution into its own distribution (git history preserved).
- New PAGI::Tools module anchors the distribution.
- The application runner ships in PAGI-Server as PAGI::Server::Runner.
- B<BREAKING>: PAGI::Response is now a value — factories build detached responses, body methods return $self, respond($send) sends, to_app makes any response mountable; Endpoint HTTP handlers RETURN a response value (await $res->json(...) no longer sends).
- B<BREAKING>: PAGI::Request->configure/->config removed; path_param strict and multipart limits are now per-call options.
- PAGI::Headers: ordered, case-insensitive, multi-value header container (rejects undef values; to_hash); Response and Request route headers through it.
- is_sent now reads response_started off the pagi.connection object, not a scope scalar, so it survives middleware's scope copy. Adds PAGI::Test::ConnectionState.
- PAGI::Response->has_body_source: predicate for whether a body source was registered.
- PAGI::Response: charset follows the body — text/html/send gain "; charset=utf-8", json() stays bare application/json.
- PAGI::Utils::to_app coerces coderefs, component objects, and class names; every composition point accepts anything it accepts.
- builder's enable() accepts configured middleware instances.
- PAGI::App::Router: coderef route middleware can transform the channel.
- PAGI::Endpoint::Router route middleware are value-flow (await $next->() returns the handler's response); App::Router dispatch returns the matched route's value.
- PAGI::Context: $ctx->text/html/json/redirect shorthands, assert_http/websocket/sse guards, on_default catch-all, raw_send accessor.
- Backpressure/lifecycle helpers: on_complete, buffered_amount/high_water_mark/ low_water_mark, on_high_water/on_drain/is_writable, WebSocket->deny().
- PAGI::Request->multipart_stream: pull-based streaming multipart parsing with app-controlled sinks; mutually exclusive with the buffered body methods.
- PAGI::App::Redirect and ::NotFound build a PAGI::Response value (modules kept for the dynamic case).
- PAGI::Lifespan coerces its app arg via to_app, and reports shutdown-handler failures instead of swallowing them.
- Spec: URLMap sets root_path; WrapCGI builds SCRIPT_NAME from root_path.
- Canonical scope-adding middleware route through the modify_scope helper.
- Documented the PAGI::Response subclassing seam for framework authors.
- Docs: recipes are now PAGI::Tools::Cookbook; Tutorial/Cookbook examples corrected against the current API; chat-showcase example uses PAGI::App::Router
- PAGI::Lifespan.
- For changes prior to 0.002000, see the Changes file of the PAGI distribution (versions up to 0.001023).
Documentation
Recipes for Common PAGI Tasks
Optional convenience helpers for PAGI applications
Modules
Try apps in sequence until success
Serve files with directory listing
Serve static files
Health check endpoint app
Load PAGI app from file
Customizable 404 response
HTTP reverse proxy (DEMO ONLY - NOT FOR PRODUCTION)
URL redirect app for the dynamic case
Unified routing for HTTP, WebSocket, and SSE
Pub/sub Server-Sent Events
Rate-limited request processing
Mount apps at URL path prefixes
Pub/sub WebSocket broadcast
Multi-room chat application
Echo WebSocket messages back to sender
Execute CGI scripts as PAGI apps
PSGI-to-PAGI adapter
Per-request context with protocol-specific subclasses
HTTP-specific context subclass
SSE context with protocol operations
WebSocket context with protocol operations
Class-based HTTP endpoint handler
Class-based router with wrapped handlers
Class-based Server-Sent Events endpoint handler
Class-based WebSocket endpoint handler
ordered, case-insensitive, multi-value HTTP header container
Wrap a PAGI app with lifecycle management
Base class for PAGI middleware
Request logging middleware
HTTP Basic Authentication middleware
Bearer token authentication middleware
DSL for composing PAGI middleware
Cross-Origin Resource Sharing middleware
Cross-Site Request Forgery protection middleware
Conditional GET/HEAD request handling
Auto Content-Length header middleware
HTTP content negotiation middleware
Cookie parsing middleware
Development debug panel middleware
ETag generation middleware
Exception handling middleware
Form request body parsing middleware
Response compression middleware
Force HTTPS redirect middleware
HEAD request handling middleware
Health check endpoint middleware
JSON request body parsing middleware
Validate PAGI application compliance
Serve maintenance page when enabled
Override HTTP method from request data
Request rate limiting middleware
Unique request ID middleware
Handle X-Forwarded-* headers from reverse proxies
URL rewriting middleware
Request timing middleware
Add retry hints to SSE events
Security headers middleware
Session management middleware with pluggable State/Store
Base class for session state extraction
Bearer token session ID transport
Custom coderef-based session ID transport
Cookie-based session ID transport
Header-based session ID transport
Base class for async session storage
In-memory session store
Static file serving middleware
Host header validation middleware
WebSocket per-message compression
Rate limiting for WebSocket connections
Delegate file serving to reverse proxy
Convenience wrapper for PAGI request scope
Streaming body consumption for PAGI requests
Async multipart/form-data parser
Pull-based streaming multipart/form-data engine
Content negotiation utilities for PAGI
Uploaded file representation
Fluent response builder for PAGI applications
Convenience wrapper for PAGI Server-Sent Events connections
Standalone helper object for session data access
Standalone helper for per-request shared state
Test client for PAGI applications
the pagi.connection object provided by PAGI::Test
HTTP response wrapper for testing
Server-Sent Events connection for testing PAGI applications
WebSocket connection for testing PAGI applications
Application toolkit for the PAGI specification
Shared utility helpers for PAGI
Cryptographically secure random bytes
Convenience wrapper for PAGI WebSocket connections
Provides
in lib/PAGI/App/WrapPSGI.pm
in lib/PAGI/Endpoint/Router.pm
in lib/PAGI/Middleware/Cookie.pm
in lib/PAGI/Request/MultipartStream.pm
in lib/PAGI/Response.pm
Examples
- examples/09-psgi-bridge/README.md
- examples/09-psgi-bridge/app.pl
- examples/10-chat-showcase/README.md
- examples/10-chat-showcase/app.pl
- examples/10-chat-showcase/lib/ChatApp/HTTP.pm
- examples/10-chat-showcase/lib/ChatApp/SSE.pm
- examples/10-chat-showcase/lib/ChatApp/State.pm
- examples/10-chat-showcase/lib/ChatApp/WebSocket.pm
- examples/10-chat-showcase/public/css/style.css
- examples/10-chat-showcase/public/index.html
- examples/10-chat-showcase/public/js/app.js
- examples/13-contact-form/README.md
- examples/13-contact-form/app.pl
- examples/13-contact-form/public/index.html
- examples/14-lifespan-utils/README.md
- examples/14-lifespan-utils/app.pl
- examples/README.md
- examples/app-01-file/README.md
- examples/app-01-file/app.pl
- examples/app-01-file/static/data.json
- examples/app-01-file/static/index.html
- examples/app-01-file/static/style.css
- examples/app-01-file/static/subdir/nested.txt
- examples/app-01-file/static/test.txt
- examples/background-tasks/README.md
- examples/background-tasks/app.pl
- examples/endpoint-demo/README.md
- examples/endpoint-demo/app.pl
- examples/endpoint-demo/public/index.html
- examples/endpoint-router-demo/README.md
- examples/endpoint-router-demo/app.pl
- examples/endpoint-router-demo/lib/MyApp/API.pm
- examples/endpoint-router-demo/lib/MyApp/Main.pm
- examples/endpoint-router-demo/public/index.html
- examples/full-demo/README.md
- examples/full-demo/app.pl
- examples/sse-dashboard/README.md
- examples/sse-dashboard/app.pl
- examples/sse-dashboard/public/index.html
- examples/test-lifespan-shutdown/README.md
- examples/test-lifespan-shutdown/app.pl
- examples/websocket-bidirectional/README.md
- examples/websocket-bidirectional/app.pl
- examples/websocket-chat-v2/README.md
- examples/websocket-chat-v2/app.pl
- examples/websocket-chat-v2/lib/ChatApp/HTTP.pm
- examples/websocket-chat-v2/lib/ChatApp/SSE.pm
- examples/websocket-chat-v2/lib/ChatApp/State.pm
- examples/websocket-chat-v2/lib/ChatApp/WebSocket.pm
- examples/websocket-echo-v2/README.md
- examples/websocket-echo-v2/app.pl