codecov[bot]: # [Codecov](https://codecov.io/gh/falconry/falcon/pull/1658?src=pr&el=h1) Report
> Merging [#1658](https://codecov.io/gh/falconry/falcon/pull/1658?src=pr&el=desc) into [master](https://codecov.io/gh/falconry/falcon/commit/00e5c9c2499c3afb5f8d48fca80591531563d461?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/falconry/falcon/pull/1658/graphs/tree.svg?width=650&token=zOtkfNQ3h6&height=150&src=pr)](https://codecov.io/gh/falconry/falcon/pull/1658?src=pr&el=tree)

```diff
@@          Coverage Diff           @@
##           master   #1658   +/-   ##
======================================
  Coverage     100%    100%           
======================================
  Files          45      45           
  Lines        3123    3123           
  Branches      482     482           
======================================
  Hits         3123    3123
```


| [Impacted Files](https://codecov.io/gh/falconry/falcon/pull/1658?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [falcon/routing/static.py](https://codecov.io/gh/falconry/falcon/pull/1658/diff?src=pr&el=tree#diff-ZmFsY29uL3JvdXRpbmcvc3RhdGljLnB5) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/falconry/falcon/pull/1658?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/falconry/falcon/pull/1658?src=pr&el=footer). Last update [00e5c9c...cf097ec](https://codecov.io/gh/falconry/falcon/pull/1658?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

CaselIT: Currently on windows is
`2146 passed, 87 skipped, 1 warning in 414.10s (0:06:54)`
CaselIT: Upon further investigation, most (about 80%) of the time on windows  is lost in the `mimetypes.init()` call.

checking to see if mimetypes has been inited before rerunning the function brings the time down to less than 2 minutes
CaselIT: I think it's ready for review.
After the change to the mimetypes init the status on windows is `2158 passed, 75 skipped, 1 warning in 92.66s (0:01:32)`
CaselIT: I'm not familiar with travis so I cannot offer any insight on how it works for windows.

Seems that codecov has thrown a fit in the last commit
diff --git a/falcon/response.py b/falcon/response.py
index 6652971..12a9ba9 100644
--- a/falcon/response.py
+++ b/falcon/response.py
@@ -1069,5 +1069,6 @@ class ResponseOptions:
         self.default_media_type = DEFAULT_MEDIA_TYPE
         self.media_handlers = Handlers()
 
-        mimetypes.init()
+        if not mimetypes.inited:
+            mimetypes.init()
         self.static_media_types = mimetypes.types_map
diff --git a/falcon/routing/static.py b/falcon/routing/static.py
index c44e29f..b5fa12e 100644
--- a/falcon/routing/static.py
+++ b/falcon/routing/static.py
@@ -49,13 +49,16 @@ class StaticRoute:
         if not prefix.startswith('/'):
             raise ValueError("prefix must start with '/'")
 
-        if not os.path.isabs(directory):
+        self._directory = os.path.normpath(directory)
+        if not os.path.isabs(self._directory):
             raise ValueError('directory must be an absolute path')
 
         if fallback_filename is None:
             self._fallback_filename = None
         else:
-            self._fallback_filename = os.path.join(directory, fallback_filename)
+            self._fallback_filename = os.path.normpath(
+                os.path.join(self._directory, fallback_filename)
+            )
             if not os.path.isfile(self._fallback_filename):
                 raise ValueError('fallback_filename is not a file')
 
@@ -66,7 +69,6 @@ class StaticRoute:
             prefix += '/'
 
         self._prefix = prefix
-        self._directory = directory
         self._downloadable = downloadable
 
     def match(self, path):

Test failure on windows
Tests on windows have some failures and errors.

The summary is `47 failed, 2094 passed, 79 skipped, 1 warning, 16 errors in 1885.17s (0:31:25)`

The errors output is here:
https://gist.github.com/CaselIT/16792866e7dd2c545b186207976e060e

Some failues are related to asgi, while other are simple stuff like `/` vs `\` in the path.
Probably a skip on the incompatible tests and the use of `os.path.normpath` would solve most of these

This is mainly an issue to let you know this, I don't think it's really necessary fixing these, since the rests run so slow on windows (31 minutes) that it would not be practical to develop on it.

diff --git a/docs/_newsfragments/1656-tests-on-windows.misc.rst b/docs/_newsfragments/1656-tests-on-windows.misc.rst
new file mode 100644
index 0000000..fd6cc3a
--- /dev/null
+++ b/docs/_newsfragments/1656-tests-on-windows.misc.rst
@@ -0,0 +1,1 @@
+Fix test errors on Windows
diff --git a/tests/asgi/_asgi_test_app.py b/tests/asgi/_asgi_test_app.py
index 7a76a6b..c6dc672 100644
--- a/tests/asgi/_asgi_test_app.py
+++ b/tests/asgi/_asgi_test_app.py
@@ -1,11 +1,14 @@
 import asyncio
 from collections import Counter
+import sys
 import time
 
 import falcon
 import falcon.asgi
 import falcon.util
 
+_WIN32 = sys.platform.startswith('win')
+
 
 class Things:
     def __init__(self):
@@ -67,7 +70,8 @@ class Things:
         cms = falcon.util.wrap_sync_to_async(callmesafely, threadsafe=False)
         loop = falcon.util.get_loop()
 
-        num_cms_tasks = 1000
+        # NOTE(caselit): on windows it takes more time so create less tasks
+        num_cms_tasks = 100 if _WIN32 else 1000
 
         for i in range(num_cms_tasks):
             # NOTE(kgriffs): create_task() is used here, so that the coroutines
diff --git a/tests/asgi/test_asgi_servers.py b/tests/asgi/test_asgi_servers.py
index b811ddd..289544f 100644
--- a/tests/asgi/test_asgi_servers.py
+++ b/tests/asgi/test_asgi_servers.py
@@ -2,6 +2,7 @@ from contextlib import contextmanager
 import os
 import platform
 import subprocess
+import sys
 import time
 
 import pytest
@@ -14,6 +15,7 @@ from falcon import testing
 _MODULE_DIR = os.path.abspath(os.path.dirname(__file__))
 
 _PYPY = platform.python_implementation() == 'PyPy'
+_WIN32 = sys.platform.startswith('win')
 
 _SERVER_HOST = '127.0.0.1'
 _SIZE_1_KB = 1024
@@ -101,6 +103,15 @@ def _run_server_isolated(process_factory, host, port):
 
     yield server
 
+    if _WIN32:
+        import signal
+        print('\n[Sending CTRL_C_EVENT to server process...]')
+        server.send_signal(signal.CTRL_C_EVENT)
+        try:
+            server.wait(timeout=10)
+        except (KeyboardInterrupt, subprocess.TimeoutExpired):
+            pass
+
     print('\n[Sending SIGTERM to server process...]')
     server.terminate()
 
@@ -148,6 +159,8 @@ def _daphne_factory(host, port):
 @pytest.fixture(params=[_uvicorn_factory, _daphne_factory])
 def server_base_url(request):
     process_factory = request.param
+    if _WIN32 and process_factory == _daphne_factory:
+        pytest.skip('daphne does not support windows')
 
     for i in range(3):
         server_port = testing.get_unused_port()
diff --git a/tests/asgi/test_boundedstream_asgi.py b/tests/asgi/test_boundedstream_asgi.py
index 7209f68..dbc83c1 100644
--- a/tests/asgi/test_boundedstream_asgi.py
+++ b/tests/asgi/test_boundedstream_asgi.py
@@ -13,7 +13,7 @@ from falcon import asgi, testing
     b'catsup',
     b'\xDE\xAD\xBE\xEF' * 512,
     testing.rand_string(1, 2048),
-])
+], ids=['empty', 'null', 'null-ff', 'normal', 'long', 'random'])
 @pytest.mark.parametrize('extra_body', [True, False])
 @pytest.mark.parametrize('set_content_length', [True, False])
 def test_read_all(body, extra_body, set_content_length):
@@ -155,7 +155,7 @@ def test_filelike():
     b'catsup',
     b'\xDE\xAD\xBE\xEF' * 512,
     testing.rand_string(1, 2048).encode(),
-])
+], ids=['empty', 'null', 'null-ff', 'normal', 'long', 'random'])
 @pytest.mark.parametrize('chunk_size', [1, 2, 10, 64, 100, 1000, 10000])
 def test_read_chunks(body, chunk_size):
     def stream():
diff --git a/tests/conftest.py b/tests/conftest.py
index 2681553..5c0f968 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -3,7 +3,7 @@ import pytest
 import falcon
 
 
-@pytest.fixture(params=[True, False])
+@pytest.fixture(params=[True, False], ids=['asgi', 'wsgi'])
 def asgi(request):
     is_asgi = request.param
 
diff --git a/tests/test_cmd_print_api.py b/tests/test_cmd_print_api.py
index d4a11a3..beeb004 100644
--- a/tests/test_cmd_print_api.py
+++ b/tests/test_cmd_print_api.py
@@ -1,4 +1,5 @@
 import io
+from os.path import normpath
 
 import pytest
 
@@ -46,7 +47,7 @@ def test_traverse_with_verbose(app):
         get_info, options_info = options_info, get_info
 
     assert options_info.startswith('-->OPTIONS')
-    assert 'falcon/responders.py:' in options_info
+    assert '{}:'.format(normpath('falcon/responders.py')) in options_info
 
     assert get_info.startswith('-->GET')
 
@@ -54,10 +55,11 @@ def test_traverse_with_verbose(app):
     # 18 or 25 (in the case of DummyResourceAsync) in the present file.
     # Adjust the test if the said responder is relocated, or just check for
     # any number if this becomes too painful to maintain.
+    path = normpath('tests/test_cmd_print_api.py')
 
     assert (
-        get_info.endswith('tests/test_cmd_print_api.py:13') or
-        get_info.endswith('tests/test_cmd_print_api.py:20')
+        get_info.endswith('{}:14'.format(path)) or
+        get_info.endswith('{}:21'.format(path))
     )
 
 
diff --git a/tests/test_response.py b/tests/test_response.py
index c3ea3d0..6971975 100644
--- a/tests/test_response.py
+++ b/tests/test_response.py
@@ -1,6 +1,8 @@
+from unittest.mock import MagicMock
+
 import pytest
 
-from falcon import MEDIA_TEXT
+from falcon import MEDIA_TEXT, ResponseOptions
 
 from _util import create_resp  # NOQA
 
@@ -58,3 +60,18 @@ def test_response_removed_stream_len(resp):
 
     with pytest.raises(AttributeError):
         resp.stream_len
+
+
+def test_response_option_mimetype_init(monkeypatch):
+    mock = MagicMock()
+    mock.inited = False
+    monkeypatch.setattr('falcon.response.mimetypes', mock)
+
+    ro = ResponseOptions()
+
+    assert ro.static_media_types is mock.types_map
+    mock.reset_mock()
+    mock.inited = True
+    ro = ResponseOptions()
+    assert ro.static_media_types is mock.types_map
+    mock.init.assert_not_called()
diff --git a/tests/test_static.py b/tests/test_static.py
index d8e60b6..c51e9c8 100644
--- a/tests/test_static.py
+++ b/tests/test_static.py
@@ -12,11 +12,11 @@ import falcon.testing as testing
 import _util  # NOQA
 
 
-@pytest.fixture(params=[True, False])
-def client(request):
-    app = _util.create_app(asgi=request.param)
+@pytest.fixture()
+def client(asgi):
+    app = _util.create_app(asgi=asgi)
     client = testing.TestClient(app)
-    client.asgi = request.param
+    client.asgi = asgi
     return client
 
 
@@ -136,6 +136,12 @@ def test_invalid_args_fallback_filename(client, default):
         client.app.add_static_route(prefix, directory, fallback_filename=default)
 
 
+# NOTE(caselit) depending on the system configuration mime types can have alternative names
+_MIME_ALTERNATIVE = {
+    'application/zip': ('application/zip', 'application/x-zip-compressed')
+}
+
+
 @pytest.mark.parametrize('uri_prefix, uri_path, expected_path, mtype', [
     ('/static/', '/css/test.css', '/css/test.css', 'text/css'),
     ('/static', '/css/test.css', '/css/test.css', 'text/css'),
@@ -180,8 +186,8 @@ def test_good_path(asgi, uri_prefix, uri_path, expected_path, mtype, monkeypatch
         sr(req, resp)
         body = resp.stream.read()
 
-    assert resp.content_type == mtype
-    assert body.decode() == '/var/www/statics' + expected_path
+    assert resp.content_type in _MIME_ALTERNATIVE.get(mtype, (mtype, ))
+    assert body.decode() == os.path.normpath('/var/www/statics' + expected_path)
 
 
 def test_lifo(client, monkeypatch):
@@ -192,11 +198,11 @@ def test_lifo(client, monkeypatch):
 
     response = client.simulate_request(path='/downloads/thing.zip')
     assert response.status == falcon.HTTP_200
-    assert response.text == '/opt/somesite/downloads/thing.zip'
+    assert response.text == os.path.normpath('/opt/somesite/downloads/thing.zip')
 
     response = client.simulate_request(path='/downloads/archive/thingtoo.zip')
     assert response.status == falcon.HTTP_200
-    assert response.text == '/opt/somesite/x/thingtoo.zip'
+    assert response.text == os.path.normpath('/opt/somesite/x/thingtoo.zip')
 
 
 def test_lifo_negative(client, monkeypatch):
@@ -207,11 +213,11 @@ def test_lifo_negative(client, monkeypatch):
 
     response = client.simulate_request(path='/downloads/thing.zip')
     assert response.status == falcon.HTTP_200
-    assert response.text == '/opt/somesite/downloads/thing.zip'
+    assert response.text == os.path.normpath('/opt/somesite/downloads/thing.zip')
 
     response = client.simulate_request(path='/downloads/archive/thingtoo.zip')
     assert response.status == falcon.HTTP_200
-    assert response.text == '/opt/somesite/downloads/archive/thingtoo.zip'
+    assert response.text == os.path.normpath('/opt/somesite/downloads/archive/thingtoo.zip')
 
 
 def test_downloadable(client, monkeypatch):
@@ -243,6 +249,7 @@ def test_downloadable_not_found(client):
 @pytest.mark.parametrize('uri, default, expected, content_type', [
     ('', 'default', 'default', 'application/octet-stream'),
     ('other', 'default.html', 'default.html', 'text/html'),
+    ('zip', 'default.zip', 'default.zip', 'application/zip'),
     ('index2', 'index', 'index2', 'application/octet-stream'),
     ('absolute', '/foo/bar/index', '/foo/bar/index', 'application/octet-stream'),
     ('docs/notes/test.txt', 'index.html', 'index.html', 'text/html'),
@@ -253,13 +260,13 @@ def test_fallback_filename(asgi, uri, default, expected, content_type, downloada
                            monkeypatch):
 
     def mock_open(path, mode):
-        if default in path:
+        if os.path.normpath(default) in path:
             return io.BytesIO(path.encode())
 
         raise IOError()
 
     monkeypatch.setattr(io, 'open', mock_open)
-    monkeypatch.setattr('os.path.isfile', lambda file: default in file)
+    monkeypatch.setattr('os.path.isfile', lambda file: os.path.normpath(default) in file)
 
     sr = create_sr(
         asgi,
@@ -290,8 +297,8 @@ def test_fallback_filename(asgi, uri, default, expected, content_type, downloada
         body = resp.stream.read()
 
     assert sr.match(req.path)
-    assert body.decode() == os.path.join('/var/www/statics', expected)
-    assert resp.content_type == content_type
+    assert body.decode() == os.path.normpath(os.path.join('/var/www/statics', expected))
+    assert resp.content_type in _MIME_ALTERNATIVE.get(content_type, (content_type, ))
 
     if downloadable:
         assert os.path.basename(expected) in resp.downloadable_as
@@ -329,7 +336,7 @@ def test_e2e_fallback_filename(client, monkeypatch, strip_slash, path, fallback,
             assert response.status == falcon.HTTP_404
         else:
             assert response.status == falcon.HTTP_200
-            assert response.text == directory + expected
+            assert response.text == os.path.normpath(directory + expected)
 
     test('/static', '/opt/somesite/static/', static_exp)
     test('/assets', '/opt/somesite/assets/', assert_axp)
@@ -357,7 +364,7 @@ def test_filesystem_traversal_fuse(client, monkeypatch):
     def suspicious_normpath(path):
         return 'assets/../../../../' + path
 
-    monkeypatch.setattr('os.path.normpath', suspicious_normpath)
     client.app.add_static_route('/static', '/etc/nginx/includes/static-data')
+    monkeypatch.setattr('os.path.normpath', suspicious_normpath)
     response = client.simulate_request(path='/static/shadow')
     assert response.status == falcon.HTTP_404

pip install -e .[dev]
parse_log_pytest
requirements.txt
apt-get update apt-get install -y gcc
3.8
requirements/bench requirements/docs requirements/tests
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
aiofiles==24.1.0
alabaster==0.7.13
asgiref==3.8.1
attrs==25.3.0
autobahn==23.1.2
Automat==24.8.1
babel==2.17.0
backports.zoneinfo==0.2.1
beautifulsoup4==4.13.3
blinker==1.8.2
bottle==0.13.2
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
click==8.1.8
colorama==0.4.6
constantly==23.10.4
coverage==7.6.1
cryptography==44.0.2
daphne==4.1.2
Django==4.2.20
doc2dash==3.1.0
docutils==0.20.1
exceptiongroup==1.2.2
-e git+https://github.com/falconry/falcon.git@ae8aa3c1c0274e33b097de40a49e01f09e972d55#egg=falcon
Flask==3.0.3
h11==0.14.0
hyperlink==21.0.0
idna==3.10
imagesize==1.4.1
importlib_metadata==8.5.0
incremental==24.7.2
iniconfig==2.1.0
itsdangerous==2.2.0
Jinja2==3.1.6
Mako==1.3.9
markdown-it-py==3.0.0
MarkupSafe==2.1.5
mdurl==0.1.2
msgpack==1.1.0
mujson==1.4
orjson==3.10.15
packaging==24.2
pecan==1.6.0
pluggy==1.5.0
pprofile==2.2.0
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycparser==2.22
Pygments==2.19.1
pygments-style-github==0.4
pyOpenSSL==25.0.0
pytest==8.3.5
python-rapidjson==1.20
pytz==2025.2
PyYAML==6.0.2
requests==2.32.3
rich==14.0.0
service-identity==24.2.0
six==1.17.0
snowballstemmer==2.2.0
soupsieve==2.6
Sphinx==7.1.2
sphinx-rtd-theme==3.0.2
sphinxcontrib-applehelp==1.0.4
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.1
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
sqlparse==0.5.3
testtools==2.7.2
tomli==2.2.1
Twisted==24.11.0
txaio==23.1.1
typing_extensions==4.13.0
ujson==5.10.0
urllib3==2.2.3
uvicorn==0.33.0
vmprof==0.4.18.1
WebOb==1.8.9
Werkzeug==3.0.6
zipp==3.20.2
zope.interface==7.2

name: falcon
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=24.2=py38h06a4308_0
  - python=3.8.20=he870216_0
  - readline=8.2=h5eee18b_0
  - setuptools=75.1.0=py38h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.44.0=py38h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - aiofiles==24.1.0
      - alabaster==0.7.13
      - asgiref==3.8.1
      - attrs==25.3.0
      - autobahn==23.1.2
      - automat==24.8.1
      - babel==2.17.0
      - backports-zoneinfo==0.2.1
      - beautifulsoup4==4.13.3
      - blinker==1.8.2
      - bottle==0.13.2
      - certifi==2025.1.31
      - cffi==1.17.1
      - charset-normalizer==3.4.1
      - click==8.1.8
      - colorama==0.4.6
      - constantly==23.10.4
      - coverage==7.6.1
      - cryptography==44.0.2
      - daphne==4.1.2
      - django==4.2.20
      - doc2dash==3.1.0
      - docutils==0.20.1
      - exceptiongroup==1.2.2
      - falcon==3.0.0.dev1
      - flask==3.0.3
      - h11==0.14.0
      - hyperlink==21.0.0
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==8.5.0
      - incremental==24.7.2
      - iniconfig==2.1.0
      - itsdangerous==2.2.0
      - jinja2==3.1.6
      - mako==1.3.9
      - markdown-it-py==3.0.0
      - markupsafe==2.1.5
      - mdurl==0.1.2
      - msgpack==1.1.0
      - mujson==1.4
      - orjson==3.10.15
      - packaging==24.2
      - pecan==1.6.0
      - pluggy==1.5.0
      - pprofile==2.2.0
      - pyasn1==0.6.1
      - pyasn1-modules==0.4.2
      - pycparser==2.22
      - pygments==2.19.1
      - pygments-style-github==0.4
      - pyopenssl==25.0.0
      - pytest==8.3.5
      - python-rapidjson==1.20
      - pytz==2025.2
      - pyyaml==6.0.2
      - requests==2.32.3
      - rich==14.0.0
      - service-identity==24.2.0
      - six==1.17.0
      - snowballstemmer==2.2.0
      - soupsieve==2.6
      - sphinx==7.1.2
      - sphinx-rtd-theme==3.0.2
      - sphinxcontrib-applehelp==1.0.4
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.1
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - sqlparse==0.5.3
      - testtools==2.7.2
      - tomli==2.2.1
      - twisted==24.11.0
      - txaio==23.1.1
      - typing-extensions==4.13.0
      - ujson==5.10.0
      - urllib3==2.2.3
      - uvicorn==0.33.0
      - vmprof==0.4.18.1
      - webob==1.8.9
      - werkzeug==3.0.6
      - zipp==3.20.2
      - zope-interface==7.2
prefix: /opt/conda/envs/falcon

tests/test_response.py::test_response_option_mimetype_init
tests/asgi/test_asgi_servers.py::TestASGIServer::test_get[_daphne_factory] tests/asgi/test_asgi_servers.py::TestASGIServer::test_put[_daphne_factory] tests/asgi/test_asgi_servers.py::TestASGIServer::test_head_405[_daphne_factory] tests/asgi/test_asgi_servers.py::TestASGIServer::test_post_multiple[_daphne_factory] tests/asgi/test_asgi_servers.py::TestASGIServer::test_post_invalid_content_length[_daphne_factory] tests/asgi/test_asgi_servers.py::TestASGIServer::test_post_read_bounded_stream[_daphne_factory] tests/asgi/test_asgi_servers.py::TestASGIServer::test_post_read_bounded_stream_no_body[_daphne_factory] tests/asgi/test_asgi_servers.py::TestASGIServer::test_sse[_daphne_factory] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-True-empty] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-True-null] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-True-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-True-normal] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-True-long] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-True-random] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-False-empty] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-False-null] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-False-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-False-normal] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-False-long] tests/asgi/test_boundedstream_asgi.py::test_read_all[True-False-random] tests/asgi/test_boundedstream_asgi.py::test_read_all[False-False-empty] tests/asgi/test_boundedstream_asgi.py::test_read_all[False-False-null] tests/asgi/test_boundedstream_asgi.py::test_read_all[False-False-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_all[False-False-normal] tests/asgi/test_boundedstream_asgi.py::test_read_all[False-False-long] tests/asgi/test_boundedstream_asgi.py::test_read_all[False-False-random] tests/asgi/test_boundedstream_asgi.py::test_filelike tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1-empty] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1-null] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1-normal] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1-long] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1-random] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[2-empty] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[2-null] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[2-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[2-normal] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[2-long] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[2-random] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10-empty] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10-null] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10-normal] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10-long] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10-random] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[64-empty] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[64-null] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[64-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[64-normal] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[64-long] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[64-random] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[100-empty] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[100-null] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[100-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[100-normal] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[100-long] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[100-random] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1000-empty] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1000-null] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1000-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1000-normal] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1000-long] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[1000-random] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10000-empty] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10000-null] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10000-null-ff] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10000-normal] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10000-long] tests/asgi/test_boundedstream_asgi.py::test_read_chunks[10000-random] tests/asgi/test_boundedstream_asgi.py::test_exhaust_with_disconnect tests/test_cmd_print_api.py::test_traverse_with_verbose[asgi] tests/test_cmd_print_api.py::test_traverse_with_verbose[wsgi] tests/test_cmd_print_api.py::test_traverse[asgi] tests/test_cmd_print_api.py::test_traverse[wsgi] tests/test_response.py::test_response_set_content_type_set[True] tests/test_response.py::test_response_set_content_type_set[False] tests/test_response.py::test_response_set_content_type_not_set[True] tests/test_response.py::test_response_set_content_type_not_set[False] tests/test_response.py::test_response_get_headers[True] tests/test_response.py::test_response_get_headers[False] tests/test_response.py::test_response_attempt_to_set_read_only_headers[True] tests/test_response.py::test_response_attempt_to_set_read_only_headers[False] tests/test_response.py::test_response_removed_stream_len[True] tests/test_response.py::test_response_removed_stream_len[False] tests/test_static.py::test_bad_path[asgi-/static] tests/test_static.py::test_bad_path[asgi-/static/] tests/test_static.py::test_bad_path[asgi-/static/.] tests/test_static.py::test_bad_path[asgi-/static/..] tests/test_static.py::test_bad_path[asgi-/static/../.] tests/test_static.py::test_bad_path[asgi-/static/.././etc/passwd] tests/test_static.py::test_bad_path[asgi-/static/../etc/passwd] tests/test_static.py::test_bad_path[asgi-/static/css/../../secret] tests/test_static.py::test_bad_path[asgi-/static/css/../../etc/passwd] tests/test_static.py::test_bad_path[asgi-/static/./../etc/passwd] tests/test_static.py::test_bad_path[asgi-/static/css/../.\\056/etc/passwd] tests/test_static.py::test_bad_path[asgi-/static/./\\056./etc/passwd] tests/test_static.py::test_bad_path[asgi-/static/\\056\\056/etc/passwd] tests/test_static.py::test_bad_path[asgi-/static//test.css] tests/test_static.py::test_bad_path[asgi-/static//COM10] tests/test_static.py::test_bad_path[asgi-/static/path//test.css] tests/test_static.py::test_bad_path[asgi-/static/path///test.css] tests/test_static.py::test_bad_path[asgi-/static/path////test.css] tests/test_static.py::test_bad_path[asgi-/static/path/foo//test.css] tests/test_static.py::test_bad_path[asgi-/static/.\x00ssh/authorized_keys] tests/test_static.py::test_bad_path[asgi-/static/.\x1fssh/authorized_keys] tests/test_static.py::test_bad_path[asgi-/static/.\x80ssh/authorized_keys] tests/test_static.py::test_bad_path[asgi-/static/.\x9fssh/authorized_keys] tests/test_static.py::test_bad_path[asgi-/static/~/.ssh/authorized_keys] tests/test_static.py::test_bad_path[asgi-/static/.ssh/authorized_key?] tests/test_static.py::test_bad_path[asgi-/static/.ssh/authorized_key>foo] tests/test_static.py::test_bad_path[asgi-/static/.ssh/authorized_key|foo] tests/test_static.py::test_bad_path[asgi-/static/.ssh/authorized_key<foo] tests/test_static.py::test_bad_path[asgi-/static/something:something] tests/test_static.py::test_bad_path[asgi-/static/thing*.sql] tests/test_static.py::test_bad_path[asgi-/static/'thing'.sql] tests/test_static.py::test_bad_path[asgi-/static/"thing".sql] tests/test_static.py::test_bad_path[asgi-/static/something.] tests/test_static.py::test_bad_path[asgi-/static/something..] tests/test_static.py::test_bad_path[asgi-/static/something tests/test_static.py::test_bad_path[asgi-/static/ tests/test_static.py::test_bad_path[asgi-/static/something\t] tests/test_static.py::test_bad_path[asgi-/static/\tsomething] tests/test_static.py::test_bad_path[asgi-/static/ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttx] tests/test_static.py::test_bad_path[asgi-/static/\ufffdsomething] tests/test_static.py::test_bad_path[wsgi-/static] tests/test_static.py::test_bad_path[wsgi-/static/] tests/test_static.py::test_bad_path[wsgi-/static/.] tests/test_static.py::test_bad_path[wsgi-/static/..] tests/test_static.py::test_bad_path[wsgi-/static/../.] tests/test_static.py::test_bad_path[wsgi-/static/.././etc/passwd] tests/test_static.py::test_bad_path[wsgi-/static/../etc/passwd] tests/test_static.py::test_bad_path[wsgi-/static/css/../../secret] tests/test_static.py::test_bad_path[wsgi-/static/css/../../etc/passwd] tests/test_static.py::test_bad_path[wsgi-/static/./../etc/passwd] tests/test_static.py::test_bad_path[wsgi-/static/css/../.\\056/etc/passwd] tests/test_static.py::test_bad_path[wsgi-/static/./\\056./etc/passwd] tests/test_static.py::test_bad_path[wsgi-/static/\\056\\056/etc/passwd] tests/test_static.py::test_bad_path[wsgi-/static//test.css] tests/test_static.py::test_bad_path[wsgi-/static//COM10] tests/test_static.py::test_bad_path[wsgi-/static/path//test.css] tests/test_static.py::test_bad_path[wsgi-/static/path///test.css] tests/test_static.py::test_bad_path[wsgi-/static/path////test.css] tests/test_static.py::test_bad_path[wsgi-/static/path/foo//test.css] tests/test_static.py::test_bad_path[wsgi-/static/.\x00ssh/authorized_keys] tests/test_static.py::test_bad_path[wsgi-/static/.\x1fssh/authorized_keys] tests/test_static.py::test_bad_path[wsgi-/static/.\x80ssh/authorized_keys] tests/test_static.py::test_bad_path[wsgi-/static/.\x9fssh/authorized_keys] tests/test_static.py::test_bad_path[wsgi-/static/~/.ssh/authorized_keys] tests/test_static.py::test_bad_path[wsgi-/static/.ssh/authorized_key?] tests/test_static.py::test_bad_path[wsgi-/static/.ssh/authorized_key>foo] tests/test_static.py::test_bad_path[wsgi-/static/.ssh/authorized_key|foo] tests/test_static.py::test_bad_path[wsgi-/static/.ssh/authorized_key<foo] tests/test_static.py::test_bad_path[wsgi-/static/something:something] tests/test_static.py::test_bad_path[wsgi-/static/thing*.sql] tests/test_static.py::test_bad_path[wsgi-/static/'thing'.sql] tests/test_static.py::test_bad_path[wsgi-/static/"thing".sql] tests/test_static.py::test_bad_path[wsgi-/static/something.] tests/test_static.py::test_bad_path[wsgi-/static/something..] tests/test_static.py::test_bad_path[wsgi-/static/something tests/test_static.py::test_bad_path[wsgi-/static/ tests/test_static.py::test_bad_path[wsgi-/static/something\t] tests/test_static.py::test_bad_path[wsgi-/static/\tsomething] tests/test_static.py::test_bad_path[wsgi-/static/ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttx] tests/test_static.py::test_bad_path[wsgi-/static/\ufffdsomething] tests/test_static.py::test_invalid_args[asgi-static-/var/www/statics] tests/test_static.py::test_invalid_args[asgi-/static-./var/www/statics] tests/test_static.py::test_invalid_args[asgi-/static-statics] tests/test_static.py::test_invalid_args[asgi-/static-../statics] tests/test_static.py::test_invalid_args[wsgi-static-/var/www/statics] tests/test_static.py::test_invalid_args[wsgi-/static-./var/www/statics] tests/test_static.py::test_invalid_args[wsgi-/static-statics] tests/test_static.py::test_invalid_args[wsgi-/static-../statics] tests/test_static.py::test_invalid_args_fallback_filename[asgi-not-existing-file] tests/test_static.py::test_invalid_args_fallback_filename[asgi-.] tests/test_static.py::test_invalid_args_fallback_filename[asgi-/tmp] tests/test_static.py::test_invalid_args_fallback_filename[wsgi-not-existing-file] tests/test_static.py::test_invalid_args_fallback_filename[wsgi-.] tests/test_static.py::test_invalid_args_fallback_filename[wsgi-/tmp] tests/test_static.py::test_good_path[asgi-/static/-/css/test.css-/css/test.css-text/css] tests/test_static.py::test_good_path[asgi-/static-/css/test.css-/css/test.css-text/css] tests/test_static.py::test_good_path[asgi-/static-/tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt-/tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt-application/octet-stream] tests/test_static.py::test_good_path[asgi-/static-/.test.css-/.test.css-text/css] tests/test_static.py::test_good_path[asgi-/some/download/-/report.pdf-/report.pdf-application/pdf] tests/test_static.py::test_good_path[asgi-/some/download/-/Fancy tests/test_static.py::test_good_path[asgi-/some/download-/report.zip-/report.zip-application/zip] tests/test_static.py::test_good_path[asgi-/some/download-/foo/../report.zip-/report.zip-application/zip] tests/test_static.py::test_good_path[asgi-/some/download-/foo/../bar/../report.zip-/report.zip-application/zip] tests/test_static.py::test_good_path[asgi-/some/download-/foo/bar/../../report.zip-/report.zip-application/zip] tests/test_static.py::test_good_path[wsgi-/static/-/css/test.css-/css/test.css-text/css] tests/test_static.py::test_good_path[wsgi-/static-/css/test.css-/css/test.css-text/css] tests/test_static.py::test_good_path[wsgi-/static-/tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt-/tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt-application/octet-stream] tests/test_static.py::test_good_path[wsgi-/static-/.test.css-/.test.css-text/css] tests/test_static.py::test_good_path[wsgi-/some/download/-/report.pdf-/report.pdf-application/pdf] tests/test_static.py::test_good_path[wsgi-/some/download/-/Fancy tests/test_static.py::test_good_path[wsgi-/some/download-/report.zip-/report.zip-application/zip] tests/test_static.py::test_good_path[wsgi-/some/download-/foo/../report.zip-/report.zip-application/zip] tests/test_static.py::test_good_path[wsgi-/some/download-/foo/../bar/../report.zip-/report.zip-application/zip] tests/test_static.py::test_good_path[wsgi-/some/download-/foo/bar/../../report.zip-/report.zip-application/zip] tests/test_static.py::test_lifo[asgi] tests/test_static.py::test_lifo[wsgi] tests/test_static.py::test_lifo_negative[asgi] tests/test_static.py::test_lifo_negative[wsgi] tests/test_static.py::test_downloadable[asgi] tests/test_static.py::test_downloadable[wsgi] tests/test_static.py::test_downloadable_not_found[asgi] tests/test_static.py::test_downloadable_not_found[wsgi] tests/test_static.py::test_fallback_filename[asgi-True--default-default-application/octet-stream] tests/test_static.py::test_fallback_filename[asgi-True-other-default.html-default.html-text/html] tests/test_static.py::test_fallback_filename[asgi-True-zip-default.zip-default.zip-application/zip] tests/test_static.py::test_fallback_filename[asgi-True-index2-index-index2-application/octet-stream] tests/test_static.py::test_fallback_filename[asgi-True-absolute-/foo/bar/index-/foo/bar/index-application/octet-stream] tests/test_static.py::test_fallback_filename[asgi-True-docs/notes/test.txt-index.html-index.html-text/html] tests/test_static.py::test_fallback_filename[asgi-True-index.html_files/test.txt-index.html-index.html_files/test.txt-text/plain] tests/test_static.py::test_fallback_filename[asgi-False--default-default-application/octet-stream] tests/test_static.py::test_fallback_filename[asgi-False-other-default.html-default.html-text/html] tests/test_static.py::test_fallback_filename[asgi-False-zip-default.zip-default.zip-application/zip] tests/test_static.py::test_fallback_filename[asgi-False-index2-index-index2-application/octet-stream] tests/test_static.py::test_fallback_filename[asgi-False-absolute-/foo/bar/index-/foo/bar/index-application/octet-stream] tests/test_static.py::test_fallback_filename[asgi-False-docs/notes/test.txt-index.html-index.html-text/html] tests/test_static.py::test_fallback_filename[asgi-False-index.html_files/test.txt-index.html-index.html_files/test.txt-text/plain] tests/test_static.py::test_fallback_filename[wsgi-True--default-default-application/octet-stream] tests/test_static.py::test_fallback_filename[wsgi-True-other-default.html-default.html-text/html] tests/test_static.py::test_fallback_filename[wsgi-True-zip-default.zip-default.zip-application/zip] tests/test_static.py::test_fallback_filename[wsgi-True-index2-index-index2-application/octet-stream] tests/test_static.py::test_fallback_filename[wsgi-True-absolute-/foo/bar/index-/foo/bar/index-application/octet-stream] tests/test_static.py::test_fallback_filename[wsgi-True-docs/notes/test.txt-index.html-index.html-text/html] tests/test_static.py::test_fallback_filename[wsgi-True-index.html_files/test.txt-index.html-index.html_files/test.txt-text/plain] tests/test_static.py::test_fallback_filename[wsgi-False--default-default-application/octet-stream] tests/test_static.py::test_fallback_filename[wsgi-False-other-default.html-default.html-text/html] tests/test_static.py::test_fallback_filename[wsgi-False-zip-default.zip-default.zip-application/zip] tests/test_static.py::test_fallback_filename[wsgi-False-index2-index-index2-application/octet-stream] tests/test_static.py::test_fallback_filename[wsgi-False-absolute-/foo/bar/index-/foo/bar/index-application/octet-stream] tests/test_static.py::test_fallback_filename[wsgi-False-docs/notes/test.txt-index.html-index.html-text/html] tests/test_static.py::test_fallback_filename[wsgi-False-index.html_files/test.txt-index.html-index.html_files/test.txt-text/plain] tests/test_static.py::test_e2e_fallback_filename[asgi-/index-index.html-index-index-True] tests/test_static.py::test_e2e_fallback_filename[asgi-/index-index.html-index-index-False] tests/test_static.py::test_e2e_fallback_filename[asgi--index.html-index.html-None-True] tests/test_static.py::test_e2e_fallback_filename[asgi--index.html-index.html-None-False] tests/test_static.py::test_e2e_fallback_filename[asgi-/-index.html-index.html-None-True] tests/test_static.py::test_e2e_fallback_filename[asgi-/-index.html-index.html-None-False] tests/test_static.py::test_e2e_fallback_filename[asgi-/other-index.html-index.html-None-True] tests/test_static.py::test_e2e_fallback_filename[asgi-/other-index.html-index.html-None-False] tests/test_static.py::test_e2e_fallback_filename[asgi-/other-index.raise-None-None-True] tests/test_static.py::test_e2e_fallback_filename[asgi-/other-index.raise-None-None-False] tests/test_static.py::test_e2e_fallback_filename[wsgi-/index-index.html-index-index-True] tests/test_static.py::test_e2e_fallback_filename[wsgi-/index-index.html-index-index-False] tests/test_static.py::test_e2e_fallback_filename[wsgi--index.html-index.html-None-True] tests/test_static.py::test_e2e_fallback_filename[wsgi--index.html-index.html-None-False] tests/test_static.py::test_e2e_fallback_filename[wsgi-/-index.html-index.html-None-True] tests/test_static.py::test_e2e_fallback_filename[wsgi-/-index.html-index.html-None-False] tests/test_static.py::test_e2e_fallback_filename[wsgi-/other-index.html-index.html-None-True] tests/test_static.py::test_e2e_fallback_filename[wsgi-/other-index.html-index.html-None-False] tests/test_static.py::test_e2e_fallback_filename[wsgi-/other-index.raise-None-None-True] tests/test_static.py::test_e2e_fallback_filename[wsgi-/other-index.raise-None-None-False] tests/test_static.py::test_match[asgi-None-/static-False] tests/test_static.py::test_match[asgi-None-/static/-True] tests/test_static.py::test_match[asgi-None-/staticfoo-False] tests/test_static.py::test_match[asgi-None-/static/foo-True] tests/test_static.py::test_match[asgi-index2-/static-True] tests/test_static.py::test_match[asgi-index2-/static/-True] tests/test_static.py::test_match[asgi-index2-/staticfoo-False] tests/test_static.py::test_match[asgi-index2-/static/foo-True] tests/test_static.py::test_match[wsgi-None-/static-False] tests/test_static.py::test_match[wsgi-None-/static/-True] tests/test_static.py::test_match[wsgi-None-/staticfoo-False] tests/test_static.py::test_match[wsgi-None-/static/foo-True] tests/test_static.py::test_match[wsgi-index2-/static-True] tests/test_static.py::test_match[wsgi-index2-/static/-True] tests/test_static.py::test_match[wsgi-index2-/staticfoo-False] tests/test_static.py::test_match[wsgi-index2-/static/foo-True] tests/test_static.py::test_filesystem_traversal_fuse[asgi] tests/test_static.py::test_filesystem_traversal_fuse[wsgi]
falcon/routing/static.py falcon/response.py
falcon/routing/static.py falcon/response.py