Revision history for WebDyne
3.026 - 2026-09-05
-
Required Carp 1.50 or newer so Devel::Confess preserves the original PAGI send failure on older Perls instead of reporting a stack-argument copy error. Installed Future::IO explicitly in CI to run the PAGI multipart tests instead of skipping them.
-
Retained the PAGI response Future before awaiting it to avoid a Perl 5.38 segmentation fault when Devel::Confess builds a stack trace for a failed response send. Exception tracing remains enabled.
-
Added regression coverage for failed PAGI response body sends, checking that the original error propagates without sending additional events.
3.025 - 2026-09-05
-
Preserved repeated Set-Cookie headers in PAGI responses and flattened repeated PSGI response headers into separate scalar pairs. Apache header snapshots now retain repeated values; their documented snapshot semantics remain unchanged.
-
Bound PAGI and PSGI HTTP request bodies with WEBDYNE_CGI_POST_MAX (512 KiB by default) before page dispatch. Added support for bodies without Content-Length and robust PSGI short-read handling, with oversized bodies rejected using HTTP 413 and invalid or incomplete PSGI bodies using HTTP 400.
-
Corrected PAGI mounted-path handling relative to root_path and normalized outgoing HTTP header names to lowercase.
-
Buffered bounded URL-encoded PAGI SSE form bodies before page setup, awaited SSE close sends, and returned explicit denial responses for SSE setup failures and WebSocket handshakes without valid page callbacks. Multipart SSE submissions remain unsupported.
-
Accepted URL-encoded form Content-Type parameters such as charset. Apache body readers now support missing Content-Length, reject incomplete reads, and enforce defensive size checks for buffered and streaming input. Multipart forms without a length are buffered for CGI::Simple parsing.
-
Documented Apache LimitRequestBody as the primary request-size protection. Adapter checks also enforce WEBDYNE_CGI_POST_MAX; uncaught defensive exceptions currently produce HTTP 500.
-
Added regression coverage for the request-adapter fixes to MANIFEST and made the new PSGI tests skip when optional Plack dependencies are unavailable. Refreshed the WebDyne 3.0 release overview and upgrade guidance.
-
Added GitHub build-provenance attestations for release distribution archives, alongside existing Cosign signatures. README.md now explains verification with gh attestation verify against aspeer/WebDyne, including archives downloaded from CPAN mirrors. Prefixed release-script shell globs with ./ to prevent filenames being interpreted as options.
-
Removed the Plack dependency from static-file subrequests used by standalone utilities. The historical PSGI::Static helper now inherits from Request::Fake; cpanfile no longer requires Plack::Request. Added regression coverage for utilities without Plack/PAGI, binary and empty static files, missing files, and PSGI/PAGI parent requests.
-
Reviewed and expanded the DocBook guide against the current code. Corrected examples and runtime defaults, and added guidance on PAGI async state and await boundaries, SSE and WebSocket completion, request and response handling, uploads, escaping, body limits, and production deployment.
3.024 - 2026-09-05
- Fixed PAGI multipart form uploads by staging bounded request bodies before synchronous CGI::Simple parsing. Binary uploads and form fields now work with asynchronous request delivery, and multipart bodies above WEBDYNE_CGI_POST_MAX return HTTP 413.
- Fixed source, template, and compiled-cache handling for files with an mtime of zero, as found on WebAssembly and other virtual filesystems. Distinguished undefined cache timestamps from valid epoch-dated caches when deciding whether to compile or load a page.
- Added the missing Fcntl import in WebDyne::Util for file-open flags.
- Added regression coverage for repeated asynchronous multipart uploads, upload size limits, and zero-timestamp source, template, and cache files. Optional PAGI tests now check dependencies before loading async modules, and the session-cookie test skips the SameSite assertion when the installed CGI::Simple cannot serialize that attribute.
3.023 - 2026-08-25
- Moved PSGI and PAGI wrapper initialization fully into
WebDyne::PSGIandWebDyne::PAGI. Thewebdyne.psgiandwebdyne.pagiscripts now use the shared application builder, so configured middleware and document-root.webdyne.conf.plloading behave the same for wrapper scripts and directly constructed applications. - Disabled PSGI and PAGI static-file middleware by default. Enable it
explicitly with
static => 1,--staticin the helper scripts, or theWEBDYNE_PSGI_STATICorWEBDYNE_PAGI_STATICconfiguration constant. This avoids serving static assets unexpectedly from directly constructed applications. - Added regression coverage for wrapper static-option forwarding and ensured static middleware does not expose files with disallowed extensions.
3.022 - 2026-08-25
- Hardened the helper script defaults for the built-in WebDyne indexer.
webdyne.psgi,webdyne.pagi, andwebdyne.apachenow leave index handling disabled by default unlessDOCUMENT_DEFAULT, a user option file, or an explicit--indexoption enables it. - Added
WEBDYNE_INDEX_SOURCE_ENABLEand--view-sourcesupport for the helper scripts. The built-in index page source viewer is now disabled unless both index handling and source viewing are explicitly enabled, preserving the directory listing/debugging workflow without exposing page source by default. - Added PSGI and PAGI application builder support for wrapper-style
initialization, including optional static handling and document-root
.webdyne.conf.plloading via the new constructor options. The helper scripts now opt in to this behaviour while directWebDyne::PSGI->new(...)->to_appandWebDyne::PAGI->new(...)->to_appconstruction retains conservative defaults. - Fixed PSGI API fallback path traversal by rejecting dot path segments before route discovery and verifying discovered API files remain inside the document root using canonical relative-path checks. Added regression coverage for traversal attempts and normal API routing.
- Restored end-of-string matching for WebDyne PSP filenames so files such as
report.psp.pdfare not treated as executable PSP pages. This fixes a double-extension execution regression introduced whenWEBDYNE_PSP_EXTbecame configurable. - Re-enabled CGI form value escaping by default and fixed the
WebDyne::HTML::Tinyentity encoder override soWEBDYNE_CGI_AUTOESCAPEworks as documented. Sticky text, password, and file form fields now escape request-derived values before rendering them into HTML attributes. - Applied automatic HTML escaping to request, environment, and method
substitution operators (
+{...},*{...}, and^{...}) whenWEBDYNE_CGI_AUTOESCAPEis enabled. The raw${...}substitution operator remains available for trusted, already-rendered values. - Added secure session cookie defaults and configuration constants for
Secure,HttpOnly, andSameSiteattributes. WebDyne sessions now emitSecure,HttpOnly, andSameSite=Laxcookies by default, with documented constants for deployments that need to adjust those attributes. - Preserved
<start_html>shortcut version overrides and added regression coverage for local-configuration isolation so tests are not affected by a developer's document-root.webdyne.conf.pl. - Updated the XML documentation, markdown sidecars,
MANIFEST, and test suite for the new helper defaults, index source controls, escaping behaviour, PSP extension matching, PSGI/PAGI initialization, API traversal checks, and session cookie flags.
3.021 - 2026-08-24
- Extended
wdlintto inspect inline Perl chunks, processing instructions, and substitution expressions in addition to__PERL__sections. Each chunk is checked independently so later syntax errors are still reported after an earlier chunk fails. Added line-preserving regression coverage. - Added
requireandimportattributes to<start_html>, using the same dependency-loading and function-import behaviour as<perl>. Declared dependencies are loaded before normal, SSE, and WebSocket handlers are dispatched. - Passed CGI parameter hashes to PAGI SSE and WebSocket subroutines as their
second argument, allowing async handlers to use request parameters
explicitly across
awaitpoints. - Fixed URL-encoded form POST handling under PAGI by asynchronously buffering
request bodies before synchronous
CGI::Simpleparsing. Kept the cached body available to the WebDyne PAGI request adapter and avoided crossing localized environment scopes duringawait. Added repeated-request regression coverage for the former Future panic. - Added documentation and WebDyne authoring guidance for start_html
dependencies, PAGI parameters, SSE/WebSocket handlers, HTMX fragments, and
the required
hx-vals="js:{ ... }"syntax when supplying values from PSP pages. - Added release-board and pizza-order SSE/HTMX demonstration pages, including WebDyne-rendered fragments, status refreshes, and PAGI handler examples. Kept these developer demos and scratch material out of distribution manifests.
3.020 - 2026-08-20
- Changed
<api>route pattern semantics so patterns are relative to the discovered API PSP file path. For example,api.pspowning/api/user/42now usespattern="/user/:id"rather thanpattern="/api/user/:id". This is a breaking change for existing<api>pages. - Updated PSGI and PAGI API fallback dispatch to strip the full API PSP
mount path from
PATH_INFObefore passing requests toRouter::Simple, keeping API route declarations independent of document-root location. - Updated API examples, release examples, tests, and local authoring
guidance to use the new suffix-only
<api pattern>convention. - Documented the WebDyne 3.020
<api>pattern breaking change in the XML documentation and tag reference.
3.013 - 2026-08-16
- Normalized generated
no_*wrapper options to numeric booleans so--dump_optoutput is stable across Perl andData::Dumperversions. - Made the
webdyne.apachewrapper tests less sensitive to whitespace inApache::TestRunPerlargument dumps and avoided macOS APXS probing by using a fake testapxshelper. - Improved PAGI smoke-test diagnostics by allowing
PAGI::Test::Clientapplication exceptions to surface int/14-pagi.tinstead of comparing only against a generic Internal Server Error response. - Added
PAGI::Toolsto thewebdyne.pagiwrapper test prerequisite gate, matching the wrapper's runtime check and avoiding noisy failures on partial PAGI installations.
3.012 - 2026-08-10
- Disabled the redundant
webdyne.apacheulimit probe, avoiding noisy stderr on restricted CPAN smoke hosts where raising the core-file ulimit is not permitted. - Guarded developer-only
doc/examplescans in the generated Makefile so CPAN install and smoke-test runs remain quiet when the documentation source tree is not shipped in the distribution tarball.
3.011 - 2026-08-07
- Extended
wdrender --quiet/--silentto suppress advisory warnings about missing optionalHTML::Tidy5or syntax-highlighting modules while leaving rendering behaviour unchanged. - Updated
wdrenderregression coverage so--headeroutput remains clean on machines withoutlibtidy-develandHTML::Tidy5installed. - Made
wdrenderhead-insert tests tolerant of harmless HTML/CSS whitespace differences while still checking that the default head insert is present or absent as requested.
3.010 - 2026-08-07
- Fixed duplicate response header emission when WebDyne handlers set headers through the request object, avoiding malformed HTTP response headers in PSGI and other runtimes.
- Fixed
wdrender --headeroutput so response headers are included consistently regardless of colour, line-number, pretty-print, or tidy settings. - Added
wdrenderregression coverage for duplicateContent-Typeheaders and for--headerbehaviour with colour/tidy output enabled and disabled. - Added explicit
filenameoverride support forWebDyne::PSGIandWebDyne::PAGIhelper applications, allowing tools such aswdrenderto render a fixed source file while still exercising PSGI or PAGI request handling. - Documented that the
WebDyne::PSGIandWebDyne::PAGIfilenameoption is an application-level source-file override and always wins over normal request-path filename derivation. - Propagated
wdrender --no-head-insert/--head-inserthandling through PSGI, PAGI, and temporary Apache/mod_perl render paths. - Simplified
wdrendertest-file routing for PSGI and PAGI helper modes by passing an explicitfilenameoverride instead of depending on request path rewriting.
3.009 - 2026-08-06
- Added
style_prepend/style_appendandscript_prepend/script_appendpseudo attributes for<start_html>, allowing pages to add resources around configuredWEBDYNE_START_HTML_PARAMdefaults without replacing them. - Clarified
<start_html>default-attribute override behaviour: page attributes replace matchingWEBDYNE_START_HTML_PARAMvalues, while the new prepend/append variants preserve and extend configured style/script resources. - Documented
<start_html>resource ordering for linked styles versusinclude_stylecontent, and external scripts versusinclude_scriptcontent. - Made PSGI and PAGI wrapper configuration loading consistent by loading
DOCUMENT_ROOT/.webdyne.conf.plwhen the app is built, including whenwebdyne.psgiorwebdyne.pagiis loaded by an external server. - Clarified root
.webdyne.conf.plloading versus per-request directory.webdyne.conf.plhandling, where onlyWEBDYNE_DIR_CONFIGis read from PSP-directory config files. - Added regression coverage for
<start_html>style/script extension attributes and PSGI/PAGI external-loader root configuration loading.
3.008 - 2026-08-04
- Added REST-style
<api>route discovery andPATH_INFOmapping toWebDyne::PAGI, bringing PAGI API support in line with PSGI. - Added per-application API filename caches for PSGI and PAGI. API filename or route-structure changes may require a server restart.
- Ensured PAGI emits a valid empty HTTP response when an API document produces no body, avoiding PAGI lint errors.
- Clarified that Apache mod_perl does not provide automatic extensionless API route discovery without additional Apache rewrite or routing rules.
- Added integration coverage for PSGI and PAGI API routing, caching, normal PSP requests, and 404 handling.
- Fixed labelled
<textfield>rendering so label-wrapped text inputs retain the correct HTML input type. - Added
default/defaultshandling for grouped form controls and popup menus, aligning generated form state with the documented attributes. - Added labelled textfield render fixtures and included them in the distribution manifest.
- Updated the XML and generated Markdown documentation for the latest API, form-control, and demo example behaviour.
3.005 - 2026-08-02
Major Version 3 release.
- Added PAGI runtime support through
WebDyne::PAGIand thewebdyne.pagiwrapper, including HTTP, server-sent event, WebSocket, and lifespan request handling. - Added a common request abstraction for standalone, Apache/mod_perl, PSGI, and PAGI execution environments.
- Refactored PSGI support into
WebDyne::PSGIand expanded runtime handling for document roots, default documents, directory indexes, static files, and API routes. - Added
webdyne.apachefor temporary local Apache/mod_perl execution without requiring a permanent system Apache configuration. - Expanded
wdapacheinitto support broader Apache installations, APXS discovery, installation and uninstall workflows, dry-run operation, and platform-specific configuration layouts. - Expanded
wdrenderto exercise multiple request backends, including fake, PSGI, PAGI, and mod_perl, with support for request methods, headers, parameters, response inspection, and comparison testing. - Added test-file modes to command-line compilation and rendering utilities.
- Added a bundled default stylesheet for generated WebDyne pages and improved the appearance of default directory index output.
- Added Docker runtime selection between PSGI and PAGI, with environment-variable tuning for server workers, timeouts, backlog, connection limits, and request body sizes.
- Improved request and static-file safety, including path traversal, upload, multipart, error handling, and binary response coverage.
- Reworked the documentation into a DocBook/MkDocs build with generated utility and module reference pages.
- Added extensive examples and expanded automated test coverage for runtime backends, wrappers, static handling, APIs, SSE, WebSockets, and command-line utilities.
- Removed the old
WebDyne::CGI::PSGIadapter in favour of the new request and runtime abstraction.
2.021 - 2025-11-07
- Added multi-line
<start_html>attributes for scripts, styles, and related inclusions. - Prevented WebDyne substitution inside executable JavaScript blocks.
- Added default viewport metadata and expanded head inclusion support, including array-valued includes.
- Added Alpine/Vue attribute compatibility handling.
2.018 - 2025-10-29
- Added the
<htmx>tag for request-aware HTML fragment rendering. - Made directory indexes and static files available by default through the PSGI wrapper.
- Improved HTML tree handling, constant importing, and error reporting.
2.017 - 2025-10-27
- Added the
<api>tag for lightweight JSON API responses usingRouter::Simplepath matching.
2.015 - 2025-10-22
- Added the
wdlintutility for checking Perl syntax in__PERL__sections of PSP files. - Added the default PSGI directory index page and
--indexsupport.
2.014 - 2025-10-18
- Replaced the CGI.pm-based HTML generation path with
CGI::SimpleandWebDyne::HTML::Tiny. - Refactored compilation and evaluation handling around the new HTML generation backend.
- Added the JSON tag, alternate div-based WebDyne syntax,
application/perlscript blocks, and expanded HTML5 tag handling. - Added PSGI/Plack support to the main WebDyne distribution, including command-line document-root and default-document selection.
- Added exported
WebDyne::html()andWebDyne::html_sr()functions for standalone PSP rendering. - Added
WebDyne::Templateto the core distribution and added PSGI static-file serving through--static. - Added
WEBDYNE_HEAD_INSERTfor injecting common content into generated document heads. - Added Docker build files and container-oriented development support,
including automatic dependency installation from a mounted
cpanfile.