Full Code of benoitc/gunicorn for AI

master 2cc38503b784 cached
621 files
2.7 MB
737.1k tokens
4532 symbols
1 requests
Download .txt
Showing preview only (2,935K chars total). Download the full file or copy to clipboard to get everything.
Repository: benoitc/gunicorn
Branch: master
Commit: 2cc38503b784
Files: 621
Total size: 2.7 MB

Directory structure:
gitextract_ti_vnsti/

├── .github/
│   ├── DISCUSSION_TEMPLATE/
│   │   ├── issue-triage.yml
│   │   └── question.yml
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── config.yml
│   │   └── preapproved.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── docker-integration.yml
│       ├── docker-publish.yml
│       ├── docs.yml
│       ├── embedding-integration.yml
│       ├── freebsd.yml
│       ├── lint.yml
│       └── tox.yml
├── .gitignore
├── .pylintrc
├── CONTRIBUTING.md
├── LICENSE
├── MAINTAINERS
├── MANIFEST.in
├── Makefile
├── NOTICE
├── README.md
├── SECURITY.md
├── THANKS
├── appveyor.yml
├── benchmarks/
│   ├── baseline.json
│   ├── dirty_bench_app.py
│   ├── dirty_bench_gunicorn.py
│   ├── dirty_bench_wsgi.py
│   ├── dirty_benchmark.py
│   ├── dirty_streaming.py
│   ├── quick_bench.sh
│   ├── results/
│   │   └── queue_refactor_results.json
│   ├── run_benchmark.py
│   └── simple_app.py
├── docker/
│   ├── .dockerignore
│   ├── Dockerfile
│   └── docker-entrypoint.sh
├── docs/
│   ├── README.md
│   ├── content/
│   │   ├── 2010-news.md
│   │   ├── 2011-news.md
│   │   ├── 2012-news.md
│   │   ├── 2013-news.md
│   │   ├── 2014-news.md
│   │   ├── 2015-news.md
│   │   ├── 2016-news.md
│   │   ├── 2017-news.md
│   │   ├── 2018-news.md
│   │   ├── 2019-news.md
│   │   ├── 2020-news.md
│   │   ├── 2021-news.md
│   │   ├── 2023-news.md
│   │   ├── 2024-news.md
│   │   ├── 2026-news.md
│   │   ├── 404.md
│   │   ├── CNAME
│   │   ├── asgi.md
│   │   ├── assets/
│   │   │   ├── javascripts/
│   │   │   │   └── toc-collapse.js
│   │   │   └── stylesheets/
│   │   │       └── home.css
│   │   ├── community.md
│   │   ├── configure.md
│   │   ├── custom.md
│   │   ├── deploy.md
│   │   ├── design.md
│   │   ├── dirty.md
│   │   ├── faq.md
│   │   ├── guides/
│   │   │   ├── docker.md
│   │   │   ├── gunicornc.md
│   │   │   └── http2.md
│   │   ├── index.md
│   │   ├── install.md
│   │   ├── instrumentation.md
│   │   ├── news.md
│   │   ├── quickstart.md
│   │   ├── reference/
│   │   │   └── settings.md
│   │   ├── run.md
│   │   ├── signals.md
│   │   ├── sponsor.md
│   │   ├── styles/
│   │   │   └── overrides.css
│   │   └── uwsgi.md
│   └── macros.py
├── examples/
│   ├── alt_spec.py
│   ├── asgi/
│   │   ├── __init__.py
│   │   ├── basic_app.py
│   │   └── websocket_app.py
│   ├── bad.py
│   ├── boot_fail.py
│   ├── celery_alternative/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── app.py
│   │   ├── docker-compose.yml
│   │   ├── gunicorn_conf.py
│   │   ├── requirements.txt
│   │   ├── run_tests.sh
│   │   ├── tasks.py
│   │   └── tests/
│   │       ├── __init__.py
│   │       ├── conftest.py
│   │       ├── test_integration.py
│   │       └── test_tasks.py
│   ├── deep/
│   │   ├── __init__.py
│   │   └── test.py
│   ├── dirty_example/
│   │   ├── Dockerfile
│   │   ├── __init__.py
│   │   ├── dirty_app.py
│   │   ├── docker-compose.yml
│   │   ├── gunicorn_conf.py
│   │   ├── test_dirty_app.py
│   │   ├── test_integration.py
│   │   ├── test_protocol.py
│   │   ├── test_stash_integration.py
│   │   ├── test_worker_integration.py
│   │   └── wsgi_app.py
│   ├── echo.py
│   ├── embedding_service/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── __init__.py
│   │   ├── docker-compose.yml
│   │   ├── embedding_app.py
│   │   ├── gunicorn_conf.py
│   │   ├── main.py
│   │   ├── requirements.txt
│   │   └── test_embedding.py
│   ├── example_config.py
│   ├── frameworks/
│   │   ├── cherryapp.py
│   │   ├── django/
│   │   │   ├── README
│   │   │   └── testing/
│   │   │       ├── manage.py
│   │   │       └── testing/
│   │   │           ├── __init__.py
│   │   │           ├── apps/
│   │   │           │   ├── __init__.py
│   │   │           │   └── someapp/
│   │   │           │       ├── __init__.py
│   │   │           │       ├── middleware.py
│   │   │           │       ├── models.py
│   │   │           │       ├── templates/
│   │   │           │       │   ├── base.html
│   │   │           │       │   └── home.html
│   │   │           │       ├── tests.py
│   │   │           │       ├── urls.py
│   │   │           │       └── views.py
│   │   │           ├── settings.py
│   │   │           ├── urls.py
│   │   │           └── wsgi.py
│   │   ├── flask_sendfile.py
│   │   ├── flaskapp.py
│   │   ├── flaskapp_aiohttp_wsgi.py
│   │   ├── pyramidapp.py
│   │   ├── requirements.txt
│   │   ├── requirements_cherryapp.txt
│   │   ├── requirements_flaskapp.txt
│   │   ├── requirements_pyramidapp.txt
│   │   ├── requirements_tornadoapp.txt
│   │   ├── requirements_webpyapp.txt
│   │   ├── tornadoapp.py
│   │   └── webpyapp.py
│   ├── gunicorn_rc
│   ├── hello.txt
│   ├── http2_features/
│   │   ├── Dockerfile
│   │   ├── __init__.py
│   │   ├── docker-compose.yml
│   │   ├── gunicorn_conf.py
│   │   ├── http2_app.py
│   │   ├── requirements.txt
│   │   └── test_http2.py
│   ├── http2_gevent/
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── app.py
│   │   ├── docker-compose.yml
│   │   ├── generate_certs.sh
│   │   ├── gunicorn_conf.py
│   │   └── test_http2_gevent.py
│   ├── log_app.ini
│   ├── log_app.py
│   ├── logging.conf
│   ├── longpoll.py
│   ├── multiapp.py
│   ├── multidomainapp.py
│   ├── nginx.conf
│   ├── read_django_settings.py
│   ├── readline_app.py
│   ├── sendfile.py
│   ├── server.crt
│   ├── server.key
│   ├── slowclient.py
│   ├── standalone_app.py
│   ├── streaming_chat/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── __init__.py
│   │   ├── chat_app.py
│   │   ├── demo_capture.txt
│   │   ├── docker-compose.yml
│   │   ├── gunicorn_conf.py
│   │   ├── main.py
│   │   ├── requirements.txt
│   │   └── test_streaming.py
│   ├── supervisor.conf
│   ├── test.py
│   ├── timeout.py
│   ├── websocket/
│   │   ├── gevent_websocket.py
│   │   └── websocket.html
│   └── when_ready.conf.py
├── gunicorn/
│   ├── __init__.py
│   ├── __main__.py
│   ├── app/
│   │   ├── __init__.py
│   │   ├── base.py
│   │   ├── pasterapp.py
│   │   └── wsgiapp.py
│   ├── arbiter.py
│   ├── asgi/
│   │   ├── __init__.py
│   │   ├── lifespan.py
│   │   ├── message.py
│   │   ├── protocol.py
│   │   ├── unreader.py
│   │   ├── uwsgi.py
│   │   └── websocket.py
│   ├── config.py
│   ├── ctl/
│   │   ├── __init__.py
│   │   ├── cli.py
│   │   ├── client.py
│   │   ├── handlers.py
│   │   ├── protocol.py
│   │   └── server.py
│   ├── debug.py
│   ├── dirty/
│   │   ├── __init__.py
│   │   ├── app.py
│   │   ├── arbiter.py
│   │   ├── client.py
│   │   ├── errors.py
│   │   ├── protocol.py
│   │   ├── stash.py
│   │   ├── tlv.py
│   │   └── worker.py
│   ├── errors.py
│   ├── glogging.py
│   ├── http/
│   │   ├── __init__.py
│   │   ├── body.py
│   │   ├── errors.py
│   │   ├── message.py
│   │   ├── parser.py
│   │   ├── unreader.py
│   │   └── wsgi.py
│   ├── http2/
│   │   ├── __init__.py
│   │   ├── async_connection.py
│   │   ├── connection.py
│   │   ├── errors.py
│   │   ├── request.py
│   │   └── stream.py
│   ├── instrument/
│   │   ├── __init__.py
│   │   └── statsd.py
│   ├── pidfile.py
│   ├── reloader.py
│   ├── sock.py
│   ├── systemd.py
│   ├── util.py
│   ├── uwsgi/
│   │   ├── __init__.py
│   │   ├── errors.py
│   │   ├── message.py
│   │   └── parser.py
│   └── workers/
│       ├── __init__.py
│       ├── base.py
│       ├── base_async.py
│       ├── gasgi.py
│       ├── geventlet.py
│       ├── ggevent.py
│       ├── gthread.py
│       ├── gtornado.py
│       ├── sync.py
│       └── workertmp.py
├── mkdocs.yml
├── overrides/
│   └── home.html
├── pyproject.toml
├── requirements_dev.txt
├── requirements_test.txt
├── scripts/
│   ├── build_settings_doc.py
│   └── update_thanks.py
├── tests/
│   ├── config/
│   │   ├── __init__.py
│   │   ├── test_cfg.py
│   │   ├── test_cfg_alt.py
│   │   └── test_cfg_with_wsgi_app.py
│   ├── conftest.py
│   ├── ctl/
│   │   ├── __init__.py
│   │   ├── test_client.py
│   │   ├── test_handlers.py
│   │   ├── test_protocol.py
│   │   └── test_server.py
│   ├── dirty/
│   │   ├── __init__.py
│   │   ├── test_arbiter_signals.py
│   │   ├── test_arbiter_streaming.py
│   │   ├── test_client_streaming.py
│   │   ├── test_client_streaming_async.py
│   │   ├── test_multi_app_routing.py
│   │   ├── test_per_app_worker_allocation.py
│   │   ├── test_streaming_integration.py
│   │   └── test_worker_streaming.py
│   ├── docker/
│   │   ├── __init__.py
│   │   ├── asgi/
│   │   │   ├── Dockerfile
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   └── test_asgi.sh
│   │   ├── asgi_compliance/
│   │   │   ├── Dockerfile.gunicorn
│   │   │   ├── Dockerfile.nginx
│   │   │   ├── __init__.py
│   │   │   ├── apps/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── framework_apps.py
│   │   │   │   ├── http_app.py
│   │   │   │   ├── lifespan_app.py
│   │   │   │   ├── main_app.py
│   │   │   │   ├── streaming_app.py
│   │   │   │   └── websocket_app.py
│   │   │   ├── certs/
│   │   │   │   ├── server.crt
│   │   │   │   └── server.key
│   │   │   ├── conftest.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── nginx.conf
│   │   │   ├── test_concurrency.py
│   │   │   ├── test_framework_integration.py
│   │   │   ├── test_http2_asgi.py
│   │   │   ├── test_http_compliance.py
│   │   │   ├── test_lifespan_compliance.py
│   │   │   ├── test_streaming_compliance.py
│   │   │   └── test_websocket_compliance.py
│   │   ├── dirty_arbiter/
│   │   │   ├── Dockerfile
│   │   │   ├── README.md
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── gunicorn_conf.py
│   │   │   └── test_parent_death.py
│   │   ├── dirty_ttin_ttou/
│   │   │   ├── Dockerfile
│   │   │   ├── __init__.py
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── gunicorn_conf.py
│   │   │   └── test_ttin_ttou_docker.py
│   │   ├── http2/
│   │   │   ├── Dockerfile.gunicorn
│   │   │   ├── Dockerfile.nginx
│   │   │   ├── README.rst
│   │   │   ├── __init__.py
│   │   │   ├── app.py
│   │   │   ├── certs/
│   │   │   │   ├── .gitkeep
│   │   │   │   ├── server.crt
│   │   │   │   └── server.key
│   │   │   ├── conftest.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── nginx.conf
│   │   │   └── test_http2_docker.py
│   │   ├── per_app_allocation/
│   │   │   ├── Dockerfile
│   │   │   ├── README.md
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── gunicorn_conf.py
│   │   │   └── test_per_app_e2e.py
│   │   ├── test_asgi_uwsgi/
│   │   │   ├── Dockerfile
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── nginx.conf
│   │   │   └── test_uwsgi.sh
│   │   └── uwsgi/
│   │       ├── Dockerfile.gunicorn
│   │       ├── Dockerfile.nginx
│   │       ├── README.md
│   │       ├── app.py
│   │       ├── conftest.py
│   │       ├── docker-compose.yml
│   │       ├── nginx.conf
│   │       ├── test_uwsgi_integration.py
│   │       └── uwsgi_params
│   ├── requests/
│   │   ├── invalid/
│   │   │   ├── 001.http
│   │   │   ├── 001.py
│   │   │   ├── 002.http
│   │   │   ├── 002.py
│   │   │   ├── 003.http
│   │   │   ├── 003.py
│   │   │   ├── 003b.http
│   │   │   ├── 003b.py
│   │   │   ├── 003c.http
│   │   │   ├── 003c.py
│   │   │   ├── 004.http
│   │   │   ├── 004.py
│   │   │   ├── 005.http
│   │   │   ├── 005.py
│   │   │   ├── 006.http
│   │   │   ├── 006.py
│   │   │   ├── 007.http
│   │   │   ├── 007.py
│   │   │   ├── 008.http
│   │   │   ├── 008.py
│   │   │   ├── 009.http
│   │   │   ├── 009.py
│   │   │   ├── 010.http
│   │   │   ├── 010.py
│   │   │   ├── 011.http
│   │   │   ├── 011.py
│   │   │   ├── 012.http
│   │   │   ├── 012.py
│   │   │   ├── 013.http
│   │   │   ├── 013.py
│   │   │   ├── 014.http
│   │   │   ├── 014.py
│   │   │   ├── 015.http
│   │   │   ├── 015.py
│   │   │   ├── 016.http
│   │   │   ├── 016.py
│   │   │   ├── 017.http
│   │   │   ├── 017.py
│   │   │   ├── 018.http
│   │   │   ├── 018.py
│   │   │   ├── 019.http
│   │   │   ├── 019.py
│   │   │   ├── 020.http
│   │   │   ├── 020.py
│   │   │   ├── 021.http
│   │   │   ├── 021.py
│   │   │   ├── 022.http
│   │   │   ├── 022.py
│   │   │   ├── 023.http
│   │   │   ├── 023.py
│   │   │   ├── 024.http
│   │   │   ├── 024.py
│   │   │   ├── 040.http
│   │   │   ├── 040.py
│   │   │   ├── chunked_01.http
│   │   │   ├── chunked_01.py
│   │   │   ├── chunked_02.http
│   │   │   ├── chunked_02.py
│   │   │   ├── chunked_03.http
│   │   │   ├── chunked_03.py
│   │   │   ├── chunked_04.http
│   │   │   ├── chunked_04.py
│   │   │   ├── chunked_05.http
│   │   │   ├── chunked_05.py
│   │   │   ├── chunked_06.http
│   │   │   ├── chunked_06.py
│   │   │   ├── chunked_07.http
│   │   │   ├── chunked_07.py
│   │   │   ├── chunked_08.http
│   │   │   ├── chunked_08.py
│   │   │   ├── chunked_09.http
│   │   │   ├── chunked_09.py
│   │   │   ├── chunked_10.http
│   │   │   ├── chunked_10.py
│   │   │   ├── chunked_11.http
│   │   │   ├── chunked_11.py
│   │   │   ├── chunked_12.http
│   │   │   ├── chunked_12.py
│   │   │   ├── chunked_13.http
│   │   │   ├── chunked_13.py
│   │   │   ├── invalid_field_value_01.http
│   │   │   ├── invalid_field_value_01.py
│   │   │   ├── nonascii_01.http
│   │   │   ├── nonascii_01.py
│   │   │   ├── nonascii_02.http
│   │   │   ├── nonascii_02.py
│   │   │   ├── nonascii_03.http
│   │   │   ├── nonascii_03.py
│   │   │   ├── nonascii_04.http
│   │   │   ├── nonascii_04.py
│   │   │   ├── obs_fold_01.http
│   │   │   ├── obs_fold_01.py
│   │   │   ├── pp_01.http
│   │   │   ├── pp_01.py
│   │   │   ├── pp_02.http
│   │   │   ├── pp_02.py
│   │   │   ├── prefix_01.http
│   │   │   ├── prefix_01.py
│   │   │   ├── prefix_02.http
│   │   │   ├── prefix_02.py
│   │   │   ├── prefix_03.http
│   │   │   ├── prefix_03.py
│   │   │   ├── prefix_04.http
│   │   │   ├── prefix_04.py
│   │   │   ├── prefix_05.http
│   │   │   ├── prefix_05.py
│   │   │   ├── prefix_06.http
│   │   │   ├── prefix_06.py
│   │   │   ├── version_01.http
│   │   │   ├── version_01.py
│   │   │   ├── version_02.http
│   │   │   └── version_02.py
│   │   └── valid/
│   │       ├── 001.http
│   │       ├── 001.py
│   │       ├── 002.http
│   │       ├── 002.py
│   │       ├── 003.http
│   │       ├── 003.py
│   │       ├── 004.http
│   │       ├── 004.py
│   │       ├── 005.http
│   │       ├── 005.py
│   │       ├── 006.http
│   │       ├── 006.py
│   │       ├── 007.http
│   │       ├── 007.py
│   │       ├── 008.http
│   │       ├── 008.py
│   │       ├── 009.http
│   │       ├── 009.py
│   │       ├── 010.http
│   │       ├── 010.py
│   │       ├── 011.http
│   │       ├── 011.py
│   │       ├── 012.http
│   │       ├── 012.py
│   │       ├── 013.http
│   │       ├── 013.py
│   │       ├── 014.http
│   │       ├── 014.py
│   │       ├── 015.http
│   │       ├── 015.py
│   │       ├── 017.http
│   │       ├── 017.py
│   │       ├── 018.http
│   │       ├── 018.py
│   │       ├── 019.http
│   │       ├── 019.py
│   │       ├── 020.http
│   │       ├── 020.py
│   │       ├── 021.http
│   │       ├── 021.py
│   │       ├── 022.http
│   │       ├── 022.py
│   │       ├── 023.http
│   │       ├── 023.py
│   │       ├── 024.http
│   │       ├── 024.py
│   │       ├── 025.http
│   │       ├── 025.py
│   │       ├── 025_line.http
│   │       ├── 025_line.py
│   │       ├── 026.http
│   │       ├── 026.py
│   │       ├── 027.http
│   │       ├── 027.py
│   │       ├── 028.http
│   │       ├── 028.py
│   │       ├── 029.http
│   │       ├── 029.py
│   │       ├── 030.http
│   │       ├── 030.py
│   │       ├── 031.http
│   │       ├── 031.py
│   │       ├── 031compat.http
│   │       ├── 031compat.py
│   │       ├── 031compat2.http
│   │       ├── 031compat2.py
│   │       ├── 040.http
│   │       ├── 040.py
│   │       ├── 040_compat.http
│   │       ├── 040_compat.py
│   │       ├── 099.http
│   │       ├── 099.py
│   │       ├── 100.http
│   │       ├── 100.py
│   │       ├── compat_obs_fold.http
│   │       ├── compat_obs_fold.py
│   │       ├── compat_obs_fold_huge.http
│   │       ├── compat_obs_fold_huge.py
│   │       ├── padding_01.http
│   │       ├── padding_01.py
│   │       ├── pp_01.http
│   │       ├── pp_01.py
│   │       ├── pp_02.http
│   │       ├── pp_02.py
│   │       ├── pp_03.http
│   │       ├── pp_03.py
│   │       ├── pp_04.http
│   │       ├── pp_04.py
│   │       ├── pp_05.http
│   │       └── pp_05.py
│   ├── support.py
│   ├── support_dirty_app.py
│   ├── support_dirty_apps.py
│   ├── t.py
│   ├── test_arbiter.py
│   ├── test_asgi.py
│   ├── test_asgi_compliance.py
│   ├── test_asgi_disconnect.py
│   ├── test_asgi_http_scope.py
│   ├── test_asgi_parser.py
│   ├── test_asgi_streaming.py
│   ├── test_asgi_uwsgi.py
│   ├── test_asgi_websocket_protocol.py
│   ├── test_asgi_worker.py
│   ├── test_config.py
│   ├── test_control_socket_integration.py
│   ├── test_dirty_app.py
│   ├── test_dirty_arbiter.py
│   ├── test_dirty_client.py
│   ├── test_dirty_config.py
│   ├── test_dirty_errors.py
│   ├── test_dirty_hooks.py
│   ├── test_dirty_integration.py
│   ├── test_dirty_protocol.py
│   ├── test_dirty_stash.py
│   ├── test_dirty_tlv.py
│   ├── test_dirty_worker.py
│   ├── test_early_hints.py
│   ├── test_gthread.py
│   ├── test_gtornado.py
│   ├── test_http.py
│   ├── test_http2_alpn.py
│   ├── test_http2_async_connection.py
│   ├── test_http2_config.py
│   ├── test_http2_connection.py
│   ├── test_http2_errors.py
│   ├── test_http2_integration.py
│   ├── test_http2_request.py
│   ├── test_http2_stream.py
│   ├── test_invalid_requests.py
│   ├── test_logger.py
│   ├── test_pidfile.py
│   ├── test_reload.py
│   ├── test_signal_integration.py
│   ├── test_sock.py
│   ├── test_ssl.py
│   ├── test_statsd.py
│   ├── test_systemd.py
│   ├── test_util.py
│   ├── test_uwsgi.py
│   ├── test_valid_requests.py
│   ├── treq.py
│   └── workers/
│       ├── __init__.py
│       ├── test_gevent_import_order.py
│       ├── test_geventlet.py
│       └── test_ggevent.py
└── tox.ini

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/DISCUSSION_TEMPLATE/issue-triage.yml
================================================
title: "[Triage] "
labels:
  - triage
body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to report an issue or suggest a feature!

        **Before submitting, please:**
        - Search [existing discussions](https://github.com/benoitc/gunicorn/discussions) and [issues](https://github.com/benoitc/gunicorn/issues) for duplicates
        - Check the [FAQ](https://gunicorn.org/faq/) and [documentation](https://gunicorn.org/)

  - type: dropdown
    id: type
    attributes:
      label: Type
      description: What type of issue is this?
      options:
        - Bug Report
        - Feature Request
        - Performance Issue
        - Documentation Issue
    validations:
      required: true

  - type: textarea
    id: description
    attributes:
      label: Description
      description: A clear description of the issue or feature request
      placeholder: |
        For bugs: What happened? What did you expect?
        For features: What problem does this solve?
    validations:
      required: true

  - type: textarea
    id: reproduce
    attributes:
      label: Steps to Reproduce (for bugs)
      description: Minimal steps to reproduce the behavior
      placeholder: |
        1. Create a simple app with...
        2. Run gunicorn with...
        3. Send request...
        4. See error...
    validations:
      required: false

  - type: textarea
    id: config
    attributes:
      label: Configuration
      description: Your gunicorn configuration (command line or config file)
      render: bash
      placeholder: |
        gunicorn --workers 4 --bind 0.0.0.0:8000 myapp:app
    validations:
      required: false

  - type: textarea
    id: logs
    attributes:
      label: Logs / Error Output
      description: Relevant logs or error messages (use --log-level debug for more detail)
      render: text
    validations:
      required: false

  - type: input
    id: gunicorn-version
    attributes:
      label: Gunicorn Version
      description: Output of `gunicorn --version`
      placeholder: gunicorn 24.1.0
    validations:
      required: true

  - type: input
    id: python-version
    attributes:
      label: Python Version
      description: Output of `python --version`
      placeholder: Python 3.12.0
    validations:
      required: true

  - type: dropdown
    id: worker-class
    attributes:
      label: Worker Class
      description: Which worker type are you using?
      options:
        - sync (default)
        - gthread
        - gevent
        - eventlet
        - tornado
        - asgi (beta)
        - custom
        - N/A (feature request)
    validations:
      required: true

  - type: input
    id: os
    attributes:
      label: Operating System
      description: Your OS and version
      placeholder: Ubuntu 22.04, macOS 14.0, etc.
    validations:
      required: true

  - type: textarea
    id: additional
    attributes:
      label: Additional Context
      description: Any other context (proxy setup, Docker, proposed solution, etc.)
    validations:
      required: false

  - type: checkboxes
    id: checklist
    attributes:
      label: Checklist
      options:
        - label: I have searched existing discussions and issues for duplicates
          required: true
        - label: I have checked the documentation and FAQ
          required: true


================================================
FILE: .github/DISCUSSION_TEMPLATE/question.yml
================================================
title: "[Question] "
body:
  - type: markdown
    attributes:
      value: |
        Have a question about Gunicorn?

        Before asking, please check:
        - [Documentation](https://gunicorn.org/)
        - [FAQ](https://gunicorn.org/faq/)
        - [Settings Reference](https://gunicorn.org/reference/settings/)
        - [Existing discussions](https://github.com/benoitc/gunicorn/discussions)

  - type: textarea
    id: question
    attributes:
      label: Question
      description: What would you like to know?
    validations:
      required: true

  - type: textarea
    id: context
    attributes:
      label: Context
      description: Any relevant context (your setup, what you've tried, etc.)
      placeholder: |
        I'm running gunicorn with...
        I've tried...
    validations:
      required: false

  - type: textarea
    id: config
    attributes:
      label: Configuration (if relevant)
      description: Your gunicorn configuration
      render: bash
    validations:
      required: false

  - type: checkboxes
    id: checklist
    attributes:
      label: Checklist
      options:
        - label: I have checked the documentation and FAQ
          required: true
        - label: I have searched existing discussions
          required: true


================================================
FILE: .github/FUNDING.yml
================================================
github: [benoitc]
open_collective: gunicorn
custom: ["https://checkout.revolut.com/pay/c934e028-3a71-44eb-b99c-491342df2044"]


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: Bug Report / Feature Request
    url: https://github.com/benoitc/gunicorn/discussions/new?category=issue-triage
    about: Report a bug or request a feature (triaged before becoming an issue)
  - name: Question
    url: https://github.com/benoitc/gunicorn/discussions/new?category=q-a
    about: Ask a question about configuration, deployment, or usage


================================================
FILE: .github/ISSUE_TEMPLATE/preapproved.md
================================================
---
name: Pre-Discussed and Approved Topics
about: Only for topics already discussed and approved in GitHub Discussions
title: ''
labels: ''
assignees: ''
---

**Only for topics already discussed and approved in the GitHub Discussions section.**

DO NOT OPEN A NEW ISSUE. PLEASE USE THE DISCUSSIONS SECTION.

Link to approved discussion:

---



================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "monthly"


================================================
FILE: .github/workflows/docker-integration.yml
================================================
name: Docker Integration Tests

on:
  push:
    branches: [master]
    paths:
      - 'gunicorn/uwsgi/**'
      - 'tests/docker/uwsgi/**'
      - '.github/workflows/docker-integration.yml'
  pull_request:
    paths:
      - 'gunicorn/uwsgi/**'
      - 'tests/docker/uwsgi/**'
      - '.github/workflows/docker-integration.yml'

permissions:
  contents: read

env:
  FORCE_COLOR: 1

jobs:
  uwsgi-nginx:
    name: uWSGI Protocol with nginx
    runs-on: ubuntu-latest
    timeout-minutes: 15

    steps:
      - uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: "3.12"
          cache: pip
          cache-dependency-path: requirements_test.txt

      - name: Install test dependencies
        run: |
          python -m pip install --upgrade pip
          python -m pip install pytest pytest-cov requests

      - name: Run uWSGI integration tests
        run: |
          pytest tests/docker/uwsgi/ -v --tb=short


================================================
FILE: .github/workflows/docker-publish.yml
================================================
name: Docker Publish
on:
  push:
    tags:
      - 'v*'
      - '[0-9]+.[0-9]+.[0-9]+'
  workflow_dispatch:

permissions:
  contents: read
  packages: write

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-and-push:
    name: Build and Push Docker Image
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=semver,pattern={{major}}
            type=raw,value=latest,enable={{is_default_branch}}

      - name: Build and push
        uses: docker/build-push-action@v6
        with:
          context: .
          file: docker/Dockerfile
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max


================================================
FILE: .github/workflows/docs.yml
================================================
name: Docs

on:
  push:
    branches: [ master ]
    paths:
      - 'docs/**'
      - 'mkdocs.yml'
      - 'scripts/build_settings_doc.py'
      - 'gunicorn/config.py'
      - 'requirements_dev.txt'
      - '.github/workflows/docs.yml'
  pull_request:
    paths:
      - 'docs/**'
      - 'mkdocs.yml'
      - 'scripts/build_settings_doc.py'
      - 'gunicorn/config.py'
      - 'requirements_dev.txt'
      - '.github/workflows/docs.yml'
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.12'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -e .
          pip install -r requirements_dev.txt

      - name: Build documentation
        run: mkdocs build

      - name: Upload site artifact
        uses: actions/upload-artifact@v7
        with:
          name: gunicorn-site
          path: site
          retention-days: 7

  deploy:
    if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master'
    needs: build
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v6

      - name: Set up Python
        uses: actions/setup-python@v6
        with:
          python-version: '3.12'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -e .
          pip install -r requirements_dev.txt

      - name: Build documentation
        run: mkdocs build

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v4
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: site
          publish_branch: gh-pages
          cname: gunicorn.org
          commit_message: "docs: deploy ${{ github.sha }}"


================================================
FILE: .github/workflows/embedding-integration.yml
================================================
name: Embedding Service Integration Tests

on:
  push:
    paths:
      - 'examples/embedding_service/**'
      - 'gunicorn/dirty/**'
  pull_request:
    paths:
      - 'examples/embedding_service/**'
      - 'gunicorn/dirty/**'

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v6

      - name: Build and start service
        run: |
          cd examples/embedding_service
          docker compose up -d --build
          docker compose logs -f &

      - name: Wait for healthy
        run: |
          for i in {1..30}; do
            curl -s http://127.0.0.1:8000/health && break
            sleep 2
          done

      - name: Run tests
        run: |
          pip install requests numpy
          python examples/embedding_service/test_embedding.py

      - name: Cleanup
        if: always()
        run: |
          cd examples/embedding_service
          docker compose down


================================================
FILE: .github/workflows/freebsd.yml
================================================
name: FreeBSD

on:
  push:
  pull_request:
  workflow_dispatch:

permissions:
  contents: read

env:
  FORCE_COLOR: 1

jobs:
  test:
    name: FreeBSD ${{ matrix.freebsd-version }} / Python ${{ matrix.python-version }}
    runs-on: ubuntu-latest
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - freebsd-version: '14.2'
            python-version: '3.12'
            python-pkg: 'python312 py312-sqlite3'
          - freebsd-version: '14.2'
            python-version: '3.13'
            python-pkg: 'python313 py313-sqlite3'
    steps:
      - uses: actions/checkout@v6

      - name: Test on FreeBSD
        uses: vmactions/freebsd-vm@v1
        with:
          release: ${{ matrix.freebsd-version }}
          usesh: true
          prepare: |
            pkg install -y ${{ matrix.python-pkg }}
          run: |
            python${{ matrix.python-version }} -m venv venv
            . venv/bin/activate
            pip install --upgrade pip
            pip install pytest pytest-cov pytest-asyncio coverage
            pip install -e .
            pytest --cov=gunicorn -v tests/ \
              --ignore=tests/workers/test_ggevent.py \
              --ignore=tests/workers/test_geventlet.py


================================================
FILE: .github/workflows/lint.yml
================================================
name: lint
on: [push, pull_request]
permissions:
  contents: read # to fetch code (actions/checkout)
env:
  # note that some tools care only for the name, not the value
  FORCE_COLOR: 1
jobs:
  lint:
    name: ${{ matrix.python-version }} / tox-${{ matrix.toxenv || '(other)' }}
    timeout-minutes: 10
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        toxenv: [lint, pycodestyle]
        python-version: [ "3.12" ]
        include:
          # for actions that want git env, not tox env
          - toxenv: null
            python-version: "3.12"
    steps:
      - uses: actions/checkout@v6
      - name: Using Python ${{ matrix.python-version }}
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
          cache: pip
      - name: Install Dependencies (tox)
        if: ${{ matrix.toxenv }}
        run: |
          python -m pip install --upgrade pip
          python -m pip install tox
      - run: tox -e ${{ matrix.toxenv }}
        if: ${{ matrix.toxenv }}
      - name: Install Dependencies (non-toxic)
        if: ${{ ! matrix.toxenv }}
        run: |
          python -m pip install --upgrade pip
          python -m pip install -e .
      - name: "Check generated docs"
        if: ${{ ! matrix.toxenv }}
        run: |
          # Regenerate settings.md and check for uncommitted changes
          python scripts/build_settings_doc.py
          if unclean=$(git status --untracked-files=no --porcelain) && [ -z "$unclean" ]; then
            echo "no uncommitted changes in working tree (as it should be)"
          else
            echo "did you forget to run 'python scripts/build_settings_doc.py'?"
            echo "$unclean"
            git diff
            exit 2
          fi


================================================
FILE: .github/workflows/tox.yml
================================================
name: tox
on: [push, pull_request]
permissions:
  contents: read # to fetch code (actions/checkout)
env:
  # note that some tools care only for the name, not the value
  FORCE_COLOR: 1
jobs:
  tox:
    name: ${{ matrix.os }} / ${{ matrix.python-version }}
    # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes
    timeout-minutes: 20
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        unsupported: [false]
        os:
         - ubuntu-latest
         # Not testing Windows: tests need Unix-only fcntl, grp, pwd, etc.
         # FreeBSD: tested in separate freebsd.yml workflow
        python-version:
         # Supporting Python 3.10 through 3.13
         - "3.10"
         - "3.11"
         - "3.12"
         - "3.13"
         - "pypy-3.10"
        include:
         # Test on macos-latest (arm64) with recent versions
         - os: macos-latest
           python-version: "3.12"
           unsupported: false
         - os: macos-latest
           python-version: "3.13"
           unsupported: false
    steps:
      - uses: actions/checkout@v6
      - name: Using Python ${{ matrix.python-version }}
        uses: actions/setup-python@v6
        with:
          python-version: ${{ matrix.python-version }}
          cache: pip
          cache-dependency-path: requirements_test.txt
          check-latest: true
          allow-prereleases: ${{ matrix.unsupported }}
      - name: Install Dependencies
        run: |
          python -m pip install --upgrade pip
          python -m pip install tox
      - run: tox -e run-module
        continue-on-error: ${{ matrix.unsupported }}
      - run: tox -e run-entrypoint
        continue-on-error: ${{ matrix.unsupported }}
      - run: tox -e py
        continue-on-error: ${{ matrix.unsupported }}


================================================
FILE: .gitignore
================================================
*.egg
*.egg-info
*.pyc
*.so
.coverage
.pytest_cache
.tox
__pycache__
build
docs/_build
coverage.xml
dist
examples/frameworks/django/testing/testdb.sql
examples/frameworks/pylonstest/PasteScript*
examples/frameworks/pylonstest/pylonstest.egg-info/
MANIFEST
nohup.out
setuptools-*
site/
docs/site/


================================================
FILE: .pylintrc
================================================
[MASTER]

ignore=
    build,
    docs,
    examples,
    scripts,
    _compat.py,
    _gaiohttp.py,

[MESSAGES CONTROL]

disable=
    attribute-defined-outside-init,
    bad-mcs-classmethod-argument,
    bare-except,
    broad-except,
    cyclic-import,
    duplicate-bases,
    duplicate-code,
    eval-used,
    fixme,
    import-error,
    import-outside-toplevel,
    import-self,
    inconsistent-return-statements,
    invalid-name,
    missing-docstring,
    no-else-return,
    no-member,
    no-self-argument,
    no-staticmethod-decorator,
    not-callable,
    possibly-used-before-assignment,
    protected-access,
    raise-missing-from,
    redefined-outer-name,
    too-few-public-methods,
    too-many-arguments,
    too-many-branches,
    too-many-instance-attributes,
    too-many-lines,
    too-many-locals,
    too-many-nested-blocks,
    too-many-positional-arguments,
    too-many-public-methods,
    too-many-statements,
    used-before-assignment,
    wrong-import-position,
    wrong-import-order,
    ungrouped-imports,
    unused-argument,
    useless-object-inheritance,
    useless-import-alias,
    comparison-with-callable,
    try-except-raise,
    consider-using-with,
    consider-using-f-string,
    unspecified-encoding


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Gunicorn

Want to hack on Gunicorn? Awesome! Here are instructions to get you
started. They are probably not perfect, please let us know if anything
feels wrong or incomplete.

## Contribution guidelines

### Pull requests are always welcome

We are always thrilled to receive pull requests, and do our best to
process them as fast as possible. Not sure if that typo is worth a pull
request? Do it! We will appreciate it.

If your pull request is not accepted on the first try, don't be
discouraged! If there's a problem with the implementation, hopefully you
received feedback on what to improve.

We're trying very hard to keep Gunicorn lean and focused. We don't want it
to do everything for everybody. This means that we might decide against
incorporating a new feature. However, there might be a way to implement
that feature *on top of* Gunicorn.

### Start with a Discussion

We use [GitHub Discussions](https://github.com/benoitc/gunicorn/discussions)
as the starting point for all bug reports, feature requests, and questions.
This allows for proper triage before creating formal issues.

- **Bug reports**: Start in [Q&A](https://github.com/benoitc/gunicorn/discussions/categories/q-a)
- **Feature requests**: Start in [Ideas](https://github.com/benoitc/gunicorn/discussions/categories/ideas)
- **Questions**: Start in [Q&A](https://github.com/benoitc/gunicorn/discussions/categories/q-a)

After discussion and triage, maintainers will create issues for confirmed
bugs and approved features.

### Check for existing discussions first!

Please take a moment to check that a discussion or issue doesn't already exist
documenting your bug report or improvement proposal. If it does, it
never hurts to add a quick "+1" or "I have this problem too". This will
help prioritize the most common problems and requests.


### Conventions

Don't comment on closed issues or PRs, instead open a new issue and link it to
the old one.

Fork the repo and make changes on your fork in a feature branch:

- If it's a bugfix branch, name it XXX-something where XXX is the number
  of the issue
- If it's a feature branch, create an enhancement issue to announce your
  intentions, and name it XXX-something where XXX is the number of the
issue.

Submit unit tests for your changes. Python has a great test framework built
in; use it! Take a look at existing tests for inspiration. Run the full
test suite on your branch before submitting a pull request.

Make sure you include relevant updates or additions to documentation
when creating or modifying features.

If you are adding a new configuration option or updating an existing one,
please do it in `gunicorn/config.py`, then run `make -C docs html` to update
`docs/source/settings.rst`.

Write clean code.

Pull requests descriptions should be as clear as possible and include a
reference to all the issues that they address.

Code review comments may be added to your pull request. Discuss, then
make the suggested modifications and push additional commits to your
feature branch. Be sure to post a comment after pushing. The new commits
will show up in the pull request automatically, but the reviewers will
not be notified unless you comment.

Before the pull request is merged, make sure that you squash your
commits into logical units of work using `git rebase -i` and `git push
-f`. After every commit the test suite should be passing. Include
documentation changes in the same commit so that a revert would remove
all traces of the feature or fix.

Commits that fix or close an issue should include a reference like
`Closes #XXX` or `Fixes #XXX`, which will automatically close the issue
when merged.

Add your name to the THANKS file, but make sure the list is sorted and
your name and email address match your git configuration. The THANKS
file is regenerated occasionally from the git commit history, so a
mismatch may result in your changes being overwritten.


## Decision process

### How are decisions made?

Short answer: with pull requests to the gunicorn repository.

Gunicorn is an open-source project under the MIT License with an open
design philosophy. This means that the repository is the source of truth
for EVERY aspect of the project, including its philosophy, design,
roadmap and APIs. *If it's part of the project, it's in the repo. It's
in the repo, it's part of the project.*

As a result, all decisions can be expressed as changes to the
repository. An implementation change is a change to the source code. An
API change is a change to the API specification. A philosophy change is
a change to the relevant documentation. And so on.

All decisions affecting gunicorn, big and small, follow the same 3 steps:

* Step 1: Open a pull request. Anyone can do this.

* Step 2: Discuss the pull request. Anyone can do this.

* Step 3: Accept or refuse a pull request. The relevant maintainer does this (see below "Who decides what?")


### Who decides what?

So all decisions are pull requests, and the relevant maintainer makes
the decision by accepting or refusing the pull request.  But how do we
identify the relevant maintainer for a given pull request?

Gunicorn follows the timeless, highly efficient and totally unfair system
known as [Benevolent dictator for
life](http://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), with
Benoit Chesneau (aka benoitc), in the role of BDFL.  This means that all
decisions are made by default by me. Since making every decision myself
would be highly unscalable, in practice decisions are spread across
multiple maintainers.

The relevant maintainer for a pull request is assigned in 3 steps:

* Step 1: Determine the subdirectory affected by the pull request. This might be src/registry, docs/source/api, or any other part of the repo.

* Step 2: Find the MAINTAINERS file which affects this directory. If the directory itself does not have a MAINTAINERS file, work your way up the repo hierarchy until you find one.

* Step 3: The first maintainer listed is the primary maintainer who is assigned the Pull Request. The primary maintainer can reassign a Pull Request to other listed maintainers.


### I'm a maintainer, should I make pull requests too?

Primary maintainers are not required to create pull requests when
changing their own subdirectory, but secondary maintainers are.

### Who assigns maintainers?

benoitc.

### How can I become a maintainer?

* Step 1: learn the component inside out
* Step 2: make yourself useful by contributing code, bugfixes, support etc.
* Step 3: volunteer on our [Libera Chat](https://libera.chat/) irc channel [#gunicorn](https://web.libera.chat/?channels=#gunicorn)

Don't forget: being a maintainer is a time investment. Make sure you
will have time to make yourself available.  You don't have to be a
maintainer to make a difference on the project!

### What are a maintainer's responsibility?

It is every maintainer's responsibility to:

* 1) Expose a clear roadmap for improving their component.
* 2) Deliver prompt feedback and decisions on pull requests.
* 3) Be available to anyone with questions, bug reports, criticism etc. on their component. This includes irc, github requests and the mailing list.
* 4) Make sure their component respects the philosophy, design and roadmap of the project.

### How is this process changed?

Just like everything else: by making a pull request :)


================================================
FILE: LICENSE
================================================
2009-2026 (c) Benoît Chesneau <benoitc@gunicorn.org>
2009-2015 (c) Paul J. Davis <paul.joseph.davis@gmail.com>

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: MAINTAINERS
================================================
Core maintainers
================

Benoit Chesneau <benoitc@gunicorn.org>
Konstantin Kapustin <sirkonst@gmail.com>
Randall Leeds <randall.leeds@gmail.com>
Berker Peksağ <berker.peksag@gmail.com>
Jason Madden <jason@nextthought.com>
Brett Randall <javabrett@gmail.com>

Alumni
======

This list contains maintainers that are no longer active on the project.
It is thanks to these people that the project has become what it is today.
Thank you!


Paul J. Davis <paul.joseph.davis@gmail.com>
Kenneth Reitz <me@kennethreitz.com>
Nikolay Kim <fafhrd91@gmail.com>
Andrew Svetlov <andrew.svetlov@gmail.com>
Stéphane Wirtel <stephane@wirtel.be>

================================================
FILE: MANIFEST.in
================================================
include .gitignore
include LICENSE
include NOTICE
include README.md
include THANKS
include requirements_dev.txt
include requirements_test.txt
include tox.ini
include .pylintrc
recursive-include tests *
recursive-include examples *
recursive-include docs *
recursive-include examples/frameworks *
recursive-exclude * __pycache__
recursive-exclude docs/build *
recursive-exclude docs/_build *
recursive-exclude * *.py[co]


================================================
FILE: Makefile
================================================
build:
	virtualenv venv
	venv/bin/pip install -e .
	venv/bin/pip install -r requirements_dev.txt

docs:
	mkdocs build

docs-serve:
	mkdocs serve

clean:
	@rm -rf .Python MANIFEST build dist venv* *.egg-info *.egg
	@find . -type f -name "*.py[co]" -delete
	@find . -type d -name "__pycache__" -delete

.PHONY: build clean docs docs-serve


================================================
FILE: NOTICE
================================================
Gunicorn

2009-2026 (c) Benoît Chesneau <benoitc@gunicorn.org>
2009-2015 (c) Paul J. Davis <paul.joseph.davis@gmail.com>

Gunicorn is released under the MIT license. See the LICENSE
file for the complete license.

gunicorn.logging_config
-----------------------
Copyright 2001-2005 by Vinay Sajip. All Rights Reserved.

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of Vinay Sajip
not be used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.

VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

gunicorn.debug
--------------

Based on eventlet.debug module under MIT license:

Unless otherwise noted, the files in Eventlet are under the following MIT license:

Copyright (c) 2005-2006, Bob Ippolito
Copyright (c) 2007-2010, Linden Research, Inc.
Copyright (c) 2008-2010, Eventlet Contributors (see Eventlet AUTHORS)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

gunicorn.reloader
-----------------

Based on greins.reloader module under MIT license:

2010 (c) Meebo, Inc.

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.


util/unlink.py
--------------

backport from python3 Lib/test/support.py


================================================
FILE: README.md
================================================
# Gunicorn

<p align="center">
  <strong>Gunicorn is maintained by volunteers. If it powers your production, please consider supporting us:</strong><br>
  <a href="https://github.com/sponsors/benoitc"><img src="https://img.shields.io/badge/GitHub_Sponsors-❤-ea4aaa?style=for-the-badge&logo=github" alt="GitHub Sponsors"></a>
  <a href="https://opencollective.com/gunicorn"><img src="https://img.shields.io/badge/Open_Collective-Support-7FADF2?style=for-the-badge&logo=opencollective" alt="Open Collective"></a>
  <a href="https://checkout.revolut.com/pay/c934e028-3a71-44eb-b99c-491342df2044"><img src="https://img.shields.io/badge/Revolut-Donate-191c20?style=for-the-badge" alt="Revolut"></a>
</p>

[![PyPI version](https://img.shields.io/pypi/v/gunicorn.svg?style=flat)](https://pypi.python.org/pypi/gunicorn)
[![Supported Python versions](https://img.shields.io/pypi/pyversions/gunicorn.svg)](https://pypi.python.org/pypi/gunicorn)
[![Build Status](https://github.com/benoitc/gunicorn/actions/workflows/tox.yml/badge.svg)](https://github.com/benoitc/gunicorn/actions/workflows/tox.yml)

Gunicorn 'Green Unicorn' is a Python WSGI HTTP Server for UNIX. It's a pre-fork
worker model ported from Ruby's [Unicorn](https://bogomips.org/unicorn/) project. The Gunicorn server is broadly
compatible with various web frameworks, simply implemented, light on server
resource usage, and fairly speedy.

**New in v25**: Per-app worker allocation for dirty arbiters, HTTP/2 support (beta)!

## Quick Start

```bash
pip install gunicorn
gunicorn myapp:app --workers 4
```

For ASGI applications (FastAPI, Starlette):

```bash
gunicorn myapp:app --worker-class asgi
```

## Features

- WSGI support for Django, Flask, Pyramid, and any WSGI framework
- **ASGI support** for FastAPI, Starlette, Quart
- **HTTP/2 support** (beta) with multiplexed streams
- **Dirty Arbiters** (beta) for heavy workloads (ML models, long-running tasks)
- uWSGI binary protocol for nginx integration
- Multiple worker types: sync, gthread, gevent, eventlet, asgi
- Graceful worker process management
- Compatible with Python 3.9+

## Documentation

Full documentation at https://gunicorn.org

- [Quickstart](https://gunicorn.org/quickstart/)
- [Configuration](https://gunicorn.org/configure/)
- [Deployment](https://gunicorn.org/deploy/)
- [Settings Reference](https://gunicorn.org/reference/settings/)

## Community

- Report bugs on [GitHub Issues](https://github.com/benoitc/gunicorn/issues)
- Chat in [#gunicorn](https://web.libera.chat/?channels=#gunicorn) on [Libera.chat](https://libera.chat/)
- See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines

## Support

Powering Python apps since 2010. Support continued development.

[![Become a Sponsor](https://img.shields.io/badge/Become_a_Sponsor-❤-ff69b4)](https://gunicorn.org/sponsor/)

## License

Gunicorn is released under the MIT License. See the [LICENSE](https://github.com/benoitc/gunicorn/blob/master/LICENSE) file for details.


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Reporting a Vulnerability

**Please note that public Github issues are open for everyone to see!**

If you believe you are found a problem in Gunicorn software, examples or documentation, we encourage you to send your
 report privately via [email](mailto:security@gunicorn.org?subject=Security%20issue%20in%20Gunicorn), or via Github
 using the *Report a vulnerability* button in the [Security](https://github.com/benoitc/gunicorn/security) section.

## Supported Releases

Please target reports against :white_check_mark: or current master. Please understand that :x: will
 not receive further security attention.

| Version | Status             |
| ------- | ------------------ |
| 25.0.0  | :white_check_mark: |
| 24.1.1  | :white_check_mark: |
| 23.0.0  | :x:                |
| 22.0.0  | :x:                |
| < 22.0  | :x:                |

## Python Versions

Gunicorn runs on Python 3.10+, supporting Python versions that are still maintained by the PSF.
We *highly recommend* the latest release of a [supported series](https://devguide.python.org/versions/)
and will not prioritize issues affecting EoL environments.


================================================
FILE: THANKS
================================================
Gunicorn THANKS
===============

A number of people have contributed to Gunicorn by reporting problems,
suggesting improvements or submitting changes. Some of these people are:

414nch4n <chanfung032@gmail.com>
Aaron Kavlie <akavlie@gmail.com>
aartur <asiekielski@soldevelo.com>
Adnane Belmadiaf <adnane002@gmail.com>
Adrien CLERC <adrien@antipoul.fr>
Alasdair Nicol <alasdair@thenicols.net>
Alex Conrad <alexandre.conrad@gmail.com>
Alex Gaynor <alex.gaynor@gmail.com>
Alex Robbins <alexander.j.robbins@gmail.com>
Alexandre Zani <alexandre.zani@gmail.com>
Alexis Le-Quoc <alq@datadoghq.com>
Anand Chitipothu <anandology@gmail.com>
Andreas Stührk <andy-python@hammerhartes.de>
Andrew Burdo <zeezooz@gmail.com>
Andrew Svetlov <andrew.svetlov@gmail.com>
Anil V <avaitla16@gmail.com>
Antoine Girard <antoine.girard.dev@gmail.com>
Anton Vlasenko <antares.spica@gmail.com>
Artur Kruchinin <arturkruchinin@gmail.com>
Bartosz Oler <bartosz@bzimage.us>
Ben Cochran <bcochran@gmail.com>
Ben Oswald <ben.oswald@root-space.de>
Benjamin Gilbert <bgilbert@backtick.net>
Benny Mei <meibenny@gmail.com>
Benoit Chesneau <bchesneau@gmail.com>
Berker Peksag <berker.peksag@gmail.com>
bninja <andrew@poundpay.com>
Bob Hagemann <bob+code@twilio.com>
Bobby Beckmann <bobby@macs-MacBook-Pro.local>
Brett Randall <javabrett@gmail.com>
Brian Rosner <brosner@gmail.com>
Bruno Bigras <bigras.bruno@gmail.com>
Caleb Brown <git@calebbrown.id.au>
Chris Adams <chris@improbable.org>
Chris Forbes <chrisf@ijw.co.nz>
Chris Lamb <lamby@debian.org>
Chris Streeter <chris@chrisstreeter.com>
Christian Clauss <cclauss@me.com>
Christoph Heer <Christoph.Heer@gmail.com>
Christos Stavrakakis <cstavr@grnet.gr>
CMGS <ilskdw@mspil.edu.cn>
Curt Micol <asenchi@asenchi.com>
Dan Callaghan <dcallagh@redhat.com>
Dan Sully <daniel-github@electricrain.com>
Daniel Quinn <code@danielquinn.org>
Dariusz Suchojad <dsuch-github@m.zato.io>
David Black <github@dhb.is>
David Vincelli <david@freshbooks.com>
David Wolever <david@wolever.net>
Denis Bilenko <denis.bilenko@gmail.com>
Diego Oliveira <contact@diegoholiveira.com>
Dima Barsky <github@kappa.ac93.org>
Djoume Salvetti <djoume@freshbooks.com>
Dmitry Medvinsky <me@dmedvinsky.name>
Dominik Działak <ddzialak@users.noreply.github.com>
Dustin Ingram <di@users.noreply.github.com>
Ed Morley <edmorley@users.noreply.github.com>
Eric Florenzano <floguy@gmail.com>
Eric Shull <eric@elevenbasetwo.com>
Eugene Obukhov <irvind25@gmail.com>
Evan Mezeske <evan@meebo-inc.com>
Florian Apolloner <florian@apolloner.eu>
Gaurav Kumar <gauravkumar37@gmail.com>
George Kollias <georgioskollias@gmail.com>
George Notaras <gnot@g-loaded.eu>
German Larrain <germanlarrainm@gmail.com>
Graham Dumpleton <Graham.Dumpleton@gmail.com>
Graham Dumpleton <graham@newrelic.com>
Greg McGuire <greg-github@greganem.com>
Greg Taylor <gtaylor@duointeractive.com>
Hasan Ramezani <hasan.r67@gmail.com>
Hebert J <hebert@mail.ru>
Hobson Lane <shopper@totalgood.com>
Hugo van Kemenade <hugovk@users.noreply.github.com>
Igor Petrov <igor.s.petrov@gmail.com>
INADA Naoki <methane@users.noreply.github.com>
Jakub Paweł Głazik <zytek@nuxi.pl>
Jan-Philip Gehrcke <jgehrcke@googlemail.com>
Jannis Leidel <jannis@leidel.info>
Jason Jones <jcjones1515@users.noreply.github.com>
Jason Madden <jason@nextthought.com>
jean-philippe serafin <serafinjp@gmail.com>
Jeremy Volkman <jeremy@jvolkman.com>
Jeroen Pulles <jeroenp@users.noreply.github.com>
Jeryn Mathew <jerynmathew@gmail.com>
Jet Sun <jet.joins.sun@gmail.com>
Jim Garrison <jim@garrison.cc>
Johan Bergström <bugs@bergstroem.nu>
John Hensley <john@fairviewcomputing.com>
Jonas Haag <jonas@lophus.org>
Jonas Nockert <jonasnockert@gmail.com>
Jorge Niedbalski <jorge@nimbic.com>
Jorge Niedbalski R <niedbalski@gmail.com>
Justin Quick <justquick@gmail.com>
keakon <keakon@gmail.com>
Keegan Carruthers-Smith <keegan.csmith@gmail.com>
Kenneth Reitz <me@kennethreitz.org>
Kevin Gessner <kevin@kevingessner.com>
Kevin Littlejohn <kevin@littlejohn.id.au>
Kevin Luikens <kluikens@gmail.com>
Kirill Zaborsky <qrilka@gmail.com>
Konstantin Kapustin <sirkonst@gmail.com>
kracekumar <kracethekingmaker@gmail.com>
Kristian Glass <git@doismellburning.co.uk>
Kristian Øllegaard <kristian.ollegaard@divio.ch>
Krystian <chrisjozwik@outlook.com>
Krzysztof Urbaniak <urban@fail.pl>
Kyle Kelley <rgbkrk@gmail.com>
Kyle Mulka <repalviglator@yahoo.com>
Lars Hansson <romabysen@gmail.com>
Leonardo Santagada <santagada@gmail.com>
Levi Gross <levi@levigross.com>
licunlong <shenxiaogll@163.com>
Łukasz Kucharski <lkucharski@leon.pl>
Mahmoud Hashemi <mahmoudrhashemi@gmail.com>
Malthe Borch <mborch@gmail.com>
Marc Abramowitz <marc@marc-abramowitz.com>
Marc Abramowitz <msabramo@gmail.com>
Mark Adams <mark@markadams.me>
Matt Behrens <askedrelic@gmail.com>
Matt Billenstein <mattb@flingo.tv>
Matt Good <matt@matt-good.net>
Matt Robenolt <m@robenolt.com>
Maxim Kamenkov <mkamenkov@gmail.com>
Mazdak Rezvani <mazdak@mac.com>
Michael Schurter <m@schmichael.com>
Mieszko <mieszko.chowaniec@gmail.com>
Mike Tigas <mike@tig.as>
Moriyoshi Koizumi <mozo@mozo.jp>
mpaolini <markopaolini@gmail.com>
Neil Chintomby <nchintomby@gmail.com>
Neil Williams <neil@reddit.com>
Nick Pillitteri <nick@tshlabs.org>
Nik Nyby <nnyby@columbia.edu>
Nikolay Kim <fafhrd91@gmail.com>
Oliver Allen <oallenj@users.noreply.github.com>
Oliver Bristow <evilumbrella+github@gmail.com>
Oliver Tonnhofer <olt@bogosoft.com>
Omer Katz <omer.drow@gmail.com>
PA Parent <paparent@paparent.me>
Paul Jeannot <paul.jeannot95@gmail.com>
Paul Davis <davisp@neb.com>
Paul J. Davis <paul.joseph.davis@gmail.com>
Paul Smith <paulsmith@pobox.com>
Phil Schanely <phil@daylife.com>
Philip Cristiano <philipcristiano@gmail.com>
Philipp Saveliev <fsfeel@gmail.com>
Prateek Singh Paudel <pratykschingh@gmail.com>
py <py@douban.com>
Qiangning Hong <hongqn@douban.com>
Randall Leeds <randall.leeds@gmail.com>
Randall Leeds <randall@bleeds.info>
Randall Leeds <randall@meebo-inc.com>
Raphaël Slinckx <rslinckx@gmail.com>
Rhys Powell <rhys@rhyspowell.com>
Rik <rvachterberg@gmail.com>
Ronan Amicel <ronan.amicel@gmail.com>
Ryan Peck <ryan@rypeck.com>
Ryuichi Watanabe <ryucrosskey@gmail.com>
Saeed Gharedaghi <saeed.ghx68@gmail.com>
Samuel Matos <samypr100@users.noreply.github.com>
Sergey Rublev <narma.nsk@gmail.com>
Shane Reustle <me@shanereustle.com>
shouse-cars <shouse@cars.com>
sib <andrew.sibley@gmail.com>
Simon Lundmark <simon.lundmark@gmail.com>
Stephane Wirtel <stephane@wirtel.be>
Stephen DiCato <Locker537@gmail.com>
Stephen Holsapple <sholsapp@gmail.com>
Steven Cummings <estebistec@gmail.com>
sylt <sylt@users.noreply.github.com>
Sébastien Fievet <zyegfryed@gmail.com>
Tal Einat <532281+taleinat@users.noreply.github.com>
Talha Malik <talham7391@hotmail.com>
TedWantsMore <TedWantsMore@gmx.com>
Teko012 <112829523+Teko012@users.noreply.github.com>
Thomas Grainger <tagrain@gmail.com>
Thomas Steinacher <tom@eggdrop.ch>
Travis Cline <travis.cline@gmail.com>
Travis Swicegood <development@domain51.com>
Trey Long <trey@ktrl.com>
W. Trevor King <wking@tremily.us>
Wojtek <wojtek@monodev.com>
Wolfgang Schnerring <wosc@wosc.de>
WoLpH <Rick@Fawo.nl>
wong2 <wonderfuly@gmail.com>
WooParadog <guohaochuan@gmail.com>
Xie Shi <xieshi@douban.com>
Yue Du <ifduyue@gmail.com>
zakdances <zakdances@gmail.com>
Emile Fugulin <emilefugulin@hotmail.com>


================================================
FILE: appveyor.yml
================================================
version: '{branch}.{build}'
environment:
  matrix:
    - TOXENV: lint
      PYTHON: "C:\\Python312-x64"
    - TOXENV: pycodestyle
      PYTHON: "C:\\Python312-x64"
    # Windows cannot even import the module when they unconditionally import, see below.
    #- TOXENV: run-module
    #  PYTHON: "C:\\Python38-x64"
    #- TOXENV: run-entrypoint
    #  PYTHON: "C:\\Python38-x64"
    # Windows is not ready for testing!!!
    # Python's fcntl, grp, pwd, os.geteuid(), and socket.AF_UNIX are all Unix-only.
    #- TOXENV: py35
    #  PYTHON: "C:\\Python35-x64"
    #- TOXENV: py36
    #  PYTHON: "C:\\Python36-x64"
    #- TOXENV: py37
    #  PYTHON: "C:\\Python37-x64"
    #- TOXENV: py38
    #  PYTHON: "C:\\Python38-x64"
    #- TOXENV: py39
    #  PYTHON: "C:\\Python39-x64"
    #- TOXENV: py310
    #  PYTHON: "C:\\Python310-x64"
    #- TOXENV: py311
    #  PYTHON: "C:\\Python311-x64"
    #- TOXENV: py312
    #  PYTHON: "C:\\Python312-x64"
matrix:
  allow_failures:
    # No failures expected for py312 and py313
init:
  - SET "PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
install:
  - pip install tox
build: false
test_script:
  - tox
cache:
  # Not including the .tox directory since it takes longer to download/extract
  # the cache archive than for tox to clean install from the pip cache.
  - '%LOCALAPPDATA%\pip\Cache -> tox.ini'
notifications:
  - provider: Email
    on_build_success: false
    on_build_status_changed: false


================================================
FILE: benchmarks/baseline.json
================================================
{
  "gthread": {
    "simple": {},
    "simple_high_concurrency": {},
    "slow_io": {},
    "large_response": {}
  }
}

================================================
FILE: benchmarks/dirty_bench_app.py
================================================
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

"""
Benchmark DirtyApp for stress testing the dirty arbiter pool.

Provides configurable workloads for testing:
- Pure sleep (scheduling overhead)
- CPU-bound work (thread pool utilization)
- Mixed I/O + CPU (realistic workloads)
- Payload generation (serialization overhead)
"""

import time

from gunicorn.dirty import DirtyApp


class BenchmarkApp(DirtyApp):
    """
    Configurable benchmark app for stress testing.

    Provides various task types to test different aspects of the
    dirty pool performance.
    """

    def init(self):
        """Fast initialization - no heavy resources to load."""
        self.call_count = 0
        self.total_sleep_ms = 0
        self.total_cpu_ms = 0

    def sleep_task(self, duration_ms):
        """
        Pure sleep task - tests scheduling overhead.

        This simulates I/O-bound work like waiting for external APIs.
        The thread is blocked but not consuming CPU.

        Args:
            duration_ms: Sleep duration in milliseconds

        Returns:
            dict with sleep duration
        """
        self.call_count += 1
        self.total_sleep_ms += duration_ms
        time.sleep(duration_ms / 1000.0)
        return {"slept_ms": duration_ms}

    def cpu_task(self, duration_ms, intensity=1.0):
        """
        CPU-bound work - tests thread pool utilization.

        Performs actual computation to simulate CPU-intensive work
        like model inference or data processing.

        Args:
            duration_ms: Target duration in milliseconds
            intensity: Work intensity multiplier (1.0 = normal)

        Returns:
            dict with computed iterations and actual duration
        """
        self.call_count += 1
        start = time.perf_counter()
        target_end = start + (duration_ms / 1000.0)

        # Perform CPU work until target duration
        iterations = 0
        work_per_iteration = int(1000 * intensity)

        while time.perf_counter() < target_end:
            # Do some actual computation
            x = 0.0
            for i in range(work_per_iteration):
                x += i * 0.001
                x = x * 1.001 if x < 1000000 else x * 0.999
            iterations += 1

        actual_ms = (time.perf_counter() - start) * 1000
        self.total_cpu_ms += actual_ms

        return {
            "iterations": iterations,
            "target_ms": duration_ms,
            "actual_ms": round(actual_ms, 2),
            "intensity": intensity
        }

    def mixed_task(self, sleep_ms, cpu_ms, intensity=1.0):
        """
        Mixed I/O + CPU task - simulates realistic workloads.

        First performs I/O (sleep), then does CPU work. This is
        common in real apps: fetch data, then process it.

        Args:
            sleep_ms: I/O simulation duration in milliseconds
            cpu_ms: CPU work duration in milliseconds
            intensity: CPU work intensity multiplier

        Returns:
            dict with both sleep and CPU metrics
        """
        self.call_count += 1

        # I/O phase (sleep)
        time.sleep(sleep_ms / 1000.0)
        self.total_sleep_ms += sleep_ms

        # CPU phase
        start = time.perf_counter()
        target_end = start + (cpu_ms / 1000.0)

        iterations = 0
        work_per_iteration = int(1000 * intensity)

        while time.perf_counter() < target_end:
            x = 0.0
            for i in range(work_per_iteration):
                x += i * 0.001
                x = x * 1.001 if x < 1000000 else x * 0.999
            iterations += 1

        actual_cpu_ms = (time.perf_counter() - start) * 1000
        self.total_cpu_ms += actual_cpu_ms

        return {
            "sleep_ms": sleep_ms,
            "cpu_iterations": iterations,
            "target_cpu_ms": cpu_ms,
            "actual_cpu_ms": round(actual_cpu_ms, 2),
            "total_ms": round(sleep_ms + actual_cpu_ms, 2)
        }

    def payload_task(self, size_bytes, duration_ms=0):
        """
        Generate payload of specified size - tests serialization.

        Creates a deterministic payload to test JSON serialization
        overhead for different response sizes.

        Args:
            size_bytes: Target payload size in bytes
            duration_ms: Optional sleep before generating payload

        Returns:
            dict with 'data' field of specified size
        """
        self.call_count += 1

        if duration_ms > 0:
            time.sleep(duration_ms / 1000.0)
            self.total_sleep_ms += duration_ms

        # Generate payload - use a pattern that compresses differently
        # than pure repeated characters for more realistic testing
        pattern = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
        repeats = (size_bytes // len(pattern)) + 1
        data = (pattern * repeats)[:size_bytes]

        return {
            "data": data,
            "size": len(data)
        }

    def echo_task(self, payload):
        """
        Echo back payload - tests round-trip serialization.

        Useful for testing request/response serialization together.

        Args:
            payload: Data to echo back

        Returns:
            dict with echoed payload and its size
        """
        self.call_count += 1

        # Calculate size based on type
        if isinstance(payload, str):
            size = len(payload)
        elif isinstance(payload, (dict, list)):
            import json
            size = len(json.dumps(payload))
        else:
            size = len(str(payload))

        return {
            "echoed_size": size,
            "payload": payload
        }

    def stats(self):
        """
        Return accumulated statistics.

        Returns:
            dict with call counts and totals
        """
        return {
            "call_count": self.call_count,
            "total_sleep_ms": self.total_sleep_ms,
            "total_cpu_ms": round(self.total_cpu_ms, 2)
        }

    def reset_stats(self):
        """Reset accumulated statistics."""
        self.call_count = 0
        self.total_sleep_ms = 0
        self.total_cpu_ms = 0
        return {"reset": True}

    def health(self):
        """Health check endpoint for warmup."""
        return {"status": "ok"}

    def close(self):
        """Cleanup on shutdown."""
        pass


================================================
FILE: benchmarks/dirty_bench_gunicorn.py
================================================
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

"""
Gunicorn configuration for dirty pool integration benchmarks.

Usage:
    gunicorn -c benchmarks/dirty_bench_gunicorn.py \
        benchmarks.dirty_bench_wsgi:app
"""

# Bind address
bind = "127.0.0.1:8000"

# HTTP worker configuration
workers = 4
worker_class = "gthread"
threads = 4
worker_connections = 1000

# Dirty pool configuration
dirty_apps = ["benchmarks.dirty_bench_app:BenchmarkApp"]
dirty_workers = 4
dirty_threads = 1
dirty_timeout = 300
dirty_graceful_timeout = 30

# Logging
accesslog = "-"
errorlog = "-"
loglevel = "info"

# Timeouts
timeout = 120
graceful_timeout = 30
keepalive = 2


# Lifecycle hooks

def on_dirty_starting(arbiter):
    """Called when dirty arbiter is starting."""
    print(f"[dirty] Arbiter starting (pid: {arbiter.pid})")


def dirty_post_fork(arbiter, worker):
    """Called after dirty worker fork."""
    print(f"[dirty] Worker {worker.pid} forked")


def dirty_worker_init(worker):
    """Called after dirty worker apps are initialized."""
    print(f"[dirty] Worker {worker.pid} initialized with apps: "
          f"{list(worker.apps.keys())}")


def dirty_worker_exit(arbiter, worker):
    """Called when dirty worker exits."""
    print(f"[dirty] Worker {worker.pid} exiting")


================================================
FILE: benchmarks/dirty_bench_wsgi.py
================================================
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

"""
WSGI app for integration benchmarking of the dirty pool.

This simple WSGI application calls the dirty pool and returns results.
Use with gunicorn for end-to-end benchmarking that includes HTTP overhead.

Example:
    gunicorn benchmarks.dirty_bench_wsgi:app \
        --workers 4 \
        --dirty-app benchmarks.dirty_bench_app:BenchmarkApp \
        --dirty-workers 2 \
        --bind 127.0.0.1:8000
"""

import json
from urllib.parse import parse_qs

from gunicorn.dirty import get_dirty_client


# Default benchmark app path
BENCHMARK_APP = "benchmarks.dirty_bench_app:BenchmarkApp"


def app(environ, start_response):
    """
    WSGI application that calls dirty pool tasks.

    Query parameters:
        action: Task action to call (default: sleep_task)
        duration: Duration in ms for sleep/cpu tasks (default: 10)
        sleep: Sleep duration for mixed_task (default: 50)
        cpu: CPU duration for mixed_task (default: 50)
        size: Payload size in bytes for payload_task (default: 100)
        intensity: CPU intensity for cpu/mixed tasks (default: 1.0)
        app: Dirty app path (default: benchmarks.dirty_bench_app:BenchmarkApp)

    Endpoints:
        /              - Default sleep_task
        /sleep         - sleep_task with ?duration=N
        /cpu           - cpu_task with ?duration=N&intensity=N
        /mixed         - mixed_task with ?sleep=N&cpu=N
        /payload       - payload_task with ?size=N
        /echo          - echo_task (POST body echoed)
        /stats         - Get accumulated stats
        /health        - Health check
    """
    path = environ.get('PATH_INFO', '/')
    method = environ.get('REQUEST_METHOD', 'GET')
    query = parse_qs(environ.get('QUERY_STRING', ''))

    # Helper to get query params with defaults
    def get_param(name, default, type_fn=int):
        values = query.get(name, [])
        if values:
            try:
                return type_fn(values[0])
            except (ValueError, TypeError):
                return default
        return default

    # Get app path from query or use default
    app_path = query.get('app', [BENCHMARK_APP])[0]

    try:
        client = get_dirty_client()

        # Route based on path
        if path in ('/', '/sleep'):
            duration = get_param('duration', 10)
            result = client.execute(app_path, "sleep_task", duration)

        elif path == '/cpu':
            duration = get_param('duration', 100)
            intensity = get_param('intensity', 1.0, float)
            result = client.execute(app_path, "cpu_task", duration, intensity)

        elif path == '/mixed':
            sleep_ms = get_param('sleep', 50)
            cpu_ms = get_param('cpu', 50)
            intensity = get_param('intensity', 1.0, float)
            result = client.execute(app_path, "mixed_task", sleep_ms, cpu_ms,
                                    intensity)

        elif path == '/payload':
            size = get_param('size', 100)
            duration = get_param('duration', 0)
            result = client.execute(app_path, "payload_task", size, duration)

        elif path == '/echo':
            # Read request body for echo
            try:
                content_length = int(environ.get('CONTENT_LENGTH', 0))
            except (ValueError, TypeError):
                content_length = 0

            if content_length > 0:
                body = environ['wsgi.input'].read(content_length)
                try:
                    payload = json.loads(body.decode('utf-8'))
                except (json.JSONDecodeError, UnicodeDecodeError):
                    payload = body.decode('utf-8', errors='replace')
            else:
                payload = ""

            result = client.execute(app_path, "echo_task", payload)

        elif path == '/stats':
            result = client.execute(app_path, "stats")

        elif path == '/reset':
            result = client.execute(app_path, "reset_stats")

        elif path == '/health':
            result = client.execute(app_path, "health")

        else:
            # Unknown path - return 404
            status = '404 Not Found'
            body = json.dumps({"error": f"Unknown path: {path}"}).encode()
            headers = [
                ('Content-Type', 'application/json'),
                ('Content-Length', str(len(body))),
            ]
            start_response(status, headers)
            return [body]

        # Success response
        status = '200 OK'
        body = json.dumps(result).encode()
        headers = [
            ('Content-Type', 'application/json'),
            ('Content-Length', str(len(body))),
        ]
        start_response(status, headers)
        return [body]

    except Exception as e:
        # Error response
        status = '500 Internal Server Error'
        error_msg = {"error": str(e), "type": type(e).__name__}
        body = json.dumps(error_msg).encode()
        headers = [
            ('Content-Type', 'application/json'),
            ('Content-Length', str(len(body))),
        ]
        start_response(status, headers)
        return [body]


# Gunicorn configuration for integration testing
# These can be overridden on the command line

# Example gunicorn invocation:
# gunicorn benchmarks.dirty_bench_wsgi:app \
#     -c benchmarks/dirty_bench_gunicorn.py \
#     --dirty-app benchmarks.dirty_bench_app:BenchmarkApp \
#     --dirty-workers 2


def post_fork(server, worker):
    """Hook called after worker fork."""
    pass


================================================
FILE: benchmarks/dirty_benchmark.py
================================================
#!/usr/bin/env python3
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

"""
Dirty Pool Benchmark Runner

Stress tests and benchmarks the dirty arbiter pool to find bottlenecks
and optimization opportunities.

Test Modes:
- Isolated: Direct client -> arbiter -> worker (no HTTP overhead)
- Integrated: HTTP workers calling dirty pool (realistic end-to-end)

Usage:
    # Quick smoke test
    python benchmarks/dirty_benchmark.py --quick

    # Full isolated suite
    python benchmarks/dirty_benchmark.py --isolated --output results.json

    # Specific scenario
    python benchmarks/dirty_benchmark.py \
        --duration 100 \
        --concurrency 50 \
        --workers 4 \
        --threads 2

    # Payload size tests
    python benchmarks/dirty_benchmark.py --payload-tests

    # Integration tests (requires gunicorn running)
    python benchmarks/dirty_benchmark.py --integrated --url http://127.0.0.1:8000
"""

import argparse
import asyncio
import json
import multiprocessing
import os
import signal
import statistics
import subprocess
import sys
import tempfile
import threading
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
from dataclasses import dataclass, field, asdict
from pathlib import Path
from typing import Any

# Add parent to path for imports
BENCHMARK_DIR = Path(__file__).parent
sys.path.insert(0, str(BENCHMARK_DIR.parent))

from gunicorn.dirty.client import DirtyClient
from gunicorn.dirty.arbiter import DirtyArbiter


# Default benchmark app path
BENCHMARK_APP = "benchmarks.dirty_bench_app:BenchmarkApp"


@dataclass
class LatencyStats:
    """Latency statistics in milliseconds."""
    min: float = 0.0
    max: float = 0.0
    mean: float = 0.0
    stddev: float = 0.0
    p50: float = 0.0
    p95: float = 0.0
    p99: float = 0.0

    @classmethod
    def from_samples(cls, samples: list[float]) -> "LatencyStats":
        """Calculate statistics from list of latency samples."""
        if not samples:
            return cls()

        sorted_samples = sorted(samples)
        n = len(sorted_samples)

        return cls(
            min=sorted_samples[0],
            max=sorted_samples[-1],
            mean=statistics.mean(sorted_samples),
            stddev=statistics.stdev(sorted_samples) if n > 1 else 0.0,
            p50=sorted_samples[int(n * 0.50)],
            p95=sorted_samples[int(n * 0.95)] if n >= 20 else sorted_samples[-1],
            p99=sorted_samples[int(n * 0.99)] if n >= 100 else sorted_samples[-1],
        )


@dataclass
class BenchmarkResult:
    """Results from a single benchmark run."""
    scenario: str
    config: dict
    total_requests: int = 0
    successful: int = 0
    failed: int = 0
    errors: list[str] = field(default_factory=list)
    duration_sec: float = 0.0
    requests_per_sec: float = 0.0
    latency_ms: LatencyStats = field(default_factory=LatencyStats)

    def to_dict(self) -> dict:
        """Convert to dictionary for JSON serialization."""
        d = asdict(self)
        d['latency_ms'] = asdict(self.latency_ms)
        return d


class MockConfig:
    """Mock gunicorn config for standalone arbiter testing."""

    def __init__(
        self,
        dirty_apps: list[str],
        dirty_workers: int = 2,
        dirty_threads: int = 1,
        dirty_timeout: int = 300,
        dirty_graceful_timeout: int = 30,
    ):
        self.dirty_apps = dirty_apps
        self.dirty_workers = dirty_workers
        self.dirty_threads = dirty_threads
        self.dirty_timeout = dirty_timeout
        self.dirty_graceful_timeout = dirty_graceful_timeout

        # Other required config
        self.env = {}
        self.uid = os.getuid()
        self.gid = os.getgid()
        self.initgroups = False
        self.proc_name = "dirty-benchmark"

        # WorkerTmp requirements
        self.umask = 0
        self.worker_tmp_dir = None

    # Hook stubs
    def on_dirty_starting(self, arbiter):
        pass

    def dirty_post_fork(self, arbiter, worker):
        pass

    def dirty_worker_init(self, worker):
        pass

    def dirty_worker_exit(self, arbiter, worker):
        pass


class MockLogger:
    """Mock logger for standalone testing."""

    def __init__(self, verbose: bool = False):
        self.verbose = verbose

    def debug(self, msg, *args):
        if self.verbose:
            print(f"[DEBUG] {msg % args if args else msg}")

    def info(self, msg, *args):
        if self.verbose:
            print(f"[INFO] {msg % args if args else msg}")

    def warning(self, msg, *args):
        print(f"[WARN] {msg % args if args else msg}")

    def error(self, msg, *args):
        print(f"[ERROR] {msg % args if args else msg}")

    def critical(self, msg, *args):
        print(f"[CRIT] {msg % args if args else msg}")

    def exception(self, msg, *args):
        print(f"[EXC] {msg % args if args else msg}")

    def reopen_files(self):
        pass

    def close_on_exec(self):
        pass


class IsolatedBenchmark:
    """
    Run benchmarks directly against the dirty pool without HTTP.

    Spawns a standalone dirty arbiter and workers, then runs concurrent
    clients to measure performance.
    """

    def __init__(
        self,
        dirty_workers: int = 2,
        dirty_threads: int = 1,
        dirty_timeout: int = 300,
        verbose: bool = False,
    ):
        self.dirty_workers = dirty_workers
        self.dirty_threads = dirty_threads
        self.dirty_timeout = dirty_timeout
        self.verbose = verbose

        self.arbiter = None
        self.arbiter_pid = None
        self.socket_path = None
        self._tmpdir = None

    def start(self):
        """Start the dirty arbiter and workers."""
        # Create temp directory for socket
        self._tmpdir = tempfile.mkdtemp(prefix="dirty-bench-")
        self.socket_path = os.path.join(self._tmpdir, "arbiter.sock")

        # Create config and logger
        cfg = MockConfig(
            dirty_apps=[BENCHMARK_APP],
            dirty_workers=self.dirty_workers,
            dirty_threads=self.dirty_threads,
            dirty_timeout=self.dirty_timeout,
        )
        log = MockLogger(verbose=self.verbose)

        # Fork arbiter process
        pid = os.fork()
        if pid == 0:
            # Child process - run arbiter
            try:
                arbiter = DirtyArbiter(cfg, log, socket_path=self.socket_path)
                arbiter.run()
            except Exception as e:
                print(f"Arbiter error: {e}")
            finally:
                os._exit(0)

        # Parent process
        self.arbiter_pid = pid

        # Wait for arbiter socket to be ready
        for _ in range(50):  # 5 seconds max
            if os.path.exists(self.socket_path):
                break
            time.sleep(0.1)
        else:
            raise RuntimeError("Arbiter socket not ready")

        # Give workers time to start
        time.sleep(0.5)

    def stop(self):
        """Stop the dirty arbiter."""
        if self.arbiter_pid:
            try:
                os.kill(self.arbiter_pid, signal.SIGTERM)
                os.waitpid(self.arbiter_pid, 0)
            except (OSError, ChildProcessError):
                pass
            self.arbiter_pid = None

        # Cleanup temp directory
        if self._tmpdir:
            try:
                for f in os.listdir(self._tmpdir):
                    os.unlink(os.path.join(self._tmpdir, f))
                os.rmdir(self._tmpdir)
            except OSError:
                pass
            self._tmpdir = None

    def warmup(self, requests: int = 10):
        """Warm up the pool with a few requests."""
        with DirtyClient(self.socket_path, timeout=30.0) as client:
            for _ in range(requests):
                client.execute(BENCHMARK_APP, "health")

    def run_benchmark(
        self,
        action: str,
        args: tuple = (),
        kwargs: dict = None,
        total_requests: int = 1000,
        concurrency: int = 10,
        timeout: float = 30.0,
    ) -> tuple[list[float], list[str]]:
        """
        Run a benchmark with specified parameters.

        Each concurrent worker maintains a persistent connection to the arbiter
        and makes sequential requests. This simulates how real HTTP workers
        use the dirty client (one connection per worker thread).

        Args:
            action: Action to call on the benchmark app
            args: Positional arguments for the action
            kwargs: Keyword arguments for the action
            total_requests: Total number of requests to make
            concurrency: Number of concurrent clients
            timeout: Timeout per request in seconds

        Returns:
            Tuple of (latencies in ms, error messages)
        """
        kwargs = kwargs or {}
        latencies = []
        errors = []
        lock = threading.Lock()

        # Calculate requests per worker
        requests_per_worker = total_requests // concurrency
        remainder = total_requests % concurrency

        def worker_task(num_requests: int) -> None:
            """Worker that makes sequential requests on a persistent connection."""
            worker_latencies = []
            worker_errors = []

            try:
                client = DirtyClient(self.socket_path, timeout=timeout)
                client.connect()

                for _ in range(num_requests):
                    try:
                        start = time.perf_counter()
                        client.execute(BENCHMARK_APP, action, *args, **kwargs)
                        elapsed = (time.perf_counter() - start) * 1000
                        worker_latencies.append(elapsed)
                    except Exception as e:
                        worker_errors.append(str(e))
                        # Reconnect on error
                        try:
                            client.close()
                            client = DirtyClient(self.socket_path, timeout=timeout)
                            client.connect()
                        except Exception:
                            pass

                client.close()
            except Exception as e:
                worker_errors.append(f"Connection error: {e}")

            # Add results to shared lists
            with lock:
                latencies.extend(worker_latencies)
                errors.extend(worker_errors)

        # Run concurrent workers
        with ThreadPoolExecutor(max_workers=concurrency) as executor:
            futures = []
            for i in range(concurrency):
                # Distribute remainder requests among first few workers
                num = requests_per_worker + (1 if i < remainder else 0)
                if num > 0:
                    futures.append(executor.submit(worker_task, num))

            # Wait for all workers to complete
            for future in as_completed(futures):
                future.result()  # Raises any exceptions

        return latencies, errors


class IntegratedBenchmark:
    """
    Run benchmarks against gunicorn with dirty pool via HTTP.

    Uses wrk or ab for load testing, or falls back to Python requests.
    """

    def __init__(
        self,
        url: str = "http://127.0.0.1:8000",
        verbose: bool = False,
    ):
        self.url = url.rstrip('/')
        self.verbose = verbose
        self._tool = None

    def check_dependencies(self) -> str | None:
        """Check for available load testing tools."""
        for tool in ['wrk', 'ab']:
            try:
                subprocess.run([tool, '--version'], capture_output=True,
                               check=False)
                return tool
            except FileNotFoundError:
                continue
        return None

    def warmup(self, requests: int = 10):
        """Warm up the server."""
        import urllib.request
        for _ in range(requests):
            try:
                urllib.request.urlopen(f"{self.url}/health", timeout=5)
            except Exception:
                pass

    def run_wrk(
        self,
        path: str,
        duration: int = 10,
        threads: int = 4,
        connections: int = 100,
    ) -> dict:
        """Run wrk benchmark and parse results."""
        url = f"{self.url}{path}"
        cmd = [
            'wrk',
            '-t', str(threads),
            '-c', str(connections),
            '-d', f'{duration}s',
            '--latency',
            url,
        ]

        result = subprocess.run(cmd, capture_output=True, text=True,
                                check=False)
        return self._parse_wrk_output(result.stdout)

    def _parse_wrk_output(self, output: str) -> dict:
        """Parse wrk output to extract metrics."""
        metrics = {
            'requests_per_sec': 0.0,
            'latency_ms': {},
            'errors': 0,
        }

        for line in output.split('\n'):
            if 'Requests/sec' in line:
                try:
                    metrics['requests_per_sec'] = float(
                        line.split(':')[1].strip())
                except (ValueError, IndexError):
                    pass
            elif 'Latency' in line and 'Distribution' not in line:
                parts = line.split()
                if len(parts) >= 2:
                    metrics['latency_ms']['avg'] = self._parse_duration(
                        parts[1])
            elif '50%' in line:
                parts = line.split()
                if len(parts) >= 2:
                    metrics['latency_ms']['p50'] = self._parse_duration(
                        parts[1])
            elif '99%' in line:
                parts = line.split()
                if len(parts) >= 2:
                    metrics['latency_ms']['p99'] = self._parse_duration(
                        parts[1])
            elif 'Socket errors' in line:
                # Parse error counts
                parts = line.split(',')
                for part in parts:
                    if any(x in part for x in ['connect', 'read', 'write',
                                                 'timeout']):
                        try:
                            metrics['errors'] += int(part.split()[-1])
                        except (ValueError, IndexError):
                            pass

        return metrics

    def _parse_duration(self, s: str) -> float:
        """Parse wrk duration string (e.g., '12.34ms', '1.23s') to ms."""
        s = s.strip()
        if s.endswith('us'):
            return float(s[:-2]) / 1000
        elif s.endswith('ms'):
            return float(s[:-2])
        elif s.endswith('s'):
            return float(s[:-1]) * 1000
        else:
            return float(s)

    def run_python_benchmark(
        self,
        path: str,
        total_requests: int = 1000,
        concurrency: int = 10,
        timeout: float = 30.0,
    ) -> tuple[list[float], list[str]]:
        """
        Run benchmark using Python urllib.

        Fallback when wrk/ab not available.
        """
        import urllib.request
        import urllib.error

        url = f"{self.url}{path}"
        latencies = []
        errors = []

        def make_request() -> tuple[float | None, str | None]:
            try:
                start = time.perf_counter()
                urllib.request.urlopen(url, timeout=timeout)
                elapsed = (time.perf_counter() - start) * 1000
                return elapsed, None
            except Exception as e:
                return None, str(e)

        with ThreadPoolExecutor(max_workers=concurrency) as executor:
            futures = [executor.submit(make_request)
                       for _ in range(total_requests)]

            for future in as_completed(futures):
                latency, error = future.result()
                if latency is not None:
                    latencies.append(latency)
                if error:
                    errors.append(error)

        return latencies, errors


def run_isolated_suite(
    workers: int = 2,
    threads: int = 1,
    verbose: bool = False,
) -> list[BenchmarkResult]:
    """Run the full isolated benchmark suite."""
    results = []

    bench = IsolatedBenchmark(
        dirty_workers=workers,
        dirty_threads=threads,
        verbose=verbose,
    )

    print(f"\nStarting isolated benchmarks (workers={workers}, "
          f"threads={threads})...")

    try:
        bench.start()
        bench.warmup()

        # Define scenarios
        scenarios = [
            # Baseline
            {
                "name": "baseline_10ms",
                "action": "sleep_task",
                "args": (10,),
                "requests": 1000,
                "concurrency": 1,
                "description": "Single request latency (10ms sleep)",
            },
            # Throughput
            {
                "name": "throughput_10ms",
                "action": "sleep_task",
                "args": (10,),
                "requests": 5000,
                "concurrency": 100,
                "description": "Max requests/sec (10ms sleep, 100 clients)",
            },
            # CPU Bound
            {
                "name": "cpu_bound_100ms",
                "action": "cpu_task",
                "args": (100,),
                "requests": 500,
                "concurrency": 20,
                "description": "CPU-bound work (100ms, 20 clients)",
            },
            # I/O Bound
            {
                "name": "io_bound_500ms",
                "action": "sleep_task",
                "args": (500,),
                "requests": 200,
                "concurrency": 50,
                "description": "I/O-bound work (500ms sleep, 50 clients)",
            },
            # Mixed
            {
                "name": "mixed_50_50",
                "action": "mixed_task",
                "args": (50, 50),
                "requests": 500,
                "concurrency": 30,
                "description": "Mixed workload (50ms sleep + 50ms CPU)",
            },
            # Overload
            {
                "name": "overload_10ms",
                "action": "sleep_task",
                "args": (10,),
                "requests": 2000,
                "concurrency": 200,
                "description": "Overload test (10ms, 200 clients)",
            },
        ]

        for scenario in scenarios:
            print(f"  Running {scenario['name']}: {scenario['description']}...")

            start_time = time.perf_counter()
            latencies, errors = bench.run_benchmark(
                action=scenario["action"],
                args=scenario.get("args", ()),
                kwargs=scenario.get("kwargs"),
                total_requests=scenario["requests"],
                concurrency=scenario["concurrency"],
            )
            duration = time.perf_counter() - start_time

            result = BenchmarkResult(
                scenario=scenario["name"],
                config={
                    "dirty_workers": workers,
                    "dirty_threads": threads,
                    "task_action": scenario["action"],
                    "task_args": scenario.get("args", ()),
                    "concurrency": scenario["concurrency"],
                },
                total_requests=scenario["requests"],
                successful=len(latencies),
                failed=len(errors),
                errors=errors[:10] if errors else [],  # First 10 errors
                duration_sec=round(duration, 2),
                requests_per_sec=round(len(latencies) / duration, 1),
                latency_ms=LatencyStats.from_samples(latencies),
            )
            results.append(result)

            print(f"    Requests/sec: {result.requests_per_sec:.1f}, "
                  f"p50: {result.latency_ms.p50:.1f}ms, "
                  f"p99: {result.latency_ms.p99:.1f}ms, "
                  f"failed: {result.failed}")

    finally:
        bench.stop()

    return results


def run_payload_suite(
    workers: int = 2,
    threads: int = 1,
    verbose: bool = False,
) -> list[BenchmarkResult]:
    """Run payload size benchmark suite."""
    results = []

    bench = IsolatedBenchmark(
        dirty_workers=workers,
        dirty_threads=threads,
        verbose=verbose,
    )

    print(f"\nStarting payload benchmarks (workers={workers})...")

    try:
        bench.start()
        bench.warmup()

        # Payload sizes to test
        payload_sizes = [
            (100, "100B", "Tiny payload"),
            (1024, "1KB", "Small payload"),
            (10240, "10KB", "Medium payload"),
            (102400, "100KB", "Large payload"),
            (1048576, "1MB", "Very large payload"),
        ]

        for size, size_label, description in payload_sizes:
            # Adjust concurrency for larger payloads
            concurrency = max(5, 100 // (size // 1024 + 1))
            requests = max(100, 1000 // (size // 1024 + 1))

            print(f"  Running payload_{size_label}: {description}...")

            start_time = time.perf_counter()
            latencies, errors = bench.run_benchmark(
                action="payload_task",
                args=(size,),
                total_requests=requests,
                concurrency=concurrency,
            )
            duration = time.perf_counter() - start_time

            result = BenchmarkResult(
                scenario=f"payload_{size_label}",
                config={
                    "dirty_workers": workers,
                    "dirty_threads": threads,
                    "payload_bytes": size,
                    "concurrency": concurrency,
                },
                total_requests=requests,
                successful=len(latencies),
                failed=len(errors),
                errors=errors[:5] if errors else [],
                duration_sec=round(duration, 2),
                requests_per_sec=round(len(latencies) / duration, 1),
                latency_ms=LatencyStats.from_samples(latencies),
            )
            results.append(result)

            # Calculate throughput in MB/s
            throughput_mb = (len(latencies) * size) / duration / 1024 / 1024

            print(f"    Requests/sec: {result.requests_per_sec:.1f}, "
                  f"p50: {result.latency_ms.p50:.1f}ms, "
                  f"throughput: {throughput_mb:.1f} MB/s")

    finally:
        bench.stop()

    return results


def run_quick_test(verbose: bool = False) -> list[BenchmarkResult]:
    """Run a quick smoke test."""
    results = []

    bench = IsolatedBenchmark(dirty_workers=1, dirty_threads=1, verbose=verbose)

    print("\nRunning quick smoke test...")

    try:
        bench.start()
        bench.warmup(5)

        # Simple test
        start_time = time.perf_counter()
        latencies, errors = bench.run_benchmark(
            action="sleep_task",
            args=(10,),
            total_requests=100,
            concurrency=10,
        )
        duration = time.perf_counter() - start_time

        result = BenchmarkResult(
            scenario="quick_test",
            config={"dirty_workers": 1, "dirty_threads": 1},
            total_requests=100,
            successful=len(latencies),
            failed=len(errors),
            errors=errors[:5] if errors else [],
            duration_sec=round(duration, 2),
            requests_per_sec=round(len(latencies) / duration, 1),
            latency_ms=LatencyStats.from_samples(latencies),
        )
        results.append(result)

        print(f"  Requests/sec: {result.requests_per_sec:.1f}, "
              f"p50: {result.latency_ms.p50:.1f}ms, "
              f"failed: {result.failed}")

        if result.failed == 0:
            print("  PASS: Quick test successful")
        else:
            print(f"  WARN: {result.failed} requests failed")

    finally:
        bench.stop()

    return results


def run_config_sweep(verbose: bool = False) -> list[BenchmarkResult]:
    """
    Sweep through different configurations to find optimal settings.

    Tests combinations of workers and threads.
    """
    results = []

    configs = [
        (1, 1),   # Baseline
        (2, 1),   # 2 workers, 1 thread each
        (4, 1),   # 4 workers, 1 thread each
        (2, 2),   # 2 workers, 2 threads each
        (2, 4),   # 2 workers, 4 threads each
        (4, 2),   # 4 workers, 2 threads each
    ]

    print("\nRunning configuration sweep...")

    for workers, threads in configs:
        print(f"\n  Testing workers={workers}, threads={threads}...")

        bench = IsolatedBenchmark(
            dirty_workers=workers,
            dirty_threads=threads,
            verbose=verbose,
        )

        try:
            bench.start()
            bench.warmup()

            # Run a standard workload
            start_time = time.perf_counter()
            latencies, errors = bench.run_benchmark(
                action="mixed_task",
                args=(20, 20),  # 20ms sleep + 20ms CPU
                total_requests=1000,
                concurrency=50,
            )
            duration = time.perf_counter() - start_time

            result = BenchmarkResult(
                scenario=f"config_w{workers}_t{threads}",
                config={
                    "dirty_workers": workers,
                    "dirty_threads": threads,
                    "task": "mixed_task(20, 20)",
                    "concurrency": 50,
                },
                total_requests=1000,
                successful=len(latencies),
                failed=len(errors),
                errors=errors[:5] if errors else [],
                duration_sec=round(duration, 2),
                requests_per_sec=round(len(latencies) / duration, 1),
                latency_ms=LatencyStats.from_samples(latencies),
            )
            results.append(result)

            print(f"    Requests/sec: {result.requests_per_sec:.1f}, "
                  f"p50: {result.latency_ms.p50:.1f}ms, "
                  f"p99: {result.latency_ms.p99:.1f}ms")

        finally:
            bench.stop()

    # Print summary
    print("\n  Configuration Summary:")
    print("  " + "-" * 60)
    sorted_results = sorted(results, key=lambda r: -r.requests_per_sec)
    for r in sorted_results:
        cfg = r.config
        print(f"    w={cfg['dirty_workers']}, t={cfg['dirty_threads']}: "
              f"{r.requests_per_sec:.1f} req/s, "
              f"p99={r.latency_ms.p99:.1f}ms")

    return results


def generate_report(results: list[BenchmarkResult], output_path: str = None):
    """Generate a summary report from benchmark results."""
    print("\n" + "=" * 70)
    print("BENCHMARK REPORT")
    print("=" * 70)

    for result in results:
        print(f"\n{result.scenario}")
        print("-" * 40)
        print(f"  Config: {json.dumps(result.config, indent=None)}")
        print(f"  Requests: {result.successful}/{result.total_requests} "
              f"({result.failed} failed)")
        print(f"  Duration: {result.duration_sec}s")
        print(f"  Throughput: {result.requests_per_sec:.1f} req/s")
        print(f"  Latency (ms):")
        print(f"    min: {result.latency_ms.min:.2f}")
        print(f"    p50: {result.latency_ms.p50:.2f}")
        print(f"    p95: {result.latency_ms.p95:.2f}")
        print(f"    p99: {result.latency_ms.p99:.2f}")
        print(f"    max: {result.latency_ms.max:.2f}")
        print(f"    mean: {result.latency_ms.mean:.2f} "
              f"(stddev: {result.latency_ms.stddev:.2f})")

        if result.errors:
            print(f"  Errors (first {len(result.errors)}):")
            for err in result.errors[:3]:
                print(f"    - {err[:80]}")

    if output_path:
        output_data = {
            "timestamp": time.strftime("%Y-%m-%dT%H:%M:%S"),
            "results": [r.to_dict() for r in results],
        }
        with open(output_path, 'w') as f:
            json.dump(output_data, f, indent=2)
        print(f"\nResults saved to: {output_path}")


def main():
    parser = argparse.ArgumentParser(
        description='Benchmark the gunicorn dirty pool',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=__doc__,
    )

    # Mode selection
    mode_group = parser.add_mutually_exclusive_group()
    mode_group.add_argument('--quick', action='store_true',
                            help='Run quick smoke test')
    mode_group.add_argument('--isolated', action='store_true',
                            help='Run isolated benchmark suite')
    mode_group.add_argument('--payload-tests', action='store_true',
                            help='Run payload size tests')
    mode_group.add_argument('--config-sweep', action='store_true',
                            help='Sweep through configurations')
    mode_group.add_argument('--integrated', action='store_true',
                            help='Run integrated HTTP benchmarks')

    # Configuration
    parser.add_argument('--workers', type=int, default=2,
                        help='Number of dirty workers (default: 2)')
    parser.add_argument('--threads', type=int, default=1,
                        help='Threads per dirty worker (default: 1)')
    parser.add_argument('--duration', type=int, default=10,
                        help='Task duration in ms for custom run')
    parser.add_argument('--concurrency', type=int, default=10,
                        help='Number of concurrent clients')
    parser.add_argument('--requests', type=int, default=1000,
                        help='Total requests to make')

    # Integration mode options
    parser.add_argument('--url', default='http://127.0.0.1:8000',
                        help='Server URL for integrated tests')

    # Output
    parser.add_argument('--output', '-o',
                        help='Output JSON file for results')
    parser.add_argument('--verbose', '-v', action='store_true',
                        help='Verbose output')

    args = parser.parse_args()

    results = []

    try:
        if args.quick:
            results = run_quick_test(verbose=args.verbose)
        elif args.isolated:
            results = run_isolated_suite(
                workers=args.workers,
                threads=args.threads,
                verbose=args.verbose,
            )
        elif args.payload_tests:
            results = run_payload_suite(
                workers=args.workers,
                threads=args.threads,
                verbose=args.verbose,
            )
        elif args.config_sweep:
            results = run_config_sweep(verbose=args.verbose)
        elif args.integrated:
            bench = IntegratedBenchmark(url=args.url, verbose=args.verbose)
            tool = bench.check_dependencies()

            if tool == 'wrk':
                print(f"\nRunning integrated benchmarks with wrk...")
                bench.warmup()

                # Run basic scenarios
                scenarios = [
                    ("/sleep?duration=10", "sleep_10ms"),
                    ("/cpu?duration=100", "cpu_100ms"),
                    ("/mixed?sleep=50&cpu=50", "mixed_50_50"),
                ]

                for path, name in scenarios:
                    print(f"  Running {name}...")
                    metrics = bench.run_wrk(path, duration=10, connections=100)
                    print(f"    Requests/sec: {metrics.get('requests_per_sec', 'N/A')}")

                print("\nNote: For detailed results, use wrk directly:")
                print(f"  wrk -t4 -c100 -d30s --latency '{args.url}/sleep?duration=10'")
            else:
                print("\nUsing Python fallback (install wrk for better results)...")
                bench.warmup()

                latencies, errors = bench.run_python_benchmark(
                    "/sleep?duration=10",
                    total_requests=args.requests,
                    concurrency=args.concurrency,
                )

                result = BenchmarkResult(
                    scenario="integrated_sleep",
                    config={"url": args.url, "concurrency": args.concurrency},
                    total_requests=args.requests,
                    successful=len(latencies),
                    failed=len(errors),
                    errors=errors[:5],
                    duration_sec=sum(latencies) / 1000 / args.concurrency,
                    requests_per_sec=len(latencies) / (sum(latencies) / 1000 /
                                                        args.concurrency),
                    latency_ms=LatencyStats.from_samples(latencies),
                )
                results.append(result)

        else:
            # Default: run custom single benchmark
            print(f"\nRunning custom benchmark: "
                  f"duration={args.duration}ms, concurrency={args.concurrency}")

            bench = IsolatedBenchmark(
                dirty_workers=args.workers,
                dirty_threads=args.threads,
                verbose=args.verbose,
            )

            try:
                bench.start()
                bench.warmup()

                start_time = time.perf_counter()
                latencies, errors = bench.run_benchmark(
                    action="sleep_task",
                    args=(args.duration,),
                    total_requests=args.requests,
                    concurrency=args.concurrency,
                )
                duration = time.perf_counter() - start_time

                result = BenchmarkResult(
                    scenario="custom",
                    config={
                        "dirty_workers": args.workers,
                        "dirty_threads": args.threads,
                        "task_duration_ms": args.duration,
                        "concurrency": args.concurrency,
                    },
                    total_requests=args.requests,
                    successful=len(latencies),
                    failed=len(errors),
                    errors=errors[:10],
                    duration_sec=round(duration, 2),
                    requests_per_sec=round(len(latencies) / duration, 1),
                    latency_ms=LatencyStats.from_samples(latencies),
                )
                results.append(result)

            finally:
                bench.stop()

        # Generate report
        if results:
            generate_report(results, args.output)

    except KeyboardInterrupt:
        print("\nBenchmark interrupted")
        sys.exit(1)
    except Exception as e:
        print(f"\nError: {e}")
        if args.verbose:
            import traceback
            traceback.print_exc()
        sys.exit(1)


if __name__ == '__main__':
    main()


================================================
FILE: benchmarks/dirty_streaming.py
================================================
#!/usr/bin/env python
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

"""
Benchmark suite for dirty worker streaming functionality.

This script benchmarks the streaming performance of dirty workers
to measure throughput, latency, and memory usage.

Usage:
    python benchmarks/dirty_streaming.py [OPTIONS]

Options:
    --quick     Run quick benchmarks only
    --full      Run full benchmark suite including stress tests
"""

import argparse
import asyncio
import gc
import json
import os
import struct
import sys
import time
import tracemalloc
from datetime import datetime
from unittest import mock

# Add parent directory to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from gunicorn.dirty.protocol import (
    DirtyProtocol,
    make_request,
    make_chunk_message,
    make_end_message,
    make_response,
)
from gunicorn.dirty.worker import DirtyWorker
from gunicorn.dirty.arbiter import DirtyArbiter
from gunicorn.dirty.client import (
    DirtyClient,
    DirtyStreamIterator,
    DirtyAsyncStreamIterator,
)
from gunicorn.config import Config


class MockStreamWriter:
    """Mock StreamWriter that captures written messages."""

    def __init__(self):
        self.messages = []
        self._buffer = b""
        self.bytes_written = 0

    def write(self, data):
        self._buffer += data
        self.bytes_written += len(data)

    async def drain(self):
        while len(self._buffer) >= DirtyProtocol.HEADER_SIZE:
            length = struct.unpack(
                DirtyProtocol.HEADER_FORMAT,
                self._buffer[:DirtyProtocol.HEADER_SIZE]
            )[0]
            total_size = DirtyProtocol.HEADER_SIZE + length
            if len(self._buffer) >= total_size:
                msg_data = self._buffer[DirtyProtocol.HEADER_SIZE:total_size]
                self._buffer = self._buffer[total_size:]
                self.messages.append(DirtyProtocol.decode(msg_data))
            else:
                break

    def close(self):
        pass

    async def wait_closed(self):
        pass


class MockStreamReader:
    """Mock StreamReader that yields predefined messages."""

    def __init__(self, messages):
        self._data = b''
        for msg in messages:
            self._data += DirtyProtocol.encode(msg)
        self._pos = 0

    async def readexactly(self, n):
        if self._pos + n > len(self._data):
            raise asyncio.IncompleteReadError(self._data[self._pos:], n)
        result = self._data[self._pos:self._pos + n]
        self._pos += n
        return result


class MockLog:
    """Silent logger for benchmarks."""

    def debug(self, msg, *args):
        pass

    def info(self, msg, *args):
        pass

    def warning(self, msg, *args):
        pass

    def error(self, msg, *args):
        pass

    def close_on_exec(self):
        pass

    def reopen_files(self):
        pass


def create_worker():
    """Create a test worker for benchmarks."""
    cfg = Config()
    cfg.set("dirty_timeout", 300)
    log = MockLog()

    with mock.patch('gunicorn.dirty.worker.WorkerTmp'):
        worker = DirtyWorker(
            age=1,
            ppid=os.getpid(),
            app_paths=["benchmark:App"],
            cfg=cfg,
            log=log,
            socket_path="/tmp/benchmark.sock"
        )

    worker.apps = {}
    worker._executor = None
    worker.tmp = mock.Mock()

    return worker


def create_arbiter():
    """Create a test arbiter for benchmarks."""
    cfg = Config()
    cfg.set("dirty_timeout", 300)
    log = MockLog()

    arbiter = DirtyArbiter(cfg=cfg, log=log)
    arbiter.alive = True
    arbiter.workers = {1234: mock.Mock()}
    arbiter.worker_sockets = {1234: '/tmp/worker.sock'}

    return arbiter


class BenchmarkResults:
    """Store and display benchmark results."""

    def __init__(self):
        self.results = []

    def add(self, name, iterations, duration, chunks=None, bytes_total=None,
            memory_start=None, memory_end=None):
        throughput = iterations / duration if duration > 0 else 0
        result = {
            "name": name,
            "iterations": iterations,
            "duration_s": round(duration, 4),
            "throughput_per_s": round(throughput, 2),
        }
        if chunks:
            result["chunks_per_s"] = round(chunks / duration, 2)
        if bytes_total:
            result["mb_per_s"] = round(bytes_total / (1024 * 1024) / duration, 2)
        if memory_start is not None and memory_end is not None:
            result["memory_start_mb"] = round(memory_start / (1024 * 1024), 2)
            result["memory_end_mb"] = round(memory_end / (1024 * 1024), 2)
            result["memory_delta_mb"] = round((memory_end - memory_start) / (1024 * 1024), 2)
        self.results.append(result)

    def display(self):
        print("\n" + "=" * 70)
        print("BENCHMARK RESULTS")
        print("=" * 70)
        for result in self.results:
            print(f"\n{result['name']}")
            print("-" * 50)
            for key, value in result.items():
                if key != "name":
                    print(f"  {key}: {value}")
        print("\n" + "=" * 70)

    def save_json(self, filepath):
        with open(filepath, 'w') as f:
            json.dump({
                "timestamp": datetime.now().isoformat(),
                "results": self.results
            }, f, indent=2)
        print(f"Results saved to {filepath}")


async def benchmark_worker_streaming_throughput(results, chunk_size=1024, num_chunks=1000):
    """Benchmark worker streaming throughput with various chunk sizes."""
    worker = create_worker()
    writer = MockStreamWriter()

    chunk_data = "x" * chunk_size

    async def sync_gen():
        for _ in range(num_chunks):
            yield chunk_data

    async def mock_execute(app_path, action, args, kwargs):
        return sync_gen()

    gc.collect()
    tracemalloc.start()
    memory_start = tracemalloc.get_traced_memory()[0]

    start = time.perf_counter()

    with mock.patch.object(worker, 'execute', side_effect=mock_execute):
        request = make_request("bench-1", "benchmark:App", "stream")
        await worker.handle_request(request, writer)

    duration = time.perf_counter() - start
    memory_end = tracemalloc.get_traced_memory()[0]
    tracemalloc.stop()

    total_bytes = chunk_size * num_chunks

    results.add(
        f"Worker streaming ({chunk_size}B chunks, {num_chunks} chunks)",
        iterations=1,
        duration=duration,
        chunks=num_chunks,
        bytes_total=total_bytes,
        memory_start=memory_start,
        memory_end=memory_end
    )


async def benchmark_arbiter_forwarding(results, num_chunks=1000):
    """Benchmark arbiter message forwarding throughput."""
    arbiter = create_arbiter()

    messages = []
    for i in range(num_chunks):
        messages.append(make_chunk_message(f"bench-{i}", f"data-{i}"))
    messages.append(make_end_message(f"bench-{num_chunks}"))

    mock_reader = MockStreamReader(messages)

    async def mock_get_connection(pid):
        return mock_reader, MockStreamWriter()

    arbiter._get_worker_connection = mock_get_connection

    client_writer = MockStreamWriter()

    gc.collect()
    start = time.perf_counter()

    request = make_request("bench-forward", "benchmark:App", "stream")
    await arbiter._execute_on_worker(1234, request, client_writer)

    duration = time.perf_counter() - start

    results.add(
        f"Arbiter forwarding ({num_chunks} chunks)",
        iterations=1,
        duration=duration,
        chunks=num_chunks,
        bytes_total=client_writer.bytes_written
    )

    arbiter._cleanup_sync()


async def benchmark_streaming_latency(results, iterations=100):
    """Benchmark time-to-first-chunk and time-to-last-chunk."""
    worker = create_worker()

    first_chunk_times = []
    total_times = []

    for _ in range(iterations):
        writer = MockStreamWriter()

        async def gen_3_chunks():
            yield "first"
            yield "second"
            yield "third"

        async def mock_execute(app_path, action, args, kwargs):
            return gen_3_chunks()

        start = time.perf_counter()

        with mock.patch.object(worker, 'execute', side_effect=mock_execute):
            request = make_request("bench-latency", "benchmark:App", "stream")
            await worker.handle_request(request, writer)

            # Find time when first chunk was received
            if writer.messages:
                first_chunk_times.append(time.perf_counter() - start)

        total_times.append(time.perf_counter() - start)

    avg_first_chunk = sum(first_chunk_times) / len(first_chunk_times) if first_chunk_times else 0
    avg_total = sum(total_times) / len(total_times)

    print(f"\nLatency Results ({iterations} iterations):")
    print(f"  Avg time-to-first-chunk: {avg_first_chunk * 1000:.3f}ms")
    print(f"  Avg time-to-last-chunk: {avg_total * 1000:.3f}ms")

    results.add(
        f"Streaming latency ({iterations} iterations)",
        iterations=iterations,
        duration=sum(total_times),
        chunks=iterations * 3
    )


async def benchmark_concurrent_streams(results, num_streams=10, chunks_per_stream=100):
    """Benchmark multiple concurrent streams."""
    arbiter = create_arbiter()

    async def run_stream(stream_id):
        messages = []
        for i in range(chunks_per_stream):
            messages.append(make_chunk_message(f"stream-{stream_id}", f"chunk-{i}"))
        messages.append(make_end_message(f"stream-{stream_id}"))

        mock_reader = MockStreamReader(messages)
        async def mock_get_connection(pid):
            return mock_reader, MockStreamWriter()

        arbiter._get_worker_connection = mock_get_connection
        client_writer = MockStreamWriter()

        request = make_request(f"bench-concurrent-{stream_id}", "benchmark:App", "stream")
        await arbiter._execute_on_worker(1234, request, client_writer)
        return len(client_writer.messages)

    gc.collect()
    start = time.perf_counter()

    # Run streams concurrently
    tasks = [run_stream(i) for i in range(num_streams)]
    results_list = await asyncio.gather(*tasks)

    duration = time.perf_counter() - start

    total_chunks = sum(results_list)

    results.add(
        f"Concurrent streams ({num_streams} streams, {chunks_per_stream} chunks each)",
        iterations=num_streams,
        duration=duration,
        chunks=total_chunks
    )

    arbiter._cleanup_sync()


async def benchmark_memory_stability(results, iterations=10, chunks=1000):
    """Check memory stability over many iterations."""
    worker = create_worker()

    gc.collect()
    tracemalloc.start()
    memory_samples = [tracemalloc.get_traced_memory()[0]]

    for i in range(iterations):
        writer = MockStreamWriter()

        async def gen_chunks():
            for j in range(chunks):
                yield f"chunk-{j}"

        async def mock_execute(app_path, action, args, kwargs):
            return gen_chunks()

        with mock.patch.object(worker, 'execute', side_effect=mock_execute):
            request = make_request(f"bench-mem-{i}", "benchmark:App", "stream")
            await worker.handle_request(request, writer)

        gc.collect()
        memory_samples.append(tracemalloc.get_traced_memory()[0])

    tracemalloc.stop()

    memory_start = memory_samples[0]
    memory_end = memory_samples[-1]
    memory_max = max(memory_samples)

    print(f"\nMemory stability ({iterations} iterations of {chunks} chunks):")
    print(f"  Start: {memory_start / 1024 / 1024:.2f}MB")
    print(f"  End: {memory_end / 1024 / 1024:.2f}MB")
    print(f"  Max: {memory_max / 1024 / 1024:.2f}MB")
    print(f"  Delta: {(memory_end - memory_start) / 1024 / 1024:.2f}MB")

    results.add(
        f"Memory stability ({iterations} x {chunks} chunks)",
        iterations=iterations * chunks,
        duration=0.001,  # Use small non-zero value to avoid division by zero
        memory_start=memory_start,
        memory_end=memory_end
    )


class MockClientReader:
    """Mock async reader that simulates receiving streaming messages."""

    def __init__(self, num_chunks, chunk_data):
        self.num_chunks = num_chunks
        self.chunk_data = chunk_data
        self._chunk_idx = 0
        self._messages = []
        self._build_messages()
        self._pos = 0
        self._data = b''
        for msg in self._messages:
            self._data += DirtyProtocol.encode(msg)

    def _build_messages(self):
        for i in range(self.num_chunks):
            self._messages.append(make_chunk_message(f"bench-{i}", self.chunk_data))
        self._messages.append(make_end_message(f"bench-end"))

    async def readexactly(self, n):
        if self._pos + n > len(self._data):
            raise asyncio.IncompleteReadError(self._data[self._pos:], n)
        result = self._data[self._pos:self._pos + n]
        self._pos += n
        return result


class MockClientWriter:
    """Mock async writer for client connection."""

    def __init__(self):
        self._buffer = b""
        self._closed = False

    def write(self, data):
        self._buffer += data

    async def drain(self):
        pass

    def close(self):
        self._closed = True

    async def wait_closed(self):
        pass


async def benchmark_async_client_streaming(results, chunk_size=1024, num_chunks=1000):
    """
    Benchmark DirtyAsyncStreamIterator directly.

    Measures async iterator overhead vs raw message reading.
    """
    chunk_data = "x" * chunk_size

    # Create mock client with mock reader/writer
    client = DirtyClient("/tmp/benchmark.sock", timeout=30.0)
    client._reader = MockClientReader(num_chunks, chunk_data)
    client._writer = MockClientWriter()

    gc.collect()
    tracemalloc.start()
    memory_start = tracemalloc.get_traced_memory()[0]

    start = time.perf_counter()

    # Use the async stream iterator directly
    iterator = DirtyAsyncStreamIterator(client, "benchmark:App", "stream", (), {})
    iterator._started = True  # Skip the request sending
    iterator._request_id = "bench-async"
    iterator._deadline = time.perf_counter() + 300  # 5 min deadline
    iterator._last_chunk_time = time.perf_counter()

    chunks_received = 0
    bytes_received = 0
    async for chunk in iterator:
        chunks_received += 1
        bytes_received += len(chunk)

    duration = time.perf_counter() - start
    memory_end = tracemalloc.get_traced_memory()[0]
    tracemalloc.stop()

    results.add(
        f"Async client streaming ({chunk_size}B chunks, {num_chunks} chunks)",
        iterations=1,
        duration=duration,
        chunks=chunks_received,
        bytes_total=bytes_received,
        memory_start=memory_start,
        memory_end=memory_end
    )


async def benchmark_sync_client_streaming(results, chunk_size=1024, num_chunks=1000):
    """
    Benchmark DirtyStreamIterator directly (for comparison with async).

    Note: This runs the sync iterator within an async context for comparison.
    """
    chunk_data = "x" * chunk_size

    # Build raw message data
    messages_data = b''
    for i in range(num_chunks):
        msg = make_chunk_message(f"bench-{i}", chunk_data)
        messages_data += DirtyProtocol.encode(msg)
    messages_data += DirtyProtocol.encode(make_end_message("bench-end"))

    # Create a mock socket-like object
    class MockSocket:
        def __init__(self, data):
            self._data = data
            self._pos = 0
            self._timeout = None

        def recv(self, n, flags=0):
            if self._pos >= len(self._data):
                return b''
            result = self._data[self._pos:self._pos + n]
            self._pos += len(result)
            return result

        def settimeout(self, timeout):
            self._timeout = timeout

    # Create mock client
    client = DirtyClient("/tmp/benchmark.sock", timeout=30.0)
    client._sock = MockSocket(messages_data)

    gc.collect()
    tracemalloc.start()
    memory_start = tracemalloc.get_traced_memory()[0]

    start = time.perf_counter()

    # Use the sync stream iterator
    iterator = DirtyStreamIterator(client, "benchmark:App", "stream", (), {})
    iterator._started = True  # Skip the request sending
    iterator._request_id = "bench-sync"
    iterator._deadline = time.perf_counter() + 300  # 5 min deadline
    iterator._last_chunk_time = time.perf_counter()

    chunks_received = 0
    bytes_received = 0
    for chunk in iterator:
        chunks_received += 1
        bytes_received += len(chunk)

    duration = time.perf_counter() - start
    memory_end = tracemalloc.get_traced_memory()[0]
    tracemalloc.stop()

    results.add(
        f"Sync client streaming ({chunk_size}B chunks, {num_chunks} chunks)",
        iterations=1,
        duration=duration,
        chunks=chunks_received,
        bytes_total=bytes_received,
        memory_start=memory_start,
        memory_end=memory_end
    )


async def benchmark_async_vs_sync_client_streaming(results, chunk_size=1024, num_chunks=1000):
    """
    Compare stream() vs stream_async() performance with the same workload.
    """
    chunk_data = "x" * chunk_size

    # --- Sync test ---
    messages_data = b''
    for i in range(num_chunks):
        msg = make_chunk_message(f"bench-{i}", chunk_data)
        messages_data += DirtyProtocol.encode(msg)
    messages_data += DirtyProtocol.encode(make_end_message("bench-end"))

    class MockSocket:
        def __init__(self, data):
            self._data = data
            self._pos = 0
            self._timeout = None

        def recv(self, n, flags=0):
            if self._pos >= len(self._data):
                return b''
            result = self._data[self._pos:self._pos + n]
            self._pos += len(result)
            return result

        def settimeout(self, timeout):
            self._timeout = timeout

    sync_client = DirtyClient("/tmp/benchmark.sock", timeout=30.0)
    sync_client._sock = MockSocket(messages_data)

    gc.collect()
    sync_start = time.perf_counter()

    sync_iter = DirtyStreamIterator(sync_client, "benchmark:App", "stream", (), {})
    sync_iter._started = True
    sync_iter._request_id = "bench-sync"
    sync_iter._deadline = time.perf_counter() + 300  # 5 min deadline
    sync_iter._last_chunk_time = time.perf_counter()

    sync_chunks = 0
    for _ in sync_iter:
        sync_chunks += 1

    sync_duration = time.perf_counter() - sync_start

    # --- Async test ---
    async_client = DirtyClient("/tmp/benchmark.sock", timeout=30.0)
    async_client._reader = MockClientReader(num_chunks, chunk_data)
    async_client._writer = MockClientWriter()

    gc.collect()
    async_start = time.perf_counter()

    async_iter = DirtyAsyncStreamIterator(async_client, "benchmark:App", "stream", (), {})
    async_iter._started = True
    async_iter._request_id = "bench-async"
    async_iter._deadline = time.perf_counter() + 300  # 5 min deadline
    async_iter._last_chunk_time = time.perf_counter()

    async_chunks = 0
    async for _ in async_iter:
        async_chunks += 1

    async_duration = time.perf_counter() - async_start

    # Report comparison
    print(f"\nSync vs Async Client Streaming Comparison ({num_chunks} x {chunk_size}B chunks):")
    print(f"  Sync:  {sync_duration * 1000:.3f}ms ({sync_chunks} chunks)")
    print(f"  Async: {async_duration * 1000:.3f}ms ({async_chunks} chunks)")
    if sync_duration > 0:
        ratio = async_duration / sync_duration
        print(f"  Ratio (async/sync): {ratio:.3f}x")

    results.add(
        f"Sync client streaming comparison ({chunk_size}B, {num_chunks} chunks)",
        iterations=1,
        duration=sync_duration,
        chunks=sync_chunks,
        bytes_total=sync_chunks * chunk_size
    )

    results.add(
        f"Async client streaming comparison ({chunk_size}B, {num_chunks} chunks)",
        iterations=1,
        duration=async_duration,
        chunks=async_chunks,
        bytes_total=async_chunks * chunk_size
    )


async def run_quick_benchmarks():
    """Run quick benchmarks."""
    results = BenchmarkResults()

    print("Running quick benchmarks...")

    await benchmark_worker_streaming_throughput(results, chunk_size=64, num_chunks=1000)
    await benchmark_worker_streaming_throughput(results, chunk_size=1024, num_chunks=1000)
    await benchmark_arbiter_forwarding(results, num_chunks=1000)
    await benchmark_streaming_latency(results, iterations=50)

    # Async client streaming benchmarks
    await benchmark_async_client_streaming(results, chunk_size=1024, num_chunks=1000)
    await benchmark_async_vs_sync_client_streaming(results, chunk_size=1024, num_chunks=1000)

    return results


async def run_full_benchmarks():
    """Run full benchmark suite including stress tests."""
    results = BenchmarkResults()

    print("Running full benchmark suite...")

    # Throughput tests with different chunk sizes
    for chunk_size in [1, 64, 1024, 65536]:
        await benchmark_worker_streaming_throughput(
            results, chunk_size=chunk_size, num_chunks=1000
        )

    # Arbiter forwarding
    await benchmark_arbiter_forwarding(results, num_chunks=10000)

    # Latency
    await benchmark_streaming_latency(results, iterations=100)

    # Concurrent streams
    await benchmark_concurrent_streams(results, num_streams=10, chunks_per_stream=100)
    await benchmark_concurrent_streams(results, num_streams=50, chunks_per_stream=100)

    # Memory stability
    await benchmark_memory_stability(results, iterations=20, chunks=1000)

    # Async client streaming benchmarks
    for chunk_size in [64, 1024, 65536]:
        await benchmark_async_client_streaming(results, chunk_size=chunk_size, num_chunks=1000)
        await benchmark_sync_client_streaming(results, chunk_size=chunk_size, num_chunks=1000)

    # Comparison benchmark
    await benchmark_async_vs_sync_client_streaming(results, chunk_size=1024, num_chunks=5000)

    return results


def main():
    parser = argparse.ArgumentParser(description="Dirty streaming benchmarks")
    parser.add_argument("--quick", action="store_true", help="Run quick benchmarks only")
    parser.add_argument("--full", action="store_true", help="Run full benchmark suite")
    parser.add_argument("--output", "-o", help="Output JSON file path")
    args = parser.parse_args()

    if args.full:
        results = asyncio.run(run_full_benchmarks())
    else:
        results = asyncio.run(run_quick_benchmarks())

    results.display()

    if args.output:
        results.save_json(args.output)
    else:
        # Save to default location
        output_dir = os.path.dirname(os.path.abspath(__file__))
        results_dir = os.path.join(output_dir, "results")
        os.makedirs(results_dir, exist_ok=True)
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        output_file = os.path.join(results_dir, f"streaming_benchmark_{timestamp}.json")
        results.save_json(output_file)


if __name__ == "__main__":
    main()


================================================
FILE: benchmarks/quick_bench.sh
================================================
#!/bin/bash
# Quick benchmark for gthread worker

set -e

cd "$(dirname "$0")"

echo "Starting gunicorn with gthread worker..."
../.venv/bin/python -m gunicorn \
    --worker-class gthread \
    --workers 2 \
    --threads 4 \
    --worker-connections 1000 \
    --bind 127.0.0.1:8765 \
    --access-logfile /dev/null \
    --error-logfile /dev/null \
    --log-level warning \
    simple_app:application &

GUNICORN_PID=$!
sleep 3

echo ""
echo "=== Benchmark: Simple requests (10000 requests, 100 concurrent) ==="
ab -n 10000 -c 100 -k http://127.0.0.1:8765/ 2>&1 | grep -E "(Requests per second|Time per request|Failed requests)"

echo ""
echo "=== Benchmark: High concurrency (5000 requests, 500 concurrent) ==="
ab -n 5000 -c 500 -k http://127.0.0.1:8765/ 2>&1 | grep -E "(Requests per second|Time per request|Failed requests)"

echo ""
echo "=== Benchmark: Large response (1000 requests, 50 concurrent) ==="
ab -n 1000 -c 50 -k http://127.0.0.1:8765/large 2>&1 | grep -E "(Requests per second|Time per request|Failed requests)"

echo ""
echo "Stopping gunicorn..."
kill $GUNICORN_PID 2>/dev/null || true
wait $GUNICORN_PID 2>/dev/null || true

echo "Done!"


================================================
FILE: benchmarks/results/queue_refactor_results.json
================================================
{
  "timestamp": "2026-01-24T10:56:33",
  "results": [
    {
      "scenario": "baseline_10ms",
      "config": {
        "dirty_workers": 4,
        "dirty_threads": 1,
        "task_action": "sleep_task",
        "task_args": [
          10
        ],
        "concurrency": 1
      },
      "total_requests": 1000,
      "successful": 1000,
      "failed": 0,
      "errors": [],
      "duration_sec": 12.27,
      "requests_per_sec": 81.5,
      "latency_ms": {
        "min": 10.432417009724304,
        "max": 13.792542013106868,
        "mean": 12.266892079642275,
        "stddev": 0.871026700472873,
        "p50": 12.80679099727422,
        "p95": 13.078375020995736,
        "p99": 13.141458010068163
      }
    },
    {
      "scenario": "throughput_10ms",
      "config": {
        "dirty_workers": 4,
        "dirty_threads": 1,
        "task_action": "sleep_task",
        "task_args": [
          10
        ],
        "concurrency": 100
      },
      "total_requests": 5000,
      "successful": 5000,
      "failed": 0,
      "errors": [],
      "duration_sec": 14.95,
      "requests_per_sec": 334.4,
      "latency_ms": {
        "min": 11.470375000499189,
        "max": 341.3927500077989,
        "mean": 294.71728502821645,
        "stddev": 34.9421432011074,
        "p50": 305.2922079805285,
        "p95": 326.4670000062324,
        "p99": 334.32295799138956
      }
    },
    {
      "scenario": "cpu_bound_100ms",
      "config": {
        "dirty_workers": 4,
        "dirty_threads": 1,
        "task_action": "cpu_task",
        "task_args": [
          100
        ],
        "concurrency": 20
      },
      "total_requests": 500,
      "successful": 500,
      "failed": 0,
      "errors": [],
      "duration_sec": 12.55,
      "requests_per_sec": 39.8,
      "latency_ms": {
        "min": 100.59350001392886,
        "max": 502.4004160077311,
        "mean": 493.9748328983551,
        "stddev": 48.57073135808595,
        "p50": 502.01483300770633,
        "p95": 502.21283300197683,
        "p99": 502.2801249870099
      }
    },
    {
      "scenario": "io_bound_500ms",
      "config": {
        "dirty_workers": 4,
        "dirty_threads": 1,
        "task_action": "sleep_task",
        "task_args": [
          500
        ],
        "concurrency": 50
      },
      "total_requests": 200,
      "successful": 200,
      "failed": 0,
      "errors": [],
      "duration_sec": 25.19,
      "requests_per_sec": 7.9,
      "latency_ms": {
        "min": 501.3219590182416,
        "max": 6563.243499986129,
        "mean": 5566.4884116455505,
        "stddev": 1566.1525736181566,
        "p50": 6052.653749997262,
        "p95": 6553.810708021047,
        "p99": 6559.503666008823
      }
    },
    {
      "scenario": "mixed_50_50",
      "config": {
        "dirty_workers": 4,
        "dirty_threads": 1,
        "task_action": "mixed_task",
        "task_args": [
          50,
          50
        ],
        "concurrency": 30
      },
      "total_requests": 500,
      "successful": 500,
      "failed": 0,
      "errors": [],
      "duration_sec": 12.98,
      "requests_per_sec": 38.5,
      "latency_ms": {
        "min": 102.34933299943805,
        "max": 839.0888340072706,
        "mean": 756.4045974735054,
        "stddev": 103.21897997316475,
        "p50": 762.6495829899795,
        "p95": 832.905125018442,
        "p99": 836.0978330019861
      }
    },
    {
      "scenario": "overload_10ms",
      "config": {
        "dirty_workers": 4,
        "dirty_threads": 1,
        "task_action": "sleep_task",
        "task_args": [
          10
        ],
        "concurrency": 200
      },
      "total_requests": 2000,
      "successful": 2000,
      "failed": 0,
      "errors": [],
      "duration_sec": 5.99,
      "requests_per_sec": 334.1,
      "latency_ms": {
        "min": 10.763874975964427,
        "max": 625.4918330232613,
        "mean": 565.1407622727129,
        "stddev": 104.98938999734894,
        "p50": 590.0453749927692,
        "p95": 617.4105420068372,
        "p99": 621.7636249784846
      }
    }
  ]
}

================================================
FILE: benchmarks/run_benchmark.py
================================================
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

#!/usr/bin/env python3
"""
Benchmark script for gunicorn gthread worker.

This script runs various benchmarks against gunicorn and reports performance metrics.
Requires: gunicorn, requests (for warmup), and wrk or ab for load testing.
"""

import argparse
import json
import os
import signal
import subprocess
import sys
import time
from pathlib import Path


BENCHMARK_DIR = Path(__file__).parent
APP_MODULE = "simple_app:application"


def check_dependencies():
    """Check if required tools are available."""
    # Check for wrk (preferred) or ab
    for tool in ['wrk', 'ab']:
        try:
            subprocess.run([tool, '--version'], capture_output=True, check=False)
            return tool
        except FileNotFoundError:
            continue
    print("Error: Neither 'wrk' nor 'ab' found. Install one of them.")
    print("  macOS: brew install wrk")
    print("  Linux: apt-get install wrk (or apache2-utils for ab)")
    sys.exit(1)


def start_gunicorn(worker_class, workers, threads, connections, bind, extra_args=None):
    """Start gunicorn server and return the process."""
    cmd = [
        sys.executable, '-m', 'gunicorn',
        '--worker-class', worker_class,
        '--workers', str(workers),
        '--threads', str(threads),
        '--worker-connections', str(connections),
        '--bind', bind,
        '--access-logfile', '-',
        '--error-logfile', '-',
        '--log-level', 'warning',
        APP_MODULE,
    ]
    if extra_args:
        cmd.extend(extra_args)

    env = os.environ.copy()
    env['PYTHONPATH'] = str(BENCHMARK_DIR.parent)

    proc = subprocess.Popen(
        cmd,
        cwd=BENCHMARK_DIR,
        env=env,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )

    # Wait for server to be ready
    time.sleep(2)
    return proc


def stop_gunicorn(proc):
    """Stop the gunicorn server."""
    proc.send_signal(signal.SIGTERM)
    try:
        proc.wait(timeout=5)
    except subprocess.TimeoutExpired:
        proc.kill()
        proc.wait()


def run_wrk_benchmark(url, duration, threads, connections):
    """Run wrk benchmark and return results."""
    cmd = [
        'wrk',
        '-t', str(threads),
        '-c', str(connections),
        '-d', f'{duration}s',
        '--latency',
        url,
    ]
    result = subprocess.run(cmd, capture_output=True, text=True, check=False)
    return parse_wrk_output(result.stdout)


def run_ab_benchmark(url, requests, concurrency):
    """Run Apache Bench benchmark and return results."""
    cmd = [
        'ab',
        '-n', str(requests),
        '-c', str(concurrency),
        '-k',  # keepalive
        url,
    ]
    result = subprocess.run(cmd, capture_output=True, text=True, check=False)
    return parse_ab_output(result.stdout)


def parse_wrk_output(output):
    """Parse wrk output to extract metrics."""
    metrics = {}
    for line in output.split('\n'):
        if 'Requests/sec' in line:
            metrics['requests_per_sec'] = float(line.split(':')[1].strip())
        elif 'Transfer/sec' in line:
            metrics['transfer_per_sec'] = line.split(':')[1].strip()
        elif 'Latency' in line and 'Distribution' not in line:
            parts = line.split()
            if len(parts) >= 2:
                metrics['latency_avg'] = parts[1]
        elif '50%' in line:
            metrics['latency_p50'] = line.split()[1]
        elif '99%' in line:
            metrics['latency_p99'] = line.split()[1]
    return metrics


def parse_ab_output(output):
    """Parse ab output to extract metrics."""
    metrics = {}
    for line in output.split('\n'):
        if 'Requests per second' in line:
            metrics['requests_per_sec'] = float(line.split(':')[1].split()[0])
        elif 'Time per request' in line and 'mean' in line:
            metrics['latency_avg'] = line.split(':')[1].strip()
        elif 'Transfer rate' in line:
            metrics['transfer_per_sec'] = line.split(':')[1].strip()
    return metrics


def run_benchmark_suite(tool, bind_addr):
    """Run a suite of benchmarks."""
    results = {}

    # Test configurations
    configs = [
        {'name': 'simple', 'path': '/', 'connections': 100},
        {'name': 'simple_high_concurrency', 'path': '/', 'connections': 500},
        {'name': 'slow_io', 'path': '/slow', 'connections': 50},
        {'name': 'large_response', 'path': '/large', 'connections': 100},
    ]

    for config in configs:
        url = f'http://{bind_addr}{config["path"]}'
        print(f"  Running {config['name']}...")

        if tool == 'wrk':
            metrics = run_wrk_benchmark(
                url,
                duration=10,
                threads=4,
                connections=config['connections'],
            )
        else:
            metrics = run_ab_benchmark(
                url,
                requests=10000,
                concurrency=config['connections'],
            )

        results[config['name']] = metrics
        print(f"    Requests/sec: {metrics.get('requests_per_sec', 'N/A')}")

    return results


def main():
    parser = argparse.ArgumentParser(description='Benchmark gunicorn gthread worker')
    parser.add_argument('--workers', type=int, default=2, help='Number of workers')
    parser.add_argument('--threads', type=int, default=4, help='Threads per worker')
    parser.add_argument('--connections', type=int, default=1000, help='Worker connections')
    parser.add_argument('--bind', default='127.0.0.1:8000', help='Bind address')
    parser.add_argument('--compare', action='store_true', help='Compare sync vs gthread')
    parser.add_argument('--output', help='Output JSON file for results')
    args = parser.parse_args()

    tool = check_dependencies()
    print(f"Using benchmark tool: {tool}")

    all_results = {}

    if args.compare:
        # Compare sync and gthread workers
        for worker_class in ['sync', 'gthread']:
            print(f"\nBenchmarking {worker_class} worker...")
            proc = start_gunicorn(
                worker_class=worker_class,
                workers=args.workers,
                threads=args.threads,
                connections=args.connections,
                bind=args.bind,
            )
            try:
                all_results[worker_class] = run_benchmark_suite(tool, args.bind)
            finally:
                stop_gunicorn(proc)
    else:
        # Just benchmark gthread
        print("\nBenchmarking gthread worker...")
        proc = start_gunicorn(
            worker_class='gthread',
            workers=args.workers,
            threads=args.threads,
            connections=args.connections,
            bind=args.bind,
        )
        try:
            all_results['gthread'] = run_benchmark_suite(tool, args.bind)
        finally:
            stop_gunicorn(proc)

    # Print summary
    print("\n" + "=" * 60)
    print("BENCHMARK SUMMARY")
    print("=" * 60)
    for worker, results in all_results.items():
        print(f"\n{worker.upper()} Worker:")
        for test, metrics in results.items():
            rps = metrics.get('requests_per_sec', 'N/A')
            print(f"  {test}: {rps} req/s")

    if args.output:
        with open(args.output, 'w') as f:
            json.dump(all_results, f, indent=2)
        print(f"\nResults saved to {args.output}")


if __name__ == '__main__':
    main()


================================================
FILE: benchmarks/simple_app.py
================================================
#
# This file is part of gunicorn released under the MIT license.
# See the NOTICE for more information.

# Simple WSGI app for benchmarking

def application(environ, start_response):
    """Basic hello world response."""
    path = environ.get('PATH_INFO', '/')

    if path == '/large':
        body = b'X' * 65536  # 64KB
    else:
        body = b'Hello, World!'

    status = '200 OK'
    headers = [
        ('Content-Type', 'text/plain'),
        ('Content-Length', str(len(body))),
    ]
    start_response(status, headers)
    return [body]


================================================
FILE: docker/.dockerignore
================================================
.git
.github
__pycache__
*.pyc
.pytest_cache
.tox
docs
tests


================================================
FILE: docker/Dockerfile
================================================
FROM python:3.12-slim

LABEL org.opencontainers.image.source=https://github.com/benoitc/gunicorn
LABEL org.opencontainers.image.description="Gunicorn Python WSGI HTTP Server"
LABEL org.opencontainers.image.licenses=MIT

# Create non-root user
RUN useradd --create-home --shell /bin/bash gunicorn

WORKDIR /app

# Install gunicorn from source
COPY pyproject.toml README.md LICENSE ./
COPY gunicorn/ ./gunicorn/
RUN pip install --no-cache-dir .

# Copy entrypoint script
COPY docker/docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

# Configuration via environment:
#   GUNICORN_BIND    - full bind address (default: 0.0.0.0:8000)
#   GUNICORN_HOST    - bind host (default: 0.0.0.0)
#   GUNICORN_PORT    - bind port (default: 8000)
#   GUNICORN_WORKERS - number of workers (default: 2 * CPU + 1)
#   GUNICORN_ARGS    - additional arguments (e.g., "--timeout 120")

USER gunicorn

EXPOSE 8000

ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["--help"]


================================================
FILE: docker/docker-entrypoint.sh
================================================
#!/bin/bash
set -e

# Allow running other commands (e.g., bash for debugging)
if [ "${1:0:1}" = '-' ] || [ -z "${1##*:*}" ]; then
    # First arg is a flag or contains ':' (app:callable), run gunicorn

    # Build bind address from GUNICORN_HOST and GUNICORN_PORT, or use GUNICORN_BIND
    PORT="${GUNICORN_PORT:-8000}"
    BIND="${GUNICORN_BIND:-${GUNICORN_HOST:-0.0.0.0}:${PORT}}"

    # Add bind if not specified in args or GUNICORN_ARGS
    if [[ ! " $* $GUNICORN_ARGS " =~ " --bind " ]] && [[ ! " $* $GUNICORN_ARGS " =~ " -b " ]] && [[ ! "$* $GUNICORN_ARGS" =~ --bind= ]] && [[ ! "$* $GUNICORN_ARGS" =~ -b= ]]; then
        set -- --bind "$BIND" "$@"
    fi

    # Add workers if not specified - default to (2 * CPU_COUNT) + 1
    if [[ ! " $* $GUNICORN_ARGS " =~ " --workers " ]] && [[ ! " $* $GUNICORN_ARGS " =~ " -w " ]] && [[ ! "$* $GUNICORN_ARGS" =~ --workers= ]] && [[ ! "$* $GUNICORN_ARGS" =~ -w= ]]; then
        WORKERS="${GUNICORN_WORKERS:-$(( 2 * $(nproc) + 1 ))}"
        set -- --workers "$WORKERS" "$@"
    fi

    # Append GUNICORN_ARGS if set
    if [ -n "$GUNICORN_ARGS" ]; then
        exec gunicorn $GUNICORN_ARGS "$@"
    fi

    exec gunicorn "$@"
fi

# Otherwise, run the command as-is (e.g., bash, sh, python)
exec "$@"


================================================
FILE: docs/README.md
================================================
# Generate Documentation

## Requirements

Install the documentation dependencies with:

```bash
pip install -r requirements_dev.txt
```

This provides MkDocs with the Material theme and supporting plugins.

## Build static HTML

```bash
mkdocs build
```

The rendered site is emitted into the `site/` directory.

## Preview locally

```bash
mkdocs serve
```

This serves the documentation at http://127.0.0.1:8000/ with live reload.


================================================
FILE: docs/content/2010-news.md
================================================
<span id="news-2010"></span>
# Changelog - 2010

## 0.12.0 / 2010-12-22

- Add support for logging configuration using a ini file.
  It uses the standard Python logging's module Configuration
  file format and allows anyone to use his custom file handler
- Add IPV6 support
- Add multidomain application example
- Improve gunicorn_django command when importing settings module
  using DJANGO_SETTINGS_MODULE environment variable
- Send appropriate error status on http parsing
- Fix pidfile, set permissions so other user can read
  it and use it.
- Fix temporary file leaking
- Fix setpgrp issue, can now be launched via ubuntu upstart
- Set the number of workers to zero on WINCH

## 0.11.2 / 2010-10-30

* Add SERVER_SOFTWARE to the os.environ
* Add support for django settings environment variable
* Add support for logging configuration in Paster ini-files
* Improve arbiter notification in asynchronous workers
* Display the right error when a worker can't be used
* Fix Django support
* Fix HUP with Paster applications
* Fix readline in wsgi.input

## 0.11.1 / 2010-09-02

* Implement max-requests feature to prevent memory leaks.
* Added 'worker_exit' server hook.
* Reseed the random number generator after fork().
* Improve Eventlet worker.
* Fix Django command `run_gunicorn`.
* Fix the default proc name internal setting.
* Workaround to prevent Gevent worker to segfault on MacOSX.

## 0.11.0 / 2010-08-12

* Improve dramatically performances of Gevent and Eventlet workers
* Optimize HTTP parsing
* Drop Server and Date headers in start_response when provided.
* Fix latency issue in async workers

## 0.10.1 / 2010-08-06

* Improve gevent's workers. Add "egg:gunicorn#gevent_wsgi" worker using
  `gevent.wsgi <http://www.gevent.org/gevent.wsgi.html>`_ and
  "egg:gunicorn#gevent_pywsgi" worker using `gevent.pywsgi
  <http://www.gevent.org/gevent.pywsgi.html>`_ .
  **"egg:gunicorn#gevent"** using our own HTTP parser is still here and
  is **recommended** for normal uses. Use the "gevent.wsgi" parser if you
  need really fast connections and don't need streaming, keepalive or ssl.
* Add pre/post request hooks
* Exit more quietly
* Fix gevent dns issue

## 0.10.0 / 2010-07-08

* New HTTP parser.
* New HUP behaviour. Re-reads the configuration and then reloads all
  worker processes without changing the master process id. Helpful for
  code reloading and monitoring applications like supervisord and runit.
* Added a preload configuration parameter. By default, application code
  is now loaded after a worker forks. This couple with the new HUP
  handling can be used for dev servers to do hot code reloading. Using
  the preload flag can help a bit in small memory VM's.
* Allow people to pass command line arguments to WSGI applications. See:
  `examples/alt_spec.py
  <http://github.com/benoitc/gunicorn/raw/master/examples/alt_spec.py>`_
* Added an example gevent reloader configuration:
  `examples/example_gevent_reloader.py
  <http://github.com/benoitc/gunicorn/blob/master/examples/example_gevent_reloader.py>`_.
* New gevent worker "egg:gunicorn#gevent2", working with gevent.wsgi.
* Internal refactoring and various bug fixes.
* New documentation website.

## 0.9.1 / 2010-05-26

* Support https via X-Forwarded-Protocol or X-Forwarded-Ssl headers
* Fix configuration
* Remove -d options which was used instead of -D for daemon.
* Fix umask in unix socket

## 0.9.0 / 2010-05-24

* Added *when_ready* hook. Called just after the server is started
* Added *preload* setting. Load application code before the worker processes
  are forked.
* Refactored Config
* Fix pidfile
* Fix QUIT/HUP in async workers
* Fix reexec
* Documentation improvements

## 0.8.1 / 2010-04-29

* Fix builtins import in config
* Fix installation with pip
* Fix Tornado WSGI support
* Delay application loading until after processing all configuration

## 0.8.0 / 2010-04-22

* Refactored Worker management for better async support. Now use the -k option
  to set the type of request processing to use
* Added support for Tornado_

## 0.7.2 / 2010-04-15

* Added --spew option to help debugging (installs a system trace hook)
* Some fixes in async arbiters
* Fix a bug in start_response on error

## 0.7.1 / 2010-04-01

* Fix bug when responses have no body.

## 0.7.0 / 2010-03-26

* Added support for Eventlet_ and Gevent_ based workers.
* Added Websockets_ support
* Fix Chunked Encoding
* Fix SIGWINCH on OpenBSD_
* Fix `PEP 333`_ compliance for the write callable.

## 0.6.5 / 2010-03-11

* Fix pidfile handling
* Fix Exception Error

## 0.6.4 / 2010-03-08

* Use cStringIO for performance when possible.
* Fix worker freeze when a remote connection closes unexpectedly.

## 0.6.3 / 2010-03-07

* Make HTTP parsing faster.
* Various bug fixes

## 0.6.2 / 2010-03-01

* Added support for chunked response.
* Added proc_name option to the config file.
* Improved the HTTP parser. It now uses buffers instead of strings to store
  temporary data.
* Improved performance when sending responses.
* Workers are now murdered by age (the oldest is killed first).

## 0.6.1 / 2010-02-24

* Added gunicorn config file support for Django admin command
* Fix gunicorn config file. -c was broken.
* Removed TTIN/TTOU from workers which blocked other signals.

## 0.6.0 / 2010-02-22

* Added setproctitle support
* Change privilege switch behavior. We now work like NGINX, master keeps the
  permissions, new uid/gid permissions are only set for workers.

## 0.5.1 / 2010-02-22

* Fix umask
* Added Debian packaging

## 0.5.0 / 2010-02-20

* Added `configuration file <configuration.html>`_ handler.
* Added support for pre/post fork hooks
* Added support for before_exec hook
* Added support for unix sockets
* Added launch of workers processes under different user/group
* Added umask option
* Added SCRIPT_NAME support
* Better support of some exotic settings for Django projects
* Better support of Paste-compatible applications
* Some refactoring to make the code easier to hack
* Allow multiple keys in request and response headers

.. _Tornado: http://www.tornadoweb.org/
.. _`PEP 333`: https://www.python.org/dev/peps/pep-0333/
.. _Eventlet: http://eventlet.net/
.. _Gevent: http://www.gevent.org/
.. _OpenBSD: https://www.openbsd.org/
.. _Websockets: https://html.spec.whatwg.org/multipage/web-sockets.html


================================================
FILE: docs/content/2011-news.md
================================================
<span id="news-2011"></span>
# Changelog - 2011

## 0.13.4 / 2011-09-23

- fix util.closerange function used to prevent leaking fds on python 2.5
  (typo.md)

## 0.13.3 / 2011-09-19
- refactor gevent worker
- prevent leaking fds on reexec
- fix inverted request_time computation

## 0.13.2 / 2011-09-17

- Add support for Tornado 2.0 in tornado worker
- Improve access logs: allows customisation of the log format & add
  request time
- Logger module is now pluggable
- Improve graceful shutdown in Python versions >= 2.6
- Fix post_request root arity for compatibility
- Fix sendfile support
- Fix Django reloading

## 0.13.1 / 2011-08-22

- Fix unix socket. log argument was missing.

## 0.13.0 / 2011-08-22

- Improve logging: allows file-reopening and add access log file
  compatible with the `apache combined log format <http://httpd.apache.org/docs/2.0/logs.html#combined>`_
- Add the possibility to set custom SSL headers. X-Forwarded-Protocol
  and X-Forwarded-SSL are still the default
- New `on_reload` hook to customize how gunicorn spawn new workers on
  SIGHUP
- Handle projects with relative path in django_gunicorn command
- Preserve path parameters in PATH_INFO
- post_request hook now accepts the environ as argument.
- When stopping the arbiter, close the listener asap.
- Fix Django command `run_gunicorn` in settings reloading
- Fix Tornado_ worker exiting
- Fix the use of sendfile in wsgi.file_wrapper


## 0.12.2 / 2011-05-18

- Add wsgi.file_wrapper optimised for FreeBSD, Linux & MacOSX (use
  sendfile if available)
- Fix django run_gunicorn command. Make sure we reload the application
  code.
- Fix django localisation
- Compatible with gevent 0.14dev

## 0.12.1 / 2011-03-23

- Add "on_starting" hook. This hook can be used to set anything before
  the arbiter really start
- Support bdist_rpm in setup
- Improve content-length handling (pep 3333)
- Improve Django support
- Fix daemonizing (#142)
- Fix ipv6 handling


.. _Tornado: http://www.tornadoweb.org/


================================================
FILE: docs/content/2012-news.md
================================================
<span id="news-2012"></span>
# Changelog - 2012

## 0.17.0 / 2012-12-25

- allows gunicorn to bind to multiple address
- add SSL support
- add syslog support
- add nworkers_changed hook
- add response arg for post_request hook
- parse command line with argparse (replace deprecated optparse)
- fix PWD detection in arbiter
- miscellaneous PEP8 fixes

## 0.16.1 / 2012-11-19

- Fix packaging

## 0.16.0 / 2012-11-19

- **Added support for Python 3.2 & 3.3**
- Expose --pythonpath command to all gunicorn commands
- Honor $PORT environment variable, useful for deployment on heroku
- Removed support for Python 2.5
- Make sure we reopen the logs on the console
- Fix django settings module detection from path
- Reverted timeout for client socket. Fix issue on blocking issues.
- Fixed gevent worker

## 0.15.0 / 2012-10-18

- new documentation site on https://gunicorn.org
- new website on http://gunicorn.org
- add `haproxy PROXY protocol <http://haproxy.1wt.eu/download/1.5/doc/proxy-protocol.txt>`_ support
- add  ForwardedAllowIPS option: allows to filter Front-end's IPs
  allowed to handle X-Forwarded-* headers.
- add callable hooks for paster config
- add x-forwarded-proto as secure scheme default (Heroku is using this)
- allows gunicorn to load a pre-compiled application
- support file reopening & reexec for all loggers
- initialize the logging config file with defaults.
- set timeout for client socket (slow client DoS).
- NoMoreData, ChunkMissingTerminator, InvalidChunkSize are now
  IOError exceptions
- fix graceful shutdown in gevent
- fix limit request line check

## 0.14.6 / 2012-07-26


- fix gevent & subproces
- fix request line length check
- fix keepalive = 0
- fix tornado worker

## 0.14.5 / 2012-06-24

- fix logging during daemonisation

## 0.14.4 / 2012-06-24

- new --graceful-timeout option
- fix multiple issues with request limit
- more fixes in django settings resolutions
- fix gevent.core import
- fix keepalive=0 in eventlet worker
- fix handle_error display with the unix worker
- fix tornado.wsgi.WSGIApplication calling error

- **breaking change**: take the control on graceful reload back.
  graceful can't be overridden anymore using the on_reload function.

## 0.14.3 / 2012-05-15

- improvement: performance of http.body.Body.readline()
- improvement: log HTTP errors in access log like Apache
- improvement: display traceback when the worker fails to boot
- improvement: makes gunicorn work with gevent 1.0
- examples: websocket example now supports hybi13
- fix: reopen log files after initialization
- fix: websockets support
- fix: django1.4 support
- fix: only load the paster application 1 time

## 0.14.2 / 2012-03-16

- add validate_class validator: allows to use a class or a method to
  initialize the app during in-code configuration
- add support for max_requests in tornado worker
- add support for disabling x_forwarded_for_header in tornado worker
- gevent_wsgi is now an alias of gevent_pywsgi
- Fix gevent_pywsgi worker

## 0.14.1 / 2012-03-02

- fixing source archive, reducing its size

## 0.14.0 / 2012-02-27

- check if Request line is too large: You can now pass the parameter
  ``--limit-request-line`` or set the ``limit_request_line`` in your
  configuration file to set the max size of the request line in bytes.
- limit the number of headers fields and their size. Add
  ``--limit-request-field`` and ``limit-request-field-size`` settings
- add ``p`` variable to the log access format to log pidfile
- add ``{HeaderName}o`` variable to the logo access format to log the
  response header HeaderName
- request header is now logged with the variable ``{HeaderName}i`` in the
  access log file
- improve error logging
- support logging.configFile
- support django 1.4 in both gunicorn_django & run_gunicorn command
- improve reload in django run_gunicorn command (should just work now)
- allows people to set the ``X-Forwarded-For`` header key and disable it by
  setting an empty string.
- fix support of Tornado
- many other fixes.


================================================
FILE: docs/content/2013-news.md
================================================
<span id="news-2013"></span>
# Changelog - 2013

## 18.0 / 2013-08-26

- new: add ``-e/--env`` command line argument to pass an environment variables to
  gunicorn
- new: add ``--chdir`` command line argument to specified directory
  before apps loading.  - new: add wsgi.file_wrapper support in async workers
- new: add ``--paste`` command line argument to set the paster config file
- deprecated: the command ``gunicorn_django`` is now deprecated. You should now
  run your application with the WSGI interface installed with your project (see
  https://docs.djangoproject.com/en/1.4/howto/deployment/wsgi/gunicorn/) for
  more infos.
- deprecated:  the command ``gunicorn_paste`` is deprecated. You now should use
  the new ``--paste`` argument to set the configuration file of your paster
  application.
- fix: Removes unmatched leading quote from the beginning of the default access
  log format string
- fix: null timeout
- fix: gevent worker
- fix: don't reload the paster app when using pserve
- fix: after closing for error do not keep alive the connection
- fix: responses 1xx, 204 and 304 should not force the connection to be closed

## 17.5 / 2013-07-03

- new: add signals documentation
- new: add post_worker_init hook for workers
- new: try to use gunicorn.conf.py in current folder as the default
  config file.
- fix graceful timeout with the Eventlet worker
- fix: don't raise an error when closing the socket if already closed
- fix: fix --settings parameter for django application and try to find
  the django settings when using the ``gunicorn`` command.
- fix: give the initial global_conf to paster application
- fix: fix 'Expect: 100-continue' support on Python 3

### New versioning:

With this release, the versioning of Gunicorn is changing. Gunicorn is
stable since a long time and there is no point to release a "1.0" now.
It should have been done since a long time. 0.17 really meant it was the
17th stable version. From the beginning we have only 2 kind of
releases:

major release: releases with major changes or huge features added
services releases: fixes and minor features added So from now we will
apply the following versioning ``<major>.<service>``. For example ``17.5`` is a
service release.

## 0.17.4 / 2013-04-24

- fix unix socket address parsing

## 0.17.3 / 2013-04-23

- add systemd sockets support
- add ``python -m gunicorn.app.wsgiapp`` support
- improve logger class inheritance
- exit when the config file isn't found
- add the -R option to enable stdio inheritance in daemon mode
- don't close file descriptors > 3 in daemon mode
- improve STDOUT/STDERR logging
- fix pythonpath option
- fix pidfile creation on Python 3
- fix gevent worker exit
- fix ipv6 detection when the platform isn't supporting it

## 0.17.2 / 2013-01-07

- optimize readline
- make imports errors more visible when loading an app or a logging
  class
- fix tornado worker: don't pass ssl options if there are none
- fix PEP3333: accept only bytetrings in the response body
- fix support on CYGWIN platforms

## 0.17.1 / 2013-01-05

- add syslog facility name setting
- fix ``--version`` command line argument
- fix wsgi url_scheme for https


================================================
FILE: docs/content/2014-news.md
================================================
<span id="news-2014"></span>
# Changelog - 2014

!!! note
    Please see [news](news.md) for the latest changes.


## 19.1.1 / 2014-08-16

### Changes

### Core

- fix [Issue #835](https://github.com/benoitc/gunicorn/issues/835): display correct pid of already running instance
- fix [PR #833](https://github.com/benoitc/gunicorn/pull/833): fix `PyTest` class in setup.py.


### Logging

- fix [Issue #838](https://github.com/benoitc/gunicorn/issues/838): statsd logger, send statsd timing metrics in milliseconds
- fix [Issue #839](https://github.com/benoitc/gunicorn/issues/839): statsd logger, allows for empty log message while pushing
  metrics and restore worker number in DEBUG logs
- fix [Issue #850](https://github.com/benoitc/gunicorn/issues/850): add timezone to logging
- fix [Issue #853](https://github.com/benoitc/gunicorn/issues/853): Respect logger_class setting unless statsd is on

### AioHttp worker

- fix [Issue #830](https://github.com/benoitc/gunicorn/issues/830) make sure gaiohttp worker is shipped with gunicorn.

## 19.1 / 2014-07-26

### Changes

### Core

- fix [Issue #785](https://github.com/benoitc/gunicorn/issues/785): handle binary type address given to a client socket address
- fix graceful shutdown. make sure QUIT and TERMS signals are switched everywhere.
- [Issue #799](https://github.com/benoitc/gunicorn/issues/799): fix support loading config from module
- [Issue #805](https://github.com/benoitc/gunicorn/issues/805): fix check for file-like objects
- fix [Issue #815](https://github.com/benoitc/gunicorn/issues/815): args validation in WSGIApplication.init
- fix [Issue #787](https://github.com/benoitc/gunicorn/issues/787): check if we load a pyc file or not.


### Tornado worker

- fix [Issue #771](https://github.com/benoitc/gunicorn/issues/771): support tornado 4.0
- fix [Issue #783](https://github.com/benoitc/gunicorn/issues/783): x_headers error. The x-forwarded-headers option has been removed
  in `c4873681299212d6082cd9902740eef18c2f14f1
  <https://github.com/benoitc/gunicorn/commit/c4873681299212d6082cd9902740eef18c2f14f1>`_.
  The discussion is available on [PR #633](https://github.com/benoitc/gunicorn/pull/633).


### AioHttp worker

- fix: fetch all body in input. fix [Issue #803](https://github.com/benoitc/gunicorn/issues/803)
- fix: don't install the worker if python < 3.3
- fix [Issue #822](https://github.com/benoitc/gunicorn/issues/822): Support UNIX sockets in gaiohttp worker


### Async worker

- fix [Issue #790](https://github.com/benoitc/gunicorn/issues/790): StopIteration shouldn't be caught at this level.


### Logging

- add statsd logging handler fix [Issue #748](https://github.com/benoitc/gunicorn/issues/748)


### Paster

- fix [Issue #809](https://github.com/benoitc/gunicorn/issues/809): Set global logging configuration from a Paste config.


### Extra

- fix RuntimeError in gunicorn.reloader ([Issue #807](https://github.com/benoitc/gunicorn/issues/807))


### Documentation

- update faq: put a note on how `watch logs in the console
  <https://gunicorn.org/faq/#why-i-dont-see-any-logs-in-the-console>`_
  since many people asked for it.


## 19.0 / 2014-06-12

Gunicorn 19.0 is a major release with new features and fixes. This
version improve a lot the usage of Gunicorn with python 3 by adding `two
new workers <https://gunicorn.org/design/#asyncio-workers>`_
to it: `gthread` a fully threaded async worker using futures and `gaiohttp` a
worker using asyncio.


### Breaking Changes

### Switch QUIT and TERM signals

With this change, when gunicorn receives a QUIT all the workers are
killed immediately and exit and TERM is used for the graceful shutdown.

Note: the old behaviour was based on the NGINX but the new one is more
correct according the following doc:

https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html

also it is complying with the way the signals are sent by heroku:

https://devcenter.heroku.com/articles/python-faq#what-constraints-exist-when-developing-applications-on-heroku

### Deprecations

`run_gunicorn`, `gunicorn_django` and `gunicorn_paster` are now
completely deprecated and will be removed in the next release. Use the
`gunicorn` command instead.


### Changes

### core

- add aiohttp worker named `gaiohttp` using asyncio. Full async worker
  on python 3.
- fix HTTP-violating excess whitespace in write_error output
- fix: try to log what happened in the worker after a timeout, add a
  `worker_abort` hook on SIGABRT signal.
- fix: save listener socket name in workers so we can handle buffered
  keep-alive requests after the listener has closed.
- add on_exit hook called just before exiting gunicorn.
- add support for python 3.4
- fix: do not swallow unexpected errors when reaping
- fix: remove incompatible SSL option with python 2.6
- add new async gthread worker and `--threads` options allows to set multiple
  threads to listen on connection
- deprecate `gunicorn_django` and `gunicorn_paster`
- switch QUIT and TERM signal
- reap workers in SIGCHLD handler
- add universal wheel support
- use `email.utils.formatdate` in gunicorn.util.http_date
- deprecate the `--debug` option
- fix: log exceptions that occur after response start …
- allows loading of applications from `.pyc` files (#693)
- fix: issue #691, raw_env config file parsing
- use a dynamic timeout to wait for the optimal time. (Reduce power
  usage)
- fix python3 support when notifying the arbiter
- add: honor $WEB_CONCURRENCY environment variable. Useful for heroku
  setups.
- add: include tz offset in access log
- add: include access logs in the syslog handler.
- add --reload option for code reloading
- add the capability to load `gunicorn.base.Application` without the loading of
  the arguments of the command line. It allows you to [embed gunicorn in   your own application](custom.md).
- improve: set wsgi.multithread to True for async workers
- fix logging: make sure to redirect wsgi.errors when needed
- add: syslog logging can now be done to a unix socket
- fix logging: don't try to redirect stdout/stderr to the logfile.
- fix logging: don't propagate log
- improve logging: file option can be overridden by the gunicorn options
  `--error-logfile` and `--access-logfile` if they are given.
- fix: don't override SERVER_* by the Host header
- fix: handle_error
- add more option to configure SSL
- fix: sendfile with SSL
- add: worker_int callback (to react on SIGTERM)
- fix: don't depend on entry point for internal classes, now absolute
  modules path can be given.
- fix: Error messages are now encoded in latin1
- fix: request line length check
- improvement: proxy_allow_ips: Allow proxy protocol if "*" specified
- fix: run worker's `setup` method  before setting num_workers
- fix: FileWrapper inherit from `object` now
- fix: Error messages are now encoded in latin1
- fix: don't spam the console on SIGWINCH.
- fix: logging -don't stringify T and D logging atoms (#621)
- add support for the latest django version
- deprecate `run_gunicorn` django option
- fix: sys imported twice


### gevent worker

- fix: make sure to stop all listeners
- fix: monkey patching is now done in the worker
- fix: "global name 'hub' is not defined"
- fix: reinit `hub` on old versions of gevent
- support gevent 1.0
- fix: add subprocess in monkey patching
- fix: add support for multiple listener


### eventlet worker

- fix: merge duplicate EventletWorker.init_process method (fixes #657)
- fix: missing errno import for eventlet sendfile patch
- fix: add support for multiple listener


### tornado worker

- add graceful stop support


================================================
FILE: docs/content/2015-news.md
================================================
<span id="news-2015"></span>
# Changelog - 2015

!!! note
    Please see [news](news.md) for the latest changes.


## 19.4.3 / 2015/12/30

- fix: don't check if a file is writable using os.stat with SELINUX ([Issue #1171](https://github.com/benoitc/gunicorn/issues/1171))

## 19.4.2 / 2015/12/29

### Core

- improvement: handle HaltServer in manage_workers ([Issue #1095](https://github.com/benoitc/gunicorn/issues/1095))
- fix: Do not rely on sendfile sending requested count ([Issue #1155](https://github.com/benoitc/gunicorn/issues/1155))
- fix: claridy --no-sendfile default ([Issue #1156](https://github.com/benoitc/gunicorn/issues/1156))
- fix: LoggingCatch sendfile failure from no file descriptor ([Issue #1160](https://github.com/benoitc/gunicorn/issues/1160))

### Logging

- fix: Always send access log to syslog if syslog is on
- fix: check auth before trying to own a file ([Issue #1157](https://github.com/benoitc/gunicorn/issues/1157))


### Documentation

- fix: Fix Slowloris broken link. ([Issue #1142](https://github.com/benoitc/gunicorn/issues/1142))
- Tweak markup in faq.rst

### Testing

- fix: gaiohttp test ([Issue #1164](https://github.com/benoitc/gunicorn/issues/1164))

## 19.4.1 / 2015/11/25

- fix tornado worker ([Issue #1154](https://github.com/benoitc/gunicorn/issues/1154))

## 19.4.0 / 2015/11/20

### Core

- fix: make sure that a user is able to access to the logs after dropping a
  privilege ([Issue #1116](https://github.com/benoitc/gunicorn/issues/1116))
- improvement: inherit the `Exception` class where it needs to be ([Issue #997](https://github.com/benoitc/gunicorn/issues/997))
- fix: make sure headers are always encoded as latin1 RFC 2616 ([Issue #1102](https://github.com/benoitc/gunicorn/issues/1102))
- improvement: reduce arbiter noise ([Issue #1078](https://github.com/benoitc/gunicorn/issues/1078))
- fix: don't close the unix socket when the worker exit ([Issue #1088](https://github.com/benoitc/gunicorn/issues/1088))
- improvement: Make last logged worker count an explicit instance var ([Issue #1078](https://github.com/benoitc/gunicorn/issues/1078))
- improvement: prefix config file with its type ([Issue #836](https://github.com/benoitc/gunicorn/issues/836))
- improvement: pidfile handing ([Issue #1042](https://github.com/benoitc/gunicorn/issues/1042))
- fix: catch OSError as well as ValueError on race condition ([Issue #1052](https://github.com/benoitc/gunicorn/issues/1052))
- improve support of ipv6 by backporting urlparse.urlsplit from Python 2.7 to
  Python 2.6.
- fix: raise InvalidRequestLine when the line contains malicious data
  ([Issue #1023](https://github.com/benoitc/gunicorn/issues/1023))
- fix: fix argument to disable sendfile
- fix: add gthread to the list of supported workers ([Issue #1011](https://github.com/benoitc/gunicorn/issues/1011))
- improvement: retry socket binding up to five times upon EADDRNOTAVAIL
  ([Issue #1004](https://github.com/benoitc/gunicorn/issues/1004))
- **breaking change**: only honor headers that can be encoded in ascii to comply to
  the RFC 7230 (See [Issue #1151](https://github.com/benoitc/gunicorn/issues/1151)).

### Logging

- add new parameters to access log ([Issue #1132](https://github.com/benoitc/gunicorn/issues/1132))
- fix: make sure that files handles are correctly reopened on HUP
  ([Issue #627](https://github.com/benoitc/gunicorn/issues/627))
- include request URL in error message ([Issue #1071](https://github.com/benoitc/gunicorn/issues/1071))
- get username in access logs ([Issue #1069](https://github.com/benoitc/gunicorn/issues/1069))
- fix statsd logging support on Python 3 ([Issue #1010](https://github.com/benoitc/gunicorn/issues/1010))

### Testing

- use last version of mock.
- many fixes in Travis CI support
- miscellaneous improvements in tests

### Thread worker

- fix: Fix self.nr usage in ThreadedWorker so that auto restart works as
  expected ([Issue #1031](https://github.com/benoitc/gunicorn/issues/1031))

### Gevent worker

- fix quit signal handling ([Issue #1128](https://github.com/benoitc/gunicorn/issues/1128))
- add support for Python 3 ([Issue #1066](https://github.com/benoitc/gunicorn/issues/1066))
- fix: make graceful shutdown thread-safe ([Issue #1032](https://github.com/benoitc/gunicorn/issues/1032))

### Tornado worker

- fix ssl options ([Issue #1146](https://github.com/benoitc/gunicorn/issues/1146), [Issue #1135](https://github.com/benoitc/gunicorn/issues/1135))
- don't check timeout when stopping gracefully ([Issue #1106](https://github.com/benoitc/gunicorn/issues/1106))

### AIOHttp worker

- add SSL support ([Issue #1105](https://github.com/benoitc/gunicorn/issues/1105))

### Documentation

- fix link to proc name setting ([Issue #1144](https://github.com/benoitc/gunicorn/issues/1144))
- fix worker class documentation ([Issue #1141](https://github.com/benoitc/gunicorn/issues/1141), [Issue #1104](https://github.com/benoitc/gunicorn/issues/1104))
- clarify graceful timeout documentation ([Issue #1137](https://github.com/benoitc/gunicorn/issues/1137))
- don't duplicate NGINX config files examples ([Issue #1050](https://github.com/benoitc/gunicorn/issues/1050), [Issue #1048](https://github.com/benoitc/gunicorn/issues/1048))
- add `web.py` framework example ([Issue #1117](https://github.com/benoitc/gunicorn/issues/1117))
- update Debian/Ubuntu installations instructions ([Issue #1112](https://github.com/benoitc/gunicorn/issues/1112))
- clarify `pythonpath` setting description ([Issue #1080](https://github.com/benoitc/gunicorn/issues/1080))
- tweak some example for python3
- clarify `sendfile` documentation
- miscellaneous typos in source code comments (thanks!)
- clarify why REMOTE_ADD may not be the user's IP address ([Issue #1037](https://github.com/benoitc/gunicorn/issues/1037))


### Misc

- fix: reloader should survive SyntaxError ([Issue #994](https://github.com/benoitc/gunicorn/issues/994))
- fix: expose the reloader class to the worker.



## 19.3.0 / 2015/03/06

### Core

- fix: [Issue #978](https://github.com/benoitc/gunicorn/issues/978) make sure a listener is inheritable
- add `check_config` class method to workers
- fix: [Issue #983](https://github.com/benoitc/gunicorn/issues/983) fix select timeout in sync worker with multiple
  connections
- allows workers to access to the reloader. close [Issue #984](https://github.com/benoitc/gunicorn/issues/984)
- raise TypeError instead of AssertionError

### Logging

- make Logger.loglevel a class attribute

### Documentation

- fix: [Issue #988](https://github.com/benoitc/gunicorn/issues/988) fix syntax errors in examples/gunicorn_rc


## 19.2.1 / 2015/02/4

### Logging

- expose loglevel in the Logger class

### AsyncIO worker (gaiohttp.md)

- fix [Issue #977](https://github.com/benoitc/gunicorn/issues/977) fix initial crash

### Documentation

- document security mailing-list in the contributing page.

## 19.2 / 2015/01/30

### Core

- optimize the sync workers when listening on a single interface
- add `--sendfile` settings to enable/disable sendfile. fix [Issue #856](https://github.com/benoitc/gunicorn/issues/856) .
- add the selectors module to the code base. [Issue #886](https://github.com/benoitc/gunicorn/issues/886)
- add `--max-requests-jitter` setting to set the maximum jitter to add to the
  max-requests setting.
- fix [Issue #899](https://github.com/benoitc/gunicorn/issues/899) propagate proxy_protocol_info to keep-alive requests
- fix [Issue #863](https://github.com/benoitc/gunicorn/issues/863) worker timeout: dynamic timeout has been removed
- fix: Avoid world writable file

### Logging

- fix [Issue #941](https://github.com/benoitc/gunicorn/issues/941)  set logconfig default to paster more trivially
- add statsd-prefix config setting: set the prefix to use when emitting statsd
  metrics
- [Issue #832](https://github.com/benoitc/gunicorn/issues/832) log to console by default

### Thread Worker

- fix [Issue #908](https://github.com/benoitc/gunicorn/issues/908) make sure the worker can continue to accept requests

### Eventlet Worker

- fix [Issue #867](https://github.com/benoitc/gunicorn/issues/867) Fix eventlet shutdown to actively shut down the workers.

### Documentation

Many improvements and fixes have been done, see the detailed changelog for
more information.


================================================
FILE: docs/content/2016-news.md
================================================
<span id="news-2016"></span>
# Changelog - 2016

!!! note
    Please see [news](news.md) for the latest changes


## 19.6.0 / 2016/05/21

### Core & Logging

- improvement of the binary upgrade behaviour using USR2: remove file locking ([Issue #1270](https://github.com/benoitc/gunicorn/issues/1270))
- add the ``--capture-output`` setting to capture stdout/stderr tot the log
  file ([Issue #1271](https://github.com/benoitc/gunicorn/issues/1271))
- Allow disabling ``sendfile()`` via the ``SENDFILE`` environment variable
  ([Issue #1252](https://github.com/benoitc/gunicorn/issues/1252))
- fix reload under pycharm ([Issue #1129](https://github.com/benoitc/gunicorn/issues/1129))

### Workers

- fix: make sure to remove the signal from the worker pipe ([Issue #1269](https://github.com/benoitc/gunicorn/issues/1269))
- fix: **gthread** worker, handle removed socket in the select loop
  ([Issue #1258](https://github.com/benoitc/gunicorn/issues/1258))

## 19.5.0 / 2016/05/10

### Core

- fix: Ensure response to HEAD request won't have message body
- fix: lock domain socket and remove on last arbiter exit ([Issue #1220](https://github.com/benoitc/gunicorn/issues/1220))
- improvement: use EnvironmentError instead of socket.error ([Issue #939](https://github.com/benoitc/gunicorn/issues/939))
- add: new ``FORWARDED_ALLOW_IPS`` environment variable ([Issue #1205](https://github.com/benoitc/gunicorn/issues/1205))
- fix: infinite recursion when destroying sockets ([Issue #1219](https://github.com/benoitc/gunicorn/issues/1219))
- fix: close sockets on shutdown ([Issue #922](https://github.com/benoitc/gunicorn/issues/922))
- fix: clean up sys.exc_info calls to drop circular refs ([Issue #1228](https://github.com/benoitc/gunicorn/issues/1228))
- fix: do post_worker_init after load_wsgi ([Issue #1248](https://github.com/benoitc/gunicorn/issues/1248))

### Workers

- fix access logging in gaiohttp worker ([Issue #1193](https://github.com/benoitc/gunicorn/issues/1193))
- eventlet: handle QUIT in a new coroutine ([Issue #1217](https://github.com/benoitc/gunicorn/issues/1217))
- gevent: remove obsolete exception clauses in run ([Issue #1218](https://github.com/benoitc/gunicorn/issues/1218))
- tornado: fix extra "Server" response header ([Issue #1246](https://github.com/benoitc/gunicorn/issues/1246))
- fix: unblock the wait loop under python 3.5 in sync worker ([Issue #1256](https://github.com/benoitc/gunicorn/issues/1256))

### Logging

- fix: log message for listener reloading ([Issue #1181](https://github.com/benoitc/gunicorn/issues/1181))
- Let logging module handle traceback printing ([Issue #1201](https://github.com/benoitc/gunicorn/issues/1201))
- improvement: Allow configuring logger_class with statsd_host ([Issue #1188](https://github.com/benoitc/gunicorn/issues/1188))
- fix: traceback formatting ([Issue #1235](https://github.com/benoitc/gunicorn/issues/1235))
- fix: print error logs on stderr and access logs on stdout ([Issue #1184](https://github.com/benoitc/gunicorn/issues/1184))


### Documentation

- Simplify installation instructions in gunicorn.org ([Issue #1072](https://github.com/benoitc/gunicorn/issues/1072))
- Fix URL and default worker type in example_config ([Issue #1209](https://github.com/benoitc/gunicorn/issues/1209))
- update django doc url to 1.8 lts ([Issue #1213](https://github.com/benoitc/gunicorn/issues/1213))
- fix: miscellaneous wording corrections ([Issue #1216](https://github.com/benoitc/gunicorn/issues/1216))
- Add PSF License Agreement of selectors.py to NOTICE (:issue: `1226`)
- document LOGGING overriding ([Issue #1051](https://github.com/benoitc/gunicorn/issues/1051))
- put a note that error logs are only errors from Gunicorn ([Issue #1124](https://github.com/benoitc/gunicorn/issues/1124))
- add a note about the requirements of the threads workers under python 2.x ([Issue #1200](https://github.com/benoitc/gunicorn/issues/1200))
- add access_log_format to config example ([Issue #1251](https://github.com/benoitc/gunicorn/issues/1251))

### Tests

- Use more pytest.raises() in test_http.py


## 19.4.5 / 2016/01/05

- fix: NameError fileno in gunicorn.http.wsgi ([Issue #1178](https://github.com/benoitc/gunicorn/issues/1178))

## 19.4.4 / 2016/01/04

- fix: check if a fileobject can be used with sendfile(2.md) ([Issue #1174](https://github.com/benoitc/gunicorn/issues/1174))
- doc: be more descriptive in errorlog option ([Issue #1173](https://github.com/benoitc/gunicorn/issues/1173))


================================================
FILE: docs/content/2017-news.md
================================================
<span id="news-2017"></span>
# Changelog - 2017

!!! note
    Please see [news](news.md) for the latest changes


## 19.7.1 / 2017/03/21

- fix: continue if SO_REUSEPORT seems to be available but fails ([Issue #1480](https://github.com/benoitc/gunicorn/issues/1480))
- fix: support non-decimal values for the umask command line option ([Issue #1325](https://github.com/benoitc/gunicorn/issues/1325))

## 19.7.0 / 2017/03/01

- The previously deprecated ``gunicorn_django`` command has been removed.
  Use the [gunicorn-cmd](run.md#gunicorn) command-line interface instead.
- The previously deprecated ``django_settings`` setting has been removed.
  Use the [raw-env](reference/settings.md#raw_env) setting instead.
- The default value of [ssl-version](reference/settings.md#ssl_version) has been changed from
  ``ssl.PROTOCOL_TLSv1`` to ``ssl.PROTOCOL_SSLv23``.
- fix: initialize the group access list when initgroups is set ([Issue #1297](https://github.com/benoitc/gunicorn/issues/1297))
- add environment variables to gunicorn access log format ([Issue #1291](https://github.com/benoitc/gunicorn/issues/1291))
- add --paste-global-conf option ([Issue #1304](https://github.com/benoitc/gunicorn/issues/1304))
- fix: print access logs to STDOUT ([Issue #1184](https://github.com/benoitc/gunicorn/issues/1184))
- remove upper limit on max header size config ([Issue #1313](https://github.com/benoitc/gunicorn/issues/1313))
- fix: print original exception on AppImportError ([Issue #1334](https://github.com/benoitc/gunicorn/issues/1334))
- use SO_REUSEPORT if available ([Issue #1344](https://github.com/benoitc/gunicorn/issues/1344))
- `fix leak <https://github.com/benoitc/gunicorn/commit/b4c41481e2d5ef127199a4601417a6819053c3fd>`_ of duplicate file descriptor for bound sockets.
- add --reload-engine option, support inotify and other backends ([Issue #1368](https://github.com/benoitc/gunicorn/issues/1368), [Issue #1459](https://github.com/benoitc/gunicorn/issues/1459))
- fix: reject request with invalid HTTP versions
- add ``child_exit`` callback ([Issue #1394](https://github.com/benoitc/gunicorn/issues/1394))
- add support for eventlets _AlreadyHandled object ([Issue #1406](https://github.com/benoitc/gunicorn/issues/1406))
- format boot tracebacks properly with reloader ([Issue #1408](https://github.com/benoitc/gunicorn/issues/1408))
- refactor socket activation and fd inheritance for better support of SystemD ([Issue #1310](https://github.com/benoitc/gunicorn/issues/1310))
- fix: o fds are given by default in gunicorn ([Issue #1423](https://github.com/benoitc/gunicorn/issues/1423))
- add ability to pass settings to GUNICORN_CMD_ARGS environment variable which helps in container world ([Issue #1385](https://github.com/benoitc/gunicorn/issues/1385))
- fix:  catch access denied to pid file ([Issue #1091](https://github.com/benoitc/gunicorn/issues/1091))
-  many additions and improvements to the documentation

### Breaking Change

- **Python 2.6.0** is the last supported version


================================================
FILE: docs/content/2018-news.md
================================================
<span id="news-2018"></span>
# Changelog - 2018

!!! note
    Please see [news](news.md) for the latest changes


## 19.9.0 / 2018/07/03

- fix: address a regression that prevented syslog support from working
  ([Issue #1668](https://github.com/benoitc/gunicorn/issues/1668), [PR #1773](https://github.com/benoitc/gunicorn/pull/1773))
- fix: correctly set `REMOTE_ADDR` on versions of Python 3 affected by
  `Python Issue 30205 <https://bugs.python.org/issue30205>`_
  ([Issue #1755](https://github.com/benoitc/gunicorn/issues/1755), [PR #1796](https://github.com/benoitc/gunicorn/pull/1796))
- fix: show zero response length correctly in access log ([PR #1787](https://github.com/benoitc/gunicorn/pull/1787))
- fix: prevent raising `AttributeError` when ``--reload`` is not passed
  in case of a `SyntaxError` raised from the WSGI application.
  ([Issue #1805](https://github.com/benoitc/gunicorn/issues/1805), [PR #1806](https://github.com/benoitc/gunicorn/pull/1806))
- The internal module ``gunicorn.workers.async`` was renamed to ``gunicorn.workers.base_async``
  since ``async`` is now a reserved word in Python 3.7.
  ([PR #1527](https://github.com/benoitc/gunicorn/pull/1527))

## 19.8.1 / 2018/04/30

- fix: secure scheme headers when bound to a unix socket
  ([Issue #1766](https://github.com/benoitc/gunicorn/issues/1766), [PR #1767](https://github.com/benoitc/gunicorn/pull/1767))

## 19.8.0 / 2018/04/28

- Eventlet 0.21.0 support ([Issue #1584](https://github.com/benoitc/gunicorn/issues/1584))
- Tornado 5 support ([Issue #1728](https://github.com/benoitc/gunicorn/issues/1728), [PR #1752](https://github.com/benoitc/gunicorn/pull/1752))
- support watching additional files with ``--reload-extra-file``
  ([PR #1527](https://github.com/benoitc/gunicorn/pull/1527))
- support configuring logging with a dictionary with ``--logging-config-dict``
  ([Issue #1087](https://github.com/benoitc/gunicorn/issues/1087), [PR #1110](https://github.com/benoitc/gunicorn/pull/1110), [PR #1602](https://github.com/benoitc/gunicorn/pull/1602))
- add support for the ``--config`` flag in the ``GUNICORN_CMD_ARGS`` environment
  variable ([Issue #1576](https://github.com/benoitc/gunicorn/issues/1576), [PR #1581](https://github.com/benoitc/gunicorn/pull/1581))
- disable ``SO_REUSEPORT`` by default and add the ``--reuse-port`` setting
  ([Issue #1553](https://github.com/benoitc/gunicorn/issues/1553), [Issue #1603](https://github.com/benoitc/gunicorn/issues/1603), [PR #1669](https://github.com/benoitc/gunicorn/pull/1669))
- fix: installing `inotify` on MacOS no longer breaks the reloader
  ([Issue #1540](https://github.com/benoitc/gunicorn/issues/1540), [PR #1541](https://github.com/benoitc/gunicorn/pull/1541))
- fix: do not throw ``TypeError`` when ``SO_REUSEPORT`` is not available
  ([Issue #1501](https://github.com/benoitc/gunicorn/issues/1501), [PR #1491](https://github.com/benoitc/gunicorn/pull/1491))
- fix: properly decode HTTP paths containing certain non-ASCII characters
  ([Issue #1577](https://github.com/benoitc/gunicorn/issues/1577), [PR #1578](https://github.com/benoitc/gunicorn/pull/1578))
- fix: remove whitespace when logging header values under gevent ([PR #1607](https://github.com/benoitc/gunicorn/pull/1607))
- fix: close unlinked temporary files ([Issue #1327](https://github.com/benoitc/gunicorn/issues/1327), [PR #1428](https://github.com/benoitc/gunicorn/pull/1428))
- fix: parse ``--umask=0`` correctly ([Issue #1622](https://github.com/benoitc/gunicorn/issues/1622), [PR #1632](https://github.com/benoitc/gunicorn/pull/1632))
- fix: allow loading applications using relative file paths
  ([Issue #1349](https://github.com/benoitc/gunicorn/issues/1349), [PR #1481](https://github.com/benoitc/gunicorn/pull/1481))
- fix: force blocking mode on the gevent sockets ([Issue #880](https://github.com/benoitc/gunicorn/issues/880), [PR #1616](https://github.com/benoitc/gunicorn/pull/1616))
- fix: preserve leading `/` in request path ([Issue #1512](https://github.com/benoitc/gunicorn/issues/1512), [PR #1511](https://github.com/benoitc/gunicorn/pull/1511))
- fix: forbid contradictory secure scheme headers
- fix: handle malformed basic authentication headers in access log
  ([Issue #1683](https://github.com/benoitc/gunicorn/issues/1683), [PR #1684](https://github.com/benoitc/gunicorn/pull/1684))
- fix: defer handling of ``USR1`` signal to a new greenlet under gevent
  ([Issue #1645](https://github.com/benoitc/gunicorn/issues/1645), [PR #1651](https://github.com/benoitc/gunicorn/pull/1651))
- fix: the threaded worker would sometimes close the wrong keep-alive
  connection under Python 2 ([Issue #1698](https://github.com/benoitc/gunicorn/issues/1698), [PR #1699](https://github.com/benoitc/gunicorn/pull/1699))
- fix: re-open log files on ``USR1`` signal using ``handler._open`` to
  support subclasses of ``FileHandler`` ([Issue #1739](https://github.com/benoitc/gunicorn/issues/1739), [PR #1742](https://github.com/benoitc/gunicorn/pull/1742))
- deprecation: the ``gaiohttp`` worker is deprecated, see the
  [worker-class](reference/settings.md#worker_class) documentation for more information
  ([Issue #1338](https://github.com/benoitc/gunicorn/issues/1338), [PR #1418](https://github.com/benoitc/gunicorn/pull/1418), [PR #1569](https://github.com/benoitc/gunicorn/pull/1569))


================================================
FILE: docs/content/2019-news.md
================================================
<span id="news-2019"></span>
# Changelog - 2019

!!! note
    Please see [news](news.md) for the latest changes


## 20.0.4 / 2019/11/26

- fix binding a socket using the file descriptor
- remove support for the `bdist_rpm` build

## 20.0.3 / 2019/11/24

- fixed load of a config file without a Python extension
- fixed `socketfromfd.fromfd` when defaults are not set

!!! note
    ```
    ## 20.0.2 / 2019/11/23
    
    - fix changelog
    
    ## 20.0.1 / 2019/11/23
    
    - fixed the way the config module is loaded. `__file__` is now available
    - fixed `wsgi.input_terminated`. It is always true.
    - use the highest protocol version of openssl by default
    - only support Python >= 3.5
    - added `__repr__` method to `Config` instance
    - fixed support of AIX platform and musl libc in  `socketfromfd.fromfd` function
    - fixed support of applications loaded from a factory function
    - fixed chunked encoding support to prevent any `request smuggling <https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn>`_
    - Capture os.sendfile before patching in gevent and eventlet workers.
      fix `RecursionError`.
    - removed locking in reloader when adding new files
    - load the WSGI application before the loader to pick up all files

{note}
as documented in Flask and other places.
```
## 19.10.0 / 2019/11/23

- unblock select loop during reload of a sync worker
- security fix: http desync attack
- handle `wsgi.input_terminated`
- added support for str and bytes in unix  socket addresses
- fixed `max_requests` setting
- headers values are now encoded as LATN1, not ASCII
- fixed `InotifyReloadeder`:  handle `module.__file__` is None
- fixed compatibility with tornado 6
- fixed root logging
- Prevent removalof unix sockets from `reuse_port`
- Clear tornado ioloop before os.fork
- Miscellaneous fixes and improvement for linting using Pylint

## 20.0 / 2019/10/30

- Fixed `fdopen` `RuntimeWarning` in Python 3.8
- Added  check and exception for str type on value in Response process_headers method.
- Ensure WSGI header value is string before conducting regex search on it.
- Added pypy3 to list of tested environments
- Grouped `StopIteration` and `KeyboardInterrupt` exceptions with same body together in Arbiter.run()
- Added `setproctitle` module to `extras_require` in setup.py
- Avoid unnecessary chown of temporary files
- Logging: Handle auth type case insensitively
- Removed `util.import_module`
- Removed fallback for `types.SimpleNamespace` in tests utils
- Use `SourceFileLoader` instead instead of `execfile_`
- Use `importlib` instead of `__import__` and eval`
- Fixed eventlet patching
- Added optional `datadog <https://www.datadoghq.com>`_ tags for statsd metrics
- Header values now are encoded using latin-1, not ascii.
- Rewritten `parse_address` util added test
- Removed redundant super() arguments
- Simplify `futures` import in gthread module
- Fixed worker_connections` setting to also affects the Gthread worker type
- Fixed setting max_requests
- Bump minimum Eventlet and Gevent versions to 0.24 and 1.4
- Use Python default SSL cipher list by default
- handle `wsgi.input_terminated` extension
- Simplify Paste Deployment documentation
- Fix root logging: root and logger are same level.
- Fixed typo in ssl_version documentation
- Documented  systemd deployment unit examples
- Added systemd sd_notify support
- Fixed typo in gthread.py
- Added `tornado <https://www.tornadoweb.org/>`_ 5 and  6 support
- Declare our setuptools dependency
- Added support to `--bind` to open file descriptors
- Document how to serve WSGI app modules from Gunicorn
- Provide guidance on X-Forwarded-For access log in documentation
- Add support for named constants in the `--ssl-version` flag
- Clarify log format usage of header & environment in documentation
- Fixed systemd documentation to properly setup gunicorn unix socket
- Prevent removal unix socket for reuse_port
- Fix `ResourceWarning` when reading a Python config module
- Remove unnecessary call to dict keys method
- Support str and bytes for UNIX socket addresses
- fixed `InotifyReloadeder`:  handle `module.__file__` is None
- `/dev/shm` as a convenient alternative to making your own tmpfs mount in fchmod FAQ
- fix examples to work on python3
- Fix typo in `--max-requests` documentation
- Clear tornado ioloop before os.fork
- Miscellaneous fixes and improvement for linting using Pylint

### Breaking Change

- Removed gaiohttp worker
- Drop support for Python 2.x
- Drop support for EOL Python 3.2 and 3.3
- Drop support for Paste Deploy server blocks


================================================
FILE: docs/content/2020-news.md
================================================
<span id="news-2020"></span>
# Changelog - 2020

!!! note
    Please see [news](news.md) for the latest changes




================================================
FILE: docs/content/2021-news.md
================================================
<span id="news-2021"></span>
# Changelog - 2021

!!! note
    Please see [news](news.md) for the latest changes


## 20.1.0 - 2021-02-12

- document WEB_CONCURRENCY is set by, at least, Heroku
- capture peername from accept: Avoid calls to getpeername by capturing the peer name returned by
  accept
- log a warning when a worker was terminated due to a signal
- fix tornado usage with latest versions of Django 
- add support for python -m gunicorn
- fix systemd socket activation example
- allows to set wsgi application in config file using `wsgi_app`
- document `--timeout = 0`
- always close a connection when the number of requests exceeds the max requests
- Disable keepalive during graceful shutdown
- kill tasks in the gthread workers during upgrade
- fix latency in gevent worker when accepting new requests
- fix file watcher: handle errors when new worker reboot and ensure the list of files is kept
- document the default name and path of the configuration file
- document how variable impact configuration
- document the `$PORT` environment variable
- added milliseconds option to request_time in access_log
- added PIP requirements to be used for example
- remove version from the Server header
- fix sendfile: use `socket.sendfile` instead of `os.sendfile`
- reloader: use  absolute path to prevent empty to prevent0 `InotifyError` when a file 
  is added to the working directory
- Add --print-config option to print the resolved settings at startup.
- remove the `--log-dict-config` CLI flag because it never had a working format
  (the `logconfig_dict` setting in configuration files continues to work)


### Breaking changes

- minimum version is Python 3.5
- remove version from the Server header 

** Documentation **



** Others **

- miscellaneous changes in the code base to be a better citizen with Python 3
- remove dead code
- fix documentation generation


================================================
FILE: docs/content/2023-news.md
================================================
<span id="news-2023"></span>
# Changelog - 2023

## 21.2.0 - 2023-07-19

- fix thread worker: revert change considering connection as idle . 

!!! note
    This is fixing the bad file description error.
    
    21.1.0 - 2023-07-18


===================

- fix thread worker: fix socket removal from the queue

## 21.0.1 - 2023-07-17

- fix documentation build

## 21.0.0 - 2023-07-17

- support python 3.11
- fix gevent and eventlet workers
- fix threads support (gththread.md): improve performance and unblock requests
- SSL: now use SSLContext object
- HTTP parser: miscellaneous fixes
- remove unnecessary setuid calls
- fix testing
- improve logging
- miscellaneous fixes to core engine

*** RELEASE NOTE ***

We made this release major to start our new release cycle. More info will be provided on our discussion forum.


================================================
FILE: docs/content/2024-news.md
================================================
<span id="news-2024"></span>
# Changelog - 2024

## 23.0.0 - 2024-08-10

- minor docs fixes ([PR #3217](https://github.com/benoitc/gunicorn/pull/3217), [PR #3089](https://github.com/benoitc/gunicorn/pull/3089), [PR #3167](https://github.com/benoitc/gunicorn/pull/3167))
- worker_class parameter accepts a class ([PR #3079](https://github.com/benoitc/gunicorn/pull/3079))
- fix deadlock if request terminated during chunked parsing ([PR #2688](https://github.com/benoitc/gunicorn/pull/2688))
- permit receiving Transfer-Encodings: compress, deflate, gzip ([PR #3261](https://github.com/benoitc/gunicorn/pull/3261))
- permit Transfer-Encoding headers specifying multiple encodings. note: no parameters, still ([PR #3261](https://github.com/benoitc/gunicorn/pull/3261))
- sdist generation now explicitly excludes sphinx build folder ([PR #3257](https://github.com/benoitc/gunicorn/pull/3257))
- decode bytes-typed status (as can be passed by gevent) as utf-8 instead of raising `TypeError` ([PR #2336](https://github.com/benoitc/gunicorn/pull/2336))
- raise correct Exception when encounting invalid chunked requests ([PR #3258](https://github.com/benoitc/gunicorn/pull/3258))
- the SCRIPT_NAME and PATH_INFO headers, when received from allowed forwarders, are no longer restricted for containing an underscore ([PR #3192](https://github.com/benoitc/gunicorn/pull/3192))
- include IPv6 loopback address ``[::1]`` in default for [forwarded-allow-ips](reference/settings.md#forwarded_allow_ips) and [proxy-allow-ips](reference/settings.md#proxy_allow_ips) ([PR #3192](https://github.com/benoitc/gunicorn/pull/3192))

!!! note
    - The SCRIPT_NAME change mitigates a regression that appeared first in the 22.0.0 release
    - Review your [forwarded-allow-ips](reference/settings.md#forwarded_allow_ips) setting if you are still not seeing the SCRIPT_NAME transmitted
    - Review your [forwarder-headers](reference/settings.md#forwarder_headers) setting if you are missing headers after upgrading from a version prior to 22.0.0


### Breaking changes

- refuse requests where the uri field is empty ([PR #3255](https://github.com/benoitc/gunicorn/pull/3255))
- refuse requests with invalid CR/LR/NUL in heade field values ([PR #3253](https://github.com/benoitc/gunicorn/pull/3253))
- remove temporary ``--tolerate-dangerous-framing`` switch from 22.0 ([PR #3260](https://github.com/benoitc/gunicorn/pull/3260))
- If any of the breaking changes affect you, be aware that now refused requests can post a security problem, especially so in setups involving request pipe-lining and/or proxies.

## 22.0.0 - 2024-04-17

- use `utime` to notify workers liveness 
- migrate setup to pyproject.toml
- fix numerous security vulnerabilities in HTTP parser (closing some request smuggling vectors)
- parsing additional requests is no longer attempted past unsupported request framing
- on HTTP versions < 1.1 support for chunked transfer is refused (only used in exploits)
- requests conflicting configured or passed SCRIPT_NAME now produce a verbose error
- Trailer fields are no longer inspected for headers indicating secure scheme
- support Python 3.12

### Breaking changes

- minimum version is Python 3.7
- the limitations on valid characters in the HTTP method have been bounded to Internet Standards
- requests specifying unsupported transfer coding (order.md) are refused by default (rare.md)
- HTTP methods are no longer casefolded by default (IANA method registry contains none affected)
- HTTP methods containing the number sign (#) are no longer accepted by default (rare.md)
- HTTP versions < 1.0 or >= 2.0 are no longer accepted by default (rare, only HTTP/1.1 is supported)
- HTTP versions consisting of multiple digits or containing a prefix/suffix are no longer accepted
- HTTP header field names Gunicorn cannot safely map to variables are silently dropped, as in other software
- HTTP headers with empty field name are refused by default (no legitimate use cases, used in exploits)
- requests with both Transfer-Encoding and Content-Length are refused by default (such a message might indicate an attempt to perform request smuggling)
- empty transfer codings are no longer permitted (reportedly seen with really old & broken proxies)


### Security

- fix CVE-2024-1135


================================================
FILE: docs/content/2026-news.md
================================================
<span id="news-2026"></span>
# Changelog - 2026

## 25.1.0 - 2026-02-13

### New Features

- **Control Interface (gunicornc)**: Add interactive control interface for managing
  running Gunicorn instances, similar to birdc for BIRD routing daemon
  ([PR #3505](https://github.com/benoitc/gunicorn/pull/3505))
  - Unix socket-based communication with JSON protocol
  - Interactive mode with readline support and command history
  - Commands: `show all/workers/dirty/config/stats/listeners`
  - Worker management: `worker add/remove/kill`, `dirty add/remove`
  - Server control: `reload`, `reopen`, `shutdown`
  - New settings: `--control-socket`, `--control-socket-mode`, `--no-control-socket`
  - New CLI tool: `gunicornc` for connecting to control socket
  - See [Control Interface Guide](guides/gunicornc.md) for details

- **Dirty Stash**: Add global shared state between workers via `dirty.stash`
  ([PR #3503](https://github.com/benoitc/gunicorn/pull/3503))
  - In-memory key-value store accessible by all workers
  - Supports get, set, delete, clear, keys, and has operations
  - Useful for sharing state like feature flags, rate limits, or cached data

- **Dirty Binary Protocol**: Implement efficient binary protocol for dirty arbiter IPC
  using TLV (Type-Length-Value) encoding
  ([PR #3500](https://github.com/benoitc/gunicorn/pull/3500))
  - More efficient than JSON for binary data
  - Supports all Python types: str, bytes, int, float, bool, None, list, dict
  - Better performance for large payloads

- **Dirty TTIN/TTOU Signals**: Add dynamic worker scaling for dirty arbiters
  ([PR #3504](https://github.com/benoitc/gunicorn/pull/3504))
  - Send SIGTTIN to increase dirty workers
  - Send SIGTTOU to decrease dirty workers
  - Respects minimum worker constraints from app configurations

### Changes

- **ASGI Worker**: Promoted from beta to stable
- **Dirty Arbiters**: Now marked as beta feature

### Documentation

- Fix Markdown formatting in /configure documentation

---

## 25.0.3 - 2026-02-07

### Bug Fixes

- Fix RuntimeError when StopIteration is raised inside ASGI response body
  coroutine (PEP 479 compliance)

- Fix deprecation warning for passing maxsplit as positional argument in
  `re.split()` (Python 3.13+)

---

## 25.0.2 - 2026-02-06

### Bug Fixes

- Fix ASGI concurrent request failures through nginx proxy by normalizing
  sockaddr tuples to handle both 2-tuple (IPv4) and 4-tuple (IPv6) formats
  ([PR #3485](https://github.com/benoitc/gunicorn/pull/3485))

- Fix graceful disconnect handling for ASGI worker to properly handle
  client disconnects without raising exceptions
  ([PR #3485](https://github.com/benoitc/gunicorn/pull/3485))

- Fix lazy import of dirty module for gevent compatibility - prevents
  import errors when concurrent.futures is imported before gevent monkey-patching
  ([PR #3483](https://github.com/benoitc/gunicorn/pull/3483))

### Changes

- Refactor: Extract `_normalize_sockaddr` utility function for consistent
  socket address handling across workers

- Add license headers to all Python source files

- Update copyright year to 2026 in LICENSE and NOTICE files

---

## 25.0.1 - 2026-02-02

### Bug Fixes

- Fix ASGI streaming responses (SSE) hanging: add chunked transfer encoding for
  HTTP/1.1 responses without Content-Length header. Without chunked encoding,
  clients wait for connection close to determine end-of-response.

### Changes

- Update celery_alternative example to use FastAPI with native ASGI worker and
  uvloop for async task execution

### Testing

- Add ASGI compliance test suite with Docker-based integration tests covering HTTP,
  WebSocket, streaming, lifespan, framework integration (Starlette, FastAPI),
  HTTP/2, and concurrency scenarios

---

## 25.0.0 - 2026-02-01

### New Features

- **Dirty Arbiters**: Separate process pool for executing long-running, blocking
  operations (AI model loading, heavy computation) without blocking HTTP workers
  ([PR #3460](https://github.com/benoitc/gunicorn/pull/3460))
  - Inspired by Erlang's dirty schedulers
  - Asyncio-based with Unix socket IPC
  - Stateful workers that persist loaded resources
  - New settings: `--dirty-app`, `--dirty-workers`, `--dirty-timeout`,
    `--dirty-threads`, `--dirty-graceful-timeout`
  - Lifecycle hooks: `on_dirty_starting`, `dirty_post_fork`,
    `dirty_worker_init`, `dirty_worker_exit`

- **Per-App Worker Allocation for Dirty Arbiters**: Control how many dirty workers
  load each app for memory optimization with heavy models
  ([PR #3473](https://github.com/benoitc/gunicorn/pull/3473))
  - Set `workers` class attribute on DirtyApp (e.g., `workers = 2`)
  - Or use config format `module:class:N` (e.g., `myapp:HeavyModel:2`)
  - Requests automatically routed to workers with the target app
  - New exception `DirtyNoWorkersAvailableError` for graceful error handling
  - Example: 8 workers × 10GB model = 80GB → with `workers=2`: 20GB (75% savings)

- **HTTP/2 Support (Beta)**: Native HTTP/2 (RFC 7540) support for improved performance
  with modern clients ([PR #3468](https://github.com/benoitc/gunicorn/pull/3468))
  - Multiplexed streams over a single connection
  - Header compression (HPACK)
  - Flow control and stream prioritization
  - Works with gthread, gevent, and ASGI workers
  - New settings: `--http-protocols`, `--http2-max-concurrent-streams`,
    `--http2-initial-window-size`, `--http2-max-frame-size`, `--http2-max-header-list-size`
  - Requires SSL/TLS and h2 library: `pip install gunicorn[http2]`
  - See [HTTP/2 Guide](guides/http2.md) for details
  - New example: `examples/http2_gevent/` w
Download .txt
gitextract_ti_vnsti/

├── .github/
│   ├── DISCUSSION_TEMPLATE/
│   │   ├── issue-triage.yml
│   │   └── question.yml
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── config.yml
│   │   └── preapproved.md
│   ├── dependabot.yml
│   └── workflows/
│       ├── docker-integration.yml
│       ├── docker-publish.yml
│       ├── docs.yml
│       ├── embedding-integration.yml
│       ├── freebsd.yml
│       ├── lint.yml
│       └── tox.yml
├── .gitignore
├── .pylintrc
├── CONTRIBUTING.md
├── LICENSE
├── MAINTAINERS
├── MANIFEST.in
├── Makefile
├── NOTICE
├── README.md
├── SECURITY.md
├── THANKS
├── appveyor.yml
├── benchmarks/
│   ├── baseline.json
│   ├── dirty_bench_app.py
│   ├── dirty_bench_gunicorn.py
│   ├── dirty_bench_wsgi.py
│   ├── dirty_benchmark.py
│   ├── dirty_streaming.py
│   ├── quick_bench.sh
│   ├── results/
│   │   └── queue_refactor_results.json
│   ├── run_benchmark.py
│   └── simple_app.py
├── docker/
│   ├── .dockerignore
│   ├── Dockerfile
│   └── docker-entrypoint.sh
├── docs/
│   ├── README.md
│   ├── content/
│   │   ├── 2010-news.md
│   │   ├── 2011-news.md
│   │   ├── 2012-news.md
│   │   ├── 2013-news.md
│   │   ├── 2014-news.md
│   │   ├── 2015-news.md
│   │   ├── 2016-news.md
│   │   ├── 2017-news.md
│   │   ├── 2018-news.md
│   │   ├── 2019-news.md
│   │   ├── 2020-news.md
│   │   ├── 2021-news.md
│   │   ├── 2023-news.md
│   │   ├── 2024-news.md
│   │   ├── 2026-news.md
│   │   ├── 404.md
│   │   ├── CNAME
│   │   ├── asgi.md
│   │   ├── assets/
│   │   │   ├── javascripts/
│   │   │   │   └── toc-collapse.js
│   │   │   └── stylesheets/
│   │   │       └── home.css
│   │   ├── community.md
│   │   ├── configure.md
│   │   ├── custom.md
│   │   ├── deploy.md
│   │   ├── design.md
│   │   ├── dirty.md
│   │   ├── faq.md
│   │   ├── guides/
│   │   │   ├── docker.md
│   │   │   ├── gunicornc.md
│   │   │   └── http2.md
│   │   ├── index.md
│   │   ├── install.md
│   │   ├── instrumentation.md
│   │   ├── news.md
│   │   ├── quickstart.md
│   │   ├── reference/
│   │   │   └── settings.md
│   │   ├── run.md
│   │   ├── signals.md
│   │   ├── sponsor.md
│   │   ├── styles/
│   │   │   └── overrides.css
│   │   └── uwsgi.md
│   └── macros.py
├── examples/
│   ├── alt_spec.py
│   ├── asgi/
│   │   ├── __init__.py
│   │   ├── basic_app.py
│   │   └── websocket_app.py
│   ├── bad.py
│   ├── boot_fail.py
│   ├── celery_alternative/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── app.py
│   │   ├── docker-compose.yml
│   │   ├── gunicorn_conf.py
│   │   ├── requirements.txt
│   │   ├── run_tests.sh
│   │   ├── tasks.py
│   │   └── tests/
│   │       ├── __init__.py
│   │       ├── conftest.py
│   │       ├── test_integration.py
│   │       └── test_tasks.py
│   ├── deep/
│   │   ├── __init__.py
│   │   └── test.py
│   ├── dirty_example/
│   │   ├── Dockerfile
│   │   ├── __init__.py
│   │   ├── dirty_app.py
│   │   ├── docker-compose.yml
│   │   ├── gunicorn_conf.py
│   │   ├── test_dirty_app.py
│   │   ├── test_integration.py
│   │   ├── test_protocol.py
│   │   ├── test_stash_integration.py
│   │   ├── test_worker_integration.py
│   │   └── wsgi_app.py
│   ├── echo.py
│   ├── embedding_service/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── __init__.py
│   │   ├── docker-compose.yml
│   │   ├── embedding_app.py
│   │   ├── gunicorn_conf.py
│   │   ├── main.py
│   │   ├── requirements.txt
│   │   └── test_embedding.py
│   ├── example_config.py
│   ├── frameworks/
│   │   ├── cherryapp.py
│   │   ├── django/
│   │   │   ├── README
│   │   │   └── testing/
│   │   │       ├── manage.py
│   │   │       └── testing/
│   │   │           ├── __init__.py
│   │   │           ├── apps/
│   │   │           │   ├── __init__.py
│   │   │           │   └── someapp/
│   │   │           │       ├── __init__.py
│   │   │           │       ├── middleware.py
│   │   │           │       ├── models.py
│   │   │           │       ├── templates/
│   │   │           │       │   ├── base.html
│   │   │           │       │   └── home.html
│   │   │           │       ├── tests.py
│   │   │           │       ├── urls.py
│   │   │           │       └── views.py
│   │   │           ├── settings.py
│   │   │           ├── urls.py
│   │   │           └── wsgi.py
│   │   ├── flask_sendfile.py
│   │   ├── flaskapp.py
│   │   ├── flaskapp_aiohttp_wsgi.py
│   │   ├── pyramidapp.py
│   │   ├── requirements.txt
│   │   ├── requirements_cherryapp.txt
│   │   ├── requirements_flaskapp.txt
│   │   ├── requirements_pyramidapp.txt
│   │   ├── requirements_tornadoapp.txt
│   │   ├── requirements_webpyapp.txt
│   │   ├── tornadoapp.py
│   │   └── webpyapp.py
│   ├── gunicorn_rc
│   ├── hello.txt
│   ├── http2_features/
│   │   ├── Dockerfile
│   │   ├── __init__.py
│   │   ├── docker-compose.yml
│   │   ├── gunicorn_conf.py
│   │   ├── http2_app.py
│   │   ├── requirements.txt
│   │   └── test_http2.py
│   ├── http2_gevent/
│   │   ├── .gitignore
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── app.py
│   │   ├── docker-compose.yml
│   │   ├── generate_certs.sh
│   │   ├── gunicorn_conf.py
│   │   └── test_http2_gevent.py
│   ├── log_app.ini
│   ├── log_app.py
│   ├── logging.conf
│   ├── longpoll.py
│   ├── multiapp.py
│   ├── multidomainapp.py
│   ├── nginx.conf
│   ├── read_django_settings.py
│   ├── readline_app.py
│   ├── sendfile.py
│   ├── server.crt
│   ├── server.key
│   ├── slowclient.py
│   ├── standalone_app.py
│   ├── streaming_chat/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── __init__.py
│   │   ├── chat_app.py
│   │   ├── demo_capture.txt
│   │   ├── docker-compose.yml
│   │   ├── gunicorn_conf.py
│   │   ├── main.py
│   │   ├── requirements.txt
│   │   └── test_streaming.py
│   ├── supervisor.conf
│   ├── test.py
│   ├── timeout.py
│   ├── websocket/
│   │   ├── gevent_websocket.py
│   │   └── websocket.html
│   └── when_ready.conf.py
├── gunicorn/
│   ├── __init__.py
│   ├── __main__.py
│   ├── app/
│   │   ├── __init__.py
│   │   ├── base.py
│   │   ├── pasterapp.py
│   │   └── wsgiapp.py
│   ├── arbiter.py
│   ├── asgi/
│   │   ├── __init__.py
│   │   ├── lifespan.py
│   │   ├── message.py
│   │   ├── protocol.py
│   │   ├── unreader.py
│   │   ├── uwsgi.py
│   │   └── websocket.py
│   ├── config.py
│   ├── ctl/
│   │   ├── __init__.py
│   │   ├── cli.py
│   │   ├── client.py
│   │   ├── handlers.py
│   │   ├── protocol.py
│   │   └── server.py
│   ├── debug.py
│   ├── dirty/
│   │   ├── __init__.py
│   │   ├── app.py
│   │   ├── arbiter.py
│   │   ├── client.py
│   │   ├── errors.py
│   │   ├── protocol.py
│   │   ├── stash.py
│   │   ├── tlv.py
│   │   └── worker.py
│   ├── errors.py
│   ├── glogging.py
│   ├── http/
│   │   ├── __init__.py
│   │   ├── body.py
│   │   ├── errors.py
│   │   ├── message.py
│   │   ├── parser.py
│   │   ├── unreader.py
│   │   └── wsgi.py
│   ├── http2/
│   │   ├── __init__.py
│   │   ├── async_connection.py
│   │   ├── connection.py
│   │   ├── errors.py
│   │   ├── request.py
│   │   └── stream.py
│   ├── instrument/
│   │   ├── __init__.py
│   │   └── statsd.py
│   ├── pidfile.py
│   ├── reloader.py
│   ├── sock.py
│   ├── systemd.py
│   ├── util.py
│   ├── uwsgi/
│   │   ├── __init__.py
│   │   ├── errors.py
│   │   ├── message.py
│   │   └── parser.py
│   └── workers/
│       ├── __init__.py
│       ├── base.py
│       ├── base_async.py
│       ├── gasgi.py
│       ├── geventlet.py
│       ├── ggevent.py
│       ├── gthread.py
│       ├── gtornado.py
│       ├── sync.py
│       └── workertmp.py
├── mkdocs.yml
├── overrides/
│   └── home.html
├── pyproject.toml
├── requirements_dev.txt
├── requirements_test.txt
├── scripts/
│   ├── build_settings_doc.py
│   └── update_thanks.py
├── tests/
│   ├── config/
│   │   ├── __init__.py
│   │   ├── test_cfg.py
│   │   ├── test_cfg_alt.py
│   │   └── test_cfg_with_wsgi_app.py
│   ├── conftest.py
│   ├── ctl/
│   │   ├── __init__.py
│   │   ├── test_client.py
│   │   ├── test_handlers.py
│   │   ├── test_protocol.py
│   │   └── test_server.py
│   ├── dirty/
│   │   ├── __init__.py
│   │   ├── test_arbiter_signals.py
│   │   ├── test_arbiter_streaming.py
│   │   ├── test_client_streaming.py
│   │   ├── test_client_streaming_async.py
│   │   ├── test_multi_app_routing.py
│   │   ├── test_per_app_worker_allocation.py
│   │   ├── test_streaming_integration.py
│   │   └── test_worker_streaming.py
│   ├── docker/
│   │   ├── __init__.py
│   │   ├── asgi/
│   │   │   ├── Dockerfile
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   └── test_asgi.sh
│   │   ├── asgi_compliance/
│   │   │   ├── Dockerfile.gunicorn
│   │   │   ├── Dockerfile.nginx
│   │   │   ├── __init__.py
│   │   │   ├── apps/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── framework_apps.py
│   │   │   │   ├── http_app.py
│   │   │   │   ├── lifespan_app.py
│   │   │   │   ├── main_app.py
│   │   │   │   ├── streaming_app.py
│   │   │   │   └── websocket_app.py
│   │   │   ├── certs/
│   │   │   │   ├── server.crt
│   │   │   │   └── server.key
│   │   │   ├── conftest.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── nginx.conf
│   │   │   ├── test_concurrency.py
│   │   │   ├── test_framework_integration.py
│   │   │   ├── test_http2_asgi.py
│   │   │   ├── test_http_compliance.py
│   │   │   ├── test_lifespan_compliance.py
│   │   │   ├── test_streaming_compliance.py
│   │   │   └── test_websocket_compliance.py
│   │   ├── dirty_arbiter/
│   │   │   ├── Dockerfile
│   │   │   ├── README.md
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── gunicorn_conf.py
│   │   │   └── test_parent_death.py
│   │   ├── dirty_ttin_ttou/
│   │   │   ├── Dockerfile
│   │   │   ├── __init__.py
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── gunicorn_conf.py
│   │   │   └── test_ttin_ttou_docker.py
│   │   ├── http2/
│   │   │   ├── Dockerfile.gunicorn
│   │   │   ├── Dockerfile.nginx
│   │   │   ├── README.rst
│   │   │   ├── __init__.py
│   │   │   ├── app.py
│   │   │   ├── certs/
│   │   │   │   ├── .gitkeep
│   │   │   │   ├── server.crt
│   │   │   │   └── server.key
│   │   │   ├── conftest.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── nginx.conf
│   │   │   └── test_http2_docker.py
│   │   ├── per_app_allocation/
│   │   │   ├── Dockerfile
│   │   │   ├── README.md
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── gunicorn_conf.py
│   │   │   └── test_per_app_e2e.py
│   │   ├── test_asgi_uwsgi/
│   │   │   ├── Dockerfile
│   │   │   ├── app.py
│   │   │   ├── docker-compose.yml
│   │   │   ├── nginx.conf
│   │   │   └── test_uwsgi.sh
│   │   └── uwsgi/
│   │       ├── Dockerfile.gunicorn
│   │       ├── Dockerfile.nginx
│   │       ├── README.md
│   │       ├── app.py
│   │       ├── conftest.py
│   │       ├── docker-compose.yml
│   │       ├── nginx.conf
│   │       ├── test_uwsgi_integration.py
│   │       └── uwsgi_params
│   ├── requests/
│   │   ├── invalid/
│   │   │   ├── 001.http
│   │   │   ├── 001.py
│   │   │   ├── 002.http
│   │   │   ├── 002.py
│   │   │   ├── 003.http
│   │   │   ├── 003.py
│   │   │   ├── 003b.http
│   │   │   ├── 003b.py
│   │   │   ├── 003c.http
│   │   │   ├── 003c.py
│   │   │   ├── 004.http
│   │   │   ├── 004.py
│   │   │   ├── 005.http
│   │   │   ├── 005.py
│   │   │   ├── 006.http
│   │   │   ├── 006.py
│   │   │   ├── 007.http
│   │   │   ├── 007.py
│   │   │   ├── 008.http
│   │   │   ├── 008.py
│   │   │   ├── 009.http
│   │   │   ├── 009.py
│   │   │   ├── 010.http
│   │   │   ├── 010.py
│   │   │   ├── 011.http
│   │   │   ├── 011.py
│   │   │   ├── 012.http
│   │   │   ├── 012.py
│   │   │   ├── 013.http
│   │   │   ├── 013.py
│   │   │   ├── 014.http
│   │   │   ├── 014.py
│   │   │   ├── 015.http
│   │   │   ├── 015.py
│   │   │   ├── 016.http
│   │   │   ├── 016.py
│   │   │   ├── 017.http
│   │   │   ├── 017.py
│   │   │   ├── 018.http
│   │   │   ├── 018.py
│   │   │   ├── 019.http
│   │   │   ├── 019.py
│   │   │   ├── 020.http
│   │   │   ├── 020.py
│   │   │   ├── 021.http
│   │   │   ├── 021.py
│   │   │   ├── 022.http
│   │   │   ├── 022.py
│   │   │   ├── 023.http
│   │   │   ├── 023.py
│   │   │   ├── 024.http
│   │   │   ├── 024.py
│   │   │   ├── 040.http
│   │   │   ├── 040.py
│   │   │   ├── chunked_01.http
│   │   │   ├── chunked_01.py
│   │   │   ├── chunked_02.http
│   │   │   ├── chunked_02.py
│   │   │   ├── chunked_03.http
│   │   │   ├── chunked_03.py
│   │   │   ├── chunked_04.http
│   │   │   ├── chunked_04.py
│   │   │   ├── chunked_05.http
│   │   │   ├── chunked_05.py
│   │   │   ├── chunked_06.http
│   │   │   ├── chunked_06.py
│   │   │   ├── chunked_07.http
│   │   │   ├── chunked_07.py
│   │   │   ├── chunked_08.http
│   │   │   ├── chunked_08.py
│   │   │   ├── chunked_09.http
│   │   │   ├── chunked_09.py
│   │   │   ├── chunked_10.http
│   │   │   ├── chunked_10.py
│   │   │   ├── chunked_11.http
│   │   │   ├── chunked_11.py
│   │   │   ├── chunked_12.http
│   │   │   ├── chunked_12.py
│   │   │   ├── chunked_13.http
│   │   │   ├── chunked_13.py
│   │   │   ├── invalid_field_value_01.http
│   │   │   ├── invalid_field_value_01.py
│   │   │   ├── nonascii_01.http
│   │   │   ├── nonascii_01.py
│   │   │   ├── nonascii_02.http
│   │   │   ├── nonascii_02.py
│   │   │   ├── nonascii_03.http
│   │   │   ├── nonascii_03.py
│   │   │   ├── nonascii_04.http
│   │   │   ├── nonascii_04.py
│   │   │   ├── obs_fold_01.http
│   │   │   ├── obs_fold_01.py
│   │   │   ├── pp_01.http
│   │   │   ├── pp_01.py
│   │   │   ├── pp_02.http
│   │   │   ├── pp_02.py
│   │   │   ├── prefix_01.http
│   │   │   ├── prefix_01.py
│   │   │   ├── prefix_02.http
│   │   │   ├── prefix_02.py
│   │   │   ├── prefix_03.http
│   │   │   ├── prefix_03.py
│   │   │   ├── prefix_04.http
│   │   │   ├── prefix_04.py
│   │   │   ├── prefix_05.http
│   │   │   ├── prefix_05.py
│   │   │   ├── prefix_06.http
│   │   │   ├── prefix_06.py
│   │   │   ├── version_01.http
│   │   │   ├── version_01.py
│   │   │   ├── version_02.http
│   │   │   └── version_02.py
│   │   └── valid/
│   │       ├── 001.http
│   │       ├── 001.py
│   │       ├── 002.http
│   │       ├── 002.py
│   │       ├── 003.http
│   │       ├── 003.py
│   │       ├── 004.http
│   │       ├── 004.py
│   │       ├── 005.http
│   │       ├── 005.py
│   │       ├── 006.http
│   │       ├── 006.py
│   │       ├── 007.http
│   │       ├── 007.py
│   │       ├── 008.http
│   │       ├── 008.py
│   │       ├── 009.http
│   │       ├── 009.py
│   │       ├── 010.http
│   │       ├── 010.py
│   │       ├── 011.http
│   │       ├── 011.py
│   │       ├── 012.http
│   │       ├── 012.py
│   │       ├── 013.http
│   │       ├── 013.py
│   │       ├── 014.http
│   │       ├── 014.py
│   │       ├── 015.http
│   │       ├── 015.py
│   │       ├── 017.http
│   │       ├── 017.py
│   │       ├── 018.http
│   │       ├── 018.py
│   │       ├── 019.http
│   │       ├── 019.py
│   │       ├── 020.http
│   │       ├── 020.py
│   │       ├── 021.http
│   │       ├── 021.py
│   │       ├── 022.http
│   │       ├── 022.py
│   │       ├── 023.http
│   │       ├── 023.py
│   │       ├── 024.http
│   │       ├── 024.py
│   │       ├── 025.http
│   │       ├── 025.py
│   │       ├── 025_line.http
│   │       ├── 025_line.py
│   │       ├── 026.http
│   │       ├── 026.py
│   │       ├── 027.http
│   │       ├── 027.py
│   │       ├── 028.http
│   │       ├── 028.py
│   │       ├── 029.http
│   │       ├── 029.py
│   │       ├── 030.http
│   │       ├── 030.py
│   │       ├── 031.http
│   │       ├── 031.py
│   │       ├── 031compat.http
│   │       ├── 031compat.py
│   │       ├── 031compat2.http
│   │       ├── 031compat2.py
│   │       ├── 040.http
│   │       ├── 040.py
│   │       ├── 040_compat.http
│   │       ├── 040_compat.py
│   │       ├── 099.http
│   │       ├── 099.py
│   │       ├── 100.http
│   │       ├── 100.py
│   │       ├── compat_obs_fold.http
│   │       ├── compat_obs_fold.py
│   │       ├── compat_obs_fold_huge.http
│   │       ├── compat_obs_fold_huge.py
│   │       ├── padding_01.http
│   │       ├── padding_01.py
│   │       ├── pp_01.http
│   │       ├── pp_01.py
│   │       ├── pp_02.http
│   │       ├── pp_02.py
│   │       ├── pp_03.http
│   │       ├── pp_03.py
│   │       ├── pp_04.http
│   │       ├── pp_04.py
│   │       ├── pp_05.http
│   │       └── pp_05.py
│   ├── support.py
│   ├── support_dirty_app.py
│   ├── support_dirty_apps.py
│   ├── t.py
│   ├── test_arbiter.py
│   ├── test_asgi.py
│   ├── test_asgi_compliance.py
│   ├── test_asgi_disconnect.py
│   ├── test_asgi_http_scope.py
│   ├── test_asgi_parser.py
│   ├── test_asgi_streaming.py
│   ├── test_asgi_uwsgi.py
│   ├── test_asgi_websocket_protocol.py
│   ├── test_asgi_worker.py
│   ├── test_config.py
│   ├── test_control_socket_integration.py
│   ├── test_dirty_app.py
│   ├── test_dirty_arbiter.py
│   ├── test_dirty_client.py
│   ├── test_dirty_config.py
│   ├── test_dirty_errors.py
│   ├── test_dirty_hooks.py
│   ├── test_dirty_integration.py
│   ├── test_dirty_protocol.py
│   ├── test_dirty_stash.py
│   ├── test_dirty_tlv.py
│   ├── test_dirty_worker.py
│   ├── test_early_hints.py
│   ├── test_gthread.py
│   ├── test_gtornado.py
│   ├── test_http.py
│   ├── test_http2_alpn.py
│   ├── test_http2_async_connection.py
│   ├── test_http2_config.py
│   ├── test_http2_connection.py
│   ├── test_http2_errors.py
│   ├── test_http2_integration.py
│   ├── test_http2_request.py
│   ├── test_http2_stream.py
│   ├── test_invalid_requests.py
│   ├── test_logger.py
│   ├── test_pidfile.py
│   ├── test_reload.py
│   ├── test_signal_integration.py
│   ├── test_sock.py
│   ├── test_ssl.py
│   ├── test_statsd.py
│   ├── test_systemd.py
│   ├── test_util.py
│   ├── test_uwsgi.py
│   ├── test_valid_requests.py
│   ├── treq.py
│   └── workers/
│       ├── __init__.py
│       ├── test_gevent_import_order.py
│       ├── test_geventlet.py
│       └── test_ggevent.py
└── tox.ini
Download .txt
Showing preview only (372K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (4532 symbols across 217 files)

FILE: benchmarks/dirty_bench_app.py
  class BenchmarkApp (line 20) | class BenchmarkApp(DirtyApp):
    method init (line 28) | def init(self):
    method sleep_task (line 34) | def sleep_task(self, duration_ms):
    method cpu_task (line 52) | def cpu_task(self, duration_ms, intensity=1.0):
    method mixed_task (line 92) | def mixed_task(self, sleep_ms, cpu_ms, intensity=1.0):
    method payload_task (line 138) | def payload_task(self, size_bytes, duration_ms=0):
    method echo_task (line 169) | def echo_task(self, payload):
    method stats (line 197) | def stats(self):
    method reset_stats (line 210) | def reset_stats(self):
    method health (line 217) | def health(self):
    method close (line 221) | def close(self):

FILE: benchmarks/dirty_bench_gunicorn.py
  function on_dirty_starting (line 42) | def on_dirty_starting(arbiter):
  function dirty_post_fork (line 47) | def dirty_post_fork(arbiter, worker):
  function dirty_worker_init (line 52) | def dirty_worker_init(worker):
  function dirty_worker_exit (line 58) | def dirty_worker_exit(arbiter, worker):

FILE: benchmarks/dirty_bench_wsgi.py
  function app (line 29) | def app(environ, start_response):
  function post_fork (line 165) | def post_fork(server, worker):

FILE: benchmarks/dirty_benchmark.py
  class LatencyStats (line 67) | class LatencyStats:
    method from_samples (line 78) | def from_samples(cls, samples: list[float]) -> "LatencyStats":
  class BenchmarkResult (line 98) | class BenchmarkResult:
    method to_dict (line 110) | def to_dict(self) -> dict:
  class MockConfig (line 117) | class MockConfig:
    method __init__ (line 120) | def __init__(
    method on_dirty_starting (line 146) | def on_dirty_starting(self, arbiter):
    method dirty_post_fork (line 149) | def dirty_post_fork(self, arbiter, worker):
    method dirty_worker_init (line 152) | def dirty_worker_init(self, worker):
    method dirty_worker_exit (line 155) | def dirty_worker_exit(self, arbiter, worker):
  class MockLogger (line 159) | class MockLogger:
    method __init__ (line 162) | def __init__(self, verbose: bool = False):
    method debug (line 165) | def debug(self, msg, *args):
    method info (line 169) | def info(self, msg, *args):
    method warning (line 173) | def warning(self, msg, *args):
    method error (line 176) | def error(self, msg, *args):
    method critical (line 179) | def critical(self, msg, *args):
    method exception (line 182) | def exception(self, msg, *args):
    method reopen_files (line 185) | def reopen_files(self):
    method close_on_exec (line 188) | def close_on_exec(self):
  class IsolatedBenchmark (line 192) | class IsolatedBenchmark:
    method __init__ (line 200) | def __init__(
    method start (line 217) | def start(self):
    method stop (line 258) | def stop(self):
    method warmup (line 278) | def warmup(self, requests: int = 10):
    method run_benchmark (line 284) | def run_benchmark(
  class IntegratedBenchmark (line 370) | class IntegratedBenchmark:
    method __init__ (line 377) | def __init__(
    method check_dependencies (line 386) | def check_dependencies(self) -> str | None:
    method warmup (line 397) | def warmup(self, requests: int = 10):
    method run_wrk (line 406) | def run_wrk(
    method _parse_wrk_output (line 428) | def _parse_wrk_output(self, output: str) -> dict:
    method _parse_duration (line 471) | def _parse_duration(self, s: str) -> float:
    method run_python_benchmark (line 483) | def run_python_benchmark(
  function run_isolated_suite (line 525) | def run_isolated_suite(
  function run_payload_suite (line 647) | def run_payload_suite(
  function run_quick_test (line 723) | def run_quick_test(verbose: bool = False) -> list[BenchmarkResult]:
  function run_config_sweep (line 773) | def run_config_sweep(verbose: bool = False) -> list[BenchmarkResult]:
  function generate_report (line 853) | def generate_report(results: list[BenchmarkResult], output_path: str = N...
  function main (line 891) | def main():

FILE: benchmarks/dirty_streaming.py
  class MockStreamWriter (line 52) | class MockStreamWriter:
    method __init__ (line 55) | def __init__(self):
    method write (line 60) | def write(self, data):
    method drain (line 64) | async def drain(self):
    method close (line 78) | def close(self):
    method wait_closed (line 81) | async def wait_closed(self):
  class MockStreamReader (line 85) | class MockStreamReader:
    method __init__ (line 88) | def __init__(self, messages):
    method readexactly (line 94) | async def readexactly(self, n):
  class MockLog (line 102) | class MockLog:
    method debug (line 105) | def debug(self, msg, *args):
    method info (line 108) | def info(self, msg, *args):
    method warning (line 111) | def warning(self, msg, *args):
    method error (line 114) | def error(self, msg, *args):
    method close_on_exec (line 117) | def close_on_exec(self):
    method reopen_files (line 120) | def reopen_files(self):
  function create_worker (line 124) | def create_worker():
  function create_arbiter (line 147) | def create_arbiter():
  class BenchmarkResults (line 161) | class BenchmarkResults:
    method __init__ (line 164) | def __init__(self):
    method add (line 167) | def add(self, name, iterations, duration, chunks=None, bytes_total=None,
    method display (line 186) | def display(self):
    method save_json (line 198) | def save_json(self, filepath):
  function benchmark_worker_streaming_throughput (line 207) | async def benchmark_worker_streaming_throughput(results, chunk_size=1024...
  function benchmark_arbiter_forwarding (line 248) | async def benchmark_arbiter_forwarding(results, num_chunks=1000):
  function benchmark_streaming_latency (line 285) | async def benchmark_streaming_latency(results, iterations=100):
  function benchmark_concurrent_streams (line 330) | async def benchmark_concurrent_streams(results, num_streams=10, chunks_p...
  function benchmark_memory_stability (line 372) | async def benchmark_memory_stability(results, iterations=10, chunks=1000):
  class MockClientReader (line 418) | class MockClientReader:
    method __init__ (line 421) | def __init__(self, num_chunks, chunk_data):
    method _build_messages (line 432) | def _build_messages(self):
    method readexactly (line 437) | async def readexactly(self, n):
  class MockClientWriter (line 445) | class MockClientWriter:
    method __init__ (line 448) | def __init__(self):
    method write (line 452) | def write(self, data):
    method drain (line 455) | async def drain(self):
    method close (line 458) | def close(self):
    method wait_closed (line 461) | async def wait_closed(self):
  function benchmark_async_client_streaming (line 465) | async def benchmark_async_client_streaming(results, chunk_size=1024, num...
  function benchmark_sync_client_streaming (line 512) | async def benchmark_sync_client_streaming(results, chunk_size=1024, num_...
  function benchmark_async_vs_sync_client_streaming (line 582) | async def benchmark_async_vs_sync_client_streaming(results, chunk_size=1...
  function run_quick_benchmarks (line 674) | async def run_quick_benchmarks():
  function run_full_benchmarks (line 692) | async def run_full_benchmarks():
  function main (line 728) | def main():

FILE: benchmarks/run_benchmark.py
  function check_dependencies (line 27) | def check_dependencies():
  function start_gunicorn (line 42) | def start_gunicorn(worker_class, workers, threads, connections, bind, ex...
  function stop_gunicorn (line 75) | def stop_gunicorn(proc):
  function run_wrk_benchmark (line 85) | def run_wrk_benchmark(url, duration, threads, connections):
  function run_ab_benchmark (line 99) | def run_ab_benchmark(url, requests, concurrency):
  function parse_wrk_output (line 112) | def parse_wrk_output(output):
  function parse_ab_output (line 131) | def parse_ab_output(output):
  function run_benchmark_suite (line 144) | def run_benchmark_suite(tool, bind_addr):
  function main (line 180) | def main():

FILE: benchmarks/simple_app.py
  function application (line 7) | def application(environ, start_response):

FILE: docs/content/assets/javascripts/toc-collapse.js
  function initCollapsibleTOC (line 3) | function initCollapsibleTOC() {

FILE: docs/macros.py
  function define_env (line 7) | def define_env(env):

FILE: examples/alt_spec.py
  function load (line 17) | def load(arg):

FILE: examples/asgi/basic_app.py
  function app (line 18) | async def app(scope, receive, send):
  function handle_lifespan (line 29) | async def handle_lifespan(scope, receive, send):
  function handle_http (line 42) | async def handle_http(scope, receive, send):
  function send_response (line 71) | async def send_response(send, status, body, content_type=b"text/plain"):
  function read_body (line 87) | async def read_body(receive):
  function get_query_param (line 98) | def get_query_param(scope, name, default=None):
  function format_headers (line 109) | def format_headers(headers):
  function format_request_info (line 117) | def format_request_info(scope):

FILE: examples/asgi/websocket_app.py
  function app (line 28) | async def app(scope, receive, send):
  function handle_lifespan (line 41) | async def handle_lifespan(scope, receive, send):
  function handle_http (line 52) | async def handle_http(scope, receive, send):
  function handle_websocket (line 82) | async def handle_websocket(scope, receive, send):
  function echo_websocket (line 95) | async def echo_websocket(scope, receive, send):
  function chat_websocket (line 135) | async def chat_websocket(scope, receive, send):

FILE: examples/bad.py
  function app (line 7) | def app(environ, start_response):

FILE: examples/boot_fail.py
  function app (line 7) | def app(environ, start_response):

FILE: examples/celery_alternative/app.py
  function lifespan (line 39) | async def lifespan(app: FastAPI):
  class EmailRequest (line 55) | class EmailRequest(BaseModel):
  class BulkEmailRequest (line 62) | class BulkEmailRequest(BaseModel):
  class ImageResizeRequest (line 68) | class ImageResizeRequest(BaseModel):
  class ThumbnailRequest (line 74) | class ThumbnailRequest(BaseModel):
  class ImageBatchRequest (line 79) | class ImageBatchRequest(BaseModel):
  class AggregateRequest (line 87) | class AggregateRequest(BaseModel):
  class ETLRequest (line 94) | class ETLRequest(BaseModel):
  class QueryRequest (line 99) | class QueryRequest(BaseModel):
  class CleanupRequest (line 104) | class CleanupRequest(BaseModel):
  class SyncRequest (line 109) | class SyncRequest(BaseModel):
  function send_email (line 118) | async def send_email(data: EmailRequest):
  function send_bulk_emails (line 146) | async def send_bulk_emails(data: BulkEmailRequest):
  function email_stats (line 182) | async def email_stats():
  function resize_image (line 197) | async def resize_image(data: ImageResizeRequest):
  function generate_thumbnail (line 219) | async def generate_thumbnail(data: ThumbnailRequest):
  function process_image_batch (line 235) | async def process_image_batch(data: ImageBatchRequest):
  function image_stats (line 262) | async def image_stats():
  function aggregate_data (line 277) | async def aggregate_data(data: AggregateRequest):
  function run_etl (line 300) | async def run_etl(data: ETLRequest):
  function cached_query (line 327) | async def cached_query(data: QueryRequest):
  function data_stats (line 343) | async def data_stats():
  function run_cleanup (line 358) | async def run_cleanup(data: CleanupRequest = CleanupRequest()):
  function run_daily_report (line 374) | async def run_daily_report():
  function run_sync (line 385) | async def run_sync(data: SyncRequest = SyncRequest()):
  function scheduled_stats (line 400) | async def scheduled_stats():
  function index (line 415) | async def index():
  function health (line 450) | async def health():

FILE: examples/celery_alternative/gunicorn_conf.py
  function on_starting (line 107) | def on_starting(server):
  function on_dirty_starting (line 115) | def on_dirty_starting(arbiter):
  function dirty_post_fork (line 121) | def dirty_post_fork(arbiter, worker):
  function dirty_worker_init (line 126) | def dirty_worker_init(worker):
  function dirty_worker_exit (line 131) | def dirty_worker_exit(arbiter, worker):
  function worker_int (line 136) | def worker_int(worker):
  function worker_exit (line 141) | def worker_exit(server, worker):

FILE: examples/celery_alternative/tasks.py
  class EmailWorker (line 37) | class EmailWorker(DirtyApp):
    method __init__ (line 48) | def __init__(self):
    method init (line 53) | def init(self):
    method _connect_smtp (line 57) | def _connect_smtp(self):
    method __call__ (line 66) | def __call__(self, action: str, *args, **kwargs) -> Any:
    method send_email (line 73) | def send_email(self, to: str, subject: str, body: str,
    method send_bulk_emails (line 96) | def send_bulk_emails(self, recipients: list, subject: str,
    method stats (line 148) | def stats(self) -> dict:
    method close (line 157) | def close(self):
  class ImageWorker (line 163) | class ImageWorker(DirtyApp):
    method __init__ (line 174) | def __init__(self):
    method init (line 178) | def init(self):
    method __call__ (line 187) | def __call__(self, action: str, *args, **kwargs) -> Any:
    method resize (line 193) | def resize(self, image_data: str, width: int, height: int) -> dict:
    method generate_thumbnail (line 224) | def generate_thumbnail(self, image_data: str, size: int = 150) -> dict:
    method process_batch (line 228) | def process_batch(self, images: list, operation: str,
    method stats (line 277) | def stats(self) -> dict:
  class DataWorker (line 285) | class DataWorker(DirtyApp):
    method __init__ (line 296) | def __init__(self):
    method init (line 301) | def init(self):
    method __call__ (line 307) | def __call__(self, action: str, *args, **kwargs) -> Any:
    method aggregate (line 313) | def aggregate(self, data: list, group_by: str,
    method etl_pipeline (line 355) | def etl_pipeline(self, source_data: list,
    method cached_query (line 429) | def cached_query(self, query_key: str, ttl: int = 300) -> dict:
    method stats (line 469) | def stats(self) -> dict:
    method close (line 477) | def close(self):
  class ScheduledWorker (line 484) | class ScheduledWorker(DirtyApp):
    method __init__ (line 494) | def __init__(self):
    method __call__ (line 498) | def __call__(self, action: str, *args, **kwargs) -> Any:
    method cleanup_old_files (line 509) | def cleanup_old_files(self, directory: str, max_age_days: int = 7) -> ...
    method generate_daily_report (line 537) | def generate_daily_report(self) -> dict:
    method sync_external_data (line 551) | def sync_external_data(self, source: str) -> dict:
    method stats (line 562) | def stats(self) -> dict:

FILE: examples/celery_alternative/tests/test_integration.py
  function read_sse_events (line 30) | def read_sse_events(response, max_events=100):
  function wait_for_app (line 48) | def wait_for_app(timeout=30):
  function ensure_app_running (line 63) | def ensure_app_running():
  class TestHealthEndpoint (line 69) | class TestHealthEndpoint:
    method test_health_check (line 72) | def test_health_check(self):
  class TestEmailTasks (line 82) | class TestEmailTasks:
    method test_send_single_email (line 85) | def test_send_single_email(self):
    method test_send_bulk_emails_streaming (line 102) | def test_send_bulk_emails_streaming(self):
    method test_email_stats (line 131) | def test_email_stats(self):
  class TestImageTasks (line 148) | class TestImageTasks:
    method test_resize_image (line 151) | def test_resize_image(self):
    method test_generate_thumbnail (line 167) | def test_generate_thumbnail(self):
    method test_batch_processing_streaming (line 182) | def test_batch_processing_streaming(self):
    method test_image_stats (line 206) | def test_image_stats(self):
  class TestDataTasks (line 216) | class TestDataTasks:
    method test_aggregate_data (line 219) | def test_aggregate_data(self):
    method test_etl_pipeline_streaming (line 241) | def test_etl_pipeline_streaming(self):
    method test_cached_query (line 275) | def test_cached_query(self):
    method test_data_stats (line 302) | def test_data_stats(self):
  class TestScheduledTasks (line 312) | class TestScheduledTasks:
    method test_cleanup_task (line 315) | def test_cleanup_task(self):
    method test_daily_report (line 327) | def test_daily_report(self):
    method test_sync_task (line 336) | def test_sync_task(self):
    method test_scheduled_stats (line 348) | def test_scheduled_stats(self):
  class TestConcurrency (line 361) | class TestConcurrency:
    method test_concurrent_requests (line 364) | def test_concurrent_requests(self):
    method test_mixed_task_types (line 383) | def test_mixed_task_types(self):
  class TestErrorHandling (line 423) | class TestErrorHandling:
    method test_invalid_action (line 426) | def test_invalid_action(self):

FILE: examples/celery_alternative/tests/test_tasks.py
  class TestEmailWorker (line 21) | class TestEmailWorker:
    method setup_method (line 24) | def setup_method(self):
    method test_send_email (line 29) | def test_send_email(self):
    method test_send_email_increments_counter (line 42) | def test_send_email_increments_counter(self):
    method test_send_bulk_emails_streaming (line 51) | def test_send_bulk_emails_streaming(self):
    method test_stats (line 75) | def test_stats(self):
    method test_unknown_action_raises (line 85) | def test_unknown_action_raises(self):
    method test_private_method_raises (line 90) | def test_private_method_raises(self):
  class TestImageWorker (line 96) | class TestImageWorker:
    method setup_method (line 99) | def setup_method(self):
    method test_resize_image (line 104) | def test_resize_image(self):
    method test_generate_thumbnail (line 115) | def test_generate_thumbnail(self):
    method test_process_batch_streaming (line 124) | def test_process_batch_streaming(self):
    method test_stats (line 151) | def test_stats(self):
  class TestDataWorker (line 162) | class TestDataWorker:
    method setup_method (line 165) | def setup_method(self):
    method test_aggregate_sum (line 170) | def test_aggregate_sum(self):
    method test_aggregate_count (line 188) | def test_aggregate_count(self):
    method test_etl_pipeline_streaming (line 205) | def test_etl_pipeline_streaming(self):
    method test_cached_query_miss_then_hit (line 237) | def test_cached_query_miss_then_hit(self):
    method test_stats (line 247) | def test_stats(self):
  class TestScheduledWorker (line 261) | class TestScheduledWorker:
    method setup_method (line 264) | def setup_method(self):
    method test_cleanup_old_files (line 268) | def test_cleanup_old_files(self):
    method test_generate_daily_report (line 279) | def test_generate_daily_report(self):
    method test_sync_external_data (line 290) | def test_sync_external_data(self):
    method test_stats_tracks_runs (line 298) | def test_stats_tracks_runs(self):

FILE: examples/deep/test.py
  function app (line 13) | def app(environ, start_response):

FILE: examples/dirty_example/dirty_app.py
  class MLApp (line 21) | class MLApp(DirtyApp):
    method __init__ (line 32) | def __init__(self):
    method init (line 37) | def init(self):
    method __call__ (line 44) | def __call__(self, action, *args, **kwargs):
    method _load_model (line 51) | def _load_model(self, name):
    method load_model (line 67) | def load_model(self, name):
    method list_models (line 75) | def list_models(self):
    method inference (line 84) | def inference(self, model_name, input_data):
    method unload_model (line 104) | def unload_model(self, name):
    method close (line 112) | def close(self):
  class ComputeApp (line 118) | class ComputeApp(DirtyApp):
    method __init__ (line 126) | def __init__(self):
    method init (line 129) | def init(self):
    method __call__ (line 132) | def __call__(self, action, *args, **kwargs):
    method fibonacci (line 138) | def fibonacci(self, n):
    method prime_check (line 151) | def prime_check(self, n):
    method stats (line 170) | def stats(self):
    method close (line 174) | def close(self):
  class SessionApp (line 178) | class SessionApp(DirtyApp):
    method __init__ (line 189) | def __init__(self):
    method init (line 192) | def init(self):
    method __call__ (line 199) | def __call__(self, action, *args, **kwargs):
    method login (line 205) | def login(self, user_id, user_data):
    method logout (line 217) | def logout(self, user_id):
    method get_session (line 226) | def get_session(self, user_id):
    method list_sessions (line 235) | def list_sessions(self):
    method get_stats (line 248) | def get_stats(self):
    method _increment_counter (line 256) | def _increment_counter(self):
    method clear_all (line 261) | def clear_all(self):
    method close (line 267) | def close(self):

FILE: examples/dirty_example/gunicorn_conf.py
  function on_starting (line 38) | def on_starting(server):
  function when_ready (line 42) | def when_ready(server):
  function on_dirty_starting (line 49) | def on_dirty_starting(arbiter):
  function dirty_post_fork (line 53) | def dirty_post_fork(arbiter, worker):
  function dirty_worker_init (line 57) | def dirty_worker_init(worker):
  function dirty_worker_exit (line 61) | def dirty_worker_exit(arbiter, worker):

FILE: examples/dirty_example/test_dirty_app.py
  function test_ml_app (line 24) | def test_ml_app():
  function test_compute_app (line 80) | def test_compute_app():
  function test_error_handling (line 116) | def test_error_handling():

FILE: examples/dirty_example/test_integration.py
  function test_endpoint (line 25) | def test_endpoint(base, path, expected_key=None):
  function main (line 45) | def main():

FILE: examples/dirty_example/test_protocol.py
  function test_protocol_encode_decode (line 36) | def test_protocol_encode_decode():
  function test_binary_data_handling (line 76) | def test_binary_data_handling():
  function test_protocol_response (line 102) | def test_protocol_response():
  function test_socket_communication (line 120) | def test_socket_communication():
  function test_async_communication (line 166) | async def test_async_communication():
  function test_error_serialization (line 210) | def test_error_serialization():

FILE: examples/dirty_example/test_stash_integration.py
  function request (line 26) | def request(path):
  function test_stash_shared_state (line 38) | def test_stash_shared_state():
  function test_stash_counter (line 69) | def test_stash_counter():
  function test_stash_list_sessions (line 96) | def test_stash_list_sessions():
  function test_stash_logout (line 120) | def test_stash_logout():
  function test_multiple_workers_see_updates (line 145) | def test_multiple_workers_see_updates():
  function main (line 173) | def main():

FILE: examples/dirty_example/test_worker_integration.py
  class MockLog (line 28) | class MockLog:
    method debug (line 30) | def debug(self, msg, *args): print(f"[DEBUG] {msg % args if args else ...
    method info (line 31) | def info(self, msg, *args): print(f"[INFO] {msg % args if args else ms...
    method warning (line 32) | def warning(self, msg, *args): print(f"[WARN] {msg % args if args else...
    method error (line 33) | def error(self, msg, *args): print(f"[ERROR] {msg % args if args else ...
    method close_on_exec (line 34) | def close_on_exec(self): pass
    method reopen_files (line 35) | def reopen_files(self): pass
  class MockWriter (line 38) | class MockWriter:
    method __init__ (line 41) | def __init__(self):
    method write (line 45) | def write(self, data):
    method drain (line 48) | async def drain(self):
    method get_last_response (line 63) | def get_last_response(self):
  function test_worker_request_handling (line 68) | async def test_worker_request_handling():
  function test_worker_with_compute_app (line 171) | async def test_worker_with_compute_app():
  function test_multiple_apps (line 217) | async def test_multiple_apps():

FILE: examples/dirty_example/wsgi_app.py
  function get_dirty_client (line 21) | def get_dirty_client():
  function app (line 30) | def app(environ, start_response):

FILE: examples/echo.py
  function app (line 10) | def app(environ, start_response):

FILE: examples/embedding_service/embedding_app.py
  class EmbeddingApp (line 8) | class EmbeddingApp(DirtyApp):
    method init (line 9) | def init(self):
    method embed (line 13) | def embed(self, texts):
    method close (line 17) | def close(self):

FILE: examples/embedding_service/main.py
  class EmbedRequest (line 12) | class EmbedRequest(BaseModel):
  class EmbedResponse (line 16) | class EmbedResponse(BaseModel):
  function embed (line 21) | async def embed(request: EmbedRequest):
  function health (line 32) | async def health():

FILE: examples/embedding_service/test_embedding.py
  function test_embedding_endpoint (line 10) | def test_embedding_endpoint():

FILE: examples/example_config.py
  function post_fork (line 190) | def post_fork(server, worker):
  function pre_fork (line 193) | def pre_fork(server, worker):
  function pre_exec (line 196) | def pre_exec(server):
  function when_ready (line 199) | def when_ready(server):
  function worker_int (line 202) | def worker_int(worker):
  function worker_abort (line 219) | def worker_abort(worker):
  function ssl_context (line 222) | def ssl_context(conf, default_ssl_context_factory):

FILE: examples/frameworks/cherryapp.py
  class Root (line 8) | class Root:
    method index (line 10) | def index(self):

FILE: examples/frameworks/django/testing/testing/apps/someapp/middleware.py
  function child_process (line 9) | def child_process(queue):
  class GunicornSubProcessTestMiddleware (line 15) | class GunicornSubProcessTestMiddleware:
    method __init__ (line 16) | def __init__(self):
    method process_request (line 22) | def process_request(self, request):
    method process_response (line 25) | def process_response(self, request, response):

FILE: examples/frameworks/django/testing/testing/apps/someapp/tests.py
  class SimpleTest (line 14) | class SimpleTest(TestCase):
    method test_basic_addition (line 15) | def test_basic_addition(self):

FILE: examples/frameworks/django/testing/testing/apps/someapp/views.py
  class MsgForm (line 14) | class MsgForm(forms.Form):
  function home (line 20) | def home(request):
  function acsv (line 55) | def acsv(request):

FILE: examples/frameworks/flask_sendfile.py
  function index (line 12) | def index():

FILE: examples/frameworks/flaskapp.py
  function hello (line 14) | def hello():

FILE: examples/frameworks/flaskapp_aiohttp_wsgi.py
  function hello (line 18) | def hello():
  function make_aiohttp_app (line 22) | def make_aiohttp_app(app):

FILE: examples/frameworks/pyramidapp.py
  function hello_world (line 8) | def hello_world(request):
  function goodbye_world (line 11) | def goodbye_world(request):

FILE: examples/frameworks/tornadoapp.py
  class MainHandler (line 15) | class MainHandler(tornado.web.RequestHandler):
    method get (line 16) | async def get(self):
  function make_app (line 22) | def make_app():

FILE: examples/frameworks/webpyapp.py
  class index (line 16) | class index:
    method GET (line 17) | def GET(self):

FILE: examples/http2_features/http2_app.py
  function app (line 29) | async def app(scope, receive, send):
  function handle_lifespan (line 40) | async def handle_lifespan(scope, receive, send):
  function handle_http (line 53) | async def handle_http(scope, receive, send):
  function handle_index (line 72) | async def handle_index(scope, receive, send):
  function handle_priority (line 94) | async def handle_priority(scope, receive, send):
  function handle_trailers (line 127) | async def handle_trailers(scope, receive, send):
  function handle_combined (line 188) | async def handle_combined(scope, receive, send):
  function send_response (line 242) | async def send_response(send, status, body, content_type=b"text/plain", ...
  function read_body (line 262) | async def read_body(receive):

FILE: examples/http2_features/test_http2.py
  function create_h2_connection (line 32) | def create_h2_connection(host, port):
  function h2_request (line 71) | def h2_request(sock, h2_conn, stream_id, method, path, authority):
  function test_http2_connection (line 133) | def test_http2_connection(host, port):
  function test_priority (line 154) | def test_priority(host, port):
  function test_trailers (line 178) | def test_trailers(host, port):
  function test_combined (line 203) | def test_combined(host, port):
  function test_multiple_streams (line 226) | def test_multiple_streams(host, port):
  function main (line 247) | def main():

FILE: examples/http2_gevent/app.py
  function app (line 19) | def app(environ, start_response):

FILE: examples/http2_gevent/gunicorn_conf.py
  function on_starting (line 65) | def on_starting(server):
  function when_ready (line 72) | def when_ready(server):
  function worker_int (line 77) | def worker_int(worker):
  function worker_abort (line 82) | def worker_abort(worker):

FILE: examples/http2_gevent/test_http2_gevent.py
  function check_server_available (line 30) | def check_server_available(host='localhost', port=8443, timeout=30):
  class TestHTTP2Gevent (line 46) | class TestHTTP2Gevent:
    method setup_class (line 52) | def setup_class(cls):
    method get_client (line 59) | def get_client(self):
    method test_root_endpoint (line 64) | def test_root_endpoint(self):
    method test_health_endpoint (line 73) | def test_health_endpoint(self):
    method test_echo_post (line 81) | def test_echo_post(self):
    method test_echo_large_body (line 90) | def test_echo_large_body(self):
    method test_info_endpoint (line 101) | def test_info_endpoint(self):
    method test_large_response (line 112) | def test_large_response(self):
    method test_streaming_response (line 121) | def test_streaming_response(self):
    method test_delay_endpoint (line 130) | def test_delay_endpoint(self):
    method test_not_found (line 141) | def test_not_found(self):
    method test_gevent_worker_header (line 148) | def test_gevent_worker_header(self):
  class TestHTTP2Concurrency (line 157) | class TestHTTP2Concurrency:
    method setup_class (line 163) | def setup_class(cls):
    method test_concurrent_requests_sync (line 168) | def test_concurrent_requests_sync(self):
  class TestHTTP2ConcurrencyAsync (line 187) | class TestHTTP2ConcurrencyAsync:
    method setup_class (line 193) | def setup_class(cls):
    method test_async_concurrent_requests (line 198) | def test_async_concurrent_requests(self):
    method test_async_multiple_streams (line 218) | def test_async_multiple_streams(self):
  function run_basic_test (line 245) | def run_basic_test():

FILE: examples/log_app.py
  function app_factory (line 11) | def app_factory(global_options, **local_options):
  function app (line 14) | def app(environ, start_response):

FILE: examples/longpoll.py
  class TestIter (line 9) | class TestIter:
    method __iter__ (line 11) | def __iter__(self):
  function app (line 17) | def app(environ, start_response):

FILE: examples/multiapp.py
  class Application (line 27) | class Application:
    method __init__ (line 28) | def __init__(self):
    method __call__ (line 33) | def __call__(self, environ, start_response):
    method error404 (line 39) | def error404(self, environ, start_response):

FILE: examples/multidomainapp.py
  class SubDomainApp (line 7) | class SubDomainApp:
    method __init__ (line 10) | def __init__(self, mapping):
    method __call__ (line 13) | def __call__(self, environ, start_response):
  function hello (line 24) | def hello(environ, start_response):
  function bye (line 28) | def bye(environ, start_response):

FILE: examples/readline_app.py
  function app (line 22) | def app(environ, start_response):

FILE: examples/sendfile.py
  function app (line 12) | def app(environ, start_response):

FILE: examples/slowclient.py
  function app (line 9) | def app(environ, start_response):

FILE: examples/standalone_app.py
  function number_of_workers (line 19) | def number_of_workers():
  function handler_app (line 23) | def handler_app(environ, start_response):
  class StandaloneApplication (line 36) | class StandaloneApplication(gunicorn.app.base.BaseApplication):
    method __init__ (line 38) | def __init__(self, app, options=None):
    method load_config (line 43) | def load_config(self):
    method load (line 49) | def load(self):

FILE: examples/streaming_chat/chat_app.py
  class ChatApp (line 10) | class ChatApp(DirtyApp):
    method init (line 18) | def init(self):
    method generate (line 64) | def generate(self, prompt):
    method generate_with_thinking (line 90) | def generate_with_thinking(self, prompt):
    method _get_response (line 112) | def _get_response(self, prompt):
    method close (line 134) | def close(self):

FILE: examples/streaming_chat/main.py
  class ChatRequest (line 18) | class ChatRequest(BaseModel):
  class ChatResponse (line 23) | class ChatResponse(BaseModel):
  function chat (line 28) | async def chat(request: ChatRequest):
  function chat_sync (line 65) | async def chat_sync(request: ChatRequest):
  function health (line 92) | async def health():
  function index (line 98) | async def index():

FILE: examples/streaming_chat/test_streaming.py
  function test_health_endpoint (line 12) | def test_health_endpoint():
  function test_streaming_chat (line 21) | def test_streaming_chat():
  function test_sync_chat (line 54) | def test_sync_chat():
  function test_thinking_mode (line 70) | def test_thinking_mode():
  function test_different_prompts (line 98) | def test_different_prompts():
  function test_sse_format (line 120) | def test_sse_format():

FILE: examples/test.py
  function app (line 13) | def app(environ, start_response):

FILE: examples/timeout.py
  function app (line 9) | def app(environ, start_response):

FILE: examples/websocket/gevent_websocket.py
  class WebSocketWSGI (line 23) | class WebSocketWSGI:
    method __init__ (line 24) | def __init__(self, handler):
    method verify_client (line 27) | def verify_client(self, ws):
    method _get_key_value (line 30) | def _get_key_value(self, key_value):
    method __call__ (line 40) | def __call__(self, environ, start_response):
  class WebSocket (line 124) | class WebSocket:
    method __init__ (line 143) | def __init__(self, sock, environ, version=76):
    method encode_hybi (line 162) | def encode_hybi(buf, opcode, base64=False):
    method decode_hybi (line 191) | def decode_hybi(buf, base64=False):
    method _pack_message (line 293) | def _pack_message(message):
    method _parse_messages (line 303) | def _parse_messages(self):
    method send (line 354) | def send(self, message):
    method wait (line 373) | def wait(self):
    method _send_closing_frame (line 393) | def _send_closing_frame(self, ignore_send_errors=False):
    method close (line 414) | def close(self):
  function handle (line 425) | def handle(ws):
  function app (line 441) | def app(environ, start_response):

FILE: examples/when_ready.conf.py
  class MemoryWatch (line 12) | class MemoryWatch(threading.Thread):
    method __init__ (line 14) | def __init__(self, server, max_mem):
    method memory_usage (line 21) | def memory_usage(self, pid):
    method run (line 29) | def run(self):
  function when_ready (line 39) | def when_ready(server):

FILE: gunicorn/app/base.py
  class BaseApplication (line 16) | class BaseApplication:
    method __init__ (line 21) | def __init__(self, usage=None, prog=None):
    method do_load_config (line 29) | def do_load_config(self):
    method load_default_config (line 41) | def load_default_config(self):
    method init (line 45) | def init(self, parser, opts, args):
    method load (line 48) | def load(self):
    method load_config (line 51) | def load_config(self):
    method reload (line 59) | def reload(self):
    method wsgi (line 64) | def wsgi(self):
    method run (line 69) | def run(self):
  class Application (line 78) | class Application(BaseApplication):
    method chdir (line 83) | def chdir(self):
    method get_config_from_filename (line 92) | def get_config_from_filename(self, filename):
    method get_config_from_module_name (line 119) | def get_config_from_module_name(self, module_name):
    method load_config_from_module_name_or_filename (line 122) | def load_config_from_module_name_or_filename(self, location):
    method load_config_from_file (line 151) | def load_config_from_file(self, filename):
    method load_config (line 154) | def load_config(self):
    method run (line 201) | def run(self):

FILE: gunicorn/app/pasterapp.py
  function get_wsgi_app (line 14) | def get_wsgi_app(config_uri, name=None, defaults=None):
  function has_logging_config (line 26) | def has_logging_config(config_file):
  function serve (line 32) | def serve(app, global_conf, **local_conf):

FILE: gunicorn/app/wsgiapp.py
  class WSGIApplication (line 12) | class WSGIApplication(Application):
    method init (line 13) | def init(self, parser, opts, args):
    method load_config (line 37) | def load_config(self):
    method load_wsgiapp (line 46) | def load_wsgiapp(self):
    method load_pasteapp (line 49) | def load_pasteapp(self):
    method load (line 53) | def load(self):
  function run (line 60) | def run(prog=None):

FILE: gunicorn/arbiter.py
  class Arbiter (line 23) | class Arbiter:
    method __init__ (line 53) | def __init__(self, app):
    method _get_num_workers (line 100) | def _get_num_workers(self):
    method _set_num_workers (line 103) | def _set_num_workers(self, value):
    method setup (line 109) | def setup(self, app):
    method start (line 141) | def start(self):
    method init_signals (line 201) | def init_signals(self):
    method signal (line 213) | def signal(self, sig, frame):
    method run (line 217) | def run(self):
    method signal_chld (line 265) | def signal_chld(self, sig, frame):
    method handle_chld (line 269) | def handle_chld(self):
    method handle_hup (line 278) | def handle_hup(self):
    method handle_term (line 291) | def handle_term(self):
    method handle_int (line 295) | def handle_int(self):
    method handle_quit (line 300) | def handle_quit(self):
    method handle_ttin (line 305) | def handle_ttin(self):
    method handle_ttou (line 313) | def handle_ttou(self):
    method handle_usr1 (line 323) | def handle_usr1(self):
    method handle_usr2 (line 334) | def handle_usr2(self):
    method handle_winch (line 343) | def handle_winch(self):
    method maybe_promote_master (line 352) | def maybe_promote_master(self):
    method wakeup (line 369) | def wakeup(self):
    method halt (line 373) | def halt(self, reason=None, exit_status=0):
    method wait_for_signals (line 390) | def wait_for_signals(self, timeout=1.0):
    method stop (line 415) | def stop(self, graceful=True):
    method reexec (line 469) | def reexec(self):
    method reload (line 503) | def reload(self):
    method murder_workers (line 576) | def murder_workers(self):
    method reap_workers (line 597) | def reap_workers(self):
    method manage_workers (line 655) | def manage_workers(self):
    method spawn_worker (line 687) | def spawn_worker(self):
    method spawn_workers (line 739) | def spawn_workers(self):
    method kill_workers (line 751) | def kill_workers(self, sig):
    method kill_worker (line 760) | def kill_worker(self, pid, sig):
    method _get_dirty_pidfile_path (line 787) | def _get_dirty_pidfile_path(self):
    method _cleanup_orphaned_dirty_arbiter (line 798) | def _cleanup_orphaned_dirty_arbiter(self):
    method spawn_dirty_arbiter (line 838) | def spawn_dirty_arbiter(self):
    method kill_dirty_arbiter (line 884) | def kill_dirty_arbiter(self, sig):
    method reap_dirty_arbiter (line 900) | def reap_dirty_arbiter(self):
    method manage_dirty_arbiter (line 931) | def manage_dirty_arbiter(self):
    method _get_control_socket_path (line 946) | def _get_control_socket_path(self):
    method _start_control_server (line 953) | def _start_control_server(self):
    method _stop_control_server (line 979) | def _stop_control_server(self):

FILE: gunicorn/asgi/lifespan.py
  class LifespanManager (line 16) | class LifespanManager:
    method __init__ (line 32) | def __init__(self, app, logger, state=None):
    method startup (line 53) | async def startup(self):
    method shutdown (line 90) | async def shutdown(self):
    method _run_lifespan (line 124) | async def _run_lifespan(self, scope):
    method _receive (line 151) | async def _receive(self):
    method _send (line 155) | async def _send(self, message):

FILE: gunicorn/asgi/message.py
  function _ip_in_allow_list (line 42) | def _ip_in_allow_list(ip_str, allow_list, networks):
  class AsyncRequest (line 62) | class AsyncRequest:
    method __init__ (line 69) | def __init__(self, cfg, unreader, peer_addr, req_number=1):
    method parse (line 118) | async def parse(cls, cfg, unreader, peer_addr, req_number=1):
    method _parse (line 138) | async def _parse(self):
    method _read_into (line 173) | async def _read_into(self, buf):
    method _read_line (line 180) | async def _read_line(self, buf, limit=0):
    method _handle_proxy_protocol (line 199) | async def _handle_proxy_protocol(self, buf, mode):
    method _proxy_protocol_access_check (line 221) | def _proxy_protocol_access_check(self):
    method _parse_proxy_protocol_v1 (line 228) | async def _parse_proxy_protocol_v1(self, buf):
    method _parse_proxy_protocol_v2 (line 287) | async def _parse_proxy_protocol_v2(self, buf):
    method _parse_request_line (line 380) | def _parse_request_line(self, line_bytes):
    method _parse_headers (line 422) | def _parse_headers(self, data, from_trailer=False):
    method _set_body_reader (line 521) | def _set_body_reader(self):
    method force_close (line 575) | def force_close(self):
    method should_close (line 579) | def should_close(self):
    method get_header (line 593) | def get_header(self, name):
    method read_body (line 601) | async def read_body(self, size=8192):
    method _read_length_body (line 618) | async def _read_length_body(self, size):
    method _read_chunked_body (line 629) | async def _read_chunked_body(self, size):
    method _chunked_body_reader (line 640) | async def _chunked_body_reader(self):
    method _read_chunk_size_line (line 683) | async def _read_chunk_size_line(self):
    method _skip_trailers (line 702) | async def _skip_trailers(self):
    method drain_body (line 728) | async def drain_body(self):

FILE: gunicorn/asgi/protocol.py
  function _normalize_sockaddr (line 23) | def _normalize_sockaddr(sockaddr):
  class ASGIResponseInfo (line 33) | class ASGIResponseInfo:
    method __init__ (line 36) | def __init__(self, status, headers, sent):
  class ASGIProtocol (line 49) | class ASGIProtocol(asyncio.Protocol):
    method __init__ (line 55) | def __init__(self, worker):
    method connection_made (line 71) | def connection_made(self, transport):
    method data_received (line 97) | def data_received(self, data):
    method connection_lost (line 102) | def connection_lost(self, exc):
    method _cancel_task_if_pending (line 137) | def _cancel_task_if_pending(self):
    method _safe_write (line 142) | def _safe_write(self, data):
    method _handle_connection (line 161) | async def _handle_connection(self):
    method _is_websocket_upgrade (line 232) | def _is_websocket_upgrade(self, request):
    method _handle_websocket (line 253) | async def _handle_websocket(self, request, sockname, peername):
    method _handle_http_request (line 263) | async def _handle_http_request(self, request, sockname, peername):
    method _read_body_to_queue (line 415) | async def _read_body_to_queue(self, request, queue):
    method _build_http_scope (line 441) | def _build_http_scope(self, request, sockname, peername):
    method _build_environ (line 481) | def _build_environ(self, request, sockname, peername):
    method _build_websocket_scope (line 499) | def _build_websocket_scope(self, request, sockname, peername):
    method _send_informational (line 537) | async def _send_informational(self, status, headers, request):
    method _send_response_start (line 565) | async def _send_response_start(self, status, headers, request):
    method _send_body (line 587) | async def _send_body(self, body, chunked=False):
    method _send_error_response (line 597) | async def _send_error_response(self, status, message):
    method _get_reason_phrase (line 610) | def _get_reason_phrase(self, status):
    method _close_transport (line 649) | def _close_transport(self):
    method _handle_http2_connection (line 665) | async def _handle_http2_connection(self, transport, ssl_object):
    method _handle_http2_request (line 736) | async def _handle_http2_request(self, request, h2_conn, sockname, peer...
    method _build_http2_scope (line 886) | def _build_http2_scope(self, request, sockname, peername):
    method _build_http2_environ (line 929) | def _build_http2_environ(self, request, sockname, peername):

FILE: gunicorn/asgi/unreader.py
  class AsyncUnreader (line 14) | class AsyncUnreader:
    method __init__ (line 24) | def __init__(self, reader, max_chunk=8192):
    method _reset_buffer (line 36) | def _reset_buffer(self):
    method _get_buffered_data (line 42) | def _get_buffered_data(self):
    method _buffer_size (line 49) | def _buffer_size(self):
    method read (line 54) | async def read(self, size=None):
    method _read_chunk (line 107) | async def _read_chunk(self):
    method unread (line 114) | def unread(self, data):
    method has_buffered_data (line 133) | def has_buffered_data(self):

FILE: gunicorn/asgi/uwsgi.py
  class AsyncUWSGIRequest (line 17) | class AsyncUWSGIRequest(UWSGIRequest):
    method __init__ (line 29) | def __init__(self, cfg, unreader, peer_addr, req_number=1):
    method parse (line 65) | async def parse(cls, cfg, unreader, peer_addr, req_number=1):
    method _async_parse (line 87) | async def _async_parse(self):
    method _async_read_exact (line 111) | async def _async_read_exact(self, size):
    method _set_body_reader (line 121) | def _set_body_reader(self):
    method read_body (line 132) | async def read_body(self, size=8192):
    method drain_body (line 149) | async def drain_body(self):
    method get_header (line 159) | def get_header(self, name):

FILE: gunicorn/asgi/websocket.py
  class WebSocketProtocol (line 42) | class WebSocketProtocol:
    method __init__ (line 45) | def __init__(self, transport, reader, scope, app, log):
    method run (line 73) | async def run(self):
    method _receive (line 96) | async def _receive(self):
    method _send (line 100) | async def _send(self, message):
    method _send_accept (line 127) | async def _send_accept(self, message):
    method _read_frames (line 169) | async def _read_frames(self):
    method _read_frame (line 215) | async def _read_frame(self):  # pylint: disable=too-many-return-statem...
    method _read_exact (line 297) | async def _read_exact(self, n):
    method _unmask (line 307) | def _unmask(self, payload, masking_key):
    method _handle_close (line 314) | async def _handle_close(self, payload):
    method _handle_continuation (line 329) | async def _handle_continuation(self, payload):  # pylint: disable=unus...
    method _send_frame (line 333) | async def _send_frame(self, opcode, payload):
    method _send_close (line 362) | async def _send_close(self, code, reason=""):

FILE: gunicorn/config.py
  function make_settings (line 28) | def make_settings(ignore=None):
  function auto_int (line 39) | def auto_int(_, x):
  class Config (line 46) | class Config:
    method __init__ (line 48) | def __init__(self, usage=None, prog=None):
    method __str__ (line 56) | def __str__(self):
    method __getattr__ (line 66) | def __getattr__(self, name):
    method __setattr__ (line 73) | def __setattr__(self, name, value):
    method set (line 78) | def set(self, name, value):
    method get_cmd_args_from_env (line 83) | def get_cmd_args_from_env(self):
    method parser (line 88) | def parser(self):
    method worker_class_str (line 107) | def worker_class_str(self):
    method worker_class (line 119) | def worker_class(self):
    method address (line 133) | def address(self):
    method uid (line 138) | def uid(self):
    method gid (line 142) | def gid(self):
    method proc_name (line 146) | def proc_name(self):
    method logger_class (line 154) | def logger_class(self):
    method is_ssl (line 176) | def is_ssl(self):
    method forwarded_allow_networks (line 179) | def forwarded_allow_networks(self):
    method proxy_allow_networks (line 189) | def proxy_allow_networks(self):
    method ssl_options (line 200) | def ssl_options(self):
    method env (line 208) | def env(self):
    method sendfile (line 227) | def sendfile(self):
    method reuse_port (line 238) | def reuse_port(self):
    method paste_global_conf (line 242) | def paste_global_conf(self):
  class SettingMeta (line 261) | class SettingMeta(type):
    method __new__ (line 262) | def __new__(cls, name, bases, attrs):
    method fmt_desc (line 276) | def fmt_desc(cls, desc):
  class Setting (line 282) | class Setting:
    method __init__ (line 297) | def __init__(self):
    method add_option (line 301) | def add_option(self, parser):
    method copy (line 331) | def copy(self):
    method get (line 334) | def get(self):
    method set (line 337) | def set(self, val):
    method __lt__ (line 342) | def __lt__(self, other):
    method __repr__ (line 347) | def __repr__(self):
  function validate_bool (line 359) | def validate_bool(val):
  function validate_dict (line 375) | def validate_dict(val):
  function validate_pos_int (line 381) | def validate_pos_int(val):
  function validate_http2_frame_size (line 392) | def validate_http2_frame_size(val):
  function validate_ssl_version (line 405) | def validate_ssl_version(val):
  function validate_string (line 411) | def validate_string(val):
  function validate_file_exists (line 419) | def validate_file_exists(val):
  function validate_list_string (line 427) | def validate_list_string(val):
  function validate_list_of_existing_files (line 438) | def validate_list_of_existing_files(val):
  function validate_string_to_addr_list (line 442) | def validate_string_to_addr_list(val):
  function validate_string_to_list (line 457) | def validate_string_to_list(val):
  function validate_class (line 466) | def validate_class(val):
  function validate_callable (line 474) | def validate_callable(arity):
  function validate_user (line 498) | def validate_user(val):
  function validate_group (line 512) | def validate_group(val):
  function validate_post_request (line 527) | def validate_post_request(val):
  function validate_chdir (line 541) | def validate_chdir(val):
  function validate_statsd_address (line 555) | def validate_statsd_address(val):
  function validate_reload_engine (line 576) | def validate_reload_engine(val):
  function get_default_config_file (line 583) | def get_default_config_file():
  class ConfigFile (line 591) | class ConfigFile(Setting):
  class WSGIApp (line 615) | class WSGIApp(Setting):
  class Bind (line 628) | class Bind(Setting):
  class Backlog (line 663) | class Backlog(Setting):
  class Workers (line 683) | class Workers(Setting):
  class WorkerClass (line 704) | class WorkerClass(Setting):
  class WorkerThreads (line 737) | class WorkerThreads(Setting):
  class WorkerConnections (line 765) | class WorkerConnections(Setting):
  class MaxRequests (line 780) | class MaxRequests(Setting):
  class MaxRequestsJitter (line 800) | class MaxRequestsJitter(Setting):
  class Timeout (line 819) | class Timeout(Setting):
  class GracefulTimeout (line 841) | class GracefulTimeout(Setting):
  class Keepalive (line 858) | class Keepalive(Setting):
  class LimitRequestLine (line 880) | class LimitRequestLine(Setting):
  class LimitRequestFields (line 904) | class LimitRequestFields(Setting):
  class LimitRequestFieldSize (line 922) | class LimitRequestFieldSize(Setting):
  class Reload (line 942) | class Reload(Setting):
  class ReloadEngine (line 974) | class ReloadEngine(Setting):
  class ReloadExtraFiles (line 994) | class ReloadExtraFiles(Setting):
  class Spew (line 1010) | class Spew(Setting):
  class ConfigCheck (line 1024) | class ConfigCheck(Setting):
  class PrintConfig (line 1037) | class PrintConfig(Setting):
  class PreloadApp (line 1049) | class PreloadApp(Setting):
  class Sendfile (line 1066) | class Sendfile(Setting):
  class ReusePort (line 1089) | class ReusePort(Setting):
  class Chdir (line 1104) | class Chdir(Setting):
  class Daemon (line 1116) | class Daemon(Setting):
  class Env (line 1131) | class Env(Setting):
  class Pidfile (line 1159) | class Pidfile(Setting):
  class WorkerTmpDir (line 1173) | class WorkerTmpDir(Setting):
  class User (line 1195) | class User(Setting):
  class Group (line 1212) | class Group(Setting):
  class Umask (line 1229) | class Umask(Setting):
  class Initgroups (line 1249) | class Initgroups(Setting):
  class TmpUploadDir (line 1266) | class TmpUploadDir(Setting):
  class SecureSchemeHeader (line 1283) | class SecureSchemeHeader(Setting):
  class ForwardedAllowIPS (line 1315) | class ForwardedAllowIPS(Setting):
  class AccessLog (line 1380) | class AccessLog(Setting):
  class DisableRedirectAccessToSyslog (line 1394) | class DisableRedirectAccessToSyslog(Setting):
  class AccessLogFormat (line 1408) | class AccessLogFormat(Setting):
  class ErrorLog (line 1452) | class ErrorLog(Setting):
  class Loglevel (line 1470) | class Loglevel(Setting):
  class CaptureOutput (line 1490) | class CaptureOutput(Setting):
  class LoggerClass (line 1504) | class LoggerClass(Setting):
  class LogConfig (line 1522) | class LogConfig(Setting):
  class LogConfigDict (line 1536) | class LogConfigDict(Setting):
  class LogConfigJson (line 1557) | class LogConfigJson(Setting):
  class SyslogTo (line 1573) | class SyslogTo(Setting):
  class Syslog (line 1612) | class Syslog(Setting):
  class SyslogPrefix (line 1628) | class SyslogPrefix(Setting):
  class SyslogFacility (line 1643) | class SyslogFacility(Setting):
  class EnableStdioInheritance (line 1655) | class EnableStdioInheritance(Setting):
  class StatsdHost (line 1673) | class StatsdHost(Setting):
  class DogstatsdTags (line 1693) | class DogstatsdTags(Setting):
  class StatsdPrefix (line 1708) | class StatsdPrefix(Setting):
  class BacklogMetric (line 1723) | class BacklogMetric(Setting):
  class Procname (line 1738) | class Procname(Setting):
  class DefaultProcName (line 1757) | class DefaultProcName(Setting):
  class PythonPath (line 1767) | class PythonPath(Setting):
  class Paste (line 1782) | class Paste(Setting):
  class OnStarting (line 1799) | class OnStarting(Setting):
    method on_starting (line 1805) | def on_starting(server):
  class OnReload (line 1815) | class OnReload(Setting):
    method on_reload (line 1821) | def on_reload(server):
  class WhenReady (line 1831) | class WhenReady(Setting):
    method when_ready (line 1837) | def when_ready(server):
  class Prefork (line 1847) | class Prefork(Setting):
    method pre_fork (line 1853) | def pre_fork(server, worker):
  class Postfork (line 1864) | class Postfork(Setting):
    method post_fork (line 1870) | def post_fork(server, worker):
  class PostWorkerInit (line 1881) | class PostWorkerInit(Setting):
    method post_worker_init (line 1887) | def post_worker_init(worker):
  class WorkerInt (line 1899) | class WorkerInt(Setting):
    method worker_int (line 1905) | def worker_int(worker):
  class WorkerAbort (line 1917) | class WorkerAbort(Setting):
    method worker_abort (line 1923) | def worker_abort(worker):
  class PreExec (line 1937) | class PreExec(Setting):
    method pre_exec (line 1943) | def pre_exec(server):
  class PreRequest (line 1953) | class PreRequest(Setting):
    method pre_request (line 1959) | def pre_request(worker, req):
  class PostRequest (line 1970) | class PostRequest(Setting):
    method post_request (line 1976) | def post_request(worker, req, environ, resp):
  class ChildExit (line 1988) | class ChildExit(Setting):
    method child_exit (line 1994) | def child_exit(server, worker):
  class WorkerExit (line 2007) | class WorkerExit(Setting):
    method worker_exit (line 2013) | def worker_exit(server, worker):
  class NumWorkersChanged (line 2024) | class NumWorkersChanged(Setting):
    method nworkers_changed (line 2030) | def nworkers_changed(server, new_value, old_value):
  class OnExit (line 2044) | class OnExit(Setting):
    method on_exit (line 2049) | def on_exit(server):
  class NewSSLContext (line 2060) | class NewSSLContext(Setting):
    method ssl_context (line 2066) | def ssl_context(config, default_ssl_context_factory):
  function validate_proxy_protocol (line 2095) | def validate_proxy_protocol(val):
  class ProxyProtocol (line 2119) | class ProxyProtocol(Setting):
  class ProxyAllowFrom (line 2161) | class ProxyAllowFrom(Setting):
  class Protocol (line 2186) | class Protocol(Setting):
  class UWSGIAllowFrom (line 2212) | class UWSGIAllowFrom(Setting):
  class KeyFile (line 2233) | class KeyFile(Setting):
  class CertFile (line 2245) | class CertFile(Setting):
  class SSLVersion (line 2257) | class SSLVersion(Setting):
  class CertReqs (line 2302) | class CertReqs(Setting):
  class CACerts (line 2321) | class CACerts(Setting):
  class SuppressRaggedEOFs (line 2333) | class SuppressRaggedEOFs(Setting):
  class DoHandshakeOnConnect (line 2345) | class DoHandshakeOnConnect(Setting):
  class Ciphers (line 2357) | class Ciphers(Setting):
  function validate_http_protocols (line 2393) | def validate_http_protocols(val):
  class HTTPProtocols (line 2428) | class HTTPProtocols(Setting):
  class HTTP2MaxConcurrentStreams (line 2469) | class HTTP2MaxConcurrentStreams(Setting):
  class HTTP2InitialWindowSize (line 2491) | class HTTP2InitialWindowSize(Setting):
  class HTTP2MaxFrameSize (line 2513) | class HTTP2MaxFrameSize(Setting):
  class HTTP2MaxHeaderListSize (line 2535) | class HTTP2MaxHeaderListSize(Setting):
  class PasteGlobalConf (line 2555) | class PasteGlobalConf(Setting):
  class PermitObsoleteFolding (line 2577) | class PermitObsoleteFolding(Setting):
  class StripHeaderSpaces (line 2598) | class StripHeaderSpaces(Setting):
  class PermitUnconventionalHTTPMethod (line 2617) | class PermitUnconventionalHTTPMethod(Setting):
  class PermitUnconventionalHTTPVersion (line 2643) | class PermitUnconventionalHTTPVersion(Setting):
  class CasefoldHTTPMethod (line 2664) | class CasefoldHTTPMethod(Setting):
  function validate_header_map_behaviour (line 2684) | def validate_header_map_behaviour(val):
  class ForwarderHeaders (line 2702) | class ForwarderHeaders(Setting):
  class HeaderMap (line 2723) | class HeaderMap(Setting):
  function validate_asgi_loop (line 2753) | def validate_asgi_loop(val):
  function validate_asgi_lifespan (line 2764) | def validate_asgi_lifespan(val):
  class ASGILoop (line 2775) | class ASGILoop(Setting):
  class ASGILifespan (line 2798) | class ASGILifespan(Setting):
  class ASGIDisconnectGracePeriod (line 2823) | class ASGIDisconnectGracePeriod(Setting):
  class RootPath (line 2848) | class RootPath(Setting):
  class DirtyApps (line 2873) | class DirtyApps(Setting):
  class DirtyWorkers (line 2928) | class DirtyWorkers(Setting):
  class DirtyTimeout (line 2951) | class DirtyTimeout(Setting):
  class DirtyThreads (line 2972) | class DirtyThreads(Setting):
  class DirtyGracefulTimeout (line 2990) | class DirtyGracefulTimeout(Setting):
  class OnDirtyStarting (line 3013) | class OnDirtyStarting(Setting):
    method on_dirty_starting (line 3019) | def on_dirty_starting(arbiter):
  class DirtyPostFork (line 3032) | class DirtyPostFork(Setting):
    method dirty_post_fork (line 3038) | def dirty_post_fork(arbiter, worker):
  class DirtyWorkerInit (line 3051) | class DirtyWorkerInit(Setting):
    method dirty_worker_init (line 3057) | def dirty_worker_init(worker):
  class DirtyWorkerExit (line 3070) | class DirtyWorkerExit(Setting):
    method dirty_worker_exit (line 3076) | def dirty_worker_exit(arbiter, worker):
  class ControlSocket (line 3091) | class ControlSocket(Setting):
  class ControlSocketMode (line 3115) | class ControlSocketMode(Setting):
  class ControlSocketDisable (line 3133) | class ControlSocketDisable(Setting):

FILE: gunicorn/ctl/cli.py
  function format_workers (line 19) | def format_workers(data: dict) -> str:
  function format_dirty (line 44) | def format_dirty(data: dict) -> str:
  function format_stats (line 86) | def format_stats(data: dict) -> str:
  function format_listeners (line 119) | def format_listeners(data: dict) -> str:
  function format_config (line 141) | def format_config(data: dict) -> str:
  function format_help (line 155) | def format_help(data: dict) -> str:
  function format_all (line 171) | def format_all(data: dict) -> str:
  function format_response (line 233) | def format_response(command: str, data: dict) -> str:  # pylint: disable...
  function run_command (line 268) | def run_command(socket_path: str, command: str, json_output: bool = Fals...
  function run_interactive (line 301) | def run_interactive(socket_path: str, json_output: bool = False) -> int:
  function main (line 391) | def main():

FILE: gunicorn/ctl/client.py
  class ControlClientError (line 20) | class ControlClientError(Exception):
  class ControlClient (line 24) | class ControlClient:
    method __init__ (line 34) | def __init__(self, socket_path: str, timeout: float = 30.0):
    method connect (line 47) | def connect(self):
    method close (line 65) | def close(self):
    method send_command (line 74) | def send_command(self, command: str, args: list = None) -> dict:
    method __enter__ (line 106) | def __enter__(self):
    method __exit__ (line 110) | def __exit__(self, *args):
  function parse_command (line 114) | def parse_command(line: str) -> tuple:

FILE: gunicorn/ctl/handlers.py
  class CommandHandlers (line 17) | class CommandHandlers:
    method __init__ (line 25) | def __init__(self, arbiter):
    method show_workers (line 34) | def show_workers(self) -> dict:
    method show_dirty (line 69) | def show_dirty(self) -> dict:
    method show_config (line 129) | def show_config(self) -> dict:
    method show_stats (line 164) | def show_stats(self) -> dict:
    method show_listeners (line 195) | def show_listeners(self) -> dict:
    method worker_add (line 227) | def worker_add(self, count: int = 1) -> dict:
    method worker_remove (line 250) | def worker_remove(self, count: int = 1) -> dict:
    method worker_kill (line 278) | def worker_kill(self, pid: int) -> dict:
    method dirty_add (line 308) | def dirty_add(self, count: int = 1) -> dict:
    method dirty_remove (line 329) | def dirty_remove(self, count: int = 1) -> dict:
    method _send_manage_message (line 350) | def _send_manage_message(self, operation: str, count: int) -> dict:
    method reload (line 419) | def reload(self) -> dict:
    method reopen (line 430) | def reopen(self) -> dict:
    method shutdown (line 440) | def shutdown(self, mode: str = "graceful") -> dict:
    method show_all (line 457) | def show_all(self) -> dict:
    method _query_dirty_workers (line 516) | def _query_dirty_workers(self) -> list:
    method help (line 561) | def help(self) -> dict:

FILE: gunicorn/ctl/protocol.py
  class ProtocolError (line 27) | class ProtocolError(Exception):
  class ControlProtocol (line 31) | class ControlProtocol:
    method encode_message (line 42) | def encode_message(data: dict) -> bytes:
    method decode_message (line 57) | def decode_message(data: bytes) -> dict:
    method read_message (line 78) | def read_message(sock) -> dict:
    method write_message (line 121) | def write_message(sock, data: dict):
    method read_message_async (line 133) | async def read_message_async(reader) -> dict:
    method write_message_async (line 159) | async def write_message_async(writer, data: dict):
  function make_request (line 172) | def make_request(request_id: int, command: str, args: list = None) -> dict:
  function make_response (line 191) | def make_response(request_id: int, data: dict = None) -> dict:
  function make_error_response (line 209) | def make_error_response(request_id: int, error: str) -> dict:

FILE: gunicorn/ctl/server.py
  function _register_fork_handlers (line 37) | def _register_fork_handlers():
  function _before_fork (line 50) | def _before_fork():
  function _after_fork_parent (line 56) | def _after_fork_parent():
  function _after_fork_child (line 62) | def _after_fork_child():
  class ControlSocketServer (line 69) | class ControlSocketServer:
    method __init__ (line 80) | def __init__(self, arbiter, socket_path, socket_mode=0o600):
    method start (line 103) | def start(self):
    method stop (line 115) | def stop(self):
    method _stop_for_fork (line 140) | def _stop_for_fork(self):
    method _restart_after_fork (line 163) | def _restart_after_fork(self):
    method _shutdown (line 173) | def _shutdown(self):
    method _run_loop (line 178) | def _run_loop(self):
    method _serve (line 186) | async def _serve(self):
    method _handle_client (line 219) | async def _handle_client(self, reader, writer):
    method _dispatch (line 260) | async def _dispatch(self, message: dict) -> dict:
    method _execute_command (line 297) | def _execute_command(self, parts: list) -> dict:  # pylint: disable=to...
    method _handle_show (line 332) | def _handle_show(self, args: list) -> dict:
    method _handle_worker (line 354) | def _handle_worker(self, args: list) -> dict:
    method _handle_dirty (line 376) | def _handle_dirty(self, args: list) -> dict:

FILE: gunicorn/debug.py
  class Spew (line 18) | class Spew:
    method __init__ (line 20) | def __init__(self, trace_names=None, show_values=True):
    method __call__ (line 24) | def __call__(self, frame, event, arg):
  function spew (line 58) | def spew(trace_names=None, show_values=False):
  function unspew (line 65) | def unspew():

FILE: gunicorn/dirty/app.py
  class DirtyApp (line 18) | class DirtyApp:
    method init (line 98) | def init(self):
    method __call__ (line 110) | def __call__(self, action, *args, **kwargs):
    method close (line 131) | def close(self):
  function parse_dirty_app_spec (line 140) | def parse_dirty_app_spec(spec):
  function load_dirty_app (line 215) | def load_dirty_app(import_path):
  function load_dirty_apps (line 281) | def load_dirty_apps(import_paths):
  function get_app_workers_attribute (line 300) | def get_app_workers_attribute(import_path):

FILE: gunicorn/dirty/arbiter.py
  class DirtyArbiter (line 49) | class DirtyArbiter:
    method __init__ (line 66) | def __init__(self, cfg, log, socket_path=None, pidfile=None):
    method _parse_app_specs (line 121) | def _parse_app_specs(self):
    method _get_minimum_workers (line 155) | def _get_minimum_workers(self):
    method _get_apps_for_new_worker (line 172) | def _get_apps_for_new_worker(self):
    method _register_worker_apps (line 199) | def _register_worker_apps(self, worker_pid, app_paths):
    method _unregister_worker (line 217) | def _unregister_worker(self, worker_pid):
    method run (line 234) | def run(self):
    method init_signals (line 266) | def init_signals(self):
    method _signal_handler (line 280) | def _signal_handler(self, sig, frame):
    method _shutdown (line 338) | def _shutdown(self):
    method _run_async (line 343) | async def _run_async(self):
    method _worker_monitor (line 383) | async def _worker_monitor(self):
    method _handle_sigchld (line 398) | async def _handle_sigchld(self):
    method handle_client (line 405) | async def handle_client(self, reader, writer):
    method route_request (line 445) | async def route_request(self, request, client_writer):
    method _start_worker_consumer (line 497) | async def _start_worker_consumer(self, worker_pid):
    method _execute_on_worker (line 523) | async def _execute_on_worker(self, worker_pid, request, client_writer):
    method _get_available_worker (line 583) | async def _get_available_worker(self, app_path=None):
    method _get_worker_connection (line 625) | async def _get_worker_connection(self, worker_pid):
    method _close_worker_connection (line 646) | def _close_worker_connection(self, worker_pid):
    method handle_status_request (line 656) | async def handle_status_request(self, message, client_writer):
    method handle_manage_request (line 697) | async def handle_manage_request(self, message, client_writer):
    method handle_stash_request (line 791) | async def handle_stash_request(self, message, client_writer):
    method manage_workers (line 908) | async def manage_workers(self):
    method spawn_worker (line 931) | def spawn_worker(self, force_all_apps=False):
    method kill_worker (line 1003) | def kill_worker(self, pid, sig):
    method _cleanup_worker (line 1011) | def _cleanup_worker(self, pid):
    method murder_workers (line 1047) | async def murder_workers(self):
    method reap_workers (line 1066) | def reap_workers(self):
    method reload (line 1091) | async def reload(self):
    method stop (line 1105) | async def stop(self, graceful=True):
    method _cleanup_sync (line 1128) | def _cleanup_sync(self):

FILE: gunicorn/dirty/client.py
  class DirtyClient (line 31) | class DirtyClient:
    method __init__ (line 40) | def __init__(self, socket_path, timeout=30.0):
    method connect (line 59) | def connect(self):
    method execute (line 80) | def execute(self, app_path, action, *args, **kwargs):
    method _execute_locked (line 101) | def _execute_locked(self, app_path, action, args, kwargs):
    method stream (line 138) | def stream(self, app_path, action, *args, **kwargs):
    method _handle_response (line 166) | def _handle_response(self, response):
    method _close_socket (line 179) | def _close_socket(self):
    method close (line 188) | def close(self):
    method connect_async (line 197) | async def connect_async(self):
    method execute_async (line 223) | async def execute_async(self, app_path, action, *args, **kwargs):
    method stream_async (line 279) | def stream_async(self, app_path, action, *args, **kwargs):
    method _close_async (line 307) | async def _close_async(self):
    method close_async (line 318) | async def close_async(self):
    method __enter__ (line 326) | def __enter__(self):
    method __exit__ (line 330) | def __exit__(self, exc_type, exc_val, exc_tb):
    method __aenter__ (line 333) | async def __aenter__(self):
    method __aexit__ (line 337) | async def __aexit__(self, exc_type, exc_val, exc_tb):
  class DirtyStreamIterator (line 346) | class DirtyStreamIterator:
    method __init__ (line 365) | def __init__(self, client, app_path, action, args, kwargs,
    method __iter__ (line 383) | def __iter__(self):
    method __next__ (line 386) | def __next__(self):
    method _start_request (line 396) | def _start_request(self):
    method _read_next_chunk (line 417) | def _read_next_chunk(self):
  class DirtyAsyncStreamIterator (line 492) | class DirtyAsyncStreamIterator:
    method __init__ (line 509) | def __init__(self, client, app_path, action, args, kwargs,
    method __aiter__ (line 527) | def __aiter__(self):
    method __anext__ (line 530) | async def __anext__(self):
    method _start_request (line 540) | async def _start_request(self):
    method _read_next_chunk (line 564) | async def _read_next_chunk(self):
  function set_dirty_socket_path (line 657) | def set_dirty_socket_path(path):
  function get_dirty_socket_path (line 667) | def get_dirty_socket_path():
  function get_dirty_client (line 681) | def get_dirty_client(timeout=30.0) -> DirtyClient:
  function get_dirty_client_async (line 710) | async def get_dirty_client_async(timeout=30.0) -> DirtyClient:
  function close_dirty_client (line 740) | def close_dirty_client():
  function close_dirty_client_async (line 748) | async def close_dirty_client_async():

FILE: gunicorn/dirty/errors.py
  class DirtyError (line 12) | class DirtyError(Exception):
    method __init__ (line 15) | def __init__(self, message, details=None):
    method __str__ (line 20) | def __str__(self):
    method to_dict (line 25) | def to_dict(self):
    method from_dict (line 34) | def from_dict(cls, data):
  class DirtyTimeoutError (line 80) | class DirtyTimeoutError(DirtyError):
    method __init__ (line 83) | def __init__(self, message="Operation timed out", timeout=None):
  class DirtyConnectionError (line 89) | class DirtyConnectionError(DirtyError):
    method __init__ (line 92) | def __init__(self, message="Connection failed", socket_path=None):
  class DirtyWorkerError (line 98) | class DirtyWorkerError(DirtyError):
    method __init__ (line 101) | def __init__(self, message, worker_id=None, traceback=None):
  class DirtyAppError (line 112) | class DirtyAppError(DirtyError):
    method __init__ (line 115) | def __init__(self, message, app_path=None, action=None, traceback=None):
  class DirtyAppNotFoundError (line 129) | class DirtyAppNotFoundError(DirtyAppError):
    method __init__ (line 132) | def __init__(self, app_path):
  class DirtyNoWorkersAvailableError (line 136) | class DirtyNoWorkersAvailableError(DirtyError):
    method __init__ (line 163) | def __init__(self, app_path, message=None):
  class DirtyProtocolError (line 170) | class DirtyProtocolError(DirtyError):
    method __init__ (line 173) | def __init__(self, message="Protocol error", raw_data=None):

FILE: gunicorn/dirty/protocol.py
  class BinaryProtocol (line 98) | class BinaryProtocol:
    method encode_header (line 115) | def encode_header(msg_type: int, request_id: int, payload_length: int)...
    method decode_header (line 131) | def decode_header(data: bytes) -> tuple:
    method encode_request (line 180) | def encode_request(request_id: int, app_path: str, action: str,
    method encode_response (line 207) | def encode_response(request_id: int, result) -> bytes:
    method encode_error (line 225) | def encode_error(request_id: int, error) -> bytes:
    method encode_chunk (line 256) | def encode_chunk(request_id: int, data) -> bytes:
    method encode_end (line 274) | def encode_end(request_id: int) -> bytes:
    method encode_status (line 289) | def encode_status(request_id: int) -> bytes:
    method encode_manage (line 304) | def encode_manage(request_id: int, op: int, count: int = 1) -> bytes:
    method encode_stash (line 326) | def encode_stash(request_id: int, op: int, table: str,
    method decode_message (line 359) | def decode_message(data: bytes) -> tuple:
    method read_message_async (line 408) | async def read_message_async(reader: asyncio.StreamReader) -> dict:
    method write_message_async (line 468) | async def write_message_async(writer: asyncio.StreamWriter,
    method _recv_exactly (line 492) | def _recv_exactly(sock: socket.socket, n: int) -> bytes:
    method read_message (line 520) | def read_message(sock: socket.socket) -> dict:
    method write_message (line 560) | def write_message(sock: socket.socket, message: dict) -> None:
    method _encode_from_dict (line 576) | def _encode_from_dict(message: dict) -> bytes:  # pylint: disable=too-...
  function make_request (line 655) | def make_request(request_id, app_path: str, action: str,
  function make_response (line 680) | def make_response(request_id, result) -> dict:
  function make_error_response (line 698) | def make_error_response(request_id, error) -> dict:
  function make_chunk_message (line 728) | def make_chunk_message(request_id, data) -> dict:
  function make_end_message (line 746) | def make_end_message(request_id) -> dict:
  function make_stash_message (line 762) | def make_stash_message(request_id, op: int, table: str,
  function make_manage_message (line 793) | def make_manage_message(request_id, op: int, count: int = 1) -> dict:

FILE: gunicorn/dirty/stash.py
  class StashError (line 69) | class StashError(DirtyError):
  class StashTableNotFoundError (line 73) | class StashTableNotFoundError(StashError):
    method __init__ (line 76) | def __init__(self, table_name):
  class StashKeyNotFoundError (line 81) | class StashKeyNotFoundError(StashError):
    method __init__ (line 84) | def __init__(self, table_name, key):
  class StashClient (line 90) | class StashClient:
    method __init__ (line 97) | def __init__(self, socket_path, timeout=30.0):
    method _get_request_id (line 110) | def _get_request_id(self):
    method _connect (line 114) | def _connect(self):
    method _close (line 128) | def _close(self):
    method _execute (line 137) | def _execute(self, op, table, key=None, value=None, pattern=None):
    method put (line 191) | def put(self, table, key, value):
    method get (line 204) | def get(self, table, key, default=None):
    method delete (line 221) | def delete(self, table, key):
    method keys (line 234) | def keys(self, table, pattern=None):
    method clear (line 247) | def clear(self, table):
    method info (line 256) | def info(self, table):
    method ensure (line 268) | def ensure(self, table):
    method exists (line 279) | def exists(self, table, key=None):
    method delete_table (line 292) | def delete_table(self, table):
    method tables (line 301) | def tables(self):
    method table (line 310) | def table(self, name):
    method close (line 322) | def close(self):
    method __enter__ (line 327) | def __enter__(self):
    method __exit__ (line 330) | def __exit__(self, exc_type, exc_val, exc_tb):
  class StashTable (line 334) | class StashTable:
    method __init__ (line 350) | def __init__(self, client, name):
    method name (line 355) | def name(self):
    method __getitem__ (line 359) | def __getitem__(self, key):
    method __setitem__ (line 367) | def __setitem__(self, key, value):
    method __delitem__ (line 370) | def __delitem__(self, key):
    method __contains__ (line 374) | def __contains__(self, key):
    method __iter__ (line 377) | def __iter__(self):
    method __len__ (line 380) | def __len__(self):
    method get (line 384) | def get(self, key, default=None):
    method keys (line 388) | def keys(self, pattern=None):
    method clear (line 392) | def clear(self):
    method items (line 396) | def items(self):
    method values (line 401) | def values(self):
  function set_stash_socket_path (line 418) | def set_stash_socket_path(path):
  function get_stash_socket_path (line 424) | def get_stash_socket_path():
  function _get_client (line 439) | def _get_client():
  function put (line 451) | def put(table, key, value):
  function get (line 456) | def get(table, key, default=None):
  function delete (line 461) | def delete(table, key):
  function keys (line 466) | def keys(table, pattern=None):
  function clear (line 471) | def clear(table):
  function info (line 476) | def info(table):
  function ensure (line 481) | def ensure(table):
  function exists (line 486) | def exists(table, key=None):
  function delete_table (line 491) | def delete_table(table):
  function tables (line 496) | def tables():
  function table (line 501) | def table(name):

FILE: gunicorn/dirty/tlv.py
  class TLVEncoder (line 44) | class TLVEncoder:
    method encode (line 53) | def encode(value) -> bytes:  # pylint: disable=too-many-return-statements
    method decode (line 128) | def decode(data: bytes, offset: int = 0) -> tuple:  # pylint: disable=...
    method decode_full (line 284) | def decode_full(data: bytes):

FILE: gunicorn/dirty/worker.py
  class DirtyWorker (line 96) | class DirtyWorker:
    method __init__ (line 107) | def __init__(self, age, ppid, app_paths, cfg, log, socket_path):
    method __str__ (line 135) | def __str__(self):
    method notify (line 138) | def notify(self):
    method init_process (line 142) | def init_process(self):
    method init_signals (line 178) | def init_signals(self):
    method _signal_handler (line 195) | def _signal_handler(self, sig, frame):
    method _shutdown (line 205) | def _shutdown(self):
    method load_apps (line 210) | def load_apps(self):
    method run (line 227) | def run(self):
    method _run_async (line 249) | async def _run_async(self):
    method _heartbeat_loop (line 282) | async def _heartbeat_loop(self):
    method handle_connection (line 288) | async def handle_connection(self, reader, writer):
    method handle_request (line 315) | async def handle_request(self, message, writer):
    method _stream_sync_generator (line 369) | async def _stream_sync_generator(self, request_id, gen, writer):
    method _stream_async_generator (line 417) | async def _stream_async_generator(self, request_id, gen, writer):
    method execute (line 450) | async def execute(self, app_path, action, args, kwargs):
    method _cleanup (line 502) | def _cleanup(self):

FILE: gunicorn/errors.py
  class HaltServer (line 14) | class HaltServer(BaseException):
    method __init__ (line 15) | def __init__(self, reason, exit_status=1):
    method __str__ (line 19) | def __str__(self):
  class ConfigError (line 23) | class ConfigError(Exception):
  class AppImportError (line 27) | class AppImportError(Exception):

FILE: gunicorn/glogging.py
  function loggers (line 88) | def loggers():
  class SafeAtoms (line 95) | class SafeAtoms(dict):
    method __init__ (line 97) | def __init__(self, atoms):
    method __getitem__ (line 105) | def __getitem__(self, k):
  function parse_syslog_address (line 118) | def parse_syslog_address(addr):
  class Logger (line 164) | class Logger:
    method __init__ (line 183) | def __init__(self, cfg):
    method setup (line 195) | def setup(self, cfg):
    method critical (line 267) | def critical(self, msg, *args, **kwargs):
    method error (line 270) | def error(self, msg, *args, **kwargs):
    method warning (line 273) | def warning(self, msg, *args, **kwargs):
    method info (line 276) | def info(self, msg, *args, **kwargs):
    method debug (line 279) | def debug(self, msg, *args, **kwargs):
    method exception (line 282) | def exception(self, msg, *args, **kwargs):
    method log (line 285) | def log(self, lvl, msg, *args, **kwargs):
    method atoms (line 290) | def atoms(self, resp, req, environ, request_time):
    method access (line 344) | def access(self, resp, req, environ, request_time):
    method now (line 366) | def now(self):
    method reopen_files (line 370) | def reopen_files(self):
    method close_on_exec (line 393) | def close_on_exec(self):
    method _get_gunicorn_handler (line 404) | def _get_gunicorn_handler(self, log):
    method _set_handler (line 409) | def _set_handler(self, log, output, fmt, stream=None):
    method _set_syslog_handler (line 433) | def _set_syslog_handler(self, log, cfg, fmt, name):
    method _get_user (line 459) | def _get_user(self, environ):

FILE: gunicorn/http/__init__.py
  function get_parser (line 9) | def get_parser(cfg, source, source_addr, http2_connection=False):

FILE: gunicorn/http/body.py
  class ChunkedReader (line 12) | class ChunkedReader:
    method __init__ (line 13) | def __init__(self, req, unreader):
    method read (line 18) | def read(self, size):
    method parse_trailers (line 40) | def parse_trailers(self, unreader, data):
    method parse_chunked (line 56) | def parse_chunked(self, unreader):
    method parse_chunk_size (line 77) | def parse_chunk_size(self, unreader, data=None):
    method get_data (line 108) | def get_data(self, unreader, buf):
  class LengthReader (line 115) | class LengthReader:
    method __init__ (line 116) | def __init__(self, unreader, length):
    method read (line 120) | def read(self, size):
  class EOFReader (line 145) | class EOFReader:
    method __init__ (line 146) | def __init__(self, unreader):
    method read (line 151) | def read(self, size):
  class Body (line 183) | class Body:
    method __init__ (line 184) | def __init__(self, reader):
    method __iter__ (line 188) | def __iter__(self):
    method __next__ (line 191) | def __next__(self):
    method getsize (line 199) | def getsize(self, size):
    method read (line 208) | def read(self, size=None):
    method readline (line 232) | def readline(self, size=None):
    method readlines (line 257) | def readlines(self, size=None):

FILE: gunicorn/http/errors.py
  class ParseException (line 12) | class ParseException(Exception):
  class NoMoreData (line 16) | class NoMoreData(IOError):
    method __init__ (line 17) | def __init__(self, buf=None):
    method __str__ (line 20) | def __str__(self):
  class ConfigurationProblem (line 24) | class ConfigurationProblem(ParseException):
    method __init__ (line 25) | def __init__(self, info):
    method __str__ (line 29) | def __str__(self):
  class InvalidRequestLine (line 33) | class InvalidRequestLine(ParseException):
    method __init__ (line 34) | def __init__(self, req):
    method __str__ (line 38) | def __str__(self):
  class InvalidRequestMethod (line 42) | class InvalidRequestMethod(ParseException):
    method __init__ (line 43) | def __init__(self, method):
    method __str__ (line 46) | def __str__(self):
  class ExpectationFailed (line 50) | class ExpectationFailed(ParseException):
    method __init__ (line 51) | def __init__(self, expect):
    method __str__ (line 54) | def __str__(self):
  class InvalidHTTPVersion (line 58) | class InvalidHTTPVersion(ParseException):
    method __init__ (line 59) | def __init__(self, version):
    method __str__ (line 62) | def __str__(self):
  class InvalidHeader (line 66) | class InvalidHeader(ParseException):
    method __init__ (line 67) | def __init__(self, hdr, req=None):
    method __str__ (line 71) | def __str__(self):
  class ObsoleteFolding (line 75) | class ObsoleteFolding(ParseException):
    method __init__ (line 76) | def __init__(self, hdr):
    method __str__ (line 79) | def __str__(self):
  class InvalidHeaderName (line 83) | class InvalidHeaderName(ParseException):
    method __init__ (line 84) | def __init__(self, hdr):
    method __str__ (line 87) | def __str__(self):
  class UnsupportedTransferCoding (line 91) | class UnsupportedTransferCoding(ParseException):
    method __init__ (line 92) | def __init__(self, hdr):
    method __str__ (line 96) | def __str__(self):
  class InvalidChunkSize (line 100) | class InvalidChunkSize(IOError):
    method __init__ (line 101) | def __init__(self, data):
    method __str__ (line 104) | def __str__(self):
  class ChunkMissingTerminator (line 108) | class ChunkMissingTerminator(IOError):
    method __init__ (line 109) | def __init__(self, term):
    method __str__ (line 112) | def __str__(self):
  class LimitRequestLine (line 116) | class LimitRequestLine(ParseException):
    method __init__ (line 117) | def __init__(self, size, max_size):
    method __str__ (line 121) | def __str__(self):
  class LimitRequestHeaders (line 125) | class LimitRequestHeaders(ParseException):
    method __init__ (line 126) | def __init__(self, msg):
    method __str__ (line 129) | def __str__(self):
  class InvalidProxyLine (line 133) | class InvalidProxyLine(ParseException):
    method __init__ (line 134) | def __init__(self, line):
    method __str__ (line 138) | def __str__(self):
  class InvalidProxyHeader (line 142) | class InvalidProxyHeader(ParseException):
    method __init__ (line 143) | def __init__(self, msg):
    method __str__ (line 147) | def __str__(self):
  class ForbiddenProxyRequest (line 151) | class ForbiddenProxyRequest(ParseException):
    method __init__ (line 152) | def __init__(self, host):
    method __str__ (line 156) | def __str__(self):
  class InvalidSchemeHeaders (line 160) | class InvalidSchemeHeaders(ParseException):
    method __str__ (line 161) | def __str__(self):

FILE: gunicorn/http/message.py
  class PPCommand (line 28) | class PPCommand(IntEnum):
  class PPFamily (line 34) | class PPFamily(IntEnum):
  class PPProtocol (line 42) | class PPProtocol(IntEnum):
  function _ip_in_allow_list (line 62) | def _ip_in_allow_list(ip_str, allow_list, networks):
  class Message (line 82) | class Message:
    method __init__ (line 83) | def __init__(self, cfg, unreader, peer_addr):
    method force_close (line 114) | def force_close(self):
    method parse (line 117) | def parse(self, unreader):
    method parse_headers (line 120) | def parse_headers(self, data, from_trailer=False):
    method set_body_reader (line 234) | def set_body_reader(self):
    method should_close (line 294) | def should_close(self):
  class Request (line 308) | class Request(Message):
    method __init__ (line 309) | def __init__(self, cfg, unreader, peer_addr, req_number=1):
    method get_data (line 326) | def get_data(self, unreader, buf, stop=False):
    method parse (line 334) | def parse(self, unreader):
    method read_into (line 373) | def read_into(self, unreader, buf, stop=False):
    method read_line (line 382) | def read_line(self, unreader, buf, limit=0):
    method read_bytes (line 401) | def read_bytes(self, unreader, buf, count):
    method _handle_proxy_protocol (line 407) | def _handle_proxy_protocol(self, unreader, buf, mode):
    method proxy_protocol_access_check (line 429) | def proxy_protocol_access_check(self):
    method _parse_proxy_protocol_v1 (line 436) | def _parse_proxy_protocol_v1(self, unreader, buf):
    method _parse_proxy_protocol_v2 (line 497) | def _parse_proxy_protocol_v2(self, unreader, buf):
    method parse_request_line (line 590) | def parse_request_line(self, line_bytes):
    method set_body_reader (line 645) | def set_body_reader(self):

FILE: gunicorn/http/parser.py
  class Parser (line 11) | class Parser:
    method __init__ (line 15) | def __init__(self, cfg, source, source_addr):
    method __iter__ (line 27) | def __iter__(self):
    method finish_body (line 30) | def finish_body(self):
    method __next__ (line 46) | def __next__(self):
  class RequestParser (line 64) | class RequestParser(Parser):

FILE: gunicorn/http/unreader.py
  class Unreader (line 12) | class Unreader:
    method __init__ (line 13) | def __init__(self):
    method chunk (line 16) | def chunk(self):
    method read (line 19) | def read(self, size=None):
    method unread (line 51) | def unread(self, data):
  class SocketUnreader (line 58) | class SocketUnreader(Unreader):
    method __init__ (line 59) | def __init__(self, sock, max_chunk=8192):
    method chunk (line 64) | def chunk(self):
  class IterUnreader (line 68) | class IterUnreader(Unreader):
    method __init__ (line 69) | def __init__(self, iterable):
    method chunk (line 73) | def chunk(self):

FILE: gunicorn/http/wsgi.py
  class FileWrapper (line 27) | class FileWrapper:
    method __init__ (line 29) | def __init__(self, filelike, blksize=8192):
    method __getitem__ (line 35) | def __getitem__(self, key):
  class WSGIErrorsWrapper (line 42) | class WSGIErrorsWrapper(io.RawIOBase):
    method __init__ (line 44) | def __init__(self, cfg):
    method write (line 60) | def write(self, data):
  function base_environ (line 69) | def base_environ(cfg):
  function default_environ (line 82) | def default_environ(req, sock, cfg):
  function proxy_environ (line 95) | def proxy_environ(req):
  function _make_early_hints_callback (line 110) | def _make_early_hints_callback(req, sock, resp):
  function create (line 161) | def create(req, sock, client, server, cfg):
  class Response (line 261) | class Response:
    method __init__ (line 263) | def __init__(self, req, sock, cfg):
    method force_close (line 277) | def force_close(self):
    method should_close (line 280) | def should_close(self):
    method start_response (line 291) | def start_response(self, status, headers, exc_info=None):
    method process_headers (line 315) | def process_headers(self, headers):
    method is_chunked (line 347) | def is_chunked(self):
    method default_headers (line 364) | def default_headers(self):
    method send_headers (line 384) | def send_headers(self):
    method write (line 394) | def write(self, arg):
    method can_sendfile (line 417) | def can_sendfile(self):
    method sendfile (line 420) | def sendfile(self, respiter):
    method write_file (line 453) | def write_file(self, respiter):
    method close (line 458) | def close(self):

FILE: gunicorn/http2/__init__.py
  function is_http2_available (line 19) | def is_http2_available():
  function get_h2_version (line 43) | def get_h2_version():
  function get_http2_connection_class (line 54) | def get_http2_connection_class():
  function get_async_http2_connection_class (line 67) | def get_async_http2_connection_class():

FILE: gunicorn/http2/async_connection.py
  function _import_h2 (line 31) | def _import_h2():
  class AsyncHTTP2Connection (line 48) | class AsyncHTTP2Connection:
    method __init__ (line 58) | def __init__(self, cfg, reader, writer, client_addr):
    method initiate_connection (line 101) | async def initiate_connection(self):
    method receive_data (line 122) | async def receive_data(self, timeout=None):
    method _handle_event (line 194) | def _handle_event(self, event):
    method _handle_request_received (line 232) | def _handle_request_received(self, event):
    method _handle_data_received (line 244) | def _handle_data_received(self, event):
    method _handle_stream_ended (line 273) | def _handle_stream_ended(self, event):
    method _handle_stream_reset (line 284) | def _handle_stream_reset(self, event):
    method _handle_connection_terminated (line 292) | def _handle_connection_terminated(self, event):
    method _handle_trailers_received (line 296) | def _handle_trailers_received(self, event):
    method _handle_priority_updated (line 307) | def _handle_priority_updated(self, event):
    method send_informational (line 321) | async def send_informational(self, stream_id, status, headers):
    method send_response (line 353) | async def send_response(self, stream_id, status, headers, body=None):
    method _wait_for_flow_control_window (line 393) | async def _wait_for_flow_control_window(self, stream_id):
    method send_data (line 433) | async def send_data(self, stream_id, data, end_stream=False):
    method send_trailers (line 476) | async def send_trailers(self, stream_id, trailers):
    method send_error (line 520) | async def send_error(self, stream_id, status_code, message=None):
    method reset_stream (line 529) | async def reset_stream(self, stream_id, error_code=0x8):
    method close (line 538) | async def close(self, error_code=0x0, last_stream_id=None):
    method _send_pending_data (line 560) | async def _send_pending_data(self):
    method is_closed (line 572) | def is_closed(self):
    method cleanup_stream (line 576) | def cleanup_stream(self, stream_id):
    method __repr__ (line 580) | def __repr__(self):

FILE: gunicorn/http2/connection.py
  function _import_h2 (line 30) | def _import_h2():
  class HTTP2ServerConnection (line 47) | class HTTP2ServerConnection:
    method __init__ (line 58) | def __init__(self, cfg, sock, client_addr):
    method initiate_connection (line 101) | def initiate_connection(self):
    method receive_data (line 122) | def receive_data(self, data=None):
    method _handle_event (line 188) | def _handle_event(self, event):
    method _handle_request_received (line 226) | def _handle_request_received(self, event):
    method _handle_data_received (line 243) | def _handle_data_received(self, event):
    method _handle_stream_ended (line 277) | def _handle_stream_ended(self, event):
    method _handle_stream_reset (line 298) | def _handle_stream_reset(self, event):
    method _handle_connection_terminated (line 311) | def _handle_connection_terminated(self, event):
    method _handle_trailers_received (line 320) | def _handle_trailers_received(self, event):
    method _handle_priority_updated (line 340) | def _handle_priority_updated(self, event):
    method send_informational (line 354) | def send_informational(self, stream_id, status, headers):
    method send_response (line 386) | def send_response(self, stream_id, status, headers, body=None):
    method _wait_for_flow_control_window (line 430) | def _wait_for_flow_control_window(self, stream_id):
    method send_data (line 488) | def send_data(self, stream_id, data, end_stream=False):
    method send_trailers (line 532) | def send_trailers(self, stream_id, trailers):
    method send_error (line 576) | def send_error(self, stream_id, status_code, message=None):
    method reset_stream (line 591) | def reset_stream(self, stream_id, error_code=0x8):
    method close (line 605) | def close(self, error_code=0x0, last_stream_id=None):
    method _send_pending_data (line 627) | def _send_pending_data(self):
    method is_closed (line 638) | def is_closed(self):
    method cleanup_stream (line 642) | def cleanup_stream(self, stream_id):
    method __repr__ (line 650) | def __repr__(self):

FILE: gunicorn/http2/errors.py
  class HTTP2ErrorCode (line 13) | class HTTP2ErrorCode:
  class HTTP2Error (line 32) | class HTTP2Error(Exception):
    method __init__ (line 37) | def __init__(self, message=None, error_code=None):
  class HTTP2ProtocolError (line 44) | class HTTP2ProtocolError(HTTP2Error):
  class HTTP2InternalError (line 50) | class HTTP2InternalError(HTTP2Error):
  class HTTP2FlowControlError (line 56) | class HTTP2FlowControlError(HTTP2Error):
  class HTTP2SettingsTimeout (line 62) | class HTTP2SettingsTimeout(HTTP2Error):
  class HTTP2StreamClosed (line 68) | class HTTP2StreamClosed(HTTP2Error):
  class HTTP2FrameSizeError (line 74) | class HTTP2FrameSizeError(HTTP2Error):
  class HTTP2RefusedStream (line 80) | class HTTP2RefusedStream(HTTP2Error):
  class HTTP2Cancel (line 86) | class HTTP2Cancel(HTTP2Error):
  class HTTP2CompressionError (line 92) | class HTTP2CompressionError(HTTP2Error):
  class HTTP2ConnectError (line 98) | class HTTP2ConnectError(HTTP2Error):
  class HTTP2EnhanceYourCalm (line 104) | class HTTP2EnhanceYourCalm(HTTP2Error):
  class HTTP2InadequateSecurity (line 110) | class HTTP2InadequateSecurity(HTTP2Error):
  class HTTP2RequiresHTTP11 (line 116) | class HTTP2RequiresHTTP11(HTTP2Error):
  class HTTP2StreamError (line 122) | class HTTP2StreamError(HTTP2Error):
    method __init__ (line 125) | def __init__(self, stream_id, message=None, error_code=None):
    method __str__ (line 129) | def __str__(self):
  class HTTP2ConnectionError (line 133) | class HTTP2ConnectionError(HTTP2Error):
  class HTTP2ConfigurationError (line 137) | class HTTP2ConfigurationError(HTTP2Error):
  class HTTP2NotAvailable (line 141) | class HTTP2NotAvailable(HTTP2Error):
    method __init__ (line 144) | def __init__(self, message=None):

FILE: gunicorn/http2/request.py
  class HTTP2Body (line 17) | class HTTP2Body:
    method __init__ (line 24) | def __init__(self, data):
    method read (line 33) | def read(self, size=None):
    method readline (line 46) | def readline(self, size=None):
    method readlines (line 59) | def readlines(self, hint=None):
    method __iter__ (line 70) | def __iter__(self):
    method __len__ (line 74) | def __len__(self):
    method close (line 78) | def close(self):
  class HTTP2Request (line 83) | class HTTP2Request:
    method __init__ (line 91) | def __init__(self, stream, cfg, peer_addr):
    method force_close (line 168) | def force_close(self):
    method should_close (line 172) | def should_close(self):
    method get_header (line 186) | def get_header(self, name):
    method content_length (line 202) | def content_length(self):
    method content_type (line 217) | def content_type(self):
    method __repr__ (line 225) | def __repr__(self):

FILE: gunicorn/http2/stream.py
  class StreamState (line 18) | class StreamState(Enum):
  class HTTP2Stream (line 30) | class HTTP2Stream:
    method __init__ (line 37) | def __init__(self, stream_id, connection):
    method is_client_stream (line 75) | def is_client_stream(self):
    method is_server_stream (line 80) | def is_server_stream(self):
    method can_receive (line 85) | def can_receive(self):
    method can_send (line 93) | def can_send(self):
    method receive_headers (line 100) | def receive_headers(self, headers, end_stream=False):
    method receive_data (line 124) | def receive_data(self, data, end_stream=False):
    method receive_trailers (line 146) | def receive_trailers(self, trailers):
    method send_headers (line 162) | def send_headers(self, headers, end_stream=False):
    method send_data (line 185) | def send_data(self, data, end_stream=False):
    method send_trailers (line 205) | def send_trailers(self, trailers):
    method reset (line 223) | def reset(self, error_code=0x8):
    method close (line 233) | def close(self):
    method update_priority (line 239) | def update_priority(self, weight=None, depends_on=None, exclusive=None):
    method _half_close_local (line 254) | def _half_close_local(self):
    method _half_close_remote (line 266) | def _half_close_remote(self):
    method get_request_body (line 278) | def get_request_body(self):
    method get_pseudo_headers (line 286) | def get_pseudo_headers(self):
    method get_regular_headers (line 299) | def get_regular_headers(self):
    method __repr__ (line 311) | def __repr__(self):

FILE: gunicorn/instrument/statsd.py
  class Statsd (line 23) | class Statsd(Logger):
    method __init__ (line 26) | def __init__(self, cfg):
    method critical (line 44) | def critical(self, msg, *args, **kwargs):
    method error (line 48) | def error(self, msg, *args, **kwargs):
    method warning (line 52) | def warning(self, msg, *args, **kwargs):
    method exception (line 56) | def exception(self, msg, *args, **kwargs):
    method info (line 61) | def info(self, msg, *args, **kwargs):
    method debug (line 65) | def debug(self, msg, *args, **kwargs):
    method log (line 68) | def log(self, lvl, msg, *args, **kwargs):
    method access (line 96) | def access(self, resp, req, environ, request_time):
    method gauge (line 113) | def gauge(self, name, value):
    method increment (line 116) | def increment(self, name, value, sampling_rate=1.0):
    method decrement (line 119) | def decrement(self, name, value, sampling_rate=1.0):
    method timer (line 122) | def timer(self, name, value):
    method histogram (line 125) | def histogram(self, name, value):
    method _sock_send (line 128) | def _sock_send(self, msg):

FILE: gunicorn/pidfile.py
  class Pidfile (line 10) | class Pidfile:
    method __init__ (line 17) | def __init__(self, fname):
    method create (line 21) | def create(self, pid):
    method rename (line 48) | def rename(self, path):
    method unlink (line 53) | def unlink(self):
    method validate (line 64) | def validate(self):

FILE: gunicorn/reloader.py
  class ReloaderBase (line 16) | class ReloaderBase(threading.Thread):
    method __init__ (line 17) | def __init__(self, extra_files=None, interval=1, callback=None):
    method add_extra_file (line 24) | def add_extra_file(self, filename):
    method get_files (line 27) | def get_files(self):
  class Reloader (line 39) | class Reloader(ReloaderBase):
    method run (line 40) | def run(self):
  class InotifyReloader (line 70) | class InotifyReloader(ReloaderBase):
    method __init__ (line 76) | def __init__(self, extra_files=None, callback=None):
    method add_extra_file (line 81) | def add_extra_file(self, filename):
    method get_dirs (line 91) | def get_dirs(self):
    method refresh_dirs (line 95) | def refresh_dirs(self):
    method run (line 102) | def run(self):
    method __init__ (line 117) | def __init__(self, extra_files=None, callback=None):
  class InotifyReloader (line 116) | class InotifyReloader:
    method __init__ (line 76) | def __init__(self, extra_files=None, callback=None):
    method add_extra_file (line 81) | def add_extra_file(self, filename):
    method get_dirs (line 91) | def get_dirs(self):
    method refresh_dirs (line 95) | def refresh_dirs(self):
    method run (line 102) | def run(self):
    method __init__ (line 117) | def __init__(self, extra_files=None, callback=None):

FILE: gunicorn/sock.py
  class BaseSocket (line 19) | class BaseSocket:
    method __init__ (line 21) | def __init__(self, address, conf, log, fd=None):
    method __str__ (line 36) | def __str__(self):
    method __getattr__ (line 39) | def __getattr__(self, name):
    method set_options (line 42) | def set_options(self, sock, bound=False):
    method bind (line 62) | def bind(self, sock):
    method close (line 65) | def close(self):
    method get_backlog (line 76) | def get_backlog(self):
  class TCPSocket (line 80) | class TCPSocket(BaseSocket):
    method __str__ (line 84) | def __str__(self):
    method set_options (line 93) | def set_options(self, sock, bound=False):
    method get_backlog (line 98) | def get_backlog(self):
    method get_backlog (line 111) | def get_backlog(self):
  class TCP6Socket (line 115) | class TCP6Socket(TCPSocket):
    method __str__ (line 119) | def __str__(self):
  class UnixSocket (line 124) | class UnixSocket(BaseSocket):
    method __init__ (line 128) | def __init__(self, addr, conf, log, fd=None):
    method __str__ (line 142) | def __str__(self):
    method bind (line 145) | def bind(self, sock):
  function _sock_type (line 152) | def _sock_type(addr):
  function create_sockets (line 165) | def create_sockets(conf, log, fds=None):
  function close_sockets (line 230) | def close_sockets(listeners, unlink=True):
  function _get_alpn_protocols (line 238) | def _get_alpn_protocols(conf):
  function ssl_context (line 267) | def ssl_context(conf):
  function ssl_wrap_socket (line 285) | def ssl_wrap_socket(sock, conf):
  function get_negotiated_protocol (line 292) | def get_negotiated_protocol(ssl_socket):
  function is_http2_negotiated (line 308) | def is_http2_negotiated(ssl_socket):

FILE: gunicorn/systemd.py
  function listen_fds (line 11) | def listen_fds(unset_environment=True):
  function sd_notify (line 48) | def sd_notify(state, logger, unset_environment=False):

FILE: gunicorn/util.py
  function _setproctitle (line 52) | def _setproctitle(title):
  function _setproctitle (line 63) | def _setproctitle(title):
  function _setproctitle (line 66) | def _setproctitle(title):
  function load_entry_point (line 70) | def load_entry_point(distribution, group, name):
  function load_class (line 79) | def load_class(uri, default="gunicorn.workers.sync.SyncWorker",
  function get_arity (line 135) | def get_arity(f):
  function get_username (line 146) | def get_username(uid):
  function set_owner_process (line 151) | def set_owner_process(uid, gid, initgroups=False):
  function chown (line 170) | def chown(path, uid, gid):
  function _waitfor (line 175) | def _waitfor(func, pathname, waitall=False):
  function _unlink (line 208) | def _unlink(filename):
  function unlink (line 214) | def unlink(filename):
  function is_ipv6 (line 223) | def is_ipv6(addr):
  function parse_address (line 233) | def parse_address(netloc, default_port='8000'):
  function close_on_exec (line 264) | def close_on_exec(fd):
  function set_non_blocking (line 270) | def set_non_blocking(fd):
  function close (line 275) | def close(sock):
  function closerange (line 285) | def closerange(fd_low, fd_high):
  function write_chunk (line 294) | def write_chunk(sock, data):
  function write (line 302) | def write(sock, data, chunked=False):
  function write_nonblock (line 308) | def write_nonblock(sock, data, chunked=False):
  function write_error (line 320) | def write_error(sock, status_int, reason, mesg):
  function _called_with_wrong_args (line 343) | def _called_with_wrong_args(f):
  function import_app (line 369) | def import_app(module):
  function getcwd (line 452) | def getcwd():
  function http_date (line 466) | def http_date(timestamp=None):
  function is_hoppish (line 474) | def is_hoppish(header):
  function daemonize (line 478) | def daemonize(enable_stdio_inheritance=False):
  function seed (line 564) | def seed():
  function check_is_writable (line 571) | def check_is_writable(path):
  function to_bytestring (line 579) | def to_bytestring(value, encoding="utf8"):
  function has_fileno (line 589) | def has_fileno(obj):
  function warn (line 602) | def warn(msg):
  function make_fail_app (line 615) | def make_fail_app(msg):
  function split_request_uri (line 628) | def split_request_uri(uri):
  function reraise (line 641) | def reraise(tp, value, tb=None):
  function bytes_to_str (line 653) | def bytes_to_str(b):
  function unquote_to_wsgi_str (line 659) | def unquote_to_wsgi_str(string):

FILE: gunicorn/uwsgi/errors.py
  class UWSGIParseException (line 12) | class UWSGIParseException(Exception):
  class InvalidUWSGIHeader (line 16) | class InvalidUWSGIHeader(UWSGIParseException):
    method __init__ (line 19) | def __init__(self, msg=""):
    method __str__ (line 23) | def __str__(self):
  class UnsupportedModifier (line 27) | class UnsupportedModifier(UWSGIParseException):
    method __init__ (line 30) | def __init__(self, modifier):
    method __str__ (line 34) | def __str__(self):
  class ForbiddenUWSGIRequest (line 38) | class ForbiddenUWSGIRequest(UWSGIParseException):
    method __init__ (line 41) | def __init__(self, host):
    method __str__ (line 45) | def __str__(self):

FILE: gunicorn/uwsgi/message.py
  class UWSGIRequest (line 19) | class UWSGIRequest:
    method __init__ (line 33) | def __init__(self, cfg, unreader, peer_addr, req_number=1):
    method _check_allowed_ip (line 72) | def _check_allowed_ip(self):
    method force_close (line 87) | def force_close(self):
    method parse (line 91) | def parse(self, unreader):
    method _read_exact (line 118) | def _read_exact(self, unreader, size):
    method _parse_vars (line 138) | def _parse_vars(self, data):
    method _extract_request_info (line 177) | def _extract_request_info(self):
    method set_body_reader (line 232) | def set_body_reader(self):
    method should_close (line 245) | def should_close(self):

FILE: gunicorn/uwsgi/parser.py
  class UWSGIParser (line 9) | class UWSGIParser(Parser):

FILE: gunicorn/workers/base.py
  class Worker (line 30) | class Worker:
    method __init__ (line 38) | def __init__(self, age, ppid, sockets, app, timeout, cfg, log):
    method __str__ (line 67) | def __str__(self):
    method notify (line 70) | def notify(self):
    method run (line 78) | def run(self):
    method init_process (line 86) | def init_process(self):
    method load_wsgi (line 146) | def load_wsgi(self):
    method init_signals (line 162) | def init_signals(self):
    method handle_usr1 (line 182) | def handle_usr1(self, sig, frame):
    method handle_exit (line 185) | def handle_exit(self, sig, frame):
    method handle_quit (line 188) | def handle_quit(self, sig, frame):
    method handle_abort (line 195) | def handle_abort(self, sig, frame):
    method handle_error (line 200) | def handle_error(self, req, client, addr, exc):
    method handle_winch (line 285) | def handle_winch(self, sig, fname):

FILE: gunicorn/workers/base_async.py
  class AsyncWorker (line 20) | class AsyncWorker(base.Worker):
    method __init__ (line 22) | def __init__(self, *args, **kwargs):
    method timeout_ctx (line 26) | def timeout_ctx(self):
    method is_already_handled (line 29) | def is_already_handled(self, respiter):
    method handle (line 33) | def handle(self, listener, client, addr):
    method handle_http2 (line 103) | def handle_http2(self, listener, client, addr):
    method handle_http2_request (line 144) | def handle_http2_request(self, listener_name, req, sock, addr, h2_conn):
    method handle_request (line 199) | def handle_request(self, listener_name, req, sock, addr):

FILE: gunicorn/workers/gasgi.py
  class ASGIWorker (line 21) | class ASGIWorker(base.Worker):
    method __init__ (line 31) | def __init__(self, *args, **kwargs):
    method check_config (line 42) | def check_config(cls, cfg, log):
    method init_process (line 48) | def init_process(self):
    method _setup_event_loop (line 54) | def _setup_event_loop(self):
    method load_wsgi (line 79) | def load_wsgi(self):
    method _make_error_app (line 89) | def _make_error_app(self, error_msg):
    method init_signals (line 111) | def init_signals(self):
    method handle_quit_signal (line 125) | def handle_quit_signal(self):
    method handle_exit_signal (line 134) | def handle_exit_signal(self):
    method handle_usr1_signal (line 138) | def handle_usr1_signal(self):
    method handle_winch_signal (line 142) | def handle_winch_signal(self):
    method handle_abort_signal (line 146) | def handle_abort_signal(self):
    method run (line 152) | def run(self):
    method _serve (line 161) | async def _serve(self):
    method _shutdown (line 221) | async def _shutdown(self):
    method _get_ssl_context (line 260) | def _get_ssl_context(self):
    method _cleanup (line 272) | def _cleanup(self):

FILE: gunicorn/workers/geventlet.py
  function _eventlet_socket_sendfile (line 55) | def _eventlet_socket_sendfile(self, file, offset=0, count=None):
  function _eventlet_serve (line 93) | def _eventlet_serve(sock, handle, concurrency):
  function _eventlet_stop (line 116) | def _eventlet_stop(client, server, conn):
  function patch_sendfile (line 134) | def patch_sendfile():
  class EventletWorker (line 148) | class EventletWorker(AsyncWorker):
    method patch (line 150) | def patch(self):
    method is_already_handled (line 158) | def is_already_handled(self, respiter):
    method init_process (line 167) | def init_process(self):
    method handle_quit (line 175) | def handle_quit(self, sig, frame):
    method handle_usr1 (line 178) | def handle_usr1(self, sig, frame):
    method timeout_ctx (line 181) | def timeout_ctx(self):
    method handle (line 184) | def handle(self, listener, client, addr):
    method run (line 189) | def run(self):

FILE: gunicorn/workers/ggevent.py
  class GeventWorker (line 32) | class GeventWorker(AsyncWorker):
    method patch (line 37) | def patch(self):
    method notify (line 47) | def notify(self):
    method timeout_ctx (line 53) | def timeout_ctx(self):
    method run (line 56) | def run(self):
    method handle (line 116) | def handle(self, listener, client, addr):
    method handle_request (line 122) | def handle_request(self, listener_name, req, sock, addr):
    method handle_quit (line 130) | def handle_quit(self, sig, frame):
    method handle_usr1 (line 135) | def handle_usr1(self, sig, frame):
    method init_process (line 140) | def init_process(self):
  class GeventResponse (line 146) | class GeventResponse:
    method __init__ (line 152) | def __init__(self, status, headers, clength):
  class PyWSGIHandler (line 158) | class PyWSGIHandler(pywsgi.WSGIHandler):
    method log_request (line 160) | def log_request(self):
    method get_environ (line 176) | def get_environ(self):
  class PyWSGIServer (line 183) | class PyWSGIServer(pywsgi.WSGIServer):
  class GeventPyWSGIWorker (line 187) | class GeventPyWSGIWorker(GeventWorker):

FILE: gunicorn/workers/gthread.py
  class TConn (line 42) | class TConn:
    method __init__ (line 44) | def __init__(self, cfg, sock, client, server):
    method init (line 60) | def init(self):
    method set_timeout (line 89) | def set_timeout(self):
    method wait_for_data (line 93) | def wait_for_data(self, timeout):
    method close (line 124) | def close(self):
  class PollableMethodQueue (line 128) | class PollableMethodQueue:
    method __init__ (line 140) | def __init__(self):
    method init (line 145) | def init(self):
    method close (line 155) | def close(self):
    method fileno (line 168) | def fileno(self):
    method defer (line 172) | def defer(self, callback, *args):
    method run_callbacks (line 188) | def run_callbacks(self, _fileobj, max_callbacks=50):
  class ThreadWorker (line 212) | class ThreadWorker(base.Worker):
    method __init__ (line 214) | def __init__(self, *args, **kwargs):
    method check_config (line 229) | def check_config(cls, cfg, log):
    method init_process (line 236) | def init_process(self):
    method get_thread_pool (line 242) | def get_thread_pool(self):
    method handle_exit (line 246) | def handle_exit(self, sig, frame):
    method handle_quit (line 253) | def handle_quit(self, sig, frame):
    method set_accept_enabled (line 258) | def set_accept_enabled(self, enabled):
    method enqueue_req (line 272) | def enqueue_req(self, conn):
    method accept (line 278) | def accept(self, listener):
    method on_client_socket_readable (line 293) | def on_client_socket_readable(self, conn, client):
    method on_pending_socket_readable (line 301) | def on_pending_socket_readable(self, conn, client):
    method murder_keepalived (line 312) | def murder_keepalived(self):
    method murder_pending (line 330) | def murder_pending(self):
    method is_parent_alive (line 348) | def is_parent_alive(self):
    method wait_for_and_dispatch_events (line 355) | def wait_for_and_dispatch_events(self, timeout):
    method run (line 366) | def run(self):
    method finish_request (line 415) | def finish_request(self, conn, fs):
    method handle (line 443) | def handle(self, conn):
    method handle_http2 (line 508) | def handle_http2(self, conn):
    method handle_http2_request (line 557) | def handle_http2_request(self, req, conn, h2_conn):
    method handle_request (line 649) | def handle_request(self, req, conn):

FILE: gunicorn/workers/gtornado.py
  class TornadoWorker (line 21) | class TornadoWorker(Worker):
    method setup (line 24) | def setup(cls):
    method handle_exit (line 35) | def handle_exit(self, sig, frame):
    method handle_request (line 39) | def handle_request(self):
    method watchdog (line 45) | def watchdog(self):
    method heartbeat (line 53) | def heartbeat(self):
    method init_process (line 67) | def init_process(self):
    method run (line 75) | def run(self):

FILE: gunicorn/workers/sync.py
  class StopWaiting (line 21) | class StopWaiting(Exception):
  class SyncWorker (line 25) | class SyncWorker(base.Worker):
    method accept (line 27) | def accept(self, listener):
    method wait (line 33) | def wait(self, timeout):
    method is_parent_alive (line 52) | def is_parent_alive(self):
    method run_for_one (line 59) | def run_for_one(self, timeout):
    method run_for_multiple (line 88) | def run_for_multiple(self, timeout):
    method run (line 112) | def run(self):
    method handle (line 135) | def handle(self, listener, client, addr):
    method handle_request (line 169) | def handle_request(self, listener, req, client, addr):

FILE: gunicorn/workers/workertmp.py
  class WorkerTmp (line 16) | class WorkerTmp:
    method __init__ (line 18) | def __init__(self, cfg):
    method notify (line 42) | def notify(self):
    method last_update (line 46) | def last_update(self):
    method fileno (line 49) | def fileno(self):
    method close (line 52) | def close(self):

FILE: scripts/build_settings_doc.py
  function _format_default (line 38) | def _format_default(setting: guncfg.Setting) -> tuple[str, bool]:
  function _format_cli (line 51) | def _format_cli(setting: guncfg.Setting) -> str | None:
  function _convert_refs (line 81) | def _convert_refs(text: str) -> str:
  function _consume_indented (line 107) | def _consume_indented(lines: List[str], start: int) -> tuple[str, int]:
  function _convert_desc (line 121) | def _convert_desc(desc: str) -> str:
  function _format_setting (line 195) | def _format_setting(setting: guncfg.Setting) -> str:
  function render_settings (line 219) | def render_settings() -> str:
  function _write_output (line 233) | def _write_output(markdown: str) -> None:
  function main (line 252) | def main() -> None:

FILE: tests/ctl/test_client.py
  class TestControlClientInit (line 22) | class TestControlClientInit:
    method test_init_attributes (line 25) | def test_init_attributes(self):
  class TestControlClientConnect (line 35) | class TestControlClientConnect:
    method test_connect_nonexistent_socket (line 38) | def test_connect_nonexistent_socket(self):
    method test_connect_success (line 47) | def test_connect_success(self):
    method test_connect_already_connected (line 66) | def test_connect_already_connected(self):
  class TestControlClientClose (line 87) | class TestControlClientClose:
    method test_close_idempotent (line 90) | def test_close_idempotent(self):
    method test_close_clears_socket (line 96) | def test_close_clears_socket(self):
  class TestControlClientContextManager (line 105) | class TestControlClientContextManager:
    method test_context_manager_connection_error (line 108) | def test_context_manager_connection_error(self):
    method test_context_manager_success (line 116) | def test_context_manager_success(self):
  class TestControlClientSendCommand (line 135) | class TestControlClientSendCommand:
    method test_send_command_success (line 138) | def test_send_command_success(self):
    method test_send_command_error_response (line 174) | def test_send_command_error_response(self):
    method test_send_command_auto_connect (line 211) | def test_send_command_auto_connect(self):
  class TestParseCommand (line 244) | class TestParseCommand:
    method test_parse_simple_command (line 247) | def test_parse_simple_command(self):
    method test_parse_command_with_args (line 253) | def test_parse_command_with_args(self):
    method test_parse_command_with_multiple_args (line 259) | def test_parse_command_with_multiple_args(self):
    method test_parse_empty_command (line 265) | def test_parse_empty_command(self):
    method test_parse_command_quoted (line 271) | def test_parse_command_quoted(self):

FILE: tests/ctl/test_handlers.py
  class MockWorker (line 14) | class MockWorker:
    method __init__ (line 17) | def __init__(self, pid, age, booted=True, aborted=False):
  class MockListener (line 26) | class MockListener:
    method __init__ (line 29) | def __init__(self, address, fd=3):
    method __str__ (line 35) | def __str__(self):
    method fileno (line 38) | def fileno(self):
  class MockConfig (line 42) | class MockConfig:
    method __init__ (line 45) | def __init__(self):
  class MockArbiter (line 68) | class MockArbiter:
    method __init__ (line 71) | def __init__(self):
    method wakeup (line 86) | def wakeup(self):
  class TestShowWorkers (line 90) | class TestShowWorkers:
    method test_show_workers_empty (line 93) | def test_show_workers_empty(self):
    method test_show_workers_with_workers (line 103) | def test_show_workers_with_workers(self):
  class TestShowStats (line 130) | class TestShowStats:
    method test_show_stats (line 133) | def test_show_stats(self):
  class TestShowConfig (line 154) | class TestShowConfig:
    method test_show_config (line 157) | def test_show_config(self):
  class TestShowListeners (line 169) | class TestShowListeners:
    method test_show_listeners_empty (line 172) | def test_show_listeners_empty(self):
    method test_show_listeners (line 182) | def test_show_listeners(self):
  class TestWorkerAdd (line 198) | class TestWorkerAdd:
    method test_worker_add_default (line 201) | def test_worker_add_default(self):
    method test_worker_add_multiple (line 215) | def test_worker_add_multiple(self):
  class TestWorkerRemove (line 227) | class TestWorkerRemove:
    method test_worker_remove_default (line 230) | def test_worker_remove_default(self):
    method test_worker_remove_cannot_go_below_one (line 244) | def test_worker_remove_cannot_go_below_one(self):
  class TestWorkerKill (line 258) | class TestWorkerKill:
    method test_worker_kill_success (line 261) | def test_worker_kill_success(self):
    method test_worker_kill_not_found (line 274) | def test_worker_kill_not_found(self):
  class TestShowDirty (line 285) | class TestShowDirty:
    method test_show_dirty_disabled (line 288) | def test_show_dirty_disabled(self):
  class TestDirtyAdd (line 299) | class TestDirtyAdd:
    method test_dirty_add_not_running (line 302) | def test_dirty_add_not_running(self):
    method test_dirty_add_no_socket (line 312) | def test_dirty_add_no_socket(self):
  class TestDirtyRemove (line 326) | class TestDirtyRemove:
    method test_dirty_remove_not_running (line 329) | def test_dirty_remove_not_running(self):
    method test_dirty_remove_no_socket (line 339) | def test_dirty_remove_no_socket(self):
  class TestReload (line 353) | class TestReload:
    method test_reload (line 356) | def test_reload(self):
  class TestReopen (line 368) | class TestReopen:
    method test_reopen (line 371) | def test_reopen(self):
  class TestShutdown (line 383) | class TestShutdown:
    method test_shutdown_graceful (line 386) | def test_shutdown_graceful(self):
    method test_shutdown_quick (line 398) | def test_shutdown_quick(self):
  class TestShowAll (line 411) | class TestShowAll:
    method test_show_all_basic (line 414) | def test_show_all_basic(self):
    method test_show_all_with_dirty (line 439) | def test_show_all_with_dirty(self):
  class TestHelp (line 452) | class TestHelp:
    method test_help (line 455) | def test_help(self):

FILE: tests/ctl/test_protocol.py
  class TestControlProtocolEncoding (line 20) | class TestControlProtocolEncoding:
    method test_encode_message_simple (line 23) | def test_encode_message_simple(self):
    method test_encode_message_unicode (line 35) | def test_encode_message_unicode(self):
    method test_decode_message_simple (line 46) | def test_decode_message_simple(self):
    method test_decode_message_too_short (line 56) | def test_decode_message_too_short(self):
    method test_decode_message_incomplete (line 62) | def test_decode_message_incomplete(self):
    method test_roundtrip (line 70) | def test_roundtrip(self):
  class TestMakeRequest (line 85) | class TestMakeRequest:
    method test_make_request_simple (line 88) | def test_make_request_simple(self):
    method test_make_request_with_args (line 96) | def test_make_request_with_args(self):
  class TestMakeResponse (line 105) | class TestMakeResponse:
    method test_make_response_simple (line 108) | def test_make_response_simple(self):
    method test_make_response_empty_data (line 116) | def test_make_response_empty_data(self):
  class TestMakeErrorResponse (line 125) | class TestMakeErrorResponse:
    method test_make_error_response (line 128) | def test_make_error_response(self):
  class TestControlProtocolSocket (line 137) | class TestControlProtocolSocket:
    method test_read_write_message (line 140) | def test_read_write_message(self):
    method test_read_connection_closed (line 166) | def test_read_connection_closed(self):
    method test_read_message_too_large (line 178) | def test_read_message_too_large(self):
  class TestControlProtocolAsync (line 196) | class TestControlProtocolAsync:
    method test_async_read_write (line 200) | async def test_async_read_write(self):
  class TestProtocolMaxSize (line 233) | class TestProtocolMaxSize:
    method test_max_message_size_constant (line 236) | def test_max_message_size_constant(self):
    method test_encode_large_message (line 241) | def test_encode_large_message(self):

FILE: tests/ctl/test_server.py
  class MockWorker (line 18) | class MockWorker:
    method __init__ (line 21) | def __init__(self, pid, age, booted=True, aborted=False):
  class MockConfig (line 30) | class MockConfig:
    method __init__ (line 33) | def __init__(self):
  class MockLog (line 56) | class MockLog:
    method debug (line 59) | def debug(self, msg, *args):
    method info (line 62) | def info(self, msg, *args):
    method warning (line 65) | def warning(self, msg, *args):
    method error (line 68) | def error(self, msg, *args):
    method exception (line 71) | def exception(self, msg, *args):
  class MockArbiter (line 75) | class MockArbiter:
    method __init__ (line 78) | def __init__(self):
    method wakeup (line 94) | def wakeup(self):
  class TestControlSocketServerInit (line 98) | class TestControlSocketServerInit:
    method test_init (line 101) | def test_init(self):
  class TestControlSocketServerLifecycle (line 112) | class TestControlSocketServerLifecycle:
    method test_start_stop (line 115) | def test_start_stop(self):
    method test_start_already_running (line 142) | def test_start_already_running(self):
    method test_stop_not_running (line 158) | def test_stop_not_running(self):
  class TestControlSocketServerIntegration (line 167) | class TestControlSocketServerIntegration:
    method test_show_workers (line 170) | def test_show_workers(self):
    method test_show_stats (line 200) | def test_show_stats(self):
    method test_help_command (line 225) | def test_help_command(self):
    method test_worker_add (line 250) | def test_worker_add(self):
    method test_invalid_command (line 278) | def test_invalid_command(self):
    method test_multiple_commands (line 303) | def test_multiple_commands(self):
  class TestControlSocketServerPermissions (line 333) | class TestControlSocketServerPermissions:
    method test_socket_permissions (line 340) | def test_socket_permissions(self):

FILE: tests/dirty/test_arbiter_signals.py
  class TestDirtyArbiterSignals (line 13) | class TestDirtyArbiterSignals:
    method arbiter (line 17) | def arbiter(self, tmp_path):
    method test_initial_num_workers_from_config (line 32) | def test_initial_num_workers_from_config(self, arbiter):
    method test_ttin_increases_num_workers (line 36) | def test_ttin_increases_num_workers(self, arbiter):
    method test_ttin_logs_info (line 42) | def test_ttin_logs_info(self, arbiter):
    method test_ttou_decreases_num_workers (line 50) | def test_ttou_decreases_num_workers(self, arbiter):
    method test_ttou_logs_info (line 56) | def test_ttou_logs_info(self, arbiter):
    method test_ttou_respects_minimum_one_worker (line 65) | def test_ttou_respects_minimum_one_worker(self, arbiter):
    method test_ttou_logs_warning_at_minimum (line 71) | def test_ttou_logs_warning_at_minimum(self, arbiter):
    method test_ttou_respects_app_minimum (line 79) | def test_ttou_respects_app_minimum(self, arbiter):
    method test_ttou_with_unlimited_app (line 96) | def test_ttou_with_unlimited_app(self, arbiter):
    method test_multiple_ttin_signals (line 111) | def test_multiple_ttin_signals(self, arbiter):
    method test_multiple_ttou_signals (line 119) | def test_multiple_ttou_signals(self, arbiter):
  class TestGetMinimumWorkers (line 130) | class TestGetMinimumWorkers:
    method arbiter (line 134) | def arbiter(self, tmp_path):
    method test_minimum_workers_no_apps (line 149) | def test_minimum_workers_no_apps(self, arbiter):
    method test_minimum_workers_single_app_with_limit (line 154) | def test_minimum_workers_single_app_with_limit(self, arbiter):
    method test_minimum_workers_single_app_unlimited (line 165) | def test_minimum_workers_single_app_unlimited(self, arbiter):
    method test_minimum_workers_multiple_apps_with_limits (line 176) | def test_minimum_workers_multiple_apps_with_limits(self, arbiter):
    method test_minimum_workers_mixed_limited_and_unlimited (line 198) | def test_minimum_workers_mixed_limited_and_unlimited(self, arbiter):
    method test_minimum_workers_all_unlimited (line 220) | def test_minimum_workers_all_unlimited(self, arbiter):

FILE: tests/dirty/test_arbiter_streaming.py
  class MockStreamWriter (line 27) | class MockStreamWriter:
    method __init__ (line 30) | def __init__(self):
    method write (line 35) | def write(self, data):
    method drain (line 38) | async def drain(self):
    method close (line 58) | def close(self):
    method wait_closed (line 61) | async def wait_closed(self):
    method get_extra_info (line 64) | def get_extra_info(self, name):
  class MockStreamReader (line 68) | class MockStreamReader:
    method __init__ (line 71) | def __init__(self, messages):
    method readexactly (line 77) | async def readexactly(self, n):
  function create_arbiter (line 85) | def create_arbiter():
  class TestArbiterStreamingForwarding (line 108) | class TestArbiterStreamingForwarding:
    method test_forwards_chunk_messages (line 112) | async def test_forwards_chunk_messages(self):
    method test_forwards_regular_response (line 141) | async def test_forwards_regular_response(self):
    method test_forwards_error_mid_stream (line 162) | async def test_forwards_error_mid_stream(self):
    method test_timeout_during_streaming (line 185) | async def test_timeout_during_streaming(self):
  class TestArbiterRouteRequestStreaming (line 209) | class TestArbiterRouteRequestStreaming:
    method test_route_request_no_workers (line 213) | async def test_route_request_no_workers(self):
    method test_route_request_starts_consumer (line 227) | async def test_route_request_starts_consumer(self):
  class TestArbiterStreamingManyChunks (line 254) | class TestArbiterStreamingManyChunks:
    method test_forwards_many_chunks (line 258) | async def test_forwards_many_chunks(self):
  class TestArbiterBackwardCompatibility (line 285) | class TestArbiterBackwardCompatibility:
    method test_handles_regular_response (line 289) | async def test_handles_regular_response(self):
    method test_handles_error_response (line 310) | async def test_handles_error_response(self):

FILE: tests/dirty/test_client_streaming.py
  class MockSocket (line 25) | class MockSocket:
    method __init__ (line 28) | def __init__(self, messages):
    method sendall (line 37) | def sendall(self, data):
    method recv (line 40) | def recv(self, n, flags=0):
    method settimeout (line 48) | def settimeout(self, timeout):
    method close (line 51) | def close(self):
  function create_client_with_mock_socket (line 55) | def create_client_with_mock_socket(messages):
  class TestDirtyStreamIterator (line 62) | class TestDirtyStreamIterator:
    method test_stream_returns_iterator (line 65) | def test_stream_returns_iterator(self):
    method test_stream_iterator_yields_chunks (line 71) | def test_stream_iterator_yields_chunks(self):
    method test_stream_iterator_yields_complex_chunks (line 85) | def test_stream_iterator_yields_complex_chunks(self):
    method test_stream_iterator_handles_error (line 100) | def test_stream_iterator_handles_error(self):
    method test_stream_iterator_empty_stream (line 119) | def test_stream_iterator_empty_stream(self):
    method test_stream_iterator_stops_after_exhausted (line 127) | def test_stream_iterator_stops_after_exhausted(self):
    method test_stream_iterator_with_for_loop (line 149) | def test_stream_iterator_with_for_loop(self):
    method test_stream_sends_request_on_first_iteration (line 165) | def test_stream_sends_request_on_first_iteration(self):
  class TestDirtyStreamIteratorEdgeCases (line 195) | class TestDirtyStreamIteratorEdgeCases:
    method test_stream_many_chunks (line 198) | def test_stream_many_chunks(self):
    method test_stream_with_kwargs (line 213) | def test_stream_with_kwargs(self):

FILE: tests/dirty/test_client_streaming_async.py
  class MockAsyncReader (line 23) | class MockAsyncReader:
    method __init__ (line 26) | def __init__(self, messages):
    method readexactly (line 32) | async def readexactly(self, n):
  class MockAsyncWriter (line 40) | class MockAsyncWriter:
    method __init__ (line 43) | def __init__(self):
    method write (line 47) | def write(self, data):
    method drain (line 50) | async def drain(self):
    method close (line 53) | def close(self):
    method wait_closed (line 56) | async def wait_closed(self):
  function create_async_client_with_mocks (line 60) | def create_async_client_with_mocks(messages):
  class TestDirtyAsyncStreamIterator (line 68) | class TestDirtyAsyncStreamIterator:
    method test_stream_async_returns_async_iterator (line 71) | def test_stream_async_returns_async_iterator(self):
    method test_async_stream_yields_chunks (line 78) | async def test_async_stream_yields_chunks(self):
    method test_async_stream_yields_complex_chunks (line 95) | async def test_async_stream_yields_complex_chunks(self):
    method test_async_stream_handles_error (line 113) | async def test_async_stream_handles_error(self):
    method test_async_stream_empty_stream (line 133) | async def test_async_stream_empty_stream(self):
    method test_async_stream_stops_after_exhausted (line 145) | async def test_async_stream_stops_after_exhausted(self):
    method test_async_stream_sends_request_on_first_iteration (line 168) | async def test_async_stream_sends_request_on_first_iteration(self):
  class TestDirtyAsyncStreamIteratorEdgeCases (line 198) | class TestDirtyAsyncStreamIteratorEdgeCases:
    method test_async_stream_many_chunks (line 202) | async def test_async_stream_many_chunks(self):
    method test_async_stream_with_kwargs (line 220) | async def test_async_stream_with_kwargs(self):
  class TestDirtyAsyncStreamTimeout (line 244) | class TestDirtyAsyncStreamTimeout:
    method test_async_stream_timeout (line 248) | async def test_async_stream_timeout(self):

FILE: tests/dirty/test_multi_app_routing.py
  class MockLog (line 36) | class MockLog:
    method __init__ (line 39) | def __init__(self):
    method debug (line 42) | def debug(self, msg, *args):
    method info (line 45) | def info(self, msg, *args):
    method warning (line 48) | def warning(self, msg, *args):
    method error (line 51) | def error(self, msg, *args):
    method critical (line 54) | def critical(self, msg, *args):
    method exception (line 57) | def exception(self, msg, *args):
    method close_on_exec (line 60) | def close_on_exec(self):
    method reopen_files (line 63) | def reopen_files(self):
  class MockStreamWriter (line 67) | class MockStreamWriter:
    method __init__ (line 70) | def __init__(self):
    method write (line 75) | def write(self, data):
    method drain (line 78) | async def drain(self):
    method close (line 98) | def close(self):
    method wait_closed (line 101) | async def wait_closed(self):
    method get_extra_info (line 104) | def get_extra_info(self, name):
  class TestWorkerMultiAppLoading (line 108) | class TestWorkerMultiAppLoading:
    method test_worker_loads_multiple_apps (line 111) | def test_worker_loads_multiple_apps(self):
    method test_worker_apps_are_distinct_instances (line 141) | def test_worker_apps_are_distinct_instances(self):
  class TestWorkerMultiAppRouting (line 172) | class TestWorkerMultiAppRouting:
    method test_worker_routes_to_counter_app (line 176) | async def test_worker_routes_to_counter_app(self):
    method test_worker_routes_to_echo_app (line 211) | async def test_worker_routes_to_echo_app(self):
    method test_worker_routes_mixed_requests (line 252) | async def test_worker_routes_mixed_requests(self):
  class TestAppStateSeparation (line 307) | class TestAppStateSeparation:
    method test_apps_maintain_separate_state (line 311) | async def test_apps_maintain_separate_state(self):
  class TestUnknownAppPath (line 374) | class TestUnknownAppPath:
    method test_unknown_app_path_raises_error (line 378) | async def test_unknown_app_path_raises_error(self):
    method test_handle_request_unknown_app_returns_error (line 406) | async def test_handle_request_unknown_app_returns_error(self):
  class TestConcurrentMultiAppRequests (line 443) | class TestConcurrentMultiAppRequests:
    method test_concurrent_requests_to_different_apps (line 447) | async def test_concurrent_requests_to_different_apps(self):
  class TestMultiAppProtocolHandling (line 495) | class TestMultiAppProtocolHandling:
    method test_handle_request_routes_correctly (line 499) | async def test_handle_request_routes_correctly(self):
  class TestMultiAppCleanup (line 550) | class TestMultiAppCleanup:
    method test_cleanup_closes_all_apps (line 553) | def test_cleanup_closes_all_apps(self):
  class TestMultiAppArbiterIntegration (line 583) | class TestMultiAppArbiterIntegration:
    method test_arbiter_routes_no_workers_error (line 587) | async def test_arbiter_routes_no_workers_error(self):
    method test_arbiter_config_has_multiple_apps (line 615) | def test_arbiter_config_has_multiple_apps(self):

FILE: tests/dirty/test_per_app_worker_allocation.py
  class MockLog (line 13) | class MockLog:
    method __init__ (line 16) | def __init__(self):
    method debug (line 19) | def debug(self, msg, *args):
    method info (line 22) | def info(self, msg, *args):
    method warning (line 25) | def warning(self, msg, *args):
    method error (line 28) | def error(self, msg, *args):
    method critical (line 31) | def critical(self, msg, *args):
    method exception (line 34) | def exception(self, msg, *args):
    method close_on_exec (line 37) | def close_on_exec(self):
    method reopen_files (line 40) | def reopen_files(self):
  class TestPerAppWorkerAllocation (line 44) | class TestPerAppWorkerAllocation:
    method test_heavy_app_loaded_on_limited_workers (line 47) | def test_heavy_app_loaded_on_limited_workers(self):
    method test_light_app_loaded_on_all_workers (line 76) | def test_light_app_loaded_on_all_workers(self):
    method test_mixed_apps_correct_distribution (line 98) | def test_mixed_apps_correct_distribution(self):
    method test_request_routing_respects_allocation (line 127) | async def test_request_routing_respects_allocation(self):
    method test_worker_crash_app_reassigned_to_new_worker (line 161) | def test_worker_crash_app_reassigned_to_new_worker(self):
    method test_worker_crash_other_workers_still_serve_app (line 195) | async def test_worker_crash_other_workers_still_serve_app(self):
    method test_worker_crash_sole_worker_app_unavailable_until_respawn (line 232) | async def test_worker_crash_sole_worker_app_unavailable_until_respawn(...
    method test_config_format_module_class_n (line 259) | def test_config_format_module_class_n(self):
    method test_class_attribute_workers_detected (line 275) | def test_class_attribute_workers_detected(self):
    method test_config_override_takes_precedence_over_class_attribute (line 300) | def test_config_override_takes_precedence_over_class_attribute(self):

FILE: tests/dirty/test_streaming_integration.py
  class MockLog (line 35) | class MockLog:
    method __init__ (line 38) | def __init__(self):
    method debug (line 41) | def debug(self, msg, *args):
    method info (line 44) | def info(self, msg, *args):
    method warning (line 47) | def warning(self, msg, *args):
    method error (line 50) | def error(self, msg, *args):
    method close_on_exec (line 53) | def close_on_exec(self):
    method reopen_files (line 56) | def reopen_files(self):
  class MockStreamWriter (line 60) | class MockStreamWriter:
    method __init__ (line 63) | def __init__(self):
    method write (line 68) | def write(self, data):
    method drain (line 71) | async def drain(self):
    method close (line 91) | def close(self):
    method wait_closed (line 94) | async def wait_closed(self):
    method get_extra_info (line 97) | def get_extra_info(self, name):
  class MockStreamReader (line 101) | class MockStreamReader:
    method __init__ (line 104) | def __init__(self, messages):
    method readexactly (line 110) | async def readexactly(self, n):
  class TestStreamingEndToEnd (line 118) | class TestStreamingEndToEnd:
    method test_sync_generator_end_to_end (line 122) | async def test_sync_generator_end_to_end(self):
    method test_async_generator_end_to_end (line 166) | async def test_async_generator_end_to_end(self):
  class TestStreamingErrorHandling (line 201) | class TestStreamingErrorHandling:
    method test_error_mid_stream (line 205) | async def test_error_mid_stream(self):
  class TestStreamingBackwardCompatibility (line 242) | class TestStreamingBackwardCompatibility:
    method test_non_streaming_response_still_works (line 246) | async def test_non_streaming_response_still_works(self):
    method test_error_response_still_works (line 279) | async def test_error_response_still_works(self):
  class TestStreamingWorkerIntegration (line 310) | class TestStreamingWorkerIntegration:
    method test_worker_handles_sync_generator (line 314) | async def test_worker_handles_sync_generator(self):
    method test_worker_handles_async_generator (line 357) | async def test_worker_handles_async_generator(self):
  class TestStreamingMixedScenarios (line 398) | class TestStreamingMixedScenarios:
    method test_large_stream (line 402) | async def test_large_stream(self):
    method test_stream_with_complex_data (line 437) | async def test_stream_with_complex_data(self):

FILE: tests/dirty/test_worker_streaming.py
  class FakeStreamWriter (line 24) | class FakeStreamWriter:
    method __init__ (line 27) | def __init__(self):
    method write (line 31) | def write(self, data):
    method drain (line 34) | async def drain(self):
    method close (line 54) | def close(self):
    method wait_closed (line 57) | async def wait_closed(self):
  function create_worker (line 61) | def create_worker():
  class TestWorkerSyncGeneratorStreaming (line 92) | class TestWorkerSyncGeneratorStreaming:
    method test_sync_generator_sends_chunks_and_end (line 96) | async def test_sync_generator_sends_chunks_and_end(self):
    method test_sync_generator_error_mid_stream (line 133) | async def test_sync_generator_error_mid_stream(self):
  class TestWorkerAsyncGeneratorStreaming (line 159) | class TestWorkerAsyncGeneratorStreaming:
    method test_async_generator_sends_chunks_and_end (line 163) | async def test_async_generator_sends_chunks_and_end(self):
    method test_async_generator_error_mid_stream (line 199) | async def test_async_generator_error_mid_stream(self):
  class TestWorkerNonStreamingBackwardCompat (line 225) | class TestWorkerNonStreamingBackwardCompat:
    method test_non_generator_returns_response (line 229) | async def test_non_generator_returns_response(self):
    method test_list_result_not_treated_as_streaming (line 248) | async def test_list_result_not_treated_as_streaming(self):
    method test_error_in_execute_sends_error (line 266) | async def test_error_in_execute_sends_error(self):
    method test_none_result (line 284) | async def test_none_result(self):
  class TestWorkerStreamingComplexData (line 302) | class TestWorkerStreamingComplexData:
    method test_streaming_dict_chunks (line 306) | async def test_streaming_dict_chunks(self):
    method test_streaming_empty_generator (line 329) | async def test_streaming_empty_generator(self):
    method test_streaming_many_chunks (line 350) | async def test_streaming_many_chunks(self):
  class TestWorkerStreamingHeartbeat (line 373) | class TestWorkerStreamingHeartbeat:
    method test_heartbeat_updated_during_streaming (line 377) | async def test_heartbeat_updated_during_streaming(self):
  class TestWorkerMessageTypeValidation (line 407) | class TestWorkerMessageTypeValidation:
    method test_unknown_message_type_sends_error (line 411) | async def test_unknown_message_type_sends_error(self):

FILE: tests/docker/asgi/app.py
  function app (line 8) | async def app(scope, receive, send):

FILE: tests/docker/asgi_compliance/apps/framework_apps.py
  function fallback_app (line 47) | async def fallback_app(scope, receive, send):
  function starlette_homepage (line 91) | async def starlette_homepage(request):
  function starlette_json (line 95) | async def starlette_json(request):
  function starlette_echo (line 104) | async def starlette_echo(request):
  function starlette_headers (line 109) | async def starlette_headers(request):
  function starlette_scope (line 113) | async def starlette_scope(request):
  function starlette_streaming (line 134) | async def starlette_streaming(request):
  function starlette_websocket_endpoint (line 143) | async def starlette_websocket_endpoint(websocket: WebSocket):
  function starlette_health (line 153) | async def starlette_health(request):
  function starlette_lifespan (line 161) | async def starlette_lifespan(app):
  function fastapi_lifespan (line 199) | async def fastapi_lifespan(app: FastAPI):
  function fastapi_root (line 214) | async def fastapi_root():
  function fastapi_json (line 219) | async def fastapi_json(request: Request) -> Dict[str, Any]:
  function fastapi_echo (line 229) | async def fastapi_echo(request: Request):
  function fastapi_headers (line 238) | async def fastapi_headers(request: Request):
  function fastapi_scope (line 243) | async def fastapi_scope(request: Request):
  function fastapi_streaming (line 260) | async def fastapi_streaming():
  function fastapi_health (line 270) | async def fastapi_health():
  function fastapi_get_item (line 275) | async def fastapi_get_item(item_id: int, q: str = None):
  function fastapi_create_item (line 280) | async def fastapi_create_item(request: Request):
  function fastapi_websocket_echo (line 286) | async def fastapi_websocket_echo(websocket: FastAPIWebSocket):
  function combined_app (line 304) | async def combined_app(scope, receive, send):

FILE: tests/docker/asgi_compliance/apps/http_app.py
  function app (line 16) | async def app(scope, receive, send):
  function handle_lifespan (line 61) | async def handle_lifespan(scope, receive, send):
  function handle_root (line 75) | async def handle_root(scope, receive, send):
  function handle_echo (line 94) | async def handle_echo(scope, receive, send):
  function handle_headers (line 123) | async def handle_headers(scope, receive, send):
  function handle_scope (line 159) | async def handle_scope(scope, receive, send):
  function handle_status (line 213) | async def handle_status(scope, receive, send):
  function handle_large (line 250) | async def handle_large(scope, receive, send):
  function handle_method (line 286) | async def handle_method(scope, receive, send):
  function handle_query (line 309) | async def handle_query(scope, receive, send):
  function handle_post_json (line 352) | async def handle_post_json(scope, receive, send):
  function handle_delay (line 397) | async def handle_delay(scope, receive, send):
  function handle_health (line 436) | async def handle_health(scope, receive, send):
  function handle_early_hints (line 457) | async def handle_early_hints(scope, receive, send):
  function handle_cookies (line 489) | async def handle_cookies(scope, receive, send):
  function handle_redirect (line 537) | async def handle_redirect(scope, receive, send):
  function handle_not_found (line 572) | async def handle_not_found(scope, receive, send):
  function drain_body (line 578) | async def drain_body(receive):
  function send_error (line 586) | async def send_error(send, status, message):

FILE: tests/docker/asgi_compliance/apps/lifespan_app.py
  function app (line 28) | async def app(scope, receive, send):
  function handle_lifespan (line 53) | async def handle_lifespan(scope, receive, send):
  function handle_root (line 97) | async def handle_root(scope, receive, send):
  function handle_state (line 124) | async def handle_state(scope, receive, send):
  function handle_lifespan_info (line 172) | async def handle_lifespan_info(scope, receive, send):
  function handle_counter (line 208) | async def handle_counter(scope, receive, send):
  function handle_health (line 241) | async def handle_health(scope, receive, send):
  function handle_not_found (line 267) | async def handle_not_found(scope, receive, send):
  function drain_body (line 273) | async def drain_body(receive):
  function send_error (line 281) | async def send_error(send, status, message):
  function create_app (line 301) | def create_app():

FILE: tests/docker/asgi_compliance/apps/main_app.py
  function app (line 29) | async def app(scope, receive, send):
  function handle_lifespan (line 98) | async def handle_lifespan(scope, receive, send):
  function handle_root (line 126) | async def handle_root(scope, receive, send):
  function handle_health (line 185) | async def handle_health(scope, receive, send):
  function handle_info (line 206) | async def handle_info(scope, receive, send):
  function drain_body (line 239) | async def drain_body(receive):

FILE: tests/docker/asgi_compliance/apps/streaming_app.py
  function app (line 17) | async def app(scope, receive, send):
  function handle_lifespan (line 51) | async def handle_lifespan(scope, receive, send):
  function handle_streaming (line 62) | async def handle_streaming(scope, receive, send):
  function handle_sse (line 106) | async def handle_sse(scope, receive, send):
  function handle_chunked (line 170) | async def handle_chunked(scope, receive, send):
  function handle_slow_stream (line 205) | async def handle_slow_stream(scope, receive, send):
  function handle_large_stream (line 249) | async def handle_large_stream(scope, receive, send):
  function handle_infinite (line 293) | async def handle_infinite(scope, receive, send):
  function handle_echo_stream (line 340) | async def handle_echo_stream(scope, receive, send):
  function handle_ndjson (line 380) | async def handle_ndjson(scope, receive, send):
  function handle_health (line 429) | async def handle_health(scope, receive, send):
  function handle_not_found (line 450) | async def handle_not_found(scope, receive, send):
  function drain_body (line 471) | async def drain_body(receive):

FILE: tests/docker/asgi_compliance/apps/websocket_app.py
  function app (line 15) | async def app(scope, receive, send):
  function handle_lifespan (line 57) | async def handle_lifespan(scope, receive, send):
  function handle_echo (line 68) | async def handle_echo(scope, receive, send):
  function handle_echo_binary (line 100) | async def handle_echo_binary(scope, receive, send):
  function handle_subprotocol (line 128) | async def handle_subprotocol(scope, receive, send):
  function handle_close (line 173) | async def handle_close(scope, receive, send):
  function handle_scope (line 206) | async def handle_scope(scope, receive, send):
  function handle_reject (line 245) | async def handle_reject(scope, receive, send):
  function handle_ping (line 259) | async def handle_ping(scope, receive, send):
  function handle_broadcast (line 290) | async def handle_broadcast(scope, receive, send):
  function handle_large_message (line 331) | async def handle_large_message(scope, receive, send):
  function handle_fragmented (line 377) | async def handle_fragmented(scope, receive, send):
  function handle_delay (line 420) | async def handle_delay(scope, receive, send):
  function handle_unknown (line 460) | async def handle_unknown(scope, receive, send):
  function send_http_error (line 480) | async def send_http_error(send, status, message):

FILE: tests/docker/asgi_compliance/conftest.py
  function generate_self_signed_cert (line 19) | def generate_self_signed_cert(certs_dir: Path) -> None:
  function wait_for_http_service (line 50) | def wait_for_http_service(host: str, port: int, timeout: int = 60) -> bool:
  function wait_for_https_service (line 62) | def wait_for_https_service(host: str, port: int, timeout: int = 60) -> b...
  function docker_compose_file (line 82) | def docker_compose_file():
  function certs_dir (line 88) | def certs_dir():
  function docker_services (line 95) | def docker_services(docker_compose_file, certs_dir):
  function gunicorn_url (line 186) | def gunicorn_url(docker_services):
  function gunicorn_ssl_url (line 192) | def gunicorn_ssl_url(docker_services):
  function nginx_url (line 198) | def nginx_url(docker_services):
  function nginx_ssl_url (line 204) | def nginx_ssl_url(docker_services):
  function http_client (line 214) | def http_client():
  function http2_client (line 223) | def http2_client():
  function async_http_client (line 232) | async def async_http_client():
  function async_http_client_factory (line 240) | def async_http_client_factory():
  function websocket_connect (line 257) | def websocket_connect():
  function sse_client (line 290) | def sse_client():
  function streaming_client (line 329) | def streaming_client():
  function pytest_configure (line 362) | def pytest_configure(config):

FILE: tests/docker/asgi_compliance/test_concurrency.py
  class TestConcurrentHTTP (line 29) | class TestConcurrentHTTP:
    method test_concurrent_simple_requests (line 32) | async def test_concurrent_simple_requests(self, async_http_client_fact...
    method test_concurrent_echo_requests (line 45) | async def test_concurrent_echo_requests(self, async_http_client_factor...
    method test_concurrent_different_endpoints (line 62) | async def test_concurrent_different_endpoints(self, async_http_client_...
    method test_concurrent_with_delays (line 87) | async def test_concurrent_with_delays(self, async_http_client_factory,...
  class TestConcurrentWebSocket (line 109) | class TestConcurrentWebSocket:
    method test_many_concurrent_websockets (line 112) | async def test_many_concurrent_websockets(self, websocket_connect, gun...
    method test_concurrent_websocket_many_messages (line 128) | async def test_concurrent_websocket_many_messages(self, websocket_conn...
  class TestMixedProtocols (line 153) | class TestMixedProtocols:
    method test_http_and_websocket_concurrent (line 156) | async def test_http_and_websocket_concurrent(
    method test_streaming_and_http_concurrent (line 186) | async def test_streaming_and_http_concurrent(
  class TestConnectionReuse (line 222) | class TestConnectionReuse:
    method test_many_requests_single_client (line 225) | async def test_many_requests_single_client(
    method test_keep_alive_stress (line 234) | async def test_keep_alive_stress(self, async_http_client_factory, guni...
  class TestLoad (line 252) | class TestLoad:
    method test_burst_requests (line 255) | async def test_burst_requests(self, async_http_client_factory, gunicor...
    method test_sustained_load (line 276) | async def test_sustained_load(self, async_http_client_factory, gunicor...
  class TestResourceHandling (line 307) | class TestResourceHandling:
    method test_many_small_requests (line 310) | async def test_many_small_requests(self, async_http_client_factory, gu...
    method test_concurrent_large_responses (line 325) | async def test_concurrent_large_responses(
  class TestProxyConcurrency (line 347) | class TestProxyConcurrency:
    method test_proxy_concurrent_http (line 350) | async def test_proxy_concurrent_http(self, async_http_client_factory, ...
    method test_proxy_concurrent_websocket (line 363) | async def test_proxy_concurrent_websocket(self, websocket_connect, ngi...
  class TestHTTPSConcurrency (line 385) | class TestHTTPSConcurrency:
    method test_https_concurrent_http (line 388) | async def test_https_concurrent_http(
    method test_https_concurrent_websocket (line 401) | async def test_https_concurrent_websocket(
  class TestStress (line 424) | class TestStress:
    method test_rapid_connect_disconnect (line 427) | async def test_rapid_connect_disconnect(
    method test_rapid_websocket_connect_disconnect (line 436) | async def test_rapid_websocket_connect_disconnect(
    method test_mixed_success_and_error_paths (line 448) | async def test_mixed_success_and_error_paths(

FILE: tests/docker/asgi_compliance/test_framework_integration.py
  class TestFrameworkAvailability (line 27) | class TestFrameworkAvailability:
    method test_framework_root_endpoint (line 30) | def test_framework_root_endpoint(self, http_client, gunicorn_url):
    method test_framework_health (line 39) | def test_framework_health(self, http_client, gunicorn_url):
  class TestStarletteBasic (line 49) | class TestStarletteBasic:
    method test_starlette_homepage (line 52) | def test_starlette_homepage(self, http_client, gunicorn_url):
    method test_starlette_json (line 60) | def test_starlette_json(self, http_client, gunicorn_url):
    method test_starlette_json_query_params (line 69) | def test_starlette_json_query_params(self, http_client, gunicorn_url):
    method test_starlette_echo (line 79) | def test_starlette_echo(self, http_client, gunicorn_url):
    method test_starlette_headers (line 91) | def test_starlette_headers(self, http_client, gunicorn_url):
    method test_starlette_scope (line 104) | def test_starlette_scope(self, http_client, gunicorn_url):
    method test_starlette_health (line 114) | def test_starlette_health(self, http_client, gunicorn_url):
  class TestStarletteStreaming (line 122) | class TestStarletteStreaming:
    method test_starlette_streaming (line 125) | def test_starlette_streaming(self, http_client, gunicorn_url):
    method test_starlette_streaming_chunks (line 133) | def test_starlette_streaming_chunks(self, streaming_client, gunicorn_u...
  class TestStarletteWebSocket (line 149) | class TestStarletteWebSocket:
    method test_starlette_websocket_echo (line 153) | async def test_starlette_websocket_echo(self, websocket_connect, gunic...
  class TestFastAPIBasic (line 171) | class TestFastAPIBasic:
    method test_fastapi_homepage (line 174) | def test_fastapi_homepage(self, http_client, gunicorn_url):
    method test_fastapi_json (line 183) | def test_fastapi_json(self, http_client, gunicorn_url):
    method test_fastapi_json_query_params (line 192) | def test_fastapi_json_query_params(self, http_client, gunicorn_url):
    method test_fastapi_echo (line 202) | def test_fastapi_echo(self, http_client, gunicorn_url):
    method test_fastapi_headers (line 216) | def test_fastapi_headers(self, http_client, gunicorn_url):
    method test_fastapi_scope (line 229) | def test_fastapi_scope(self, http_client, gunicorn_url):
    method test_fastapi_health (line 239) | def test_fastapi_health(self, http_client, gunicorn_url):
  class TestFastAPIPathParameters (line 249) | class TestFastAPIPathParameters:
    method test_path_parameter_int (line 252) | def test_path_parameter_int(self, http_client, gunicorn_url):
    method test_path_parameter_with_query (line 261) | def test_path_parameter_with_query(self, http_client, gunicorn_url):
    method test_create_item (line 271) | def test_create_item(self, http_client, gunicorn_url):
  class TestFastAPIStreaming (line 285) | class TestFastAPIStreaming:
    method test_fastapi_streaming (line 288) | def test_fastapi_streaming(self, http_client, gunicorn_url):
    method test_fastapi_streaming_chunks (line 296) | def test_fastapi_streaming_chunks(self, streaming_client, gunicorn_url):
  class TestFastAPIWebSocket (line 312) | class TestFastAPIWebSocket:
    method test_fastapi_websocket_echo (line 316) | async def test_fastapi_websocket_echo(self, websocket_connect, gunicor...
  class TestCrossFramework (line 334) | class TestCrossFramework:
    method test_both_frameworks_available (line 337) | def test_both_frameworks_available(self, http_client, gunicorn_url):
    method test_framework_independence (line 351) | def test_framework_independence(self, http_client, gunicorn_url):
  class TestProxyFramework (line 373) | class TestProxyFramework:
    method test_proxy_framework_root (line 376) | def test_proxy_framework_root(self, http_client, nginx_url):
    method test_proxy_starlette (line 383) | def test_proxy_starlette(self, http_client, nginx_url):
    method test_proxy_fastapi (line 392) | def test_proxy_fastapi(self, http_client, nginx_url):
  class TestHTTPSFramework (line 407) | class TestHTTPSFramework:
    method test_https_starlette (line 410) | def test_https_starlette(self, http_client, gunicorn_ssl_url):
    method test_https_fastapi (line 419) | def test_https_fastapi(self, http_client, gunicorn_ssl_url):
    method test_https_proxy_starlette (line 428) | def test_https_proxy_starlette(self, http_client, nginx_ssl_url):
    method test_https_proxy_fastapi (line 435) | def test_https_proxy_fastapi(self, http_client, nginx_ssl_url):
  class TestAsyncFramework (line 457) | class TestAsyncFramework:
    method test_async_starlette (line 460) | async def test_async_starlette(self, async_http_client_factory, gunico...
    method test_async_fastapi (line 470) | async def test_async_fastapi(self, async_http_client_factory, gunicorn...
    method test_concurrent_framework_requests (line 480) | async def test_concurrent_framework_requests(self, async_http_client_f...

FILE: tests/docker/asgi_compliance/test_http2_asgi.py
  class TestHTTP2Basic (line 27) | class TestHTTP2Basic:
    method test_http2_request (line 30) | def test_http2_request(self, http2_client, nginx_ssl_url):
    method test_http2_scope (line 37) | def test_http2_scope(self, http2_client, nginx_ssl_url):
    method test_http2_headers (line 46) | def test_http2_headers(self, http2_client, nginx_ssl_url):
  class TestHTTP2Multiplexing (line 66) | class TestHTTP2Multiplexing:
    method test_concurrent_requests_single_connection (line 69) | async def test_concurrent_requests_single_connection(
    method test_interleaved_requests (line 86) | async def test_interleaved_requests(
  class TestHTTP2Streaming (line 116) | class TestHTTP2Streaming:
    method test_http2_streaming_response (line 119) | def test_http2_streaming_response(self, http2_client, nginx_ssl_url):
    method test_http2_sse (line 125) | def test_http2_sse(self, http2_client, nginx_ssl_url):
    method test_http2_large_response (line 131) | def test_http2_large_response(self, http2_client, nginx_ssl_url):
  class TestHTTP2RequestBody (line 142) | class TestHTTP2RequestBody:
    method test_http2_post_json (line 145) | def test_http2_post_json(self, http2_client, nginx_ssl_url):
    method test_http2_post_echo (line 156) | def test_http2_post_echo(self, http2_client, nginx_ssl_url):
    method test_http2_large_request_body (line 166) | def test_http2_large_request_body(self, http2_client, nginx_ssl_url):
  class TestHTTP2ASGIScope (line 181) | class TestHTTP2ASGIScope:
    method test_scope_type_http (line 184) | def test_scope_type_http(self, http2_client, nginx_ssl_url):
    method test_scope_asgi_version (line 191) | def test_scope_asgi_version(self, http2_client, nginx_ssl_url):
    method test_scope_scheme_https (line 199) | def test_scope_scheme_https(self, http2_client, nginx_ssl_url):
    method test_scope_method_preserved (line 207) | def test_scope_method_preserved(self, http2_client, nginx_ssl_url):
    method test_scope_path_preserved (line 214) | def test_scope_path_preserved(self, http2_client, nginx_ssl_url):
    method test_scope_query_string (line 222) | def test_scope_query_string(self, http2_client, nginx_ssl_url):
  class TestHTTP2Framework (line 234) | class TestHTTP2Framework:
    method test_http2_starlette (line 237) | def test_http2_starlette(self, http2_client, nginx_ssl_url):
    method test_http2_fastapi (line 246) | def test_http2_fastapi(self, http2_client, nginx_ssl_url):
  class TestHTTP2Errors (line 260) | class TestHTTP2Errors:
    method test_http2_404 (line 263) | def test_http2_404(self, http2_client, nginx_ssl_url):
    method test_http2_500 (line 268) | def test_http2_500(self, http2_client, nginx_ssl_url):
    method test_http2_various_status_codes (line 273) | def test_http2_various_status_codes(self, http2_client, nginx_ssl_url):
  class TestHTTP2Async (line 288) | class TestHTTP2Async:
    method test_async_http2_streaming (line 291) | async def test_async_http2_streaming(
    method test_async_http2_concurrent_streams (line 307) | async def test_async_http2_concurrent_streams(
    method test_async_http2_mixed_requests (line 325) | async def test_async_http2_mixed_requests(
  class TestHTTP2Lifespan (line 363) | class TestHTTP2Lifespan:
    method test_http2_lifespan_state (line 366) | def test_http2_lifespan_state(self, http2_client, nginx_ssl_url):
    method test_http2_lifespan_counter (line 374) | def test_http2_lifespan_counter(self, http2_client, nginx_ssl_url):
  class TestHTTP2Direct (line 387) | class TestHTTP2Direct:
    method test_direct_https_request (line 390) | def test_direct_https_request(self, http_client, gunicorn_ssl_url):
    method test_direct_https_scope (line 395) | def test_direct_https_scope(self, http_client, gunicorn_ssl_url):
    method test_direct_https_streaming (line 404) | def test_direct_https_streaming(self, http_client, gunicorn_ssl_url):

FILE: tests/docker/asgi_compliance/test_http_compliance.py
  class TestBasicHTTPRequests (line 27) | class TestBasicHTTPRequests:
    method test_root_endpoint (line 30) | def test_root_endpoint(self, http_client, gunicorn_url):
    method test_health_endpoint (line 36) | def test_health_endpoint(self, http_client, gunicorn_url):
    method test_http_app_root (line 42) | def test_http_app_root(self, http_client, gunicorn_url):
    method test_not_found (line 48) | def test_not_found(self, http_client, gunicorn_url):
  class TestHTTPMethods (line 54) | class TestHTTPMethods:
    method test_get_method (line 57) | def test_get_method(self, http_client, gunicorn_url):
    method test_post_method (line 64) | def test_post_method(self, http_client, gunicorn_url):
    method test_put_method (line 71) | def test_put_method(self, http_client, gunicorn_url):
    method test_delete_method (line 78) | def test_delete_method(self, http_client, gunicorn_url):
    method test_patch_method (line 85) | def test_patch_method(self, http_client, gunicorn_url):
    method test_head_method (line 92) | def test_head_method(self, http_client, gunicorn_url):
    method test_options_method (line 98) | def test_options_method(self, http_client, gunicorn_url):
  class TestHTTPStatusCodes (line 106) | class TestHTTPStatusCodes:
    method test_status_codes (line 112) | def test_status_codes(self, http_client, gunicorn_url, status_code):
    method test_invalid_status_code (line 117) | def test_invalid_status_code(self, http_client, gunicorn_url):
  class TestRequestBody (line 127) | class TestRequestBody:
    method test_echo_small_body (line 130) | def test_echo_small_body(self, http_client, gunicorn_url):
    method test_echo_large_body (line 137) | def test_echo_large_body(self, http_client, gunicorn_url):
    method test_echo_empty_body (line 145) | def test_echo_empty_body(self, http_client, gunicorn_url):
    method test_post_json (line 151) | def test_post_json(self, http_client, gunicorn_url):
    method test_post_json_array (line 163) | def test_post_json_array(self, http_client, gunicorn_url):
  class TestResponseBody (line 176) | class TestResponseBody:
    method test_large_response (line 179) | def test_large_response(self, http_client, gunicorn_url):
    method test_large_response_custom_size (line 185) | def test_large_response_custom_size(self, http_client, gunicorn_url):
  class TestRequestHeaders (line 197) | class TestRequestHeaders:
    method test_headers_received (line 200) | def test_headers_received(self, http_client, gunicorn_url):
    method test_host_header (line 214) | def test_host_header(self, http_client, gunicorn_url):
    method test_user_agent_header (line 221) | def test_user_agent_header(self, http_client, gunicorn_url):
    method test_content_type_header (line 231) | def test_content_type_header(self, http_client, gunicorn_url):
  class TestResponseHeaders (line 243) | class TestResponseHeaders:
    method test_content_type_response (line 246) | def test_content_type_response(self, http_client, gunicorn_url):
    method test_content_length_response (line 251) | def test_content_length_response(self, http_client, gunicorn_url):
  class TestASGIScope (line 261) | class TestASGIScope:
    method test_scope_type (line 264) | def test_scope_type(self, http_client, gunicorn_url):
    method test_scope_asgi_version (line 271) | def test_scope_asgi_version(self, http_client, gunicorn_url):
    method test_scope_http_version (line 278) | def test_scope_http_version(self, http_client, gunicorn_url):
    method test_scope_method (line 284) | def test_scope_method(self, http_client, gunicorn_url):
    method test_scope_scheme (line 290) | def test_scope_scheme(self, http_client, gunicorn_url):
    method test_scope_path (line 296) | def test_scope_path(self, http_client, gunicorn_url):
    method test_scope_query_string (line 302) | def test_scope_query_string(self, http_client, gunicorn_url):
    method test_scope_headers_are_list (line 308) | def test_scope_headers_are_list(self, http_client, gunicorn_url):
    method test_scope_server (line 317) | def test_scope_server(self, http_client, gunicorn_url):
    method test_scope_client (line 325) | def test_scope_client(self, http_client, gunicorn_url):
  class TestQueryStrings (line 338) | class TestQueryStrings:
    method test_simple_query (line 341) | def test_simple_query(self, http_client, gunicorn_url):
    method test_multiple_params (line 348) | def test_multiple_params(self, http_client, gunicorn_url):
    method test_empty_query (line 357) | def test_empty_query(self, http_client, gunicorn_url):
    method test_url_encoded_query (line 365) | def test_url_encoded_query(self, http_client, gunicorn_url):
  class TestCookies (line 377) | class TestCookies:
    method test_set_cookie (line 380) | def test_set_cookie(self, http_client, gunicorn_url):
    method test_receive_cookie (line 386) | def test_receive_cookie(self, http_client, gunicorn_url):
  class TestRedirects (line 401) | class TestRedirects:
    method test_redirect_302 (line 404) | def test_redirect_302(self, http_client, gunicorn_url):
    method test_redirect_301 (line 410) | def test_redirect_301(self, http_client, gunicorn_url):
    method test_redirect_307 (line 415) | def test_redirect_307(self, http_client, gunicorn_url):
  class TestConnections (line 425) | class TestConnections:
    method test_multiple_requests_same_connection (line 428) | def test_multiple_requests_same_connection(self, http_client, gunicorn...
    method test_concurrent_requests (line 434) | def test_concurrent_requests(self, http_client, gunicorn_url):
  class TestProxyRequests (line 455) | class TestProxyRequests:
    method test_proxy_basic_request (line 458) | def test_proxy_basic_request(self, http_client, nginx_url):
    method test_proxy_headers_forwarded (line 464) | def test_proxy_headers_forwarded(self, http_client, nginx_url):
    method test_proxy_large_request (line 472) | def test_proxy_large_request(self, http_client, nginx_url):
    method test_proxy_large_response (line 479) | def test_proxy_large_response(self, http_client, nginx_url):
  class TestHTTPS (line 491) | class TestHTTPS:
    method test_https_basic_request (line 494) | def test_https_basic_request(self, http_client, gunicorn_ssl_url):
    method test_https_scope_scheme (line 499) | def test_https_scope_scheme(self, http_client, gunicorn_ssl_url):
    method test_https_via_proxy (line 506) | def test_https_via_proxy(self, http_client, nginx_ssl_url):
  class TestErrorHandling (line 516) | class TestErrorHandling:
    method test_invalid_json_body (line 519) | def test_invalid_json_body(self, http_client, gunicorn_url):
    method test_method_not_allowed (line 529) | def test_method_not_allowed(self, http_client, gunicorn_url):

FILE: tests/docker/asgi_compliance/test_lifespan_compliance.py
  class TestLifespanStartup (line 26) | class TestLifespanStartup:
    method test_startup_complete (line 29) | def test_startup_complete(self, http_client, gunicorn_url):
    method test_startup_called (line 38) | def test_startup_called(self, http_client, gunicorn_url):
    method test_startup_time_recorded (line 46) | def test_startup_time_recorded(self, http_client, gunicorn_url):
    method test_health_after_startup (line 54) | def test_health_after_startup(self, http_client, gunicorn_url):
  class TestLifespanInfo (line 64) | class TestLifespanInfo:
    method test_lifespan_info_endpoint (line 67) | def test_lifespan_info_endpoint(self, http_client, gunicorn_url):
    method test_uptime_tracking (line 76) | def test_uptime_tracking(self, http_client, gunicorn_url):
  class TestStateSharing (line 91) | class TestStateSharing:
    method test_state_endpoint (line 94) | def test_state_endpoint(self, http_client, gunicorn_url):
    method test_request_count_increments (line 101) | def test_request_count_increments(self, http_client, gunicorn_url):
  class TestCounter (line 122) | class TestCounter:
    method test_counter_endpoint (line 125) | def test_counter_endpoint(self, http_client, gunicorn_url):
    method test_counter_increments_multiple_times (line 133) | def test_counter_increments_multiple_times(self, http_client, gunicorn...
  class TestBasicEndpoints (line 149) | class TestBasicEndpoints:
    method test_root_endpoint (line 152) | def test_root_endpoint(self, http_client, gunicorn_url):
    method test_not_found (line 158) | def test_not_found(self, http_client, gunicorn_url):
  class TestProxyLifespan (line 168) | class TestProxyLifespan:
    method test_proxy_health (line 171) | def test_proxy_health(self, http_client, nginx_url):
    method test_proxy_state (line 177) | def test_proxy_state(self, http_client, nginx_url):
    method test_proxy_counter (line 184) | def test_proxy_counter(self, http_client, nginx_url):
  class TestHTTPSLifespan (line 197) | class TestHTTPSLifespan:
    method test_https_health (line 200) | def test_https_health(self, http_client, gunicorn_ssl_url):
    method test_https_state (line 205) | def test_https_state(self, http_client, gunicorn_ssl_url):
    method test_https_proxy_health (line 212) | def test_https_proxy_health(self, http_client, nginx_ssl_url):
  class TestConcurrentLifespan (line 223) | class TestConcurrentLifespan:
    method test_concurrent_counter_access (line 226) | async def test_concurrent_counter_access(self, async_http_client_facto...

FILE: tests/docker/asgi_compliance/test_streaming_compliance.py
  class TestBasicStreaming (line 29) | class TestBasicStreaming:
    method test_streaming_endpoint (line 32) | def test_streaming_endpoint(self, http_client, gunicorn_url):
    method test_streaming_multiple_chunks (line 38) | def test_streaming_multiple_chunks(self, http_client, gunicorn_url):
    method test_streaming_single_chunk (line 47) | def test_streaming_single_chunk(self, http_client, gunicorn_url):
  class TestChunkedStreaming (line 54) | class TestChunkedStreaming:
    method test_stream_chunks_received (line 57) | def test_stream_chunks_received(self, streaming_client, gunicorn_url):
    method test_stream_variable_chunk_sizes (line 65) | def test_stream_variable_chunk_sizes(self, streaming_client, gunicorn_...
    method test_stream_lines (line 73) | def test_stream_lines(self, streaming_client, gunicorn_url):
  class TestServerSentEvents (line 84) | class TestServerSentEvents:
    method test_sse_content_type (line 87) | def test_sse_content_type(self, http_client, gunicorn_url):
    method test_sse_event_format (line 93) | def test_sse_event_format(self, http_client, gunicorn_url):
    method test_sse_data_is_json (line 117) | def test_sse_data_is_json(self, http_client, gunicorn_url):
    method test_sse_multiple_events (line 130) | def test_sse_multiple_events(self, http_client, gunicorn_url):
  class TestSSEClient (line 140) | class TestSSEClient:
    method test_sse_client_receives_events (line 143) | def test_sse_client_receives_events(self, sse_client, gunicorn_url):
    method test_sse_client_parses_data (line 148) | def test_sse_client_parses_data(self, sse_client, gunicorn_url):
  class TestNDJSONStreaming (line 163) | class TestNDJSONStreaming:
    method test_ndjson_content_type (line 166) | def test_ndjson_content_type(self, http_client, gunicorn_url):
    method test_ndjson_format (line 172) | def test_ndjson_format(self, http_client, gunicorn_url):
    method test_ndjson_streaming (line 186) | def test_ndjson_streaming(self, streaming_client, gunicorn_url):
  class TestSlowStreaming (line 199) | class TestSlowStreaming:
    method test_slow_stream_completes (line 202) | def test_slow_stream_completes(self, http_client, gunicorn_url):
    method test_slow_stream_chunks_timed (line 212) | def test_slow_stream_chunks_timed(self, streaming_client, gunicorn_url):
  class TestLargeStreaming (line 232) | class TestLargeStreaming:
    method test_large_stream_size (line 235) | def test_large_stream_size(self, http_client, gunicorn_url):
    method test_large_stream_chunked (line 242) | def test_large_stream_chunked(self, streaming_client, gunicorn_url):
  class TestEchoStreaming (line 261) | class TestEchoStreaming:
    method test_echo_stream_response (line 264) | def test_echo_stream_response(self, http_client, gunicorn_url):
    method test_echo_stream_large_body (line 274) | def test_echo_stream_large_body(self, http_client, gunicorn_url):
  class TestTransferEncoding (line 289) | class TestTransferEncoding:
    method test_chunked_encoding_header (line 292) | def test_chunked_encoding_header(self, http_client, gunicorn_url):
    method test_no_content_length_in_stream (line 299) | def test_no_content_length_in_stream(self, http_client, gunicorn_url):
  class TestProxyStreaming (line 311) | class TestProxyStreaming:
    method test_proxy_streaming (line 314) | def test_proxy_streaming(self, http_client, nginx_url):
    method test_proxy_sse (line 320) | def test_proxy_sse(self, http_client, nginx_url):
    method test_proxy_large_stream (line 327) | def test_proxy_large_stream(self, http_client, nginx_url):
    method test_proxy_slow_stream (line 334) | def test_proxy_slow_stream(self, streaming_client, nginx_url):
  class TestHTTPSStreaming (line 348) | class TestHTTPSStreaming:
    method test_https_streaming (line 351) | def test_https_streaming(self, http_client, gunicorn_ssl_url):
    method test_https_sse (line 357) | def test_https_sse(self, http_client, gunicorn_ssl_url):
    method test_https_proxy_streaming (line 363) | def test_https_proxy_streaming(self, http_client, nginx_ssl_url):
  class TestAsyncStreaming (line 374) | class TestAsyncStreaming:
    method test_async_streaming (line 377) | async def test_async_streaming(self, async_http_client_factory, gunico...
    method test_async_stream_chunks (line 384) | async def test_async_stream_chunks(self, async_http_client_factory, gu...
    method test_async_sse (line 396) | async def test_async_sse(self, async_http_client_factory, gunicorn_url):
  class TestStreamingEdgeCases (line 419) | class TestStreamingEdgeCases:
    method test_empty_stream (line 422) | def test_empty_stream(self, http_client, gunicorn_url):
    method test_single_byte_chunks (line 428) | def test_single_byte_chunks(self, streaming_client, gunicorn_url):
    method test_sse_no_delay (line 436) | def test_sse_no_delay(self, http_client, gunicorn_url):

FILE: tests/docker/asgi_compliance/test_websocket_compliance.py
  class TestWebSocketHandshake (line 30) | class TestWebSocketHandshake:
    method test_basic_connection (line 33) | async def test_basic_connection(self, websocket_connect, gunicorn_url):
    method test_echo_after_connect (line 42) | async def test_echo_after_connect(self, websocket_connect, gunicorn_url):
    method test_connection_path_preserved (line 50) | async def test_connection_path_preserved(self, websocket_connect, guni...
    method test_connection_with_query_string (line 58) | async def test_connection_with_query_string(self, websocket_connect, g...
  class TestTextMessages (line 73) | class TestTextMessages:
    method test_echo_text (line 76) | async def test_echo_text(self, websocket_connect, gunicorn_url):
    method test_echo_unicode (line 84) | async def test_echo_unicode(self, websocket_connect, gunicorn_url):
    method test_echo_empty_string (line 93) | async def test_echo_empty_string(self, websocket_connect, gunicorn_url):
    method test_multiple_messages (line 101) | async def test_multiple_messages(self, websocket_connect, gunicorn_url):
    method test_rapid_messages (line 111) | async def test_rapid_messages(self, websocket_connect, gunicorn_url):
  class TestBinaryMessages (line 129) | class TestBinaryMessages:
    method test_echo_binary (line 132) | async def test_echo_binary(self, websocket_connect, gunicorn_url):
    method test_echo_binary_large (line 141) | async def test_echo_binary_large(self, websocket_connect, gunicorn_url):
    method test_text_to_binary_conversion (line 150) | async def test_text_to_binary_conversion(self, websocket_connect, guni...
  class TestSubprotocols (line 164) | class TestSubprotocols:
    method test_single_subprotocol (line 167) | async def test_single_subprotocol(self, websocket_connect, gunicorn_url):
    method test_multiple_subprotocols (line 176) | async def test_multiple_subprotocols(self, websocket_connect, gunicorn...
    method test_preferred_subprotocol (line 186) | async def test_preferred_subprotocol(self, websocket_connect, gunicorn...
    method test_no_subprotocol (line 195) | async def test_no_subprotocol(self, websocket_connect, gunicorn_url):
  class TestCloseCodes (line 210) | class TestCloseCodes:
    method test_normal_close (line 213) | async def test_normal_close(self, websocket_connect, gunicorn_url):
    method test_going_away_close (line 224) | async def test_going_away_close(self, websocket_connect, gunicorn_url):
    method test_protocol_error_close (line 235) | async def test_protocol_error_close(self, websocket_connect, gunicorn_...
    method test_close_with_reason (line 246) | async def test_close_with_reason(self, websocket_connect, gunicorn_url):
    method test_application_close_code (line 258) | async def test_application_close_code(self, websocket_connect, gunicor...
  class TestConnectionRejection (line 275) | class TestConnectionRejection:
    method test_reject_connection (line 278) | async def test_reject_connection(self, websocket_connect, gunicorn_url):
  class TestWebSocketScope (line 294) | class TestWebSocketScope:
    method test_scope_type (line 297) | async def test_scope_type(self, websocket_connect, gunicorn_url):
    method test_scope_asgi_version (line 305) | async def test_scope_asgi_version(self, websocket_connect, gunicorn_url):
    method test_scope_http_version (line 314) | async def test_scope_http_version(self, websocket_connect, gunicorn_url):
    method test_scope_scheme (line 322) | async def test_scope_scheme(self, websocket_connect, gunicorn_url):
    method test_scope_server (line 330) | async def test_scope_server(self, websocket_connect, gunicorn_url):
    method test_scope_client (line 339) | async def test_scope_client(self, websocket_connect, gunicorn_url):
    method test_scope_headers (line 348) | async def test_scope_headers(self, websocket_connect, gunicorn_url):
  class TestLargeMessages (line 367) | class TestLargeMessages:
    method test_receive_large_message (line 370) | async def test_receive_large_message(self, websocket_connect, gunicorn...
    method test_send_large_message (line 378) | async def test_send_large_message(self, websocket_connect, gunicorn_url):
    method test_various_sizes (line 393) | async def test_various_sizes(self, websocket_connect, gunicorn_url):
  class TestBroadcast (line 409) | class TestBroadcast:
    method test_broadcast_default_count (line 412) | async def test_broadcast_default_count(self, websocket_connect, gunico...
    method test_broadcast_custom_count (line 429) | async def test_broadcast_custom_count(self, websocket_connect, gunicor...
  class TestDelayedResponses (line 448) | class TestDelayedResponses:
    method test_delayed_response (line 451) | async def test_delayed_response(self, websocket_connect, gunicorn_url):
    method test_minimal_delay (line 466) | async def test_minimal_delay(self, websocket_connect, gunicorn_url):
  class TestFragmentedMessages (line 481) | class TestFragmentedMessages:
    method test_fragmented_endpoint (line 484) | async def test_fragmented_endpoint(self, websocket_connect, gunicorn_u...
    method test_message_reassembly (line 493) | async def test_message_reassembly(self, websocket_connect, gunicorn_url):
  class TestProxyWebSocket (line 515) | class TestProxyWebSocket:
    method test_proxy_echo (line 518) | async def test_proxy_echo(self, websocket_connect, nginx_url):
    method test_proxy_binary (line 526) | async def test_proxy_binary(self, websocket_connect, nginx_url):
    method test_proxy_subprotocol (line 535) | async def test_proxy_subprotocol(self, websocket_connect, nginx_url):
    method test_proxy_scope (line 543) | async def test_proxy_scope(self, websocket_connect, nginx_url):
  class TestSecureWebSocket (line 559) | class TestSecureWebSocket:
    method test_wss_connection (line 562) | async def test_wss_connection(self, websocket_connect, gunicorn_ssl_url):
    method test_wss_scope_scheme (line 570) | async def test_wss_scope_scheme(self, websocket_connect, gunicorn_ssl_...
    method test_wss_through_proxy (line 578) | async def test_wss_through_proxy(self, websocket_connect, nginx_ssl_url):
  class TestConcurrentConnections (line 592) | class TestConcurrentConnections:
    method test_multiple_concurrent_connections (line 595) | async def test_multiple_concurrent_connections(self, websocket_connect...
    method test_concurrent_different_endpoints (line 613) | async def test_concurrent_different_endpoints(self, websocket_connect,...
  class TestWebSocketEdgeCases (line 648) | class TestWebSocketEdgeCases:
    method test_unknown_path (line 651) | async def test_unknown_path(self, websocket_connect, gunicorn_url):
    method test_special_characters_in_message (line 667) | async def test_special_characters_in_message(self, websocket_connect, ...
    method test_null_bytes_in_binary (line 676) | async def test_null_bytes_in_binary(self, websocket_connect, gunicorn_...
    method test_json_message (line 685) | async def test_json_message(self, websocket_connect, gunicorn_url):
    method test_rapid_close_reconnect (line 694) | async def test_rapid_close_reconnect(self, websocket_connect, gunicorn...

FILE: tests/docker/dirty_arbiter/app.py
  function application (line 12) | def application(environ, start_response):
  class TestDirtyApp (line 18) | class TestDirtyApp(DirtyApp):
    method init (line 21) | def init(self):
    method ping (line 24) | def ping(self):
    method echo (line 28) | def echo(self, message):

FILE: tests/docker/dirty_arbiter/test_parent_death.py
  class DockerContainer (line 34) | class DockerContainer:
    method __init__ (line 37) | def __init__(self, name="gunicorn-test", build=True):
    method __enter__ (line 42) | def __enter__(self):
    method __exit__ (line 88) | def __exit__(self, exc_type, exc_val, exc_tb):
    method _wait_for_ready (line 101) | def _wait_for_ready(self, timeout=30):
    method exec (line 112) | def exec(self, cmd, check=True):
    method get_logs (line 123) | def get_logs(self):
    method get_gunicorn_pids (line 132) | def get_gunicorn_pids(self):
    method kill_process (line 222) | def kill_process(self, pid, signal=9):
    method wait_for_process_exit (line 229) | def wait_for_process_exit(self, pid, timeout=5):
    method wait_for_no_gunicorn (line 243) | def wait_for_no_gunicorn(self, timeout=5):
    method wait_for_dirty_arbiter (line 258) | def wait_for_dirty_arbiter(self, timeout=10, exclude_pid=None):
    method restart_gunicorn (line 269) | def restart_gunicorn(self):
  class TestParentDeath (line 280) | class TestParentDeath:
    method setup (line 284) | def setup(self):
    method test_dirty_arbiter_exits_on_parent_sigkill (line 293) | def test_dirty_arbiter_exits_on_parent_sigkill(self):
    method test_orphan_cleanup_on_restart (line 335) | def test_orphan_cleanup_on_restart(self):
    method test_dirty_arbiter_respawn (line 382) | def test_dirty_arbiter_respawn(self):
    method test_graceful_shutdown (line 423) | def test_graceful_shutdown(self):
    method test_sigquit_quick_shutdown (line 453) | def test_sigquit_quick_shutdown(self):
  class TestDirtyArbiterWorkers (line 476) | class TestDirtyArbiterWorkers:
    method setup (line 480) | def setup(self):
    method test_dirty_worker_exists (line 489) | def test_dirty_worker_exists(self):
    method test_dirty_worker_respawn (line 500) | def test_dirty_worker_respawn(self):

FILE: tests/docker/dirty_ttin_ttou/app.py
  class UnlimitedTask (line 14) | class UnlimitedTask(DirtyApp):
    method setup (line 17) | def setup(self):
    method process (line 20) | def process(self, data):
  class LimitedTask (line 25) | class LimitedTask(DirtyApp):
    method setup (line 30) | def setup(self):
    method process (line 33) | def process(self, data):
  function app (line 40) | def app(environ, start_response):

FILE: tests/docker/dirty_ttin_ttou/test_ttin_ttou_docker.py
  function docker_services (line 28) | def docker_services():
  function get_dirty_arbiter_pid (line 63) | def get_dirty_arbiter_pid():
  function get_dirty_worker_count (line 77) | def get_dirty_worker_count():
  function send_signal_to_dirty_arbiter (line 90) | def send_signal_to_dirty_arbiter(sig):
  class TestTTINSignal (line 103) | class TestTTINSignal:
    method test_ttin_increases_workers (line 106) | def test_ttin_increases_workers(self, docker_services):
    method test_multiple_ttin_increases (line 117) | def test_multiple_ttin_increases(self, docker_services):
  class TestTTOUSignal (line 129) | class TestTTOUSignal:
    method test_ttou_decreases_workers (line 132) | def test_ttou_decreases_workers(self, docker_services):
    method test_ttou_respects_minimum (line 145) | def test_ttou_respects_minimum(self, docker_services):
  class TestUnlimitedApps (line 159) | class TestUnlimitedApps:
    method test_unlimited_app_works (line 162) | def test_unlimited_app_works(self, docker_services):
    method test_limited_app_works (line 169) | def test_limited_app_works(self, docker_services):
    method test_apps_work_after_scaling (line 176) | def test_apps_work_after_scaling(self, docker_services):

FILE: tests/docker/http2/app.py
  function app (line 10) | def app(environ, start_response):

FILE: tests/docker/http2/conftest.py
  function generate_self_signed_cert (line 18) | def generate_self_signed_cert(certs_dir: Path) -> None:
  function wait_for_service (line 49) | def wait_for_service(url: str, timeout: int = 60) -> bool:
  function docker_compose_file (line 75) | def docker_compose_file():
  function certs_dir (line 81) | def certs_dir():
  function docker_services (line 88) | def docker_services(docker_compose_file, certs_dir):
  function gunicorn_url (line 163) | def gunicorn_url(docker_services):
  function nginx_url (line 169) | def nginx_url(docker_services):
  function h2_client (line 175) | def h2_client():
  function h1_client (line 184) | def h1_client():
  function async_h2_client (line 193) | def async_h2_client():

FILE: tests/docker/http2/test_http2_docker.py
  class TestDirectHTTP2Connection (line 26) | class TestDirectHTTP2Connection:
    method test_simple_get (line 29) | def test_simple_get(self, h2_client, gunicorn_url):
    method test_health_endpoint (line 36) | def test_health_endpoint(self, h2_client, gunicorn_url):
    method test_post_with_body (line 42) | def test_post_with_body(self, h2_client, gunicorn_url):
    method test_post_large_body (line 49) | def test_post_large_body(self, h2_client, gunicorn_url):
    method test_headers_endpoint (line 57) | def test_headers_endpoint(self, h2_client, gunicorn_url):
    method test_version_endpoint (line 68) | def test_version_endpoint(self, h2_client, gunicorn_url):
    method test_large_response (line 75) | def test_large_response(self, h2_client, gunicorn_url):
    method test_different_methods (line 82) | def test_different_methods(self, h2_client, gunicorn_url):
    method test_status_codes (line 89) | def test_status_codes(self, h2_client, gunicorn_url):
    method test_not_found (line 95) | def test_not_found(self, h2_client, gunicorn_url):
  class TestConcurrentStreams (line 101) | class TestConcurrentStreams:
    method test_concurrent_requests (line 105) | async def test_concurrent_requests(self, async_h2_client, gunicorn_url):
    method test_concurrent_mixed_requests (line 123) | async def test_concurrent_mixed_requests(self, async_h2_client, gunico...
    method test_many_concurrent_streams (line 141) | async def test_many_concurrent_streams(self, async_h2_client, gunicorn...
  class TestHTTP2BehindProxy (line 157) | class TestHTTP2BehindProxy:
    method test_simple_get_via_proxy (line 160) | def test_simple_get_via_proxy(self, h2_client, nginx_url):
    method test_post_via_proxy (line 167) | def test_post_via_proxy(self, h2_client, nginx_url):
    method test_headers_preserved (line 174) | def test_headers_preserved(self, h2_client, nginx_url):
    method test_forwarded_headers (line 185) | def test_forwarded_headers(self, h2_client, nginx_url):
    method test_large_response_via_proxy (line 195) | def test_large_response_via_proxy(self, h2_client, nginx_url):
    method test_concurrent_via_proxy (line 202) | async def test_concurrent_via_proxy(self, async_h2_client, nginx_url):
  class TestHTTP2Protocol (line 218) | class TestHTTP2Protocol:
    method test_alpn_negotiation (line 221) | def test_alpn_negotiation(self, gunicorn_url):
    method test_alpn_http11_fallback (line 233) | def test_alpn_http11_fallback(self, gunicorn_url):
    method test_http11_client_works (line 245) | def test_http11_client_works(self, h1_client, gunicorn_url):
    method test_tls_version (line 252) | def test_tls_version(self, gunicorn_url):
  class TestHTTP2ErrorHandling (line 264) | class TestHTTP2ErrorHandling:
    method test_invalid_path (line 267) | def test_invalid_path(self, h2_client, gunicorn_url):
    method test_server_error (line 273) | def test_server_error(self, h2_client, gunicorn_url):
    method test_connection_reuse_after_error (line 280) | async def test_connection_reuse_after_error(self, async_h2_client, gun...
  class TestHTTP2Headers (line 295) | class TestHTTP2Headers:
    method test_response_headers (line 298) | def test_response_headers(self, h2_client, gunicorn_url):
    method test_many_request_headers (line 306) | def test_many_request_headers(self, h2_client, gunicorn_url):
    method test_header_case_insensitivity (line 317) | def test_header_case_insensitivity(self, h2_client, gunicorn_url):
  class TestHTTP2Performance (line 329) | class TestHTTP2Performance:
    method test_parallel_large_requests (line 333) | async def test_parallel_large_requests(self, async_h2_client, gunicorn...
    method test_connection_keepalive (line 348) | def test_connection_keepalive(self, h2_client, gunicorn_url):
  class TestHTTP2EarlyHints (line 357) | class TestHTTP2EarlyHints:
    method test_early_hints_endpoint (line 360) | def test_early_hints_endpoint(self, h2_client, gunicorn_url):
    method test_early_hints_multiple_endpoint (line 366) | def test_early_hints_multiple_endpoint(self, h2_client, gunicorn_url):
    method test_early_hints_via_proxy (line 372) | def test_early_hints_via_proxy(self, h2_client, nginx_url):
    method test_concurrent_early_hints (line 379) | async def test_concurrent_early_hints(self, async_h2_client, gunicorn_...

FILE: tests/docker/per_app_allocation/app.py
  function application (line 21) | def application(environ, start_response):
  class LightweightApp (line 88) | class LightweightApp(DirtyApp):
    method __init__ (line 95) | def __init__(self):
    method init (line 100) | def init(self):
    method ping (line 104) | def ping(self):
    method get_worker_id (line 113) | def get_worker_id(self):
    method close (line 117) | def close(self):
  class HeavyApp (line 121) | class HeavyApp(DirtyApp):
    method __init__ (line 130) | def __init__(self):
    method init (line 135) | def init(self):
    method predict (line 141) | def predict(self, data):
    method get_worker_id (line 148) | def get_worker_id(self):
    method close (line 152) | def close(self):
  class ConfigLimitedApp (line 156) | class ConfigLimitedApp(DirtyApp):
    method __init__ (line 164) | def __init__(self):
    method init (line 168) | def init(self):
    method get_info (line 172) | def get_info(self):
    method get_worker_id (line 179) | def get_worker_id(self):
    method close (line 183) | def close(self):

FILE: te
Condensed preview — 621 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (3,010K chars).
[
  {
    "path": ".github/DISCUSSION_TEMPLATE/issue-triage.yml",
    "chars": 3381,
    "preview": "title: \"[Triage] \"\nlabels:\n  - triage\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Thanks for taking "
  },
  {
    "path": ".github/DISCUSSION_TEMPLATE/question.yml",
    "chars": 1286,
    "preview": "title: \"[Question] \"\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        Have a question about Gunicorn?\n\n  "
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 126,
    "preview": "github: [benoitc]\nopen_collective: gunicorn\ncustom: [\"https://checkout.revolut.com/pay/c934e028-3a71-44eb-b99c-491342df2"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 406,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: Bug Report / Feature Request\n    url: https://github.com/benoitc/gu"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/preapproved.md",
    "chars": 344,
    "preview": "---\nname: Pre-Discussed and Approved Topics\nabout: Only for topics already discussed and approved in GitHub Discussions\n"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 119,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"monthly\"\n"
  },
  {
    "path": ".github/workflows/docker-integration.yml",
    "chars": 996,
    "preview": "name: Docker Integration Tests\n\non:\n  push:\n    branches: [master]\n    paths:\n      - 'gunicorn/uwsgi/**'\n      - 'tests"
  },
  {
    "path": ".github/workflows/docker-publish.yml",
    "chars": 1485,
    "preview": "name: Docker Publish\non:\n  push:\n    tags:\n      - 'v*'\n      - '[0-9]+.[0-9]+.[0-9]+'\n  workflow_dispatch:\n\npermissions"
  },
  {
    "path": ".github/workflows/docs.yml",
    "chars": 1966,
    "preview": "name: Docs\n\non:\n  push:\n    branches: [ master ]\n    paths:\n      - 'docs/**'\n      - 'mkdocs.yml'\n      - 'scripts/buil"
  },
  {
    "path": ".github/workflows/embedding-integration.yml",
    "chars": 947,
    "preview": "name: Embedding Service Integration Tests\n\non:\n  push:\n    paths:\n      - 'examples/embedding_service/**'\n      - 'gunic"
  },
  {
    "path": ".github/workflows/freebsd.yml",
    "chars": 1250,
    "preview": "name: FreeBSD\n\non:\n  push:\n  pull_request:\n  workflow_dispatch:\n\npermissions:\n  contents: read\n\nenv:\n  FORCE_COLOR: 1\n\nj"
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 1789,
    "preview": "name: lint\non: [push, pull_request]\npermissions:\n  contents: read # to fetch code (actions/checkout)\nenv:\n  # note that "
  },
  {
    "path": ".github/workflows/tox.yml",
    "chars": 1856,
    "preview": "name: tox\non: [push, pull_request]\npermissions:\n  contents: read # to fetch code (actions/checkout)\nenv:\n  # note that s"
  },
  {
    "path": ".gitignore",
    "chars": 296,
    "preview": "*.egg\n*.egg-info\n*.pyc\n*.so\n.coverage\n.pytest_cache\n.tox\n__pycache__\nbuild\ndocs/_build\ncoverage.xml\ndist\nexamples/framew"
  },
  {
    "path": ".pylintrc",
    "chars": 1256,
    "preview": "[MASTER]\n\nignore=\n    build,\n    docs,\n    examples,\n    scripts,\n    _compat.py,\n    _gaiohttp.py,\n\n[MESSAGES CONTROL]\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 7374,
    "preview": "# Contributing to Gunicorn\n\nWant to hack on Gunicorn? Awesome! Here are instructions to get you\nstarted. They are probab"
  },
  {
    "path": "LICENSE",
    "chars": 1135,
    "preview": "2009-2026 (c) Benoît Chesneau <benoitc@gunicorn.org>\n2009-2015 (c) Paul J. Davis <paul.joseph.davis@gmail.com>\n\nPermissi"
  },
  {
    "path": "MAINTAINERS",
    "chars": 636,
    "preview": "Core maintainers\n================\n\nBenoit Chesneau <benoitc@gunicorn.org>\nKonstantin Kapustin <sirkonst@gmail.com>\nRanda"
  },
  {
    "path": "MANIFEST.in",
    "chars": 420,
    "preview": "include .gitignore\ninclude LICENSE\ninclude NOTICE\ninclude README.md\ninclude THANKS\ninclude requirements_dev.txt\ninclude "
  },
  {
    "path": "Makefile",
    "chars": 337,
    "preview": "build:\n\tvirtualenv venv\n\tvenv/bin/pip install -e .\n\tvenv/bin/pip install -r requirements_dev.txt\n\ndocs:\n\tmkdocs build\n\nd"
  },
  {
    "path": "NOTICE",
    "chars": 3776,
    "preview": "Gunicorn\n\n2009-2026 (c) Benoît Chesneau <benoitc@gunicorn.org>\n2009-2015 (c) Paul J. Davis <paul.joseph.davis@gmail.com>"
  },
  {
    "path": "README.md",
    "chars": 2973,
    "preview": "# Gunicorn\n\n<p align=\"center\">\n  <strong>Gunicorn is maintained by volunteers. If it powers your production, please cons"
  },
  {
    "path": "SECURITY.md",
    "chars": 1149,
    "preview": "# Security Policy\n\n## Reporting a Vulnerability\n\n**Please note that public Github issues are open for everyone to see!**"
  },
  {
    "path": "THANKS",
    "chars": 7279,
    "preview": "Gunicorn THANKS\n===============\n\nA number of people have contributed to Gunicorn by reporting problems,\nsuggesting impro"
  },
  {
    "path": "appveyor.yml",
    "chars": 1430,
    "preview": "version: '{branch}.{build}'\nenvironment:\n  matrix:\n    - TOXENV: lint\n      PYTHON: \"C:\\\\Python312-x64\"\n    - TOXENV: py"
  },
  {
    "path": "benchmarks/baseline.json",
    "chars": 119,
    "preview": "{\n  \"gthread\": {\n    \"simple\": {},\n    \"simple_high_concurrency\": {},\n    \"slow_io\": {},\n    \"large_response\": {}\n  }\n}"
  },
  {
    "path": "benchmarks/dirty_bench_app.py",
    "chars": 6440,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nBenchmark "
  },
  {
    "path": "benchmarks/dirty_bench_gunicorn.py",
    "chars": 1336,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nGunicorn c"
  },
  {
    "path": "benchmarks/dirty_bench_wsgi.py",
    "chars": 5605,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nWSGI app f"
  },
  {
    "path": "benchmarks/dirty_benchmark.py",
    "chars": 34775,
    "preview": "#!/usr/bin/env python3\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more infor"
  },
  {
    "path": "benchmarks/dirty_streaming.py",
    "chars": 23176,
    "preview": "#!/usr/bin/env python\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more inform"
  },
  {
    "path": "benchmarks/quick_bench.sh",
    "chars": 1163,
    "preview": "#!/bin/bash\n# Quick benchmark for gthread worker\n\nset -e\n\ncd \"$(dirname \"$0\")\"\n\necho \"Starting gunicorn with gthread wor"
  },
  {
    "path": "benchmarks/results/queue_refactor_results.json",
    "chars": 4094,
    "preview": "{\n  \"timestamp\": \"2026-01-24T10:56:33\",\n  \"results\": [\n    {\n      \"scenario\": \"baseline_10ms\",\n      \"config\": {\n      "
  },
  {
    "path": "benchmarks/run_benchmark.py",
    "chars": 7466,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#!/usr/bin/env"
  },
  {
    "path": "benchmarks/simple_app.py",
    "chars": 550,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Simple WSGI "
  },
  {
    "path": "docker/.dockerignore",
    "chars": 61,
    "preview": ".git\n.github\n__pycache__\n*.pyc\n.pytest_cache\n.tox\ndocs\ntests\n"
  },
  {
    "path": "docker/Dockerfile",
    "chars": 979,
    "preview": "FROM python:3.12-slim\n\nLABEL org.opencontainers.image.source=https://github.com/benoitc/gunicorn\nLABEL org.opencontainer"
  },
  {
    "path": "docker/docker-entrypoint.sh",
    "chars": 1248,
    "preview": "#!/bin/bash\nset -e\n\n# Allow running other commands (e.g., bash for debugging)\nif [ \"${1:0:1}\" = '-' ] || [ -z \"${1##*:*}"
  },
  {
    "path": "docs/README.md",
    "chars": 434,
    "preview": "# Generate Documentation\n\n## Requirements\n\nInstall the documentation dependencies with:\n\n```bash\npip install -r requirem"
  },
  {
    "path": "docs/content/2010-news.md",
    "chars": 6315,
    "preview": "<span id=\"news-2010\"></span>\n# Changelog - 2010\n\n## 0.12.0 / 2010-12-22\n\n- Add support for logging configuration using a"
  },
  {
    "path": "docs/content/2011-news.md",
    "chars": 1990,
    "preview": "<span id=\"news-2011\"></span>\n# Changelog - 2011\n\n## 0.13.4 / 2011-09-23\n\n- fix util.closerange function used to prevent "
  },
  {
    "path": "docs/content/2012-news.md",
    "chars": 4006,
    "preview": "<span id=\"news-2012\"></span>\n# Changelog - 2012\n\n## 0.17.0 / 2012-12-25\n\n- allows gunicorn to bind to multiple address\n-"
  },
  {
    "path": "docs/content/2013-news.md",
    "chars": 3169,
    "preview": "<span id=\"news-2013\"></span>\n# Changelog - 2013\n\n## 18.0 / 2013-08-26\n\n- new: add ``-e/--env`` command line argument to "
  },
  {
    "path": "docs/content/2014-news.md",
    "chars": 7590,
    "preview": "<span id=\"news-2014\"></span>\n# Changelog - 2014\n\n!!! note\n    Please see [news](news.md) for the latest changes.\n\n\n## 19"
  },
  {
    "path": "docs/content/2015-news.md",
    "chars": 8295,
    "preview": "<span id=\"news-2015\"></span>\n# Changelog - 2015\n\n!!! note\n    Please see [news](news.md) for the latest changes.\n\n\n## 19"
  },
  {
    "path": "docs/content/2016-news.md",
    "chars": 4475,
    "preview": "<span id=\"news-2016\"></span>\n# Changelog - 2016\n\n!!! note\n    Please see [news](news.md) for the latest changes\n\n\n## 19."
  },
  {
    "path": "docs/content/2017-news.md",
    "chars": 3005,
    "preview": "<span id=\"news-2017\"></span>\n# Changelog - 2017\n\n!!! note\n    Please see [news](news.md) for the latest changes\n\n\n## 19."
  },
  {
    "path": "docs/content/2018-news.md",
    "chars": 5323,
    "preview": "<span id=\"news-2018\"></span>\n# Changelog - 2018\n\n!!! note\n    Please see [news](news.md) for the latest changes\n\n\n## 19."
  },
  {
    "path": "docs/content/2019-news.md",
    "chars": 4601,
    "preview": "<span id=\"news-2019\"></span>\n# Changelog - 2019\n\n!!! note\n    Please see [news](news.md) for the latest changes\n\n\n## 20."
  },
  {
    "path": "docs/content/2020-news.md",
    "chars": 114,
    "preview": "<span id=\"news-2020\"></span>\n# Changelog - 2020\n\n!!! note\n    Please see [news](news.md) for the latest changes\n\n\n"
  },
  {
    "path": "docs/content/2021-news.md",
    "chars": 1885,
    "preview": "<span id=\"news-2021\"></span>\n# Changelog - 2021\n\n!!! note\n    Please see [news](news.md) for the latest changes\n\n\n## 20."
  },
  {
    "path": "docs/content/2023-news.md",
    "chars": 826,
    "preview": "<span id=\"news-2023\"></span>\n# Changelog - 2023\n\n## 21.2.0 - 2023-07-19\n\n- fix thread worker: revert change considering "
  },
  {
    "path": "docs/content/2024-news.md",
    "chars": 4276,
    "preview": "<span id=\"news-2024\"></span>\n# Changelog - 2024\n\n## 23.0.0 - 2024-08-10\n\n- minor docs fixes ([PR #3217](https://github.c"
  },
  {
    "path": "docs/content/2026-news.md",
    "chars": 12538,
    "preview": "<span id=\"news-2026\"></span>\n# Changelog - 2026\n\n## 25.1.0 - 2026-02-13\n\n### New Features\n\n- **Control Interface (gunico"
  },
  {
    "path": "docs/content/404.md",
    "chars": 663,
    "preview": "# Page Not Found\n\nThe page you're looking for doesn't exist or has moved.\n\n<div class=\"quick-links\" style=\"margin-top: 2"
  },
  {
    "path": "docs/content/CNAME",
    "chars": 12,
    "preview": "gunicorn.org"
  },
  {
    "path": "docs/content/asgi.md",
    "chars": 6421,
    "preview": "# ASGI Worker\n\nGunicorn includes a native ASGI worker that enables running async Python web frameworks\nlike FastAPI, Sta"
  },
  {
    "path": "docs/content/assets/javascripts/toc-collapse.js",
    "chars": 2352,
    "preview": "// Collapsible TOC for settings page\n(function() {\n  function initCollapsibleTOC() {\n    // Only apply to pages with man"
  },
  {
    "path": "docs/content/assets/stylesheets/home.css",
    "chars": 8724,
    "preview": "/* ============================================\n   Gunicorn Landing Page\n   Inspired by Caddy: minimal, spacious, clean\n"
  },
  {
    "path": "docs/content/community.md",
    "chars": 1232,
    "preview": "# Community\n\nConnect with the project through these channels.\n\n## Project management & discussions\n\nProject maintenance "
  },
  {
    "path": "docs/content/configure.md",
    "chars": 2123,
    "preview": "<span id=\"configuration\"></span>\n# Configuration Overview\n\nGunicorn reads configuration from five places, in increasing "
  },
  {
    "path": "docs/content/custom.md",
    "chars": 1570,
    "preview": "<span id=\"custom\"></span>\n# Custom Application\n\n!!! info \"Added in 19.0\"\n    Use Gunicorn as part of your own WSGI appli"
  },
  {
    "path": "docs/content/deploy.md",
    "chars": 9875,
    "preview": "# Deploying Gunicorn\n\nWe strongly recommend running Gunicorn behind a proxy server.\n\n## Nginx configuration\n\nAlthough ma"
  },
  {
    "path": "docs/content/design.md",
    "chars": 6354,
    "preview": "<span id=\"design\"></span>\n# Design\n\nA brief look at Gunicorn's architecture.\n\n## Server Model\n\nGunicorn uses a **pre-for"
  },
  {
    "path": "docs/content/dirty.md",
    "chars": 38619,
    "preview": "---\ntitle: Dirty Arbiters\nmenu:\n    guides:\n        weight: 10\n---\n\n# Dirty Arbiters\n\n!!! warning \"Beta Feature\"\n    Dir"
  },
  {
    "path": "docs/content/faq.md",
    "chars": 4562,
    "preview": "<span id=\"faq\"></span>\n# FAQ\n\n## WSGI bits\n\n### How do I set `SCRIPT_NAME`?\n\nBy default `SCRIPT_NAME` is an empty string"
  },
  {
    "path": "docs/content/guides/docker.md",
    "chars": 8365,
    "preview": "# Docker Deployment\n\nRunning Gunicorn in Docker containers is the most common deployment pattern\nfor modern Python appli"
  },
  {
    "path": "docs/content/guides/gunicornc.md",
    "chars": 6498,
    "preview": "---\ntitle: Control Interface (gunicornc)\nmenu:\n    guides:\n        weight: 15\n---\n\n# Control Interface (gunicornc)\n\nGuni"
  },
  {
    "path": "docs/content/guides/http2.md",
    "chars": 23778,
    "preview": "# HTTP/2 Support\n\n!!! warning \"Beta Feature\"\n    HTTP/2 support is a beta feature introduced in Gunicorn 25.0.0. While i"
  },
  {
    "path": "docs/content/index.md",
    "chars": 4724,
    "preview": "---\ntemplate: home.html\ntitle: Gunicorn - Python WSGI HTTP Server\n---\n\n<section class=\"hero\">\n  <div class=\"container\">\n"
  },
  {
    "path": "docs/content/install.md",
    "chars": 3351,
    "preview": "# Installation\n\n!!! note\n    Gunicorn requires **Python 3.12 or newer**.\n\n## Quick Install\n\n=== \"pip\"\n\n    ```bash\n    p"
  },
  {
    "path": "docs/content/instrumentation.md",
    "chars": 1199,
    "preview": "<span id=\"instrumentation\"></span>\n# Instrumentation\n\n!!! info \"Added in 19.1\"\n    Gunicorn exposes optional instrumenta"
  },
  {
    "path": "docs/content/news.md",
    "chars": 15222,
    "preview": "<span id=\"news\"></span>\n# Changelog\n\n## unreleased\n\n### Performance\n\n- **ASGI HTTP Parser Optimizations**: Improve ASGI "
  },
  {
    "path": "docs/content/quickstart.md",
    "chars": 1889,
    "preview": "# Quickstart\n\nGet a Python web application running with Gunicorn in 5 minutes.\n\n## Install\n\n```bash\npip install gunicorn"
  },
  {
    "path": "docs/content/reference/settings.md",
    "chars": 51115,
    "preview": "> **Generated file** — update `gunicorn/config.py` instead.\n\n# Settings\n\nThis reference is built directly from `gunicorn"
  },
  {
    "path": "docs/content/run.md",
    "chars": 4511,
    "preview": "# Running Gunicorn\n\nYou can run Gunicorn directly from the command line or integrate it with\npopular frameworks like Dja"
  },
  {
    "path": "docs/content/signals.md",
    "chars": 4218,
    "preview": "<span id=\"signals\"></span>\n# Signal Handling\n\nA quick reference to the signals handled by Gunicorn. This includes the si"
  },
  {
    "path": "docs/content/sponsor.md",
    "chars": 2267,
    "preview": "# Support Gunicorn\n\nGunicorn has been serving Python web applications since 2010. It's downloaded millions of times per "
  },
  {
    "path": "docs/content/styles/overrides.css",
    "chars": 10774,
    "preview": "/* Gunicorn Punchy Theme */\n:root {\n  --gunicorn-green: #00a650;\n  --gunicorn-green-dark: #008542;\n  --gunicorn-green-li"
  },
  {
    "path": "docs/content/uwsgi.md",
    "chars": 6063,
    "preview": "# uWSGI Protocol\n\nGunicorn supports the uWSGI binary protocol, allowing it to receive requests from\nnginx using the `uws"
  },
  {
    "path": "docs/macros.py",
    "chars": 508,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom importlib"
  },
  {
    "path": "examples/alt_spec.py",
    "chars": 822,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#\n# An example"
  },
  {
    "path": "examples/asgi/__init__.py",
    "chars": 154,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nASGI examp"
  },
  {
    "path": "examples/asgi/basic_app.py",
    "chars": 3949,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nBasic ASGI"
  },
  {
    "path": "examples/asgi/websocket_app.py",
    "chars": 6927,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nWebSocket "
  },
  {
    "path": "examples/bad.py",
    "chars": 310,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport tempfil"
  },
  {
    "path": "examples/boot_fail.py",
    "chars": 213,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nraise RuntimeE"
  },
  {
    "path": "examples/celery_alternative/Dockerfile",
    "chars": 1297,
    "preview": "# Dockerfile for Celery Replacement Example\n#\n# This demonstrates running a production-ready application with\n# Gunicorn"
  },
  {
    "path": "examples/celery_alternative/README.md",
    "chars": 8768,
    "preview": "# Celery Alternative Example\n\nThis example demonstrates how to replace Celery with Gunicorn's **dirty arbiters** for bac"
  },
  {
    "path": "examples/celery_alternative/app.py",
    "chars": 13740,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nWeb Applic"
  },
  {
    "path": "examples/celery_alternative/docker-compose.yml",
    "chars": 1751,
    "preview": "# Docker Compose for Celery Replacement Example\n#\n# Notice: Only ONE service needed!\n# Compare with typical Celery deplo"
  },
  {
    "path": "examples/celery_alternative/gunicorn_conf.py",
    "chars": 5333,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nGunicorn C"
  },
  {
    "path": "examples/celery_alternative/requirements.txt",
    "chars": 125,
    "preview": "# Celery Replacement Example Dependencies\nfastapi>=0.109.0\nuvloop>=0.19.0\nhttpx>=0.26.0\npytest>=8.0.0\npytest-asyncio>=0."
  },
  {
    "path": "examples/celery_alternative/run_tests.sh",
    "chars": 1015,
    "preview": "#!/bin/bash\n# Run tests for Celery Replacement example\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" && pwd"
  },
  {
    "path": "examples/celery_alternative/tasks.py",
    "chars": 18234,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nTask Worke"
  },
  {
    "path": "examples/celery_alternative/tests/__init__.py",
    "chars": 122,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Tests packag"
  },
  {
    "path": "examples/celery_alternative/tests/conftest.py",
    "chars": 343,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nPytest con"
  },
  {
    "path": "examples/celery_alternative/tests/test_integration.py",
    "chars": 13489,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nIntegratio"
  },
  {
    "path": "examples/celery_alternative/tests/test_tasks.py",
    "chars": 10322,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nUnit Tests"
  },
  {
    "path": "examples/deep/__init__.py",
    "chars": 106,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n"
  },
  {
    "path": "examples/deep/test.py",
    "chars": 636,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n#\n# Example cod"
  },
  {
    "path": "examples/dirty_example/Dockerfile",
    "chars": 573,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nFROM python:3."
  },
  {
    "path": "examples/dirty_example/__init__.py",
    "chars": 106,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n"
  },
  {
    "path": "examples/dirty_example/dirty_app.py",
    "chars": 8695,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nExample Di"
  },
  {
    "path": "examples/dirty_example/docker-compose.yml",
    "chars": 1984,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nservices:\n  # "
  },
  {
    "path": "examples/dirty_example/gunicorn_conf.py",
    "chars": 1449,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nGunicorn c"
  },
  {
    "path": "examples/dirty_example/test_dirty_app.py",
    "chars": 4030,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#!/usr/bin/env"
  },
  {
    "path": "examples/dirty_example/test_integration.py",
    "chars": 2180,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#!/usr/bin/env"
  },
  {
    "path": "examples/dirty_example/test_protocol.py",
    "chars": 7981,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#!/usr/bin/env"
  },
  {
    "path": "examples/dirty_example/test_stash_integration.py",
    "chars": 6713,
    "preview": "#!/usr/bin/env python3\n#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more infor"
  },
  {
    "path": "examples/dirty_example/test_worker_integration.py",
    "chars": 8671,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#!/usr/bin/env"
  },
  {
    "path": "examples/dirty_example/wsgi_app.py",
    "chars": 7988,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nExample WS"
  },
  {
    "path": "examples/echo.py",
    "chars": 654,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n#\n# Example cod"
  },
  {
    "path": "examples/embedding_service/Dockerfile",
    "chars": 423,
    "preview": "FROM python:3.12-slim\n\nWORKDIR /app\n\n# Install dependencies\nRUN pip install --no-cache-dir \\\n    sentence-transformers \\"
  },
  {
    "path": "examples/embedding_service/README.md",
    "chars": 3159,
    "preview": "# Embedding Service Example\n\nA FastAPI-based text embedding service using sentence-transformers, powered by\ngunicorn's d"
  },
  {
    "path": "examples/embedding_service/__init__.py",
    "chars": 134,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Embedding se"
  },
  {
    "path": "examples/embedding_service/docker-compose.yml",
    "chars": 396,
    "preview": "services:\n  embedding-service:\n    build:\n      context: ../..\n      dockerfile: examples/embedding_service/Dockerfile\n "
  },
  {
    "path": "examples/embedding_service/embedding_app.py",
    "chars": 476,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom gunicorn."
  },
  {
    "path": "examples/embedding_service/gunicorn_conf.py",
    "chars": 284,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nbind = \"0.0.0."
  },
  {
    "path": "examples/embedding_service/main.py",
    "chars": 723,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom fastapi i"
  },
  {
    "path": "examples/embedding_service/requirements.txt",
    "chars": 54,
    "preview": "sentence-transformers\nfastapi\npydantic\nrequests\nnumpy\n"
  },
  {
    "path": "examples/embedding_service/test_embedding.py",
    "chars": 1115,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport os\nimpo"
  },
  {
    "path": "examples/example_config.py",
    "chars": 7699,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Sample Gunic"
  },
  {
    "path": "examples/frameworks/cherryapp.py",
    "chars": 296,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport cherryp"
  },
  {
    "path": "examples/frameworks/django/README",
    "chars": 60,
    "preview": "Applications to test Django support:\n\ntesting -> Django 1.4\n"
  },
  {
    "path": "examples/frameworks/django/testing/manage.py",
    "chars": 350,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#!/usr/bin/env"
  },
  {
    "path": "examples/frameworks/django/testing/testing/__init__.py",
    "chars": 106,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n"
  },
  {
    "path": "examples/frameworks/django/testing/testing/apps/__init__.py",
    "chars": 106,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n"
  },
  {
    "path": "examples/frameworks/django/testing/testing/apps/someapp/__init__.py",
    "chars": 106,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n"
  },
  {
    "path": "examples/frameworks/django/testing/testing/apps/someapp/middleware.py",
    "chars": 725,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom multiproc"
  },
  {
    "path": "examples/frameworks/django/testing/testing/apps/someapp/models.py",
    "chars": 106,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n"
  },
  {
    "path": "examples/frameworks/django/testing/testing/apps/someapp/templates/base.html",
    "chars": 759,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"utf-8\"/>\n        <title>gunicorn django example app</"
  },
  {
    "path": "examples/frameworks/django/testing/testing/apps/someapp/templates/home.html",
    "chars": 471,
    "preview": "{% extends \"base.html\" %}\n\n{% block content %}\n<form method=\"post\" enctype='multipart/form-data'>\n        {% csrf_token "
  },
  {
    "path": "examples/frameworks/django/testing/testing/apps/someapp/tests.py",
    "chars": 615,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nThis file "
  },
  {
    "path": "examples/frameworks/django/testing/testing/apps/someapp/urls.py",
    "chars": 239,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom django.co"
  },
  {
    "path": "examples/frameworks/django/testing/testing/apps/someapp/views.py",
    "chars": 1654,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport csv\nimp"
  },
  {
    "path": "examples/frameworks/django/testing/testing/settings.py",
    "chars": 5836,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Django setti"
  },
  {
    "path": "examples/frameworks/django/testing/testing/urls.py",
    "chars": 683,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom django.co"
  },
  {
    "path": "examples/frameworks/django/testing/testing/wsgi.py",
    "chars": 1465,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nWSGI confi"
  },
  {
    "path": "examples/frameworks/flask_sendfile.py",
    "chars": 397,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport io\n\nfro"
  },
  {
    "path": "examples/frameworks/flaskapp.py",
    "chars": 253,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Run with:\n#\n"
  },
  {
    "path": "examples/frameworks/flaskapp_aiohttp_wsgi.py",
    "chars": 607,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Example comm"
  },
  {
    "path": "examples/frameworks/pyramidapp.py",
    "chars": 444,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom pyramid.c"
  },
  {
    "path": "examples/frameworks/requirements.txt",
    "chars": 150,
    "preview": "-r requirements_flaskapp.txt\n-r requirements_cherryapp.txt\n-r requirements_pyramidapp.txt\n-r requirements_tornadoapp.txt"
  },
  {
    "path": "examples/frameworks/requirements_cherryapp.txt",
    "chars": 9,
    "preview": "cherrypy\n"
  },
  {
    "path": "examples/frameworks/requirements_flaskapp.txt",
    "chars": 6,
    "preview": "flask\n"
  },
  {
    "path": "examples/frameworks/requirements_pyramidapp.txt",
    "chars": 8,
    "preview": "pyramid\n"
  },
  {
    "path": "examples/frameworks/requirements_tornadoapp.txt",
    "chars": 10,
    "preview": "tornado<6\n"
  },
  {
    "path": "examples/frameworks/requirements_webpyapp.txt",
    "chars": 7,
    "preview": "web-py\n"
  },
  {
    "path": "examples/frameworks/tornadoapp.py",
    "chars": 644,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n#\n# Run with:\n#"
  },
  {
    "path": "examples/frameworks/webpyapp.py",
    "chars": 303,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Run with\n#\n#"
  },
  {
    "path": "examples/gunicorn_rc",
    "chars": 215,
    "preview": "#!/bin/sh\n\nGUNICORN=/usr/local/bin/gunicorn\nROOT=/path/to/project\nPID=/var/run/gunicorn.pid\n\nAPP=main:application\n\nif [ "
  },
  {
    "path": "examples/hello.txt",
    "chars": 13,
    "preview": "Hello world!\n"
  },
  {
    "path": "examples/http2_features/Dockerfile",
    "chars": 538,
    "preview": "FROM python:3.12-slim\n\nWORKDIR /app\n\n# Install h2 for HTTP/2 support and httpx for testing\nRUN pip install --no-cache-di"
  },
  {
    "path": "examples/http2_features/__init__.py",
    "chars": 105,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n"
  },
  {
    "path": "examples/http2_features/docker-compose.yml",
    "chars": 349,
    "preview": "services:\n  http2-features:\n    build:\n      context: ../..\n      dockerfile: examples/http2_features/Dockerfile\n    por"
  },
  {
    "path": "examples/http2_features/gunicorn_conf.py",
    "chars": 535,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Gunicorn con"
  },
  {
    "path": "examples/http2_features/http2_app.py",
    "chars": 8660,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nHTTP/2 ASG"
  },
  {
    "path": "examples/http2_features/requirements.txt",
    "chars": 57,
    "preview": "# Requirements for testing HTTP/2 features\nhttpx>=0.24.0\n"
  },
  {
    "path": "examples/http2_features/test_http2.py",
    "chars": 8843,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#!/usr/bin/env"
  },
  {
    "path": "examples/http2_gevent/.gitignore",
    "chars": 68,
    "preview": "# Generated certificates - run ./generate_certs.sh to create\ncerts/\n"
  },
  {
    "path": "examples/http2_gevent/Dockerfile",
    "chars": 1322,
    "preview": "# HTTP/2 with Gevent Example\n#\n# Build: docker build -t gunicorn-http2-gevent .\n# Run:   docker run -p 8443:8443 -v $(pw"
  },
  {
    "path": "examples/http2_gevent/README.md",
    "chars": 3727,
    "preview": "# HTTP/2 with Gevent Worker Example\n\nThis example demonstrates how to run Gunicorn with HTTP/2 support using the gevent "
  },
  {
    "path": "examples/http2_gevent/app.py",
    "chars": 4162,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nExample WS"
  },
  {
    "path": "examples/http2_gevent/docker-compose.yml",
    "chars": 1149,
    "preview": "# HTTP/2 with Gevent Docker Compose\n#\n# Usage:\n#   # Generate certificates first (or use your own)\n#   ./generate_certs."
  },
  {
    "path": "examples/http2_gevent/generate_certs.sh",
    "chars": 1123,
    "preview": "#!/bin/bash\n#\n# Generate self-signed certificates for HTTP/2 testing.\n#\n# Usage: ./generate_certs.sh\n#\n\nset -e\n\nCERTS_DI"
  },
  {
    "path": "examples/http2_gevent/gunicorn_conf.py",
    "chars": 2683,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nGunicorn c"
  },
  {
    "path": "examples/http2_gevent/test_http2_gevent.py",
    "chars": 10300,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#!/usr/bin/env"
  },
  {
    "path": "examples/log_app.ini",
    "chars": 448,
    "preview": "[app:main]\npaste.app_factory = log_app:app_factory\n\n[server:main]\nuse = egg:gunicorn#main\nhost = 127.0.0.1\nport = 8080\nw"
  },
  {
    "path": "examples/log_app.py",
    "chars": 478,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport logging"
  },
  {
    "path": "examples/logging.conf",
    "chars": 841,
    "preview": "[loggers]\nkeys=root, gunicorn.error, gunicorn.access\n\n[handlers]\nkeys=console, error_file, access_file\n\n[formatters]\nkey"
  },
  {
    "path": "examples/longpoll.py",
    "chars": 707,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\nimport sys\nim"
  },
  {
    "path": "examples/multiapp.py",
    "chars": 1440,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n#\n# Run this ap"
  },
  {
    "path": "examples/multidomainapp.py",
    "chars": 971,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport re\n\ncla"
  },
  {
    "path": "examples/nginx.conf",
    "chars": 1980,
    "preview": "worker_processes 1;\n\nuser nobody nogroup;\n# 'user nobody nobody;' for systems with 'nobody' as a group instead\nerror_log"
  },
  {
    "path": "examples/read_django_settings.py",
    "chars": 509,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"\nUse this c"
  },
  {
    "path": "examples/readline_app.py",
    "chars": 993,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n#\n# Simple exam"
  },
  {
    "path": "examples/sendfile.py",
    "chars": 583,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n#\n# Example cod"
  },
  {
    "path": "examples/server.crt",
    "chars": 1257,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIDdDCCAlwCCQC3MfdcOMwt6DANBgkqhkiG9w0BAQUFADB8MQswCQYDVQQGEwJG\nUjERMA8GA1UECBMIUGljYXJkaWU"
  },
  {
    "path": "examples/server.key",
    "chars": 1679,
    "preview": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAy9RQSiGpB+HyjMpRCEfV9M/4g7gXq/qRizxDspJujoBzSW0d\n4FqMHaSRX2QOA+euhtlOYTg"
  },
  {
    "path": "examples/slowclient.py",
    "chars": 582,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport sys\nimp"
  },
  {
    "path": "examples/standalone_app.py",
    "chars": 1421,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n#!/usr/bin/env"
  },
  {
    "path": "examples/streaming_chat/Dockerfile",
    "chars": 383,
    "preview": "FROM python:3.12-slim\n\nWORKDIR /app\n\n# Install dependencies\nRUN pip install --no-cache-dir \\\n    fastapi \\\n    pydantic\n"
  },
  {
    "path": "examples/streaming_chat/README.md",
    "chars": 5109,
    "preview": "# Streaming Chat Example\n\nA FastAPI-based chat demo that simulates LLM token-by-token streaming, powered\nby Gunicorn's d"
  },
  {
    "path": "examples/streaming_chat/__init__.py",
    "chars": 205,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n# Streaming Ch"
  },
  {
    "path": "examples/streaming_chat/chat_app.py",
    "chars": 4911,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport time\nim"
  },
  {
    "path": "examples/streaming_chat/demo_capture.txt",
    "chars": 4551,
    "preview": "================================================================================\n                        STREAMING CHAT "
  },
  {
    "path": "examples/streaming_chat/docker-compose.yml",
    "chars": 367,
    "preview": "services:\n  streaming-chat:\n    build:\n      context: ../..\n      dockerfile: examples/streaming_chat/Dockerfile\n    por"
  },
  {
    "path": "examples/streaming_chat/gunicorn_conf.py",
    "chars": 271,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nbind = \"0.0.0."
  },
  {
    "path": "examples/streaming_chat/main.py",
    "chars": 8301,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport json\nfr"
  },
  {
    "path": "examples/streaming_chat/requirements.txt",
    "chars": 33,
    "preview": "fastapi>=0.100.0\npydantic>=2.0.0\n"
  },
  {
    "path": "examples/streaming_chat/test_streaming.py",
    "chars": 4619,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\n\"\"\"Integration"
  },
  {
    "path": "examples/supervisor.conf",
    "chars": 182,
    "preview": "[program:gunicorn]\ncommand=/usr/local/bin/gunicorn main:application -c /path/to/project/gunicorn.conf.py\ndirectory=/path"
  },
  {
    "path": "examples/test.py",
    "chars": 636,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n#\n# Example cod"
  },
  {
    "path": "examples/timeout.py",
    "chars": 598,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport sys\nimp"
  },
  {
    "path": "examples/websocket/gevent_websocket.py",
    "chars": 15763,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport collect"
  },
  {
    "path": "examples/websocket/websocket.html",
    "chars": 1320,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n<!-- idea and code swiped from\nhttp://assorted.svn.sourceforge.net/viewvc/assorted/real-ti"
  },
  {
    "path": "examples/when_ready.conf.py",
    "chars": 1126,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nimport signal\n"
  },
  {
    "path": "gunicorn/__init__.py",
    "chars": 257,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nversion_info ="
  },
  {
    "path": "gunicorn/__main__.py",
    "chars": 338,
    "preview": "#\n# This file is part of gunicorn released under the MIT license.\n# See the NOTICE for more information.\n\nfrom gunicorn."
  }
]

// ... and 421 more files (download for full content)

About this extraction

This page contains the full source code of the benoitc/gunicorn GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 621 files (2.7 MB), approximately 737.1k tokens, and a symbol index with 4532 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!