diff --git a/README.md b/README.md index 8d8470b..a3713a0 100644 --- a/README.md +++ b/README.md @@ -183,11 +183,12 @@ Configurable middleware arguments include: **validator** - Type: `Callable[[str], bool]` -- Default: `is_valid_uuid4` ( - found [here](https://github.com/snok/asgi-correlation-id/blob/main/asgi_correlation_id/middleware.py#L17)) -- Description: The validator function is used when reading incoming HTTP header values. By default, we discard non-UUID - formatted header values, to enforce correlation ID uniqueness. If you prefer to allow any header value, you can set - this setting to `None`, or pass your own validator. +- Default: `is_valid_uuid4` +- Description: The validator function is used when reading incoming HTTP header values. By default, we accept any + 32-character hex string that can be parsed as a UUID — this includes standard UUIDv4s, nginx-generated request IDs + (`$request_id`), and OpenTelemetry trace IDs. Non-hex or malformed values are rejected and a new ID is generated + instead. If you prefer to allow any header value, set this to `None`. For stricter UUIDv4 validation, pass your own + validator. **transformer** diff --git a/asgi_correlation_id/middleware.py b/asgi_correlation_id/middleware.py index a43d8c5..4ecc008 100644 --- a/asgi_correlation_id/middleware.py +++ b/asgi_correlation_id/middleware.py @@ -17,10 +17,16 @@ def is_valid_uuid4(uuid_: str) -> bool: """ - Check whether a string is a valid v4 uuid. + Check whether a string can be parsed as a UUID. + + This is a loose check that accepts any 32-character hex string, + including IDs generated by nginx ($request_id) and OpenTelemetry + trace IDs. It does not strictly validate UUIDv4 version/variant bits. + + For stricter validation, pass a custom ``validator`` to the middleware. """ try: - return UUID(uuid_).version == 4 + return bool(UUID(uuid_, version=4)) except ValueError: return False diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 1367589..8ca0598 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -174,9 +174,14 @@ async def test_custom_generator(): def test_is_valid_uuid4(): + # Standard UUIDv4 strings assert is_valid_uuid4('3758c31e-1177-4540-ba33-0109c405579a') is True assert is_valid_uuid4('9e6454c4-21d5-4e4a-a66a-b28f15576414') is True assert is_valid_uuid4('9e6454c421d54e4aa66ab28f15576414') is True + # Nginx-style 16 random bytes as hex (not strictly UUIDv4, but should be accepted) + assert is_valid_uuid4('c10f7ebebd95e5bb8749430d3485370c') is True + # All zeros (accepted by loose check) + assert is_valid_uuid4('00000000000000000000000000000000') is True + # Invalid strings assert is_valid_uuid4('foo') is False assert is_valid_uuid4('9e6454c4-21d5-4e4a-a66a-b28f15576414-1') is False - assert is_valid_uuid4('00000000000000000000000000000000') is False