Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Workerman Bundle Laravel Package

crazy-goat/workerman-bundle

Symfony bundle integrating Workerman to run a high-performance async HTTP server, scheduler and supervisor in pure PHP. Keeps the Symfony kernel/container alive between requests for faster apps. Supports SO_REUSEPORT and optional direct Request creation for speed.

View on GitHub
Deep Wiki
Context7
v0.24.1

Security

  • Prevent middleware header mutations from persisting in Workerman's request cache and being replayed to later requests with the same raw buffer. Headers are restored after each request dispatch, preventing cross-request identity, proxy, and tenant-state leakage (#576)

  • Fix remote unauthenticated denial-of-service: a single control byte in any request header value killed the worker process. The request lifecycle in HttpRequestHandler::__invoke() is now wrapped in a try/catch that converts throwables into 400/500 responses, and ServerWorker::onConnect installs a TcpConnection::$errorHandler backstop that closes the connection instead of letting Workerman call Worker::stopAll(250). Client errors (MalformedRequestException, FileUploadValidationException) are logged at debug level to prevent log flooding; server faults are logged at error level. A nested try/catch around the error-response send ensures doTerminate() and the reboot check still run when even the send fails (#577)

Changed

  • RequestConverter now throws MalformedRequestException (extends \InvalidArgumentException, implements ClientInputExceptionInterface) instead of bare \InvalidArgumentException for malformed client input (control bytes in headers, invalid URI/method). This lets HttpRequestHandler distinguish client errors (400) from server faults (500) — a middleware throwing \InvalidArgumentException is now correctly a 500, not a 400 (#577)

Added

  • CrazyGoat\WorkermanBundle\Exception\ClientInputExceptionInterface — marker interface for exceptions caused by malformed client input, implemented by MalformedRequestException and FileUploadValidationException (#577)

  • CrazyGoat\WorkermanBundle\Exception\MalformedRequestException — thrown by RequestConverter for malformed client input (control bytes, invalid URI/method) (#577)

v0.24.0

Performance

  • Optimize InotifyMonitorWatcher startup by deferring the recursive directory walk to after the event loop starts. At boot only the top-level source directories are watched; remaining subdirectories are watched lazily via a single deferred pass. This eliminates a synchronous full-directory walk that could delay worker readiness on very large source trees (#324)

  • Optimize FileMonitorWatcher::checkPattern() by compiling glob patterns to a single PCRE regex at construction time, reducing per-tick matching from O(files × patterns) to O(files) (#339)

Tests

  • Harden PHAR-build tests against silent phar.readonly skips: add phar.readonly=0 to composer test / composer test:coverage scripts and CI workflow ini-values, introduce PharReadOnlyGuardTest that fails under CI when phar.readonly is set without explicit opt-out (WORKERMAN_ALLOW_PHAR_READONLY_SKIP=1), and refactor testCommandFailsWhenPharReadonlyIsSet to use injected PharCapabilities instead of depending on the runtime INI setting (#340)

  • Harden UtilsTest signal-logic tests: add pcntl and posix extensions to CI runner, introduce guard test that fails when extensions are missing without explicit opt-out (WORKERMAN_ALLOW_PCNTL_SKIP=1). macOS contributors can skip these tests locally by setting the env var (#346)

  • Populate <coverage/> in phpunit.xml with Clover and text report output, add composer test:coverage and composer coverage:check scripts, and enforce a line-coverage threshold in CI using bin/check-coverage.php. CI enables PCOV, generates var/coverage.xml, and uploads it as an artifact per matrix job. A regression test asserts the coverage gate remains present in .github/workflows/tests.yaml (#357)

  • Expand ProcessTest from a single PID-file recency check to full process lifecycle coverage: ProcessStartEvent dispatch regression check, ProcessErrorEvent dispatch on throwable (via new TestErrorProcess), no-error-event assertion during normal operation, and SIGTERM-to-worker restart verification (locates the worker PID via /proc on Linux or ps on macOS). Introduces ProcessEventRecorder test listener and ProcessMarkerPaths constants class as the shared source of truth for marker file paths (#348)

Added

  • Add PHPBench benchmark suite covering the five documented hot paths: RequestConverter::toSymfonyRequest, ResponseConverter::convert, MemoryRebootStrategy::shouldReboot, PeriodicalTrigger::getNextRunDate, and HttpRequestHandler::__invoke (composed middleware chain). Run via composer bench. CI executes the suite on every PR in advisory mode (results are logged but do not block merge). Documented measurement protocol in CONTRIBUTING.md (#328)

  • Add a cross-platform middleware dispatch contract test (MiddlewareDispatchContractTest). A dedicated test server on port 9991 runs a counting middleware that increments a shared counter file under flock() and tags every response with X-Dispatch-Count. The contract asserts that exactly one dispatch is observed per incoming HTTP request (single + sequential request cases), so any regression of the issue #533 dispatch-count class — including the macOS-specific triple-dispatch — fails CI immediately and on every supported OS (#542)

Changed

  • Extract the side-effectful phar.readonly INI probe and \Phar extension presence check out of PharBuilder::build() into a new PharCapabilities collaborator. PharBuilder now accepts the capability checker via constructor (defaults to a live PharCapabilities::probe()), making the runtime checks individually testable and stubbable. The DI container registers PharCapabilities and injects it into the workerman.phar_builder service. No behavioural change observable for the build:phar flow (#372)

Fixed

  • Reset the test middleware execution-order accumulator on the first middleware invocation so MiddlewareTest::testHeaders no longer sees a stale X-Test-Middleware-request-order value on subsequent keep-alive requests under macOS / Workerman. Added a regression test that performs two consecutive requests through the same HTTP client and asserts identical middleware order on both responses (#533)

  • Make ProcessInspector::isProcessAlive() portable across POSIX systems — on macOS and other non-Linux platforms where /proc is unavailable, the function now uses posix_kill($pid, 0) for the primary liveness check and falls back to a non-blocking pcntl_waitpid() to distinguish running processes from zombies. The Linux /proc/{pid}/status zombie check is preserved as a Linux-only refinement. getParentPid(), isMasterRunning(), and killOrphanedIntermediateFork() are likewise gated on PHP_OS_FAMILY === 'Linux' so they no longer crash on macOS. Fixes ServerManager::stop() returning false on macOS because waitForProcessToStop() never observed the process dying (#530)

  • ProcessTest::testProcessIsLive failed on macOS because TestProcess wrote the status timestamp only once per __invoke() invocation, then exited. Once Workerman's boot + shutdown + supervisor respawn cycle exceeded 4 seconds (common on macOS), the persisted timestamp always looked stale. TestProcess now refreshes the status file on a 1-second heartbeat inside a loop so the timestamp always stays within the test's recency window; the test's secondary budget is widened from 4 to 10 seconds as a safety net (#534)

  • Fix race condition in ServerManager::getStatus() / getConnections() where PHP's stat cache and stale status files from interrupted runs could cause waitForFile() to read an empty or incomplete file written by Workerman's SIGIOT/SIGIO handler. StatusFileReader::waitForFile() now calls clearstatcache() before each poll and rejects 0-byte files. ServerManager deletes the stale status/connections file before signaling, ensuring waitForFile() always waits for fresh output from the current signal. Fixes WorkermanCommandTest failures on macOS where slower filesystem operations widened the race window (#535)

Security

  • Harden PharBuilder's user-supplied exclude_patterns against accidental ReDoS at build time. ExcludePattern now performs defense-in-depth: (1) a structural lint at construction time that rejects patterns containing nested unbounded quantifiers ((a+)+, (.+)*, (a+){2,}, ...) before the build ever traverses the source tree, (2) a PCRE compile-check against a probe string that surfaces patterns PHP itself rejects with a clear error message, (3) a per-call pcre.backtrack_limit/pcre.recursion_limit guard inside matches() that returns false rather than hanging if the limit trips. The temporary ini values are restored on every exit path. Negative regression test (testBuildRefusesNestedUnboundedQuantifierPattern) and a behavioural test for the per-call guard prevent future regressions. Documentation in docs/build-packaging.md recommends atomic groups ((?>...)) as the PCRE-native alternative for matching power that would otherwise require nested quantifiers (#334)
  • Add explicit PHPDoc security warnings on Request::setHeader() and Request::withHeader() flagging that re-injecting X-Forwarded-* or Forwarded headers from untrusted input re-creates the trusted-proxy bypass class of bugs (#344)
  • Document the middleware header re-injection trust model in a new docs/security.md section — covers the risk, recommended ordering (run trusted-proxy filtering after middleware that mutates headers), scope-limiting forwarding-header writes, and the canonical Symfony setTrustedProxies() / setTrustedHosts() alternative (#344)
  • Replace the loose str_contains('/proc/$pid/cmdline', 'WorkerMan') check in ProcessInspector with a fingerprint-based verification. ServerManager now writes a sidecar fingerprint file (<pid_file>.fingerprint) at start time, recording the master PID, start time (clock ticks since boot, Linux only), and UID. ProcessInspector verifies all three fields before signaling, preventing misidentification of unrelated co-located processes whose command line happens to contain "WorkerMan". The legacy cmdline-based check is retained as a fallback when no fingerprint file is present (backward compatibility and daemon mode). The fingerprint file is created with 0600 permissions and removed on stop() (#327)
  • Document the Composer audit advisory suppression policy in docs/security.md. The audit.ignore list is kept empty — no Composer security advisory is suppressed globally. Dev-only advisories are handled via composer audit --no-dev (the CI/production audit mode), so production dependencies are never shielded by a global suppression. Add testAuditIgnoreListIsEmpty and testComposerAuditNoDevIsClean tests to enforce the policy and prevent accidental re-introduction of suppressed advisories (#337)

Code Quality

  • Replace $_SERVER['WORKERMAN_CACHE_WARMUP_TIMEOUT'] superglobal mutation with a typed CacheWarmupTimeoutConfig static holder that bridges the bundle extension loader (runs during kernel boot) and Runner construction (runs later, outside the DI container via Runtime::getRunner() or ServerManager::start()/restart()). The env-var override path is preserved — WorkermanBundle::loadExtension() still reads WORKERMAN_CACHE_WARMUP_TIMEOUT from $_SERVER/$_ENV and applies it before storing the resolved value in the holder. Runner now accepts the timeout as a constructor argument with a default of 30 seconds, and the validation rule (>= 1) lives in one place on the holder (#368, #367)

Docs

  • Update docs/security.md Static Files Protection examples to use the StaticFilesMiddleware service approach instead of the deprecated serve_files and root_dir server options. All YAML examples now show the recommended service registration pattern (#345)

  • Add explicit [@api](https://github.com/api) annotation to Utils::reload() to clarify that it is the canonical public API for programmatic worker reload, resolving the remaining ambiguity from the [@internal](https://github.com/internal) removal in 0.21.0 (#352)

  • Delegate issue triage and code review steps in docs/workflow.md to subagents with their own context, protecting the main session's token budget for implementation and fixes (#531)

v0.23.0

Tests

  • Replace testRunnerUsesCorrectForkErrorHandling (which read Runner.php as a string) with testForkFailureThrowsRuntimeException — a behavioral test that stubs the fork() method via a readonly subclass and asserts RuntimeException is thrown when pcntl_fork() returns -1. Removes the dead fork_failure case from the isolated test fixture (#313)
  • Replace testBootstrapClosesProcOpenPipes and testWorkermanCommandClosesProcOpenPipes (which read source-code files as strings and asserted on substrings) with behavioral tests that exercise the proc_open pipe cleanup pattern on actual subprocesses and assert all pipe resources are closed after fclose() (#319, #326)
  • Replace testSourceFileNoLongerContainsGetFileInfo (which read PollingMonitorWatcher.php as a string and asserted on a substring) with testPollUsesSingleStatPerFile — a behavioral test that instruments the iterator with CountingSplFileInfo and asserts exactly one stat() call per file. The new test catches any redundant stat-touching call (getFileInfo(), getSize(), isFile(), duplicate getMTime(), etc.) under any name, not just getFileInfo() (#330)
  • Expand StreamedBinaryFileResponseTest with comprehensive test coverage: content type detection, Content-Length verification, Content-Disposition, offset/maxlen behavior, deleteFileAfterSend cleanup, output correctness for small and large files, chunk size validation, auto ETag/Last-Modified headers, and edge cases (empty file, non-readable file, private responses) (#353)
  • Replace testSchedulerWorkerLogsExceptionsInChildProcess (which read SchedulerWorker.php as a string and asserted on substrings) with a behavioral test that forks a child, invokes SchedulerWorker::handleChild via reflection with a TaskHandler that throws, and asserts the child exits with code 1 and the exception is logged via Worker::log() (#306)

Security

  • Add world-writable permission check to ConfigLoader::loadFromCache() before requiring the generated PHP cache file. Cache files with world-writable permissions are now rejected with a clear error message, preventing arbitrary code execution if the cache directory is misconfigured (#323)
  • Force umask(0077) while writing the config cache file in ConfigLoader::warmUp() so the generated PHP file is always created with restrictive 0600 permissions, regardless of the surrounding umask (#323)
  • Document the trust requirement for the config cache directory in docs/security.md — the cache directory must not be writable by untrusted users (#323)
  • Remove [@unlink](https://github.com/unlink) error suppression in BinaryFileResponseStrategy cleanup callback; unlink failures are now checked and logged through the injected PSR-3 logger (#314)
  • Use onBufferDrain as the primary cleanup hook in BinaryFileResponseStrategy instead of onClose, so file deletion runs at the correct lifecycle point (after the send buffer is flushed) and does not persist across keep-alive requests; onClose is retained as a fallback for early disconnects; both callbacks self-remove after firing and chain to any previously-set handlers (#308)
  • Use atomic rename-before-read (TOCTOU fix) in ServerManager::consumeFile() for status and connections files to prevent symlink-swap redirection of the unlink. A failure to unlink the renamed temp file is now logged through the PSR-3 logger instead of being silently suppressed (#304)

Performance

  • Make Connection: close header check case-insensitive in HttpRequestHandler — RFC 7230 treats the token case-insensitively, so Close, CLOSE, etc. now correctly trigger connection close, preventing wasted file descriptors and unexpected request reuse in long-running workers (#336)
  • Gate memory_reset_peak_usage() behind a boot-time flag so the per-request syscall is skipped when no reboot strategy needs memory_get_peak_usage() — currently no bundled strategy uses peak memory, so the call is eliminated entirely on the hot path (#317)
  • Replace ExceptionRebootStrategy's full Throwable storage with a boolean flag to eliminate a memory leak in long-running workers — the previous implementation retained the exception's entire stack trace (including referenced Request, controller, and service object graphs) until shouldReboot() was consumed (#307)
  • Cache method_exists() results per (class, method) pair in ServiceHandlerTrait to avoid redundant reflection lookups on every tick/invocation in TaskHandler and ProcessHandler (#315)

Code Quality

  • Extract Util\Wait::until() to unify the polling strategy in StatusFileReader::waitForFile() (previously a fixed 50ms cadence) and ProcessInspector::waitForProcessToStop() (previously an inline exponential-backoff loop with time()-based deadlines). The shared helper polls a condition with exponential backoff from 10ms up to 250ms and uses microtime(true) deadlines, so the total wall time stays at or below the configured upper bound (the old time()-based path could overshoot by up to one second) (#362)
  • PollingMonitorWatcher: relax final on the class and on FileMonitorWatcher::createRecursiveIterator() so a test-only subclass can inject a counting RecursiveDirectoryIterator. The behavioral test in PollingMonitorWatcherTest requires this extension point to verify the watcher makes exactly one stat() call per file; without it, the test would be limited to flaky wall-time heuristics (#330)
  • CronExpressionTrigger: remove redundant class_exists(Cron\CronExpression::class) gate from the constructor — the check is already performed by TriggerFactory::create() before instantiation, making the duplicate guard unreachable and misleading (#355)
  • TriggerFactory: replace falsy object check (if ($dateTime)) with explicit instanceof \DateTimeImmutable check to clarify that the branch is taken only when ISO-8601 datetime parsing succeeds, and to avoid relying on object truthiness (#361)
  • WorkermanCommand: rename $allowedActions local variable to $invalidActionMessage so the name accurately reflects that it holds an error message, not a list of allowed actions (#373)
  • StaticFilesMiddleware: replace repeated DIRECTORY_SEPARATOR . ltrim($path, '/') with a named joinPaths() helper that normalises both root and request path separators explicitly, eliminating implicit coupling that would silently produce wrong paths if a future change stripped the leading slash (#365)
  • WorkermanCompilerPass: standardise tag set ordering — $responseConverterStrategies remain sorted by priority (descending) for correct dispatch order in ResponseConverter::convert(), while $tasks, $processes, and $rebootStrategies are now sorted by service ID via ksort for deterministic ServiceLocator registration and reproducible container builds (#371)
  • BinaryComposer: reduce MAGIC_BYTES visibility from public to private — the constant is only used internally and was accidentally exposed as part of the public API (#363)
  • PeriodicalTrigger: remove fragile (array) cast on \DateInterval to read the private from_string property; replace with a flat 'DateInterval' description for directly-passed DateInterval objects (#360)
  • ServicesConfigurator: use === true consistently for all boolean active config flags in configureRebootStrategies() — previously only memory.active used strict comparison, while always, max_requests, and exception used a truthy check (#370)
  • DateTimeTrigger: move assignment out of if condition to eliminate assignment-in-condition smell and avoid potential =/== confusion (#359)
  • Http\Request: add runtime deprecation notice to withHeader() warning that the PSR-7-named alias is misleading — it mutates the request in place rather than returning a new instance; users should migrate to setHeader() (#364)

Docs

  • Add comprehensive interface-level and per-method PHPDoc to MiddlewareInterface, RebootStrategyInterface, and TriggerInterface — every interface now documents its purpose, lifecycle, consumption site, and parameter/return semantics so third-party implementers have a complete contract reference (#322)

  • Update "What's new in this fork" section in README.md with a comprehensive comparison against upstream luzrain/workerman-bundle, covering 20+ feature additions, dependency differences, and architectural changes (#491)

  • Document composer test port binding, troubleshooting steps, and workarounds in CONTRIBUTING.md to help contributors avoid "Address already in use" errors (#358)

  • Update README main configuration example to demonstrate StaticFilesMiddleware instead of relying on the deprecated serve_files option; the replacement was previously only shown in a dedicated subsection (#342)

  • Document --include-tests and --kernel-class CLI options in docs/build-packaging.md — these options were already supported by workerman:build:phar but omitted from the documentation (#331)

  • Resolve contradiction between CONTRIBUTING.md and CHANGELOG.md on approval policy: CONTRIBUTING.md now accurately reflects the current "no approval count required (solo dev project)" policy, matching the historical CHANGELOG 0.15.0 entry (#333)

  • Document runtime_dir in the README.md configuration reference, with full semantics (writable, must live outside the PHAR in PHAR/BIN mode, restrictive 0700 permissions on subdirectories) and a cross-link to docs/build-packaging.md; align the ConfigurationTreeBuilder info string with the README so config:dump-reference matches (#343)

  • Replace [@param](https://github.com/param) mixed[] with typed array{...} shapes on ServerWorker::__construct()/configureHandler()/createSslContext(), PharBuilder::build()/buildExcludePatterns()/buildExcludeFiles()/generateStub(), BuildPathResolver::resolveBuildDir()/resolvePharPath()/resolveBinPath()/resolveFilename(), and WorkermanBundle::loadExtension() — the shapes mirror the ConfigurationTreeBuilder definitions so PHPStan can verify config access and IDEs can autocomplete keys (#332)

v0.22.0

Security

  • Route exception logging in HttpRequestHandler through PSR-3 logger instead of error_log() (#296) — #466
  • StaticFilesMiddleware: add follow_symlinks option (default: false) (#292) — #473
  • ServerWorker: validate SSL cert/key paths are regular files and not symlinks (#286) — #474
  • Add connection_timeout, keepalive_timeout and per-server body_size_cap for slowloris protection (#279) — #477

Performance

  • Cache PID file handles in SchedulerWorker to avoid fopen/fclose in event loop (#297) — #464
  • Replace per-tick closure allocation in SchedulerWorker with first-class callable (#293) — #479
  • Cache normalizeHeaderName results and fix irregular header acronyms (#287) — #468
  • Add early return in FileUploadValidator::validate when no uploaded files (#281) — #469

Code Quality

  • ConfigLoader::getConfig: split into named methods, replace silent empty-fallback with exception (#325) — #480
  • ConfigLoader: move setBuildConfig into setters block (#329) — #481
  • Make TaskErrorEvent immutable by removing unused setError mutator (#338) — #467
  • Remove redundant function_exists checks in InotifyMonitorWatcher (#341) — #478
  • Fix InotifyMonitorWatcher::$pathByWd PHPDoc type (#347) — #484

Deprecated

  • Utils::reboot() deprecated since 0.17.0; Utils::reload() is the replacement (#318) — #485

Tests

  • Add event ordering and __invoke fallback tests to TaskHandler and ProcessHandler (#276) — #472
  • Add onWorkerStart invocation tests to ServerWorkerTest (#284) — #471
  • Add in-process pipeline coverage and gate live-server test in MiddlewareTest (#288) — #470
  • Add coverage for processFiles non-array drop branch in RequestConverterTest (#294) — #475
  • Replace source-grep test in SchedulerWorkerSigchldTest with behavioral test (#302) — #476

Docs

  • Add class-level and constructor PHPDoc to AsTask and AsProcess attributes (#309) — #486
  • Add class-level PHPDoc to HttpRequestHandler explaining the request lifecycle (#320) — #482
  • Add class-level and method PHPDoc to Request class (#321) — #487
  • Add class-level PHPDoc to Start/Error events marking them as extension points (#335) — #483
  • Fix orphaned footnote notation for php-event extension note in README (#311) — #489
  • Add License section and MIT badge to README (#300) — #488
  • Normalise ** list/emphasis markers to * / blockquote format in README (#310) — #490

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.21.0...v0.22.0

v0.21.0

[0.21.0] - 2026-05-29

Security

  • Validate kernel_class in PHAR stub generation — reject invalid PHP class names to prevent code injection (#263)
  • Validate PHAR alias before stub generation — reject filenames with dangerous characters that could alter generated stub code (#259)
  • Restrict runtime directory creation to explicit 0700 mode — prevents other users on multi-user systems from reading PID/status files (#270, #274, #453)

Performance

  • Pre-compose middleware pipeline once at startup instead of rebuilding on every request (#266)
  • Remove per-request Timer::add(0, ...) for terminate scheduling — reduces event-loop timer churn (#273)
  • Skip file processing in RequestConverter when no files are present in the request (#277)

Changed

  • Remove PharHelper::getProjectDir — thin wrapper that duplicates rtrim() with no added value (#316)
  • Make WorkermanCompilerPass final — leaf class with no subclasses (#312)
  • Extract buildServerBag() and detectFormData() from RequestConverter::toSymfonyRequest() — reduces a 180-line method to coordinated delegates (#301)
  • Extract helper methods from HttpRequestHandler::__invoke() — eliminates duplicate terminate try/catch (#291)
  • Extract magic timeout numbers into named constants in ServerManager — replaces opaque formula comment (#295)
  • Extract shared RecursiveDirectoryIterator setup into a single method — removes duplicated boilerplate in Polling/Inotify watchers (#285)
  • Extract shared AbstractErrorListener and AbstractHandler base classes — eliminates near-identical code in Task/Process error listeners and handlers (#278, #275)
  • Extract configureHandler() from ServerWorker::onWorkerStart() — reduces closure complexity

Fixed

  • Fix StaticFilesMiddleware to work with phar:// stream wrappers — realpath() returns false for phar:// paths, making the middleware unusable when running as PHAR/standalone binary (#447)
  • Fix README.md RebootStrategyInterface example — wrong FQCN caused copy-paste to fail (#289)
  • Add ext-zip and ext-inotify to CI, fix test assertions for missing extensions
  • Fix PHPStan type annotations in test helpers

Tests

  • Add end-to-end tests for Runner::run() covering all decomposed entry points and process lifecycle (#260)
  • Cover full ServerManager public surface with integration tests (#264)
  • Invoke HttpRequestHandler in test instead of only testing construction and inheritance (#253)
  • Add tests for AsProcess and AsTask attributes covering all configuration options (#247)
  • Verify gc_collect_cycles() is actually invoked in MemoryRebootStrategy (#271)

Docs

  • Add troubleshooting guide for long-running worker semantics — covers common pitfalls with stateful services, memory leaks, connection reuse (#283)
  • Resolve [@internal](https://github.com/internal) vs public-API contradiction in Utils class — Utils::reload() is now explicitly documented as a public API for programmatic graceful worker reload (#290)
  • Disambiguate bin/console in README — clarify it refers to the application's console, not the bundle's bin/ directory; add bin/README.md (#282)
  • Exclude docs/superpowers/ planning artifacts from Composer package export (#298)
  • Expand composer.json keywords and description for Packagist discoverability (#299)
v0.20.0

[0.20.0] - 2026-05-26

Security

  • Add extension denylist + allowlist filtering for static file serving in `StaticFilesMiddleware` (#235)
  • Fix TOCTOU race in `SchedulerWorker` PID file handling — uses exclusive flock with strict permissions (#240)
  • Add zip-slip protection to `SfxDownloader::extractZip` — validates entry paths against destination (#252)
  • Block cross-scheme redirects and require SHA-256 checksum for SFX downloads (#433)

Performance

  • Add LRU cache and conditional `If-Modified-Since` / `If-None-Match` support to `StaticFilesMiddleware` (#254)
  • Shard `PollingMonitorWatcher` directory scan across ticks with `MAX_FILES_PER_TICK` (#246)
  • Defer `gc_collect_cycles` and use single `memory_get_usage` call in `MemoryRebootStrategy` (#250, #272)
  • Replace 10-year `DatePeriod` with O(1) `DateTime::add()` in `PeriodicalTrigger` (#239)

Added

  • New `ListenScheme` enum for type-safe listen scheme (#305)
  • New `BuildPathResolver` consolidating duplicated `resolveXxxPath` helpers (#242)
  • New `ServiceMethod` value object replacing stringly-typed concatenation (#258)
  • New `SfxSourceResolver` extracted from `BuildBinCommand::resolveSfx` (#238)
  • New `e2e/README.md`

Changed

  • Moved PHAR stub from HEREDOC to `resources/phar-stub.tpl` (#234)
  • Split `ServicesConfigurator::configure()` into per-domain methods (#249)
  • Split `SfxDownloader::extractZip` into staged methods (#251)
  • `SchedulerWorker::$handler` now readonly on final class (#262)
  • `SupervisorWorker` now `final` (#265)

Tests

  • `KernelFactoryTest` (#224)
  • `RuntimeTest` (#228)
  • `ResolverTest` (#230)
  • `ByteFormatterTest` (#241)
  • `TaskErrorListenerTest` and `ProcessErrorListenerTest` (#237)

Docs

  • Add `UPGRADE.md` covering 0.12–0.17 (#256)
  • Document `build.sfx.sha256` and `build.sfx.allow_insecure` (#267)
  • Document `workerman:server` connections output columns (#269)
  • Clean up stale README 'What's new' section (#268)
v0.19.0
  • docs: add CHANGELOG for 0.19.0 release
  • feat: stream StreamedResponse body in chunks instead of buffering entire body
  • [Performance] DefaultResponseStrategy sends large responses in chunks
  • [Code Quality] Extract ProcessInspector and StatusFileReader from ServerManag...
  • [Tests] Add SchedulerWorker behavioral tests covering fork, flock, and PID li...
  • [Tests] Add InotifyMonitorWatcherTest covering isFlagSet, start, watchDir, on...
  • [Code Quality] Inject ConfigLoader into ServerManager, consolidate PHAR path ...
  • [Docs] Add Configuration reference section covering all top-level config options
  • [Code Quality] FileUploadValidator::validateFileEntry refactored into focused...
  • [Docs] Add Middlewares section to README with StaticFilesMiddleware example
  • [Code Quality] Refactor Runner::run into focused helper methods (#210)
  • feat: add trusted_hosts config for Host header enforcement (#394)
  • [Tests] FileMonitorWorker has no test (#218)
  • [Security] Cookie header merged with comma allows cookie smuggling (#217)
  • [Code Quality] RequestConverter::processFiles silently drops non-array file e...
  • [Performance] Chain onClose callbacks in BinaryFileResponseStrategy instead o...
  • docs: document that servers.listen is effectively required and list supported...
  • [Security] Validate URI and HTTP method in RequestConverter (#220) (#388)
  • [Code Quality] Refactor SchedulerWorker::runCallback into extracted branch ha...
  • [Tests] SupervisorWorker has no test (#215) (#386)
  • [Performance] Batch-load all ReflectionProperty instances in one ReflectionCl...
  • [Docs] Document reload_strategy.memory in README (#233)
  • [Docs] Add docs/README.md index page for user-facing documentation (#244) (#383)
  • [Code Quality] Consolidate BinaryFileResponseStrategy reflection helpers into...
  • [Tests] FileMonitorWatcher base class create() and checkPattern() tests (#221...
  • [Docs] Use unprivileged port in README quick-start example (#245) (#380)
  • [Code Quality] Split ConfigurationTreeBuilder::configure into per-section hel...
  • refactor: extract PharBuilder inline filter into named classes (#378)
  • fix: reorder CHANGELOG.md 0.16.0 to correct reverse-chronological position (#...
  • fix: resolve StaticFilesMiddleware path traversal (#226)
  • fix: nullify request/response refs in SymfonyController on exception path (#375)
v0.18.0

Added

  • PHAR and standalone binary packaging support (#191)
    • New workerman:build:phar and workerman:build:bin commands
    • New PharHelper utility for PHAR mode detection
    • New build configuration section
    • --kernel-class CLI option
    • File monitor auto-disabled in PHAR mode

Changed

  • Runner source path now configurable (#130)

Fixed

  • Improved cache warmup error messages (#129)
  • Closed proc_open pipes to prevent FD leaks (#170)
  • Replaced boolval() with (bool) cast (#159)
  • Added final keyword to test classes (#168)
  • Removed redundant getFileInfo() call (#166)
  • Replaced deprecated Rector LevelSetList (#164)
  • Enabled composer audit block-insecure (#43)
  • Aligned test namespace with PSR-4 (#167)
  • Updated phpunit.xml schema (#162)
  • Pinned PHP version in CI lint job (#169)
  • Replaced flaky composer audit test with E2E (#188)
v0.17.0

v0.17.0 — Code quality, DI improvements, and dead code removal

Added

  • Utils::reload() — New canonical method name for graceful worker restart. Utils::reboot() is preserved as a deprecated alias with a deprecation notice. All internal callers and watcher classes have been updated. (#32)
  • SymfonyController via DIHttpRequestHandler now receives SymfonyController $controller through constructor injection instead of instantiating it internally. This enables easier testing, decoration, and swapping of the controller. A new workerman.symfony_controller service with autowiring alias is registered via WorkermanCompilerPass. (#158)

Changed

  • require pattern refactored — Replaced the require() calls in WorkermanBundle with proper injectable classes: ConfigurationTreeBuilder (configuration tree definition) and ServicesConfigurator (service registration). Removed src/config/configuration.php and src/config/services.php. (#145)
  • CompilerPass simplification — Removed unnecessary array_map transformations and simplified data flow in WorkermanCompilerPass. (#24)
  • Abandoned packages now reported — Changed composer.json audit.abandoned from "ignore" to "report" so abandoned package warnings are no longer silently suppressed during composer install/composer update. (#163)

Fixed

  • FPM-specific no-ops removedStreamedBinaryFileResponse no longer calls ignore_user_abort() and connection_aborted(), which have no effect in Workermans event-driven architecture. Added 14 unit tests and 1 E2E test. (#160)
  • Magic string extracted — The literal "+10 year" in PeriodicalTrigger is now a named class constant MAX_SCHEDULE_HORIZON. (#156)

Removed

  • Dead stream code — Deleted StreamResponseInterface and the streamContent() generator method from StreamedBinaryFileResponse. The interface was never referenced externally, and the generator was never called — BinaryFileResponseStrategy handles all BinaryFileResponse subclasses via instanceof using Workermans native withFile(). (#165)
  • Skipped tests — Removed 8 permanently skipped (never-executed) test methods from HttpRequestHandlerTest that inflated test metrics without providing coverage. (#154)

BC Breaks

  • HttpRequestHandler constructor — Changed from 3 parameters (KernelInterface $kernel, RebootStrategyInterface $rebootStrategy, ResponseConverter $responseConverter) to 2 parameters (SymfonyController $controller, RebootStrategyInterface $rebootStrategy). The class is final; all in-repo callers have been updated. (#158)

Security

  • No security changes in this release.

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.16.0...v0.17.0

v0.16.0

v0.16.0 - 2026-05-18

Added

  • Configurable cache warmup timeout (#142, #180)
    • New cache_warmup_timeout config node (minimum 1s, default 30s)
    • New WORKERMAN_CACHE_WARMUP_TIMEOUT environment variable override
    • Removed hardcoded 30s constant from Runner

Security (breaking change)

  • RequestConverter no longer trusts X-Forwarded-Proto header unconditionally (#152)
    • HTTPS is now detected only from Workerman's actual SSL transport layer
    • Users behind reverse proxies must configure Symfony's trusted proxies to restore HTTPS detection

Fixed

  • Runner::run()mkdir() return value now checked; throws RuntimeException on failure instead of silent failure (#151)
  • Runner::run() — cache warmup timeout added; uses posix_kill() instead of exit() to avoid deadlock with extensions (e.g., grpc) (#141)
  • ProcessHandler/TaskHandler — dynamic method calls now validated; throws InvalidArgumentException when method doesn't exist instead of crashing the worker (#153)
  • Utils::cpuCount() — handles null from shell_exec('nproc') (e.g., minimal containers); returns 1 as safe fallback (#150)
  • PeriodicalTrigger — removed useless assert() calls (#178)
  • SchedulerWorker — exceptions in forked child processes are now logged with full diagnostic information instead of being silently swallowed (#178)
  • ServerManager — replaced hardcoded sleep(1) with a polling loop and configurable timeout for status/connections file generation (#155)
  • WorkermanCompilerPass — improved PHPDoc for referenceMap() (#171)

CI

  • Upgraded actions/checkout from v2 to v6.0.2 with SHA pinning (#172)
  • Pinned shivammathur/setup-php to commit SHA in tests workflow (#149, #175)
v0.15.0

What's Changed

Security

  • Enabled branch protection on master branch

Added

  • ServerAction enum for type-safe command actions (START, STOP, RESTART, RELOAD, STATUS)
  • Config validation in ConfigLoader::warmUp() with new ConfigSection enum
  • Pre-push git hook to run composer lint

Fixed

  • TriggerFactory — robust cron expression detection using CronExpression::isValidExpression()
  • SupervisorWorker — removed sleep(1) hack, added proper logging
  • WorkermanCompilerPass — replaced anonymous class with proper named class

Breaking Changes

  • Config cache format changed from numeric indices to string keys

Migration: Clear cache after upgrade: rm -rf var/cache/*

Full CHANGELOG: https://github.com/crazy-goat/workerman-bundle/blob/master/CHANGELOG.md

v0.14.0

Release 0.14.0 - Milestone 1 Complete

This release completes Milestone 1: Critical Fixes & Stability with all HIGH priority bug fixes, security improvements, and HTTP correctness fixes.

Deprecated

  • Request::withHeader() - use setHeader() instead (#38)

Added

  • ServerWorker SSL certificate validation for HTTPS/WSS servers (#18)

Fixed

  • Critical: Middleware Pipeline closure capturing wrong request (#21)
  • KernelFactory singleton kernel state reset between requests (#22)
  • RequestConverter missing nested file handling (#26)
  • ResponseConverter generic HTTP header normalization (#25)
  • Runner proper error handling for fork and cache warmup (#23)

Changed

  • BinaryFileResponseStrategy connection-aware temp file cleanup (#104)
  • RequestConverter multipart/form-data returns empty content (#68)
  • StreamedBinaryFileResponse simplified chunking logic (#27)

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.13.0...v0.14.0

v0.13.0

What's Changed

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.12.0...v0.13.0

v0.12.0

What's Changed

New Contributors

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.10.0...v0.12.0

v0.11.0

Changes

  • Fix #45: Update PHP requirement to 8.2
  • Fix #31: Reset exception state in ExceptionRebootStrategy
  • Fix #41: Implement SIGCHLD handler for child process crash detection
  • Add comprehensive unit tests for core components
v0.10.0

Changes

  • Fix #19: Race Condition in SchedulerWorker during PID check
  • Fix #20: Infinite loop during graceful shutdown
  • Fix #17: Path Traversal vulnerability in StaticFilesMiddleware
v0.9.9

What's New

  • feat: Add workerman:server console command for managing the Workerman server (start, stop, restart, reload, status, connections)
  • feat: Support -d (daemon) and -g (graceful) options
  • refactor: Extract ServerManager for direct signal-based process control
  • fix: Remove extra quotes from process titles
  • fix: Use positional arg for suggestedValues (Symfony 6.4 compatibility)
  • docs: Add workerman:server command usage to README
  • test: Add WorkermanCommand integration tests
v0.9.8

What's Changed

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.9.7...v0.9.8

v0.9.7

What's Changed

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.9.6...v0.9.7

v0.9.6

What's Changed

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.9.5...v0.9.6

v0.9.5

What's Changed

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.9.4...v0.9.5

v0.9.3

What's Changed

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.9.2...v0.9.3

v0.9.1

What's Changed

New Contributors

Full Changelog: https://github.com/crazy-goat/workerman-bundle/compare/v0.9.0...v0.9.1

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky