diff --git a/docs/_newsfragments/1594.bugfix.rst b/docs/_newsfragments/1594.bugfix.rst
new file mode 100644
index 0000000..814c057
--- /dev/null
+++ b/docs/_newsfragments/1594.bugfix.rst
@@ -0,0 +1,3 @@
+:meth:`falcon.uri.decode` and :meth:`falcon.uri.parse_query_string` no longer
+explode quadratically for a large number of percent-encoded characters. The
+time complexity of these utility functions is now always close to *O*(*n*).
diff --git a/falcon/util/uri.py b/falcon/util/uri.py
index 9af38b6..2ff296c 100644
--- a/falcon/util/uri.py
+++ b/falcon/util/uri.py
@@ -24,6 +24,8 @@ in the `falcon` module, and so must be explicitly imported::
 
 """
 
+import platform
+
 try:
     from falcon.cyutil.uri import (
         decode as _cy_decode,
@@ -51,6 +53,8 @@ _HEX_TO_BYTE = dict(((a + b).encode(), bytes([int(a + b, 16)]))
                     for a in _HEX_DIGITS
                     for b in _HEX_DIGITS)
 
+_PYPY = platform.python_implementation() == 'PyPy'
+
 
 def _create_char_encoder(allowed_chars):
 
@@ -168,6 +172,52 @@ Returns:
 """
 
 
