Summary: Middleware.use() / Router.use() register a global middleware class into _global_middleware, but the request dispatcher never reads that list — it iterates only each route's own middleware. So globally-registered middleware silently never runs. Severity: high (a documented API that does nothing).
Version: tina4-python 3.13.37.
Where
Registration — tina4_python/core/middleware.py (~29–53):
class Middleware:
_global_middleware: list = []
@classmethod
def use(cls, middleware_class) -> None:
if middleware_class not in cls._global_middleware:
cls._global_middleware.append(middleware_class)
@classmethod
def get_global(cls) -> list: ...
Dispatch — tina4_python/core/server.py::_run_before_middleware() (~1250–1260) and _run_after_middleware() (~1284):
for _mw_cls in route.get("middleware", []): # <-- ONLY route-level; globals ignored
...
Neither consults Middleware.get_global() / _global_middleware.
Impact
Apps that want app-wide middleware (tenant resolution, auth) can't use the documented Middleware.use() — we had to monkey-patch Router.add to prepend our middleware to every route's list.
Repro / regression test
from tina4_python.core.middleware import Middleware
ran = []
class Probe:
@staticmethod
def before_probe(req, resp):
ran.append(1); return req, resp
Middleware.use(Probe)
# register a plain route with NO per-route middleware, dispatch a request to it, then:
assert ran, "Middleware.use() global was never invoked"
ran is empty today; populated after the fix.
Suggested fix
Prepend the registered globals in the dispatcher (mirror in _run_after_middleware):
for _mw_cls in Middleware.get_global() + list(route.get("middleware", [])):
...
or merge Middleware.get_global() into each route's middleware once in Router.add.
Summary:
Middleware.use()/Router.use()register a global middleware class into_global_middleware, but the request dispatcher never reads that list — it iterates only each route's ownmiddleware. So globally-registered middleware silently never runs. Severity: high (a documented API that does nothing).Version: tina4-python 3.13.37.
Where
Registration —
tina4_python/core/middleware.py(~29–53):Dispatch —
tina4_python/core/server.py::_run_before_middleware()(~1250–1260) and_run_after_middleware()(~1284):Neither consults
Middleware.get_global()/_global_middleware.Impact
Apps that want app-wide middleware (tenant resolution, auth) can't use the documented
Middleware.use()— we had to monkey-patchRouter.addto prepend our middleware to every route's list.Repro / regression test
ranis empty today; populated after the fix.Suggested fix
Prepend the registered globals in the dispatcher (mirror in
_run_after_middleware):or merge
Middleware.get_global()into each route'smiddlewareonce inRouter.add.