The middleware provides two hook points in the request/response lifecycle:
-
process_request(req, resp): Called before routing the request to a resource. This is where the correlation ID will be retrieved from incoming headers or generated. -
process_response(req, resp, resource, req_succeeded): Called after the resource responder has been invoked. This is where the correlation ID established by this middleware will be added to response headers and any cleanup will be performed.
For Falcon ASGI applications, CorrelationIDMiddlewareASGI exposes the same
hook names as coroutine methods. Request selection, response-header echoing,
and cleanup follow the same rules as the WSGI middleware.
ASGI context variables are request-local. While an ASGI request is running,
req.context.correlation_id and correlation_id_var.get() expose the same
active correlation ID to application code. Concurrent ASGI requests keep
separate values even when their resource responders overlap in the event loop.
After response processing completes, correlation_id_var is reset to its
previous ambient value. That value is usually None when no correlation ID was
set before the request, but nested or already-populated contexts can restore a
non-None value. Response header echoing still follows the
echo_header_in_response setting.
Header retrieval and trusted source behaviour
During process_request, the middleware reads the configured header name and
checks whether the request originates from a trusted source. The correlation ID
stored on req.context.correlation_id is determined as follows:
-
If a valid header value is present, the request source is trusted, and the value passes validation (when a validator is configured), the incoming ID is accepted after trimming leading and trailing whitespace.
-
If a valid header value is present and the request source is trusted, but the value fails validation, the incoming ID is rejected and a new ID is generated. The validation failure is logged at
DEBUGlevel. -
If a valid header value is present but the request source is not trusted, the incoming ID is rejected and a new ID is generated using the configured generator. The validator is not called in this case.
-
If the header is missing, empty, or contains only whitespace, a new ID is generated using the configured generator.
When no validator is configured (the default), incoming IDs from trusted sources are accepted without format checking, preserving backwards compatibility.
This design ensures that every request receives a correlation ID for complete traceability, while preventing untrusted clients from injecting arbitrary IDs into the system.