+def _join_tokens_bytearray(tokens):
+    decoded_uri = bytearray(tokens[0])
+    for token in tokens[1:]:
+        token_partial = token[:2]
+        try:
+            decoded_uri += _HEX_TO_BYTE[token_partial] + token[2:]
+        except KeyError:
+            # malformed percentage like "x=%" or "y=%+"
+            decoded_uri += b'%' + token
+
+    # Convert back to str
+    return decoded_uri.decode('utf-8', 'replace')
+
+
+def _join_tokens_list(tokens):
+    decoded = tokens[:1]
+    # PERF(vytas): Do not copy list: a simple bool flag is fastest on PyPy JIT.
+    skip = True
+    for token in tokens:
+        if skip:
+            skip = False
+            continue
+
+        token_partial = token[:2]
+        try:
+            decoded.append(_HEX_TO_BYTE[token_partial] + token[2:])
+        except KeyError:
+            # malformed percentage like "x=%" or "y=%+"
+            decoded.append(b'%' + token)
+
+    # Convert back to str
+    return b''.join(decoded).decode('utf-8', 'replace')
+
+
+# PERF(vytas): The best method to join many byte strings depends on the Python
+#   implementation and many other factors such as the total string length,
+#   and the number of items to join.
+# Considering that CPython users are likely to choose the Cython implementation
+#   of decode anyway, we pick one best allrounder per platform:
+#   * On pure CPython, bytearray += often comes on top, also with the added
+#     benefit of being able to decode() off it directly.
+#   * On PyPy, b''.join(list) is the recommended approach, although it may
+#     narrowly lose to BytesIO on the extreme end.
+_join_tokens = _join_tokens_list if _PYPY else _join_tokens_bytearray
+
+
 def decode(encoded_uri, unquote_plus=True):
     """Decodes percent-encoded characters in a URI or query string.
 
@@ -209,17 +259,23 @@ def decode(encoded_uri, unquote_plus=True):
     # PERF(kgriffs): This was found to be faster than using
     # a regex sub call or list comprehension with a join.
     tokens = decoded_uri.split(b'%')
-    decoded_uri = tokens[0]
-    for token in tokens[1:]:
-        token_partial = token[:2]
-        try:
-            decoded_uri += _HEX_TO_BYTE[token_partial] + token[2:]
-        except KeyError:
-            # malformed percentage like "x=%" or "y=%+"
-            decoded_uri += b'%' + token
-
-    # Convert back to str
-    return decoded_uri.decode('utf-8', 'replace')
+    # PERF(vytas): Just use in-place add for a low number of items:
+    if len(tokens) < 8:
+        decoded_uri = tokens[0]
+        for token in tokens[1:]:
+            token_partial = token[:2]
+            try:
+                decoded_uri += _HEX_TO_BYTE[token_partial] + token[2:]
+            except KeyError:
+                # malformed percentage like "x=%" or "y=%+"
+                decoded_uri += b'%' + token
+
+        # Convert back to str
+        return decoded_uri.decode('utf-8', 'replace')
+
+    # NOTE(vytas): Decode percent-encoded bytestring fragments and join them
+    # back to a string using the platform-dependent method.
+    return _join_tokens(tokens)
 
 
 def parse_query_string(query_string, keep_blank=False, csv=True):

diff --git a/tests/test_utils.py b/tests/test_utils.py
index af300ad..8c5d430 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -31,6 +31,15 @@ def _arbitrary_uris(count, length):
     )
 
 
+@pytest.fixture(params=['bytearray', 'join_list'])
+def decode_approach(request, monkeypatch):
+    method = uri._join_tokens_list
+    if request.param == 'bytearray':
+        method = uri._join_tokens_bytearray
+    monkeypatch.setattr(uri, '_join_tokens', method)
+    return method
+
+
 class TestFalconUtils:
 
     def setup_method(self, method):
@@ -196,7 +205,7 @@ class TestFalconUtils:
         assert uri.encode_value('ab/cd') == 'ab%2Fcd'
         assert uri.encode_value('ab+cd=42,9') == 'ab%2Bcd%3D42%2C9'
 
-    def test_uri_decode(self):
+    def test_uri_decode(self, decode_approach):
         assert uri.decode('abcd') == 'abcd'
         assert uri.decode('ab%20cd') == 'ab cd'
 
@@ -210,16 +219,24 @@ class TestFalconUtils:
             'http://example.com?x=ab%2Bcd%3D42%2C9'
         ) == 'http://example.com?x=ab+cd=42,9'
 
+    @pytest.mark.parametrize('encoded,expected', [
+        ('ab%2Gcd', 'ab%2Gcd'),
+        ('ab%2Fcd: 100% coverage', 'ab/cd: 100% coverage'),
+        ('%s' * 100, '%s' * 100),
+    ])
+    def test_uri_decode_bad_coding(self, encoded, expected, decode_approach):
+        assert uri.decode(encoded) == expected
+
     @pytest.mark.parametrize('encoded,expected', [
         ('+%80', ' �'),
         ('+++%FF+++', '   �   '),  # impossible byte
         ('%fc%83%bf%bf%bf%bf', '������'),  # overlong sequence
         ('%ed%ae%80%ed%b0%80', '������'),  # paired UTF-16 surrogates
     ])
-    def test_uri_decode_replace_bad_unicode(self, encoded, expected):
+    def test_uri_decode_bad_unicode(self, encoded, expected, decode_approach):
         assert uri.decode(encoded) == expected
 
-    def test_uri_decode_unquote_plus(self):
+    def test_uri_decode_unquote_plus(self, decode_approach):
         assert uri.decode('/disk/lost+found/fd0') == '/disk/lost found/fd0'
         assert uri.decode('/disk/lost+found/fd0', unquote_plus=True) == (
             '/disk/lost found/fd0')

Low performance in req._parse_form_urlencoded()
It's really slow when invoking req._parse_form_urlencoded() if the form body is huge. 
And after digging deeper, I found it was caused by the function named decode(encoded_uri, unquote_plus=True) defined in falcon/util/uri.py. The root cause is the low performance of list concatenation. 
A little refactor can improve performance greatly.
The code before:
```python
def decode(encoded_uri, unquote_plus=True):
    """Decodes percent-encoded characters in a URI or query string.
    This function models the behavior of `urllib.parse.unquote_plus`,
    albeit in a faster, more straightforward manner.
    Args:
        encoded_uri (str): An encoded URI (full or partial).
    Keyword Arguments:
        unquote_plus (bool): Set to ``False`` to retain any plus ('+')
            characters in the given string, rather than converting them to
            spaces (default ``True``). Typically you should set this
            to ``False`` when decoding any part of a URI other than the
            query string.
    Returns:
        str: A decoded URL. If the URL contains escaped non-ASCII
        characters, UTF-8 is assumed per RFC 3986.
    """

    decoded_uri = encoded_uri

    # PERF(kgriffs): Don't take the time to instantiate a new
    # string unless we have to.
    if '+' in decoded_uri and unquote_plus:
        decoded_uri = decoded_uri.replace('+', ' ')

    # Short-circuit if we can
    if '%' not in decoded_uri:
        return decoded_uri

    # NOTE(kgriffs): Clients should never submit a URI that has
    # unescaped non-ASCII chars in them, but just in case they
    # do, let's encode into a non-lossy format.
    decoded_uri = decoded_uri.encode('utf-8')

    # PERF(kgriffs): This was found to be faster than using
    # a regex sub call or list comprehension with a join.
    tokens = decoded_uri.split(b'%')
    decoded_uri = tokens[0]
    for token in tokens[1:]:
        token_partial = token[:2]
        try:
            decoded_uri += _HEX_TO_BYTE[token_partial] + token[2:]
        except KeyError:
            # malformed percentage like "x=%" or "y=%+"
            decoded_uri += b'%' + token

    # Convert back to str
    return decoded_uri.decode('utf-8', 'replace')
```

The code optimized:
```python
import io
def decode(encoded_uri, unquote_plus=True):
    """Decodes percent-encoded characters in a URI or query string.
    This function models the behavior of `urllib.parse.unquote_plus`,
    albeit in a faster, more straightforward manner.
    Args:
        encoded_uri (str): An encoded URI (full or partial).
    Keyword Arguments:
        unquote_plus (bool): Set to ``False`` to retain any plus ('+')
            characters in the given string, rather than converting them to
            spaces (default ``True``). Typically you should set this
            to ``False`` when decoding any part of a URI other than the
            query string.
    Returns:
        str: A decoded URL. If the URL contains escaped non-ASCII
        characters, UTF-8 is assumed per RFC 3986.
    """

    decoded_uri = encoded_uri

    # PERF(kgriffs): Don't take the time to instantiate a new
    # string unless we have to.
    if '+' in decoded_uri and unquote_plus:
        decoded_uri = decoded_uri.replace('+', ' ')

    # Short-circuit if we can
    if '%' not in decoded_uri:
        return decoded_uri

    # NOTE(kgriffs): Clients should never submit a URI that has
    # unescaped non-ASCII chars in them, but just in case they
    # do, let's encode into a non-lossy format.
    decoded_uri = decoded_uri.encode('utf-8')

    # PERF(kgriffs): This was found to be faster than using
    # a regex sub call or list comprehension with a join.
    tokens = decoded_uri.split(b'%')
    bytes = io.BytesIO()
    bytes.write(tokens[0])
    # decoded_uri = tokens[0]
    for token in tokens[1:]:
        token_partial = token[:2]
        try:
            bytes.write(_HEX_TO_BYTE[token_partial])
            bytes.write(token[2:])
            # decoded_uri += _HEX_TO_BYTE[token_partial] + token[2:]
        except KeyError:
            # malformed percentage like "x=%" or "y=%+"
            # decoded_uri += b'%' + token
            bytes.write(b'%')
            bytes.write(token)

    # Convert back to str
    # return decoded_uri.decode('utf-8', 'replace')
    return bytes.getvalue().decode('utf-8', 'replace')
```
And the time costs before optimizing is
python3.7 test.py 
2019-10-27 23:25:38,030 urllib3.connectionpool: DEBUG    Starting new HTTP connection (1): 127.0.0.1:8080
2019-10-27 23:26:04,819 urllib3.connectionpool: DEBUG    http://127.0.0.1:8080 "POST /api/import/postdata/async HTTP/1.1" 200 146
2019-10-27 23:26:04,820 __main__    : DEBUG    post data return: {"status":"ok","error_msg":"","successRecords":[],"failedRecords":[],"totalSuccessRecords":500,"totalFailedRecords":0,"timeElapsed":26.7830269337}
2019-10-27 23:26:04,821 __main__    : DEBUG    time elapsed: 27.266945600509644
After optimizing is:
python3.7 test.py 
2019-10-27 23:54:09,490 urllib3.connectionpool: DEBUG    Starting new HTTP connection (1): 127.0.0.1:8080
2019-10-27 23:54:09,791 urllib3.connectionpool: DEBUG    http://127.0.0.1:8080 "POST /api/import/postdata/async HTTP/1.1" 200 145
2019-10-27 23:54:09,794 __main__    : DEBUG    post data return: {"status":"ok","error_msg":"","successRecords":[],"failedRecords":[],"totalSuccessRecords":500,"totalFailedRecords":0,"timeElapsed":0.2936162949}
2019-10-27 23:54:09,794 __main__    : DEBUG    time elapsed: 0.862856388092041

As you can see, there is a great improvement

tests/test_utils.py::TestFalconUtils::test_uri_decode[bytearray] tests/test_utils.py::TestFalconUtils::test_uri_decode[join_list] tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_coding[bytearray-ab%2Gcd-ab%2Gcd] tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_coding[bytearray-ab%2Fcd: tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_coding[bytearray-%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s-%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s] tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_coding[join_list-ab%2Gcd-ab%2Gcd] tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_coding[join_list-ab%2Fcd: tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_coding[join_list-%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s-%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s] tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_unicode[bytearray-+%80- tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_unicode[bytearray-+++%FF+++- tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_unicode[bytearray-%fc%83%bf%bf%bf%bf-\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd] tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_unicode[bytearray-%ed%ae%80%ed%b0%80-\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd] tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_unicode[join_list-+%80- tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_unicode[join_list-+++%FF+++- tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_unicode[join_list-%fc%83%bf%bf%bf%bf-\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd] tests/test_utils.py::TestFalconUtils::test_uri_decode_bad_unicode[join_list-%ed%ae%80%ed%b0%80-\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd] tests/test_utils.py::TestFalconUtils::test_uri_decode_unquote_plus[bytearray] tests/test_utils.py::TestFalconUtils::test_uri_decode_unquote_plus[join_list]
tests/test_utils.py::TestFalconUtils::test_deprecated_decorator tests/test_utils.py::TestFalconUtils::test_http_now tests/test_utils.py::TestFalconUtils::test_dt_to_http tests/test_utils.py::TestFalconUtils::test_http_date_to_dt tests/test_utils.py::TestFalconUtils::test_pack_query_params_none tests/test_utils.py::TestFalconUtils::test_pack_query_params_one tests/test_utils.py::TestFalconUtils::test_pack_query_params_several tests/test_utils.py::TestFalconUtils::test_uri_encode tests/test_utils.py::TestFalconUtils::test_uri_encode_double tests/test_utils.py::TestFalconUtils::test_uri_encode_value tests/test_utils.py::TestFalconUtils::test_prop_uri_encode_models_stdlib_quote tests/test_utils.py::TestFalconUtils::test_prop_uri_encode_value_models_stdlib_quote_safe_tilde tests/test_utils.py::TestFalconUtils::test_prop_uri_decode_models_stdlib_unquote_plus tests/test_utils.py::TestFalconUtils::test_unquote_string tests/test_utils.py::TestFalconUtils::test_parse_query_string tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[-True-expected0] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[-False-expected1] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[flag1&&&&&flag2&&&-True-expected2] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[flag1&&&&&flag2&&&-False-expected3] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[malformed=%FG%1%Hi%%%a-False-expected4] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[=-False-expected5] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[==-False-expected6] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[%==+==&&&&&&&&&%%==+=&&&&&&%0g%=%=-False-expected7] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[%=&%%=&&%%%=-False-expected8] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[%=&%%=&&%%%=-True-expected9] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[+=&%+=&&%++=-True-expected10] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[=x=&=x=+1=x=&%=x-False-expected11] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[%=+&%=&+%+=&%+&=%&=+%&+==%+&=%&+=+%&=+&%=&%+=&+%+%=&+%&=+=%&+=&%+&%=+&=%&%=+&%+=&=%+&=+%&+%=&+=%-False-expected12] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[%%%\x00%\x00==\x00\x00==-True-expected13] tests/test_utils.py::TestFalconUtils::test_parse_query_string_edge_cases[spade=\u2660&spade=\u2660-False-expected14] tests/test_utils.py::TestFalconUtils::test_parse_host tests/test_utils.py::TestFalconUtils::test_get_http_status_warns tests/test_utils.py::TestFalconUtils::test_get_http_status tests/test_utils.py::TestFalconUtils::test_code_to_http_status[703-703 tests/test_utils.py::TestFalconUtils::test_code_to_http_status[404-404 tests/test_utils.py::TestFalconUtils::test_code_to_http_status[404.9-404 tests/test_utils.py::TestFalconUtils::test_code_to_http_status[123-123] tests/test_utils.py::TestFalconUtils::test_code_to_http_status_neg[not_a_number] tests/test_utils.py::TestFalconUtils::test_code_to_http_status_neg[0_0] tests/test_utils.py::TestFalconUtils::test_code_to_http_status_neg[0_1] tests/test_utils.py::TestFalconUtils::test_code_to_http_status_neg[99_0] tests/test_utils.py::TestFalconUtils::test_code_to_http_status_neg[99_1] tests/test_utils.py::TestFalconUtils::test_code_to_http_status_neg[404.3] tests/test_utils.py::TestFalconUtils::test_code_to_http_status_neg[-404.3_0] tests/test_utils.py::TestFalconUtils::test_code_to_http_status_neg[-404] tests/test_utils.py::TestFalconUtils::test_code_to_http_status_neg[-404.3_1] tests/test_utils.py::TestFalconUtils::test_http_status_to_code[HTTPStatus.HTTP_VERSION_NOT_SUPPORTED-505_0] tests/test_utils.py::TestFalconUtils::test_http_status_to_code[712-712_0] tests/test_utils.py::TestFalconUtils::test_http_status_to_code[712-712_1] tests/test_utils.py::TestFalconUtils::test_http_status_to_code[404 tests/test_utils.py::TestFalconUtils::test_http_status_to_code[712 tests/test_utils.py::TestFalconUtils::test_http_status_to_code[123 tests/test_utils.py::TestFalconUtils::test_http_status_to_code[HTTPStatus.HTTP_VERSION_NOT_SUPPORTED-505_1] tests/test_utils.py::TestFalconUtils::test_http_status_to_code_neg[0] tests/test_utils.py::TestFalconUtils::test_http_status_to_code_neg[ tests/test_utils.py::TestFalconUtils::test_http_status_to_code_neg[1] tests/test_utils.py::TestFalconUtils::test_http_status_to_code_neg[12] tests/test_utils.py::TestFalconUtils::test_http_status_to_code_neg[99] tests/test_utils.py::TestFalconUtils::test_http_status_to_code_neg[catsup] tests/test_utils.py::TestFalconUtils::test_http_status_to_code_neg[2] tests/test_utils.py::TestFalconUtils::test_http_status_to_code_neg[5.2] tests/test_utils.py::TestFalconUtils::test_etag_dumps_to_header_format tests/test_utils.py::TestFalconUtils::test_etag_strong_vs_weak_comparison tests/test_utils.py::TestFalconUtils::test_secure_filename[.-_] tests/test_utils.py::TestFalconUtils::test_secure_filename[..-_.] tests/test_utils.py::TestFalconUtils::test_secure_filename[hello.txt-hello.txt] tests/test_utils.py::TestFalconUtils::test_secure_filename[\u0104\u017euolai tests/test_utils.py::TestFalconUtils::test_secure_filename[/etc/shadow-_etc_shadow] tests/test_utils.py::TestFalconUtils::test_secure_filename[. tests/test_utils.py::TestFalconUtils::test_secure_filename[C:\\Windows\\kernel32.dll-C__Windows_kernel32.dll] tests/test_utils.py::TestFalconUtils::test_secure_filename_empty_value tests/test_utils.py::TestFalconUtils::test_misc_isascii[-True] tests/test_utils.py::TestFalconUtils::test_misc_isascii[/-True] tests/test_utils.py::TestFalconUtils::test_misc_isascii[/api-True] tests/test_utils.py::TestFalconUtils::test_misc_isascii[/data/items/something?query=apples%20and%20oranges-True] tests/test_utils.py::TestFalconUtils::test_misc_isascii[/food?item=\xf0\x9f\x8d\x94-False] tests/test_utils.py::TestFalconUtils::test_misc_isascii[\x00\x00\x7f\x00\x00\x7f\x00-True] tests/test_utils.py::TestFalconUtils::test_misc_isascii[\x00\x00\x7f\x00\x00\x80\x00-False] tests/test_utils.py::test_simulate_request_protocol[asgi-https-CONNECT] tests/test_utils.py::test_simulate_request_protocol[asgi-https-DELETE] tests/test_utils.py::test_simulate_request_protocol[asgi-https-GET] tests/test_utils.py::test_simulate_request_protocol[asgi-https-HEAD] tests/test_utils.py::test_simulate_request_protocol[asgi-https-OPTIONS] tests/test_utils.py::test_simulate_request_protocol[asgi-https-PATCH] tests/test_utils.py::test_simulate_request_protocol[asgi-https-POST] tests/test_utils.py::test_simulate_request_protocol[asgi-https-PUT] tests/test_utils.py::test_simulate_request_protocol[asgi-https-TRACE] tests/test_utils.py::test_simulate_request_protocol[asgi-http-CONNECT] tests/test_utils.py::test_simulate_request_protocol[asgi-http-DELETE] tests/test_utils.py::test_simulate_request_protocol[asgi-http-GET] tests/test_utils.py::test_simulate_request_protocol[asgi-http-HEAD] tests/test_utils.py::test_simulate_request_protocol[asgi-http-OPTIONS] tests/test_utils.py::test_simulate_request_protocol[asgi-http-PATCH] tests/test_utils.py::test_simulate_request_protocol[asgi-http-POST] tests/test_utils.py::test_simulate_request_protocol[asgi-http-PUT] tests/test_utils.py::test_simulate_request_protocol[asgi-http-TRACE] tests/test_utils.py::test_simulate_request_protocol[wsgi-https-CONNECT] tests/test_utils.py::test_simulate_request_protocol[wsgi-https-DELETE] tests/test_utils.py::test_simulate_request_protocol[wsgi-https-GET] tests/test_utils.py::test_simulate_request_protocol[wsgi-https-HEAD] tests/test_utils.py::test_simulate_request_protocol[wsgi-https-OPTIONS] tests/test_utils.py::test_simulate_request_protocol[wsgi-https-PATCH] tests/test_utils.py::test_simulate_request_protocol[wsgi-https-POST] tests/test_utils.py::test_simulate_request_protocol[wsgi-https-PUT] tests/test_utils.py::test_simulate_request_protocol[wsgi-https-TRACE] tests/test_utils.py::test_simulate_request_protocol[wsgi-http-CONNECT] tests/test_utils.py::test_simulate_request_protocol[wsgi-http-DELETE] tests/test_utils.py::test_simulate_request_protocol[wsgi-http-GET] tests/test_utils.py::test_simulate_request_protocol[wsgi-http-HEAD] tests/test_utils.py::test_simulate_request_protocol[wsgi-http-OPTIONS] tests/test_utils.py::test_simulate_request_protocol[wsgi-http-PATCH] tests/test_utils.py::test_simulate_request_protocol[wsgi-http-POST] tests/test_utils.py::test_simulate_request_protocol[wsgi-http-PUT] tests/test_utils.py::test_simulate_request_protocol[wsgi-http-TRACE] tests/test_utils.py::test_simulate_free_functions[asgi-simulate_get] tests/test_utils.py::test_simulate_free_functions[asgi-simulate_head] tests/test_utils.py::test_simulate_free_functions[asgi-simulate_post] tests/test_utils.py::test_simulate_free_functions[asgi-simulate_put] tests/test_utils.py::test_simulate_free_functions[asgi-simulate_options] tests/test_utils.py::test_simulate_free_functions[asgi-simulate_patch] tests/test_utils.py::test_simulate_free_functions[asgi-simulate_delete] tests/test_utils.py::test_simulate_free_functions[wsgi-simulate_get] tests/test_utils.py::test_simulate_free_functions[wsgi-simulate_head] tests/test_utils.py::test_simulate_free_functions[wsgi-simulate_post] tests/test_utils.py::test_simulate_free_functions[wsgi-simulate_put] tests/test_utils.py::test_simulate_free_functions[wsgi-simulate_options] tests/test_utils.py::test_simulate_free_functions[wsgi-simulate_patch] tests/test_utils.py::test_simulate_free_functions[wsgi-simulate_delete] tests/test_utils.py::TestFalconTestingUtils::test_path_escape_chars_in_create_environ tests/test_utils.py::TestFalconTestingUtils::test_no_prefix_allowed_for_query_strings_in_create_environ tests/test_utils.py::TestFalconTestingUtils::test_plus_in_path_in_create_environ tests/test_utils.py::TestFalconTestingUtils::test_none_header_value_in_create_environ tests/test_utils.py::TestFalconTestingUtils::test_decode_empty_result[asgi] tests/test_utils.py::TestFalconTestingUtils::test_decode_empty_result[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_httpnow_alias_for_backwards_compat tests/test_utils.py::TestFalconTestingUtils::test_default_headers[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_default_headers_with_override[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_status[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_wsgi_iterable_not_closeable tests/test_utils.py::TestFalconTestingUtils::test_path_must_start_with_slash[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_cached_text_in_result[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_simple_resource_body_json_xor[SimpleTestResource] tests/test_utils.py::TestFalconTestingUtils::test_simple_resource_body_json_xor[SimpleTestResourceAsync] tests/test_utils.py::TestFalconTestingUtils::test_query_string[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_query_string_no_question[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_query_string_in_path[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[asgi-16.0625] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[asgi-123456789] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[asgi-True] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[asgi-] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[asgi-I tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[asgi-document5] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[asgi-document6] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[asgi-document7] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[wsgi-16.0625] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[wsgi-123456789] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[wsgi-True] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[wsgi-] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[wsgi-I tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[wsgi-document5] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[wsgi-document6] tests/test_utils.py::TestFalconTestingUtils::test_simulate_json_body[wsgi-document7] tests/test_utils.py::TestFalconTestingUtils::test_simulate_remote_addr[wsgi-None] tests/test_utils.py::TestFalconTestingUtils::test_simulate_remote_addr[wsgi-127.0.0.1] tests/test_utils.py::TestFalconTestingUtils::test_simulate_remote_addr[wsgi-8.8.8.8] tests/test_utils.py::TestFalconTestingUtils::test_simulate_remote_addr[wsgi-104.24.101.85] tests/test_utils.py::TestFalconTestingUtils::test_simulate_remote_addr[wsgi-2606:4700:30::6818:6455] tests/test_utils.py::TestFalconTestingUtils::test_simulate_hostname[wsgi] tests/test_utils.py::TestFalconTestingUtils::test_simulate_with_environ_extras[extras0-expected_headers0] tests/test_utils.py::TestFalconTestingUtils::test_simulate_with_environ_extras[extras1-expected_headers1] tests/test_utils.py::TestFalconTestingUtils::test_override_method_with_extras[wsgi] tests/test_utils.py::TestNoApiClass::test_something tests/test_utils.py::TestSetupApi::test_something tests/test_utils.py::test_get_argnames tests/test_utils.py::TestContextType::test_attributes[CustomContextType] tests/test_utils.py::TestContextType::test_attributes[Context] tests/test_utils.py::TestContextType::test_items_from_attributes[CustomContextType] tests/test_utils.py::TestContextType::test_items_from_attributes[Context] tests/test_utils.py::TestContextType::test_attributes_from_items[CustomContextType] tests/test_utils.py::TestContextType::test_attributes_from_items[Context] tests/test_utils.py::TestContextType::test_dict_interface[CustomContextType-CustomContextType] tests/test_utils.py::TestContextType::test_dict_interface[Context-Context] tests/test_utils.py::TestContextType::test_keys_and_values[CustomContextType] tests/test_utils.py::TestContextType::test_keys_and_values[Context] tests/test_utils.py::TestDeprecatedArgs::test_method tests/test_utils.py::TestDeprecatedArgs::test_function