Blob Blame History Raw
From 245dee21fd6537600154912b9505311c3431274a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Ba=C5=A1ti?= <mbasti@redhat.com>
Date: Thu, 11 Jul 2019 19:01:43 +0200
Subject: [PATCH] Logging: Handle auth type case insensitively
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

According RFC-7617 (inherited from RFC-2978) schema and parameter names are handled
case insensitively:
```
Note that both scheme and parameter names are matched case-
insensitively.
```

Signed-off-by: Martin Bašti <mbasti@redhat.com>
(cherry picked from commit 7e640f804cacc2189e6f539b7b8861a2ef1a2461)
---
 gunicorn/glogging.py |  2 +-
 tests/test_logger.py | 12 ++++++++++--
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/gunicorn/glogging.py b/gunicorn/glogging.py
index 041a74d..3a83eb0 100644
--- a/gunicorn/glogging.py
+++ b/gunicorn/glogging.py
@@ -460,7 +460,7 @@ class Logger(object):
     def _get_user(self, environ):
         user = None
         http_auth = environ.get("HTTP_AUTHORIZATION")
-        if http_auth and http_auth.startswith('Basic'):
+        if http_auth and http_auth.lower().startswith('basic'):
             auth = http_auth.split(" ", 1)
             if len(auth) == 2:
                 try:
diff --git a/tests/test_logger.py b/tests/test_logger.py
index f276794..9ec0f52 100644
--- a/tests/test_logger.py
+++ b/tests/test_logger.py
@@ -1,5 +1,7 @@
 import datetime
 
+import pytest
+
 from gunicorn.config import Config
 from gunicorn.glogging import Logger
 
@@ -48,7 +50,13 @@ def test_atoms_zero_bytes():
     assert atoms['B'] == 0
 
 
-def test_get_username_from_basic_auth_header():
+@pytest.mark.parametrize('auth', [
+    # auth type is case in-sensitive
+    'Basic YnJrMHY6',
+    'basic YnJrMHY6',
+    'BASIC YnJrMHY6',
+])
+def test_get_username_from_basic_auth_header(auth):
     request = SimpleNamespace(headers=())
     response = SimpleNamespace(
         status='200', response_length=1024, sent=1024,
@@ -58,7 +66,7 @@ def test_get_username_from_basic_auth_header():
         'REQUEST_METHOD': 'GET', 'RAW_URI': '/my/path?foo=bar',
         'PATH_INFO': '/my/path', 'QUERY_STRING': 'foo=bar',
         'SERVER_PROTOCOL': 'HTTP/1.1',
-        'HTTP_AUTHORIZATION': 'Basic YnJrMHY6',
+        'HTTP_AUTHORIZATION': auth,
     }
     logger = Logger(Config())
     atoms = logger.atoms(response, request, environ, datetime.timedelta(seconds=1))
-- 
2.20.1