Skip to content

No longer possible to tell if path had escaped characters in it #261

@simonw

Description

@simonw

This commit introduced behaviour which is causing me problems: b420242

For my application (Datasette) I need to be able to tell the difference between the following two URLs:

This is because Datasette's URL design allows for the name of a SQLite database table to be incorporated into the URL path - and SQLite tables can (bizarrely) include slashes in their names. As you can see in the above example, this works: you can %2F encode those slashes and Datasette will know that they are part of the table name.

Prior to the b420242 uvicorn handled this in a way that works for my application. Here's a debugging tool I deployed using an older version of uvicorn that illustrates the behaviour I need:

https://asgi-scope.now.sh/fixtures/table%2Fwith%2Fslashes.csv

This tool ( https://github.com/simonw/asgi-scope ) simply outputs the current ASGI scope. As you can see, the path component looks like this:

 'method': 'GET',
 'path': '/fixtures/table%2Fwith%2Fslashes.csv',
 'query_string': b'',

But... here's a new version of the above tool I just deployed using the latest uvicorn release:

https://asgi-scope-uvicorn-0-3-23.now.sh/fixtures/table%2Fwith%2Fslashes.csv

 'method': 'GET',
 'path': '/fixtures/table/with/slashes.csv',
 'query_string': b'',

The path has been decoded for me! This means that my application code has no way of telling if the initial input had %2F or / - that information has been lost entirely.

Unfortunately, this appears to be a behaviour that is encoded in the ASGI spec itself:

https://github.com/django/asgiref/blob/5fe2e535e64f85ada8078ad6aabf5e418b77d26b/specs/www.rst#L63-L65

I'm going to open a similar bug against the spec, but assuming the spec doesn't change how about adding a new key to the scope called something like raw_path which exposes the original bytes?

Alternatively, how about making it so I can easily subclass the relevant part of uvicorn and get back the behaviour that I need?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions