Repository navigation
release: v0.2.0 hardening from dev - #69
Merged
Merged
Conversation
- Cursor rule: ordered steps including read issue, CI parity before push - development-workflow: checklist; fix ci workflow link - CONTRIBUTING: sync dev first, linters, pointer to workflow
- Add CompiledRouters (Arc) cloned from per-method matchit tables at freeze - match_route and methods_matching_path use snapshot when set; mutex path before freeze - Unit tests for match parity and methods_matching_path Closes #4
Issue 4 lock free route snapshot
…afe deadlock - Run handle_rsgi via run_in_executor + asyncio.run on a worker loop; main ASGI loop remains free to drain run_coroutine_threadsafe from the RSGI protocol. - Add 50-concurrent-GET stress test (httpx ASGITransport). - Document bridge behavior and uvicorn single-worker note in docs/asgi.md. Closes #17
fix(asgi): run handle_rsgi in executor to avoid run_coroutine_threads…
- Expose types.SimpleNamespace on App.state; document in class docstring and rsgi.md - rsgi_lifespan_app: ThreadPoolExecutor + asyncio.Semaphore, safe shutdown in __rsgi_del__ - test: app.state is a mutable SimpleNamespace; refresh feature.md and PRIORITIES Closes #18
feat(app): add per-process app.state; expand lifespan example (#18)
- Route flag read_form_body; inject form (dict) and files (list of part dicts) - Parse with form_urlencoded crate and multer; 400/415 on bad input; 413 when body exceeds OXYROUTE_MAX_BODY_BYTES (default 8 MiB; 0 disables) - Mutual exclusion with read_json_body in Rust and app._route - Tests: httpx ASGI urlencoded, multipart upload, oversize 413 - docs/handlers.md + feature.md; PRIORITIES marks #47 done Closes #47
feat: form bodies (urlencoded + multipart) with read_form_body (#47)
feat: HTTPException for non-500 JSON responses (#48)
- Add oxyroute.router: APIRouter (same route decorators as App), join_path, nested APIRouter.include_router - App.include_router: merge default kwargs, filter by method signature, register on native app + OpenAPI - tests, examples/routers_include_app.py, docs/routing.md; PRIORITIES + feature.md Closes #46
feat: APIRouter and App.include_router (#46)
- Add oxyroute.cors with CORSConfig, preflightResponse, apply_cors(chain=) - App.set_cors and exports; Rust merges response_header_pairs after handlers/middleware - Fix Py<PyAny> clone under GIL, PyO3 0.25 extract + merge_cors_to_handler_map - tests/test_cors.py, docs/cors.md, backlog and feature table updates
- Ensure .venv with PY_BOOTSTRAP; UV_PYTHON points at .venv to avoid PEP 668 on /usr - One shot: sync, ruff, rustfmt+clippy, maturin develop --uv, pytest in temp dir
- AGENTS.md and git-workflow: prefer make test, human runs before push - oxyroute: RUF022 __all__ order, ruff format cors.py
Issue 49 cors
- Rust: state.security_headers, set_security_headers, merge if-absent then CORS replace - oxyroute.security_headers: HSTS on https only, optional CSP/Permissions-Policy, extra - tests, docs/security-headers.md, backlog; App.set_security_headers
Issue 54 security headers
- oxyroute.csrf: CSRFConfig.guard, constant-time compare, 403 JSON - apply_csrf + csrf_layer for chain with apply_cors - docs/csrf.md, tests, backlog; export in __init__
Issue 53 csrf
Clarify what OxyRoute guarantees for HTTP/2 versus what is owned by Granian/proxy TLS setup, and add a docs index entry for discoverability.
docs: document HTTP/2 deployment guarantees with Granian
Allow applications to register exact-path websocket handlers and dispatch them through the ASGI bridge as a practical spike for issue #52.
Add an end-to-end style websocket test for connect, receive, send, and close to validate the new ASGI websocket spike behavior.
Document the new websocket API, its current ASGI-only scope, and the split between Python spike implementation and future Rust/RSGI work.
Add the websocket page to the main documentation index so the new ASGI spike API is discoverable.
Mark websocket support as partial via the ASGI spike and clarify that RSGI-native websocket support is still pending.
feat: add ASGI websocket spike with docs and tests
Replace run_coroutine_threadsafe(...).result() with a thread-safe outgoing queue drained on the main ASGI loop to reduce deadlock risk under concurrent load.
Document the queue-based response bridge and align the deadlock explanation with the new non-blocking send scheduling model.
fix: harden ASGI bridge response scheduling under load
Ensure ASGI queue drain shutdown runs reliably in exception/cancellation paths and preserve the original request failure instead of leaking drain-task state.
Dispatch synchronous websocket handlers entirely in the executor so user sync code does not block the main ASGI event loop.
Cover executor failure behavior to verify the ASGI outgoing drain task is finalized without hanging tasks.
Add coverage that synchronous websocket handlers run outside the loop thread and still complete accept/close flow.
Synchronize Python package, Rust crate, lockfiles, and OpenAPI info version so release artifacts and runtime docs report 0.2.0 consistently.
Refresh development guide examples so the release tagging instructions match the current target version.
This was
linked to
issues
Apr 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan
make test(maintainer run)tests/test_asgi.py::test_asgi_queue_drain_shutdown_when_executor_path_raisestests/test_websocket_asgi.py::test_asgi_websocket_sync_handler_runs_off_loop_threadThis PR is opened with base
mainas requested and includes currentdevline + release hardening commits.