3355 Commits

Author SHA1 Message Date
Benoit Chesneau
a182066bea fix: use proper exception chaining with 'raise from' in glogging.py
Use 'raise X from e' syntax instead of just 'raise X' when wrapping
exceptions. This provides more accurate exception chaining messages
("The above exception was the direct cause of" vs "During handling of").

Closes #2360
2026-01-23 11:39:05 +01:00
Benoit Chesneau
33e5337395 docs: fix post_request hook signature description
The description incorrectly stated the callable accepts two parameters
(Worker and Request), but the signature shows four parameters including
environ and resp.

Closes #2592
2026-01-23 11:39:05 +01:00
Benoit Chesneau
7c22955837
Merge pull request #3450 from benoitc/fix/ssl-want-read-error-3448
fix: handle SSLWantReadError in finish_body() (#3448)
2026-01-23 11:17:46 +01:00
Benoit Chesneau
4ef635446b docs: add dogstatsd_tags example to description
Clarify the expected format with a concrete example.

Closes #3288
2026-01-23 10:37:30 +01:00
Benoit Chesneau
36f3807a74 docs: remove RuntimeDirectory from systemd service example
The RuntimeDirectory directive is unused by gunicorn and causes
unnecessary directory creation in /run.

Closes #3341
2026-01-23 10:36:42 +01:00
Benoit Chesneau
46e7726838 fix: make syslog_addr default platform-neutral in docs
The syslog_addr setting has different defaults depending on the
platform (macOS, FreeBSD, OpenBSD, Linux). Added default_doc to
show all platform-specific defaults in the documentation, ensuring
consistent output regardless of which platform generates the docs.

Also kept the diagnostic git diff in CI for future debugging.
2026-01-23 10:08:01 +01:00
Benoit Chesneau
f68ad2e095 ci: add git diff output to diagnose settings.md issue 2026-01-23 10:04:57 +01:00
Benoit Chesneau
38e23175e7 docs: regenerate settings.md with updated worker versions 2026-01-23 09:57:33 +01:00
Benoit Chesneau
0e175a2d34 fix: resolve lint issues and remove obsolete Sphinx references
- Fix lint issues in test_gthread.py:
  - Remove unused imports (queue, partial, http)
  - Move fcntl import to top level
  - Remove unused variable assignment
  - Replace unnecessary lambdas with method references
  - Add blank lines before nested function definitions (E306)

- Update .github/workflows/lint.yml:
  - Replace Sphinx docs check with MkDocs settings generator
  - docs/source directory no longer exists after MkDocs migration

- Update tox.ini:
  - Remove docs/source/*.rst lint (directory doesn't exist)
  - Add tests/test_gthread.py to lint targets
2026-01-23 09:56:32 +01:00
Benoit Chesneau
47b9a18619 fix: handle SSLWantReadError in finish_body() (#3448)
The finish_body() function can raise ssl.SSLWantReadError when
discarding unread request body data on SSL connections. This causes
TLS requests to fail intermittently with "Invalid request" errors.

Handle SSLWantReadError by treating it as "no more data to read".
This is safe because finish_body() only discards leftover data before
keepalive - if SSL says "need to wait for more data", there's nothing
left to discard.

Fixes #3448
2026-01-23 09:38:41 +01:00
Benoit Chesneau
cae2ef4fe4 github: Consolidate triage into single Issue Triage category 2026-01-23 02:23:31 +01:00
Benoit Chesneau
6a46d66a56 github: Add discussions-first triage workflow
Redirect issue creation to GitHub Discussions for proper triage:
- Disable blank issues, redirect to discussion categories
- Add structured discussion templates for bugs, features, questions
- Add preapproved issue template for maintainer use only
- Update CONTRIBUTING.md to reflect new workflow
2026-01-23 02:13:34 +01:00
Benoit Chesneau
e021e3e93f docs: Update 24.0.0 changelog with security fixes 2026-01-23 01:39:23 +01:00
Benoit Chesneau
3960372b82
Merge pull request #3426 from benoitc/website-2025
Migrate docs build to MkDocs
2026-01-23 01:20:42 +01:00
Benoit Chesneau
d34d3de01b docs: Set release date for 24.0.0 2026-01-23 01:20:03 +01:00
Benoit Chesneau
066e6d8bb3 docs: Move ASGI worker tab after Gthread 2026-01-23 01:20:03 +01:00
Benoit Chesneau
c6b1159483 docs: Add Tornado worker to design page 2026-01-23 01:20:03 +01:00
Benoit Chesneau
c959daeb82 docs: Redesign architecture page with visual components
Add tabbed worker types, comparison table, decision guide admonitions,
and scaling callouts. Rename master to arbiter throughout.
2026-01-23 01:20:03 +01:00
Benoit Chesneau
571bc121d1 docs: Add punchy theme with vibrant colors and modern features
- Brighter green palette (#00a650, #00c853) with teal accent
- Dark/light mode toggle with system preference detection
- Gradient header, tabs, buttons, and footer
- Inter font for text, JetBrains Mono for code
- Sticky navigation tabs, auto-hide header
- Progress indicator, search sharing, breadcrumbs
- Custom scrollbars and selection highlighting
- Enhanced code blocks, tables, and admonitions
2026-01-23 01:20:03 +01:00
Benoit Chesneau
73adc7cb29 docs: Add collapsible TOC for settings reference
- Change settings headers to h2 sections / h3 settings for TOC visibility
- Enable toc.integrate to show TOC in left sidebar
- Add JavaScript for collapsible section toggles on settings page
2026-01-23 01:20:03 +01:00
Benoit Chesneau
dcec6e701a docs: Modern landing page with custom template
- Add custom home.html template to break out of MkDocs constraints
- Create Caddy-inspired minimal CSS for landing page
- Redesign hero section with terminal demo
- Add framework tags and worker type cards
- Full-width sections with vertical narrative flow
- Dark mode support
2026-01-23 01:20:03 +01:00
Benoit Chesneau
5ea4eb340a docs: Add 2026 changelog and modernize README 2026-01-23 01:20:03 +01:00
Benoit Chesneau
0b961036b7 docs: Configure GitHub Pages deployment with custom domain 2026-01-23 01:20:03 +01:00
Benoit Chesneau
e9bc51cce4 docs: Modernize landing page with hero, pillars, and framework cards 2026-01-23 01:20:03 +01:00
Benoit Chesneau
819d2a2490 docs: Add quickstart guide and Docker deployment 2026-01-23 01:20:03 +01:00
Benoit Chesneau
0a697cde7f docs: Add ASGI worker and uWSGI protocol documentation 2026-01-23 01:20:03 +01:00
Benoit Chesneau
19a2efec63 Migrate docs build to MkDocs 2026-01-23 01:20:03 +01:00
Benoit Chesneau
58d803977d bump version to 24.0.0, remove sphinx docs 2026-01-23 01:12:46 +01:00
Benoit Chesneau
f9df39f600 gevent: Require gevent 24.10.1+ to address CVE-2024-3219 2026-01-23 00:59:51 +01:00
Benoit Chesneau
db3b0819dc build: Update license config to PEP 639 format for uv compatibility 2026-01-23 00:51:32 +01:00
Benoit Chesneau
3663895651
Merge pull request #3445 from benoitc/async-workers-security-upgrade
Require secure versions of async worker dependencies
2026-01-23 00:42:48 +01:00
Benoit Chesneau
9aaa75c0bf fix: Add noqa comments for E402 in geventlet worker 2026-01-23 00:36:05 +01:00
Benoit Chesneau
086dadfa1e testing: Pin gevent and eventlet minimum versions 2026-01-23 00:26:35 +01:00
Benoit Chesneau
4062a82ba7 eventlet: Require eventlet 0.40.3+ for security fixes
Upgrade minimum eventlet version to 0.40.3 to address security
vulnerabilities:

- CVE-2021-21419 (Moderate 6.9): Websocket memory exhaustion via
  large/compressed frames (fixed in 0.31.0)
- CVE-2025-58068 (Moderate 6.3): HTTP Request Smuggling via improper
  trailer handling (fixed in 0.40.3)

Also restructure module to call monkey_patch() at import time for
better patching coverage, while keeping hubs.use_hub() in the worker's
patch() method since it creates OS resources that don't survive fork.

Add comprehensive tests for the eventlet worker.
2026-01-23 00:25:50 +01:00
Benoit Chesneau
543854c123 gevent: Require gevent 23.9.0+ for security fixes
Address CVE-2023-41419 (Critical - remote privilege escalation via
WSGIServer) by requiring gevent 23.9.0 or higher.

Changes:
- Update minimum gevent version from 1.4.0 to 23.9.0
- Remove legacy server.kill() code path (gevent < 1.0)
- Update documentation to reflect new version requirement
- Add comprehensive tests for gevent worker
2026-01-23 00:14:11 +01:00
Benoit Chesneau
4b9d787c93 tornado: Require Tornado 6.5.0+ for security fixes
Update minimum Tornado version to 6.5.0 to address:
- CVE-2024-52804 (Medium): HTTP Cookie Parsing DoS
- CVE-2025-47287 (High 7.5): Multipart/Form-Data Parser DoS

This simplifies the tornado worker by removing legacy code paths
for Tornado < 5.0 and < 6.0, reducing the codebase by ~30%.

Changes:
- pyproject.toml: Update tornado requirement to >=6.5.0
- gtornado.py: Remove TORNADO5 constant and legacy code paths
- tornadoapp.py: Update example to use async/await syntax
- test_gtornado.py: Add comprehensive test suite
2026-01-23 00:02:01 +01:00
Benoit Chesneau
5b50487bab
Merge pull request #3444 from benoitc/asgi-worker
Add native ASGI worker and uWSGI binary protocol support
2026-01-22 20:31:23 +01:00
Benoit Chesneau
81b653457c ci: Fix test dependencies for Docker and FreeBSD workflows
- Docker integration: Install pytest-cov to support coverage addopts
- FreeBSD: Install pytest-asyncio for ASGI async test support
2026-01-22 19:33:57 +01:00
Benoit Chesneau
1521266e2f asgi/uwsgi: Address PR review feedback
- asgi: Check HTTP method is GET for WebSocket upgrade per RFC 6455
  Section 4.1. Previously HEAD and other methods with upgrade headers
  could trigger WebSocket handling.

- uwsgi: Add detailed docstring explaining header mapping from CGI-style
  environment variables to HTTP headers, including the lossy nature of
  underscore-to-hyphen conversion.
2026-01-22 19:28:11 +01:00
Benoit Chesneau
99ffa0cc6b tests: Exclude docker tests from regular pytest runs
- Add tests/docker to norecursedirs in pyproject.toml to prevent
  docker tests from running during regular test suite (they require
  docker and the requests library)
- Add -p no:cov to docker integration workflow to disable coverage
  plugin since pytest-cov is not installed in that environment
2026-01-22 19:24:30 +01:00
Benoit Chesneau
ecc471f3b4 tests: Add Docker integration tests for uWSGI protocol with nginx
Add comprehensive integration tests verifying gunicorn's uWSGI binary
protocol works correctly with nginx's uwsgi_pass directive.

Test categories:
- Basic GET/POST requests with query strings and large bodies
- Header preservation (custom headers, Host, Content-Type)
- HTTP keep-alive connections
- Error responses (400-503 status codes)
- WSGI environ variables
- Large response streaming (1MB)
- Concurrent request handling
- Edge cases (binary data, unicode, long headers)

Architecture: pytest -> nginx:8080 -> uwsgi_pass -> gunicorn:8000

Also adds GitHub Actions workflow that runs on changes to uwsgi module
or docker test files.
2026-01-22 19:06:30 +01:00
Benoit Chesneau
ac7296ec49 uwsgi: Add native uWSGI binary protocol support
Add support for the uWSGI binary protocol, enabling gunicorn to work
with nginx's uwsgi_pass directive.

New module gunicorn/uwsgi/ with:
- UWSGIRequest: Parses 4-byte binary header and key-value vars block
- UWSGIParser: Protocol parser following existing Parser pattern
- Error classes: InvalidUWSGIHeader, UnsupportedModifier, ForbiddenUWSGIRequest

New configuration options:
- --protocol: Select 'http' (default) or 'uwsgi' protocol
- --uwsgi-allow-from: IP allowlist for uWSGI requests (default: localhost)

Worker integration via get_parser() factory in gunicorn/http/__init__.py,
updates to sync, gthread, and base_async workers.

Example nginx config:
    upstream gunicorn {
        server 127.0.0.1:8000;
    }
    location / {
        uwsgi_pass gunicorn;
        include uwsgi_params;
    }
2026-01-22 18:32:17 +01:00
Benoit Chesneau
903a1fdf3c tests: Add pytest-asyncio for ASGI worker tests
The ASGI worker tests use @pytest.mark.asyncio decorator which
requires the pytest-asyncio plugin to be installed.
2026-01-22 18:32:17 +01:00
Benoit Chesneau
11c6a97c47 asgi: Fix pylint and pycodestyle warnings
- Remove unused imports (ssl, os, base64, hashlib, traceback)
- Remove unused variables (body_parts, has_content_length, etc.)
- Fix no-else-break patterns in protocol.py and websocket.py
- Replace __anext__() with anext() builtin
- Remove unnecessary pass statements
- Add proper access logging to ASGI protocol handler
- Add ASGIResponseInfo class and _build_environ method for logging
- Disable too-many-return-statements for _read_frame method
- Fix raising-bad-type error (use 'is not None' check)
- Fix whitespace before colon in message.py
2026-01-22 18:03:14 +01:00
Benoit Chesneau
ae1eea8108 asgi: Add native ASGI worker with HTTP and WebSocket support
Add a new ASGI worker type that provides native async support using
gunicorn's own HTTP parsing infrastructure adapted for asyncio.

Features:
- HTTP/1.1 with keepalive support
- WebSocket connections (RFC 6455)
- ASGI lifespan protocol for startup/shutdown hooks
- Optional uvloop support for improved performance
- Full proxy protocol support (inherited from gunicorn)

New configuration options:
- --asgi-loop: Event loop selection (auto/asyncio/uvloop)
- --asgi-lifespan: Lifespan protocol control (auto/on/off)
- --root-path: ASGI root path for reverse proxy setups

Usage: gunicorn -k asgi myapp:app
2026-01-22 17:05:29 +01:00
Benoit Chesneau
ea98400820
ci: Fix macOS tests and add FreeBSD support (#3442)
* ci: Remove failing macos-13 from test matrix

* ci: Add FreeBSD testing workflow

* ci: Document test matrix rationale

* ci: Update cross-platform-actions to v0.32.0 for FreeBSD 14.2 support

* ci: Use FreeBSD 14.1 (14.2 has SSH connectivity issues)

* ci: Switch to vmactions/freebsd-vm for FreeBSD testing

* ci: Fix FreeBSD package names (pip included in Python)

* ci: Simplify FreeBSD matrix and fix package names

* ci: Use specific Python version command on FreeBSD

* ci: Add sqlite3 package for FreeBSD

* tests: Increase signal integration test timeouts for CI

The signal integration tests were flaky in CI environments,
especially FreeBSD VMs, due to 10-second timeouts being too short.
Increased timeouts to 30 seconds to handle slower CI environments.
2026-01-22 14:00:02 +01:00
Benoit Chesneau
6f103ba9b2 THANKS: Add contributors from signal handling PRs 2026-01-22 12:01:50 +01:00
Benoit Chesneau
b650332c70
Arbiter signal handling improvements (#3441)
* tests: Add tests for current signal handling behavior

Add tests for arbiter signal handling:
- TestSignalHandlerRegistration (4 tests): Verify signal handler
  registration, pipe creation, SIGCHLD separate handler, and
  expected signals list
- TestSignalQueue (4 tests): Test signal queueing, max queue size,
  wakeup writes to pipe, and sleep returns on pipe data
- TestReapWorkers (6 tests): Test worker reaping for normal exit,
  error exit codes, WORKER_BOOT_ERROR, APP_LOAD_ERROR, signal
  termination, and SIGKILL OOM hint

These tests establish baseline coverage before refactoring the
signal handling code for safety and reliability improvements.

* tests: Add tests for SIGHUP reload and worker lifecycle

Add tests for reload and worker management:
- TestSighupReload (3 tests): Verify reload spawns configured number
  of workers, calls manage_workers, and logs hang up message
- TestWorkerLifecycle (4 tests): Test spawn_worker adds to WORKERS
  dict, kill_worker sends correct signal, murder_workers sends
  SIGABRT first then SIGKILL on subsequent timeout

* arbiter: Fix waitpid status parsing using POSIX macros

Use os.WIFEXITED/WEXITSTATUS and os.WIFSIGNALED/WTERMSIG instead
of manual bit shifting for waitpid status interpretation. This
correctly distinguishes between normal exits and signal termination.

The previous code used 'status >> 8' which only worked for normal
exits, and used raw status values for signal detection which was
incorrect.

Fixes part of #3435 and #3056 (signal name display issues)

* arbiter: Change SIGTERM log level to warning

Log signal termination at warning level for expected signals
(SIGTERM, SIGQUIT) since these typically occur during normal
graceful shutdown. SIGKILL remains at error level with the
OOM hint since it indicates abnormal termination.

Fixes #3311, #3050 (SIGTERM logged as error)

* arbiter: Remove logging from SIGCHLD signal handler

Move reap_workers() call from signal handler context to main loop.
The signal handler (now signal_chld) only queues the signal and
wakes up the main loop. The actual reap_workers() is called from
handle_chld() in the main loop where logging is safe.

This fixes potential deadlocks caused by logging from signal
handler context when holding the logging lock.

Fixes #3198, #3004 (logging in signal handlers unsafe, deadlock)

* arbiter: Replace PIPE+select with queue.SimpleQueue

Use queue.SimpleQueue for signal handling instead of PIPE+select.
SimpleQueue is reentrant-safe and can be used from signal handlers.

Changes:
- Remove PIPE-based wakeup mechanism
- Add SIG_QUEUE as SimpleQueue instance
- Add WAKEUP_REQUEST sentinel for non-signal wakeups
- Replace sleep() with wait_for_signals() using queue.get()
- Simplify signal handler to just put_nowait()
- Update main loop to iterate over wait_for_signals()
- Add reap_workers() call in stop() to properly clean up workers
  since SIGCHLD is no longer processed during shutdown

This simplifies the code and removes the dependency on select().

Also adds integration tests for signal handling that verify:
- Basic request/response
- Graceful shutdown with SIGTERM/SIGINT
- SIGHUP reload
- Multiple concurrent requests

* arbiter: Wait for old workers on SIGHUP reload

After spawning new workers during reload, wait for old workers to
terminate before returning from reload(). This prevents the issue
where old workers could receive double SIGTERM - once from
manage_workers() and again from the arbiter loop.

The reload now tracks worker_age before spawning, then waits up to
graceful_timeout for workers older than that age to exit.

Fixes #3312, #3274 (SIGHUP can send double SIGTERM)

* arbiter: Log SIGCHLD at debug level

SIGCHLD is received frequently (whenever a worker exits) and doesn't
need to be logged at info level. Log it at debug level to reduce
noise in the logs while still making it available for debugging.

* tests: Fix lint warnings in test_arbiter.py
2026-01-22 11:56:23 +01:00
Benoit Chesneau
7af8cccb4a
Merge pull request #3438 from benoitc/dependabot/github_actions/actions/checkout-6
Bump actions/checkout from 5 to 6
2026-01-22 10:00:34 +01:00
Benoit Chesneau
6df99ce99b
Merge pull request #3440 from benoitc/gthread-improvements
gthread: Lock-free refactoring with PollableMethodQueue
2026-01-22 09:56:45 +01:00