From d6cbb0aef1b03d75ad0b02fea689c35795f21f4b Mon Sep 17 00:00:00 2001
From: mhorky <mhorky@redhat.com>
Date: Mon, 23 Sep 2024 10:35:58 +0200
Subject: [PATCH] fix: Handle Retry-After headers better for 429 responses

* Card ID: CCT-759

We have to ensure we normalize the headers before we search for the
Retry-After header.

(cherry picked from commit 4c8a44a366fcf0537a6a20458e6e6cbd75010f81)
---
 src/rhsm/connection.py            |  6 +++++-
 test/rhsm/unit/test_connection.py | 12 ++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/rhsm/connection.py b/src/rhsm/connection.py
index 3a5a391616..4c7a069bb1 100644
--- a/src/rhsm/connection.py
+++ b/src/rhsm/connection.py
@@ -453,7 +453,11 @@ class RateLimitExceededException(RestlibException):
     def __init__(self, code, msg=None, headers=None):
         super(RateLimitExceededException, self).__init__(code, msg)
         self.headers = headers or {}
-        self.retry_after = safe_int(self.headers.get('retry-after'))
+        self.retry_after = None
+        for header, value in self.headers.items():
+            if header.lower() == "retry-after":
+                self.retry_after = safe_int(value)
+                break
         self.msg = msg or "Access rate limit exceeded"
         if self.retry_after is not None:
             self.msg += ", retry access after: %s seconds." % self.retry_after
diff --git a/test/rhsm/unit/test_connection.py b/test/rhsm/unit/test_connection.py
index a304525ca5..e195e91e86 100644
--- a/test/rhsm/unit/test_connection.py
+++ b/test/rhsm/unit/test_connection.py
@@ -740,6 +740,18 @@ def test_429_body(self):
         else:
             self.fail("Should have raised a RateLimitExceededException")
 
+    def test_429_weird_case(self):
+        content = '{"errors": ["TooFast"]}'
+        headers = {"RETry-aFteR": 20}
+        try:
+            self.vr("429", content, headers)
+        except RateLimitExceededException as e:
+            self.assertEqual(20, e.retry_after)
+            self.assertEqual("TooFast, retry access after: 20 seconds.", e.msg)
+            self.assertEqual("429", e.code)
+        else:
+            self.fail("Should have raised a RateLimitExceededException")
+
     def test_500_empty(self):
         try:
             self.vr("500", "")