Repository: mitmproxy/mitmproxy

Issue:
uppercase breaks block_list
#### Problem Description

using these values for `block_list`

~~~
/~u AccountsSignInUi/444
/~u accountssigninui/444
~~~

neither one is blocking the expected URL:

~~~
https://accounts.google.com/v3/signin/_/AccountsSignInUi/data/batchexecute
~~~

this works:

~~~
/~u .ccounts.ign.n.i/444
~~~

why is uppercase character breaking the search?

#### System Information

tried with both:

~~~
> mitmproxy --version
Mitmproxy: 8.0.0 binary
Python:    3.10.2
OpenSSL:   OpenSSL 1.1.1n  15 Mar 2022
Platform:  Windows-10-10.0.18363-SP0

> mitmproxy --version
Mitmproxy: 10.0.0 binary
Python:    3.11.4
OpenSSL:   OpenSSL 3.1.2 1 Aug 2023
Platform:  Windows-10-10.0.18363-SP0
~~~



Discussion:
I didn't verify this, but peeking at the code the issue should be here (I literally just ctrl+f for `lower`):

https://github.com/mitmproxy/mitmproxy/blob/7aa41a8467f73d86ad6ce5b95439c147a26896f9/mitmproxy/addons/blocklist.py#L27

If you are interested you can create a PR and add a case sensitive test here https://github.com/mitmproxy/mitmproxy/blob/7aa41a8467f73d86ad6ce5b95439c147a26896f9/test/mitmproxy/addons/test_blocklist.py

I am using a script like this as a workaround:

~~~py
from mitmproxy import http

def request(f: http.HTTPFlow) -> None:
   if f.request.path == '/v3/signin/_/AccountsSignInUi/data/batchexecute':
      f.kill()
~~~


Resolving patch:
diff --git a/mitmproxy/flowfilter.py b/mitmproxy/flowfilter.py
--- a/mitmproxy/flowfilter.py
+++ b/mitmproxy/flowfilter.py
@@ -402,6 +402,7 @@ class FUrl(_Rex):
     code = "u"
     help = "URL"
     is_binary = False
+    flags = re.IGNORECASE
 
     # FUrl is special, because it can be "naked".
 


Test patch:
diff --git a/test/mitmproxy/addons/test_blocklist.py b/test/mitmproxy/addons/test_blocklist.py
--- a/test/mitmproxy/addons/test_blocklist.py
+++ b/test/mitmproxy/addons/test_blocklist.py
@@ -22,20 +22,21 @@ def test_parse_spec_err(filter, err):
 
 class TestBlockList:
     @pytest.mark.parametrize(
-        "filter,status_code",
+        "filter,request_url,status_code",
         [
-            (":~u example.org:404", 404),
-            (":~u example.com:404", None),
-            ("/!jpg/418", None),
-            ("/!png/418", 418),
+            (":~u example.org:404", b"https://example.org/images/test.jpg", 404),
+            (":~u example.com:404", b"https://example.org/images/test.jpg", None),
+            (":~u test:404", b"https://example.org/images/TEST.jpg", 404),
+            ("/!jpg/418", b"https://example.org/images/test.jpg", None),
+            ("/!png/418", b"https://example.org/images/test.jpg", 418),
         ],
     )
-    def test_block(self, filter, status_code):
+    def test_block(self, filter, request_url, status_code):
         bl = blocklist.BlockList()
         with taddons.context(bl) as tctx:
             tctx.configure(bl, block_list=[filter])
             f = tflow.tflow()
-            f.request.url = b"https://example.org/images/test.jpg"
+            f.request.url = request_url
             bl.request(f)
             if status_code is not None:
                 assert f.response.status_code == status_code