Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-opentelemetry-util-http for 
openSUSE:Factory checked in at 2025-09-23 16:07:18
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-opentelemetry-util-http (Old)
 and      /work/SRC/openSUSE:Factory/.python-opentelemetry-util-http.new.27445 
(New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-opentelemetry-util-http"

Tue Sep 23 16:07:18 2025 rev:5 rq:1306353 version:0.58b0

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-opentelemetry-util-http/python-opentelemetry-util-http.changes
    2025-06-03 17:51:53.357499187 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-opentelemetry-util-http.new.27445/python-opentelemetry-util-http.changes
 2025-09-23 16:07:41.760611717 +0200
@@ -1,0 +2,51 @@
+Sun Sep 21 15:08:22 UTC 2025 - Dirk Müller <[email protected]>
+
+- update to 0.58b0:
+  * `opentelemetry-instrumentation-fastapi`: Fix middleware
+    ordering to cover all exception handling use cases.
+  * `opentelemetry-instrumentation-asgi`: Make all user hooks
+    failsafe and record exceptions in hooks.
+  * `opentelemetry-instrumentation-fastapi`: Fix memory leak in
+    `uninstrument_app()` by properly removing apps from the
+    tracking set
+  * `opentelemetry-instrumentation-tornado` Fix server (request)
+    duration metric calculation
+  * `opentelemetry-instrumentation-tornado`: Fix to properly skip
+    all server telemetry when URL excluded.
+  * `opentelemetry-instrumentation`: Avoid calls to
+    `context.detach` with `None` token.
+  * `opentelemetry-instrumentation-starlette`/`opentelemetry-
+    instrumentation-fastapi`: Fixes a crash when host-based
+    routing is used
+  * Fix documentation order of sections and headers for Django,
+    Flask, MySQL, mysqlclient, psycopg, psycopg2, pymysql,
+    sqlalchemy instrumentations.
+  * `opentelemetry-instrumentation-asgi` Fixed an issue where
+    FastAPI reports IP instead of URL.
+  * `opentelemetry-instrumentation-httpx`: fix missing metric
+    response attributes when tracing is disabled
+  * `opentelemetry-instrumentation-fastapi`:  Don't pass bounded
+    server_request_hook when using
+    `FastAPIInstrumentor.instrument()`
+- update to 0.57b0:
+  * `opentelemetry-instrumentation`: Fix dependency conflict
+    detection when instrumented packages are not installed by
+    moving check back to before instrumentors are loaded. Add
+    "instruments-any" feature for instrumentations that target
+    multiple packages.
+  * `opentelemetry-instrumentation-psycopg2` Utilize instruments-
+    any functionality.
+  * `opentelemetry-instrumentation-kafka-python` Utilize
+    instruments-any functionality.
+- update to 0.56b0:
+  * `opentelemetry-instrumentation-pika` Added instrumentation
+    for All `SelectConnection` adapters
+  * `opentelemetry-instrumentation-tornado` Add support for
+    `WebSocketHandler` instrumentation
+  * `opentelemetry-util-http` Added support for redacting
+    specific url query string values and url credentials in
+    instrumentations
+  * `opentelemetry-instrumentation-pymongo` `aggregate` and
+    `getMore` capture statements support
+
+-------------------------------------------------------------------

Old:
----
  opentelemetry_util_http-0.54b1.tar.gz

New:
----
  opentelemetry_util_http-0.58b0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-opentelemetry-util-http.spec ++++++
--- /var/tmp/diff_new_pack.PzFguh/_old  2025-09-23 16:07:42.312634898 +0200
+++ /var/tmp/diff_new_pack.PzFguh/_new  2025-09-23 16:07:42.316635067 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-opentelemetry-util-http
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-opentelemetry-util-http
-Version:        0.54b1
+Version:        0.58b0
 Release:        0
 Summary:        Instrumentation Tools & Auto Instrumentation for OpenTelemetry 
Python
 License:        Apache-2.0

++++++ opentelemetry_util_http-0.54b1.tar.gz -> 
opentelemetry_util_http-0.58b0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/opentelemetry_util_http-0.54b1/PKG-INFO 
new/opentelemetry_util_http-0.58b0/PKG-INFO
--- old/opentelemetry_util_http-0.54b1/PKG-INFO 2020-02-02 01:00:00.000000000 
+0100
+++ new/opentelemetry_util_http-0.58b0/PKG-INFO 2020-02-02 01:00:00.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.4
 Name: opentelemetry-util-http
-Version: 0.54b1
+Version: 0.58b0
 Summary: Web util for OpenTelemetry
 Project-URL: Homepage, 
https://github.com/open-telemetry/opentelemetry-python-contrib/tree/main/util/opentelemetry-util-http
 Project-URL: Repository, 
https://github.com/open-telemetry/opentelemetry-python-contrib
@@ -11,13 +11,12 @@
 Classifier: License :: OSI Approved :: Apache Software License
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.8
 Classifier: Programming Language :: Python :: 3.9
 Classifier: Programming Language :: Python :: 3.10
 Classifier: Programming Language :: Python :: 3.11
 Classifier: Programming Language :: Python :: 3.12
 Classifier: Programming Language :: Python :: 3.13
-Requires-Python: >=3.8
+Requires-Python: >=3.9
 Description-Content-Type: text/x-rst
 
 OpenTelemetry Util HTTP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/opentelemetry_util_http-0.54b1/pyproject.toml 
new/opentelemetry_util_http-0.58b0/pyproject.toml
--- old/opentelemetry_util_http-0.54b1/pyproject.toml   2020-02-02 
01:00:00.000000000 +0100
+++ new/opentelemetry_util_http-0.58b0/pyproject.toml   2020-02-02 
01:00:00.000000000 +0100
@@ -8,7 +8,7 @@
 description = "Web util for OpenTelemetry"
 readme = "README.rst"
 license = "Apache-2.0"
-requires-python = ">=3.8"
+requires-python = ">=3.9"
 authors = [
   { name = "OpenTelemetry Authors", email = 
"[email protected]" },
 ]
@@ -18,7 +18,6 @@
   "License :: OSI Approved :: Apache Software License",
   "Programming Language :: Python",
   "Programming Language :: Python :: 3",
-  "Programming Language :: Python :: 3.8",
   "Programming Language :: Python :: 3.9",
   "Programming Language :: Python :: 3.10",
   "Programming Language :: Python :: 3.11",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_util_http-0.54b1/src/opentelemetry/util/http/__init__.py 
new/opentelemetry_util_http-0.58b0/src/opentelemetry/util/http/__init__.py
--- old/opentelemetry_util_http-0.54b1/src/opentelemetry/util/http/__init__.py  
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_util_http-0.58b0/src/opentelemetry/util/http/__init__.py  
2020-02-02 01:00:00.000000000 +0100
@@ -20,9 +20,20 @@
 from re import compile as re_compile
 from re import search
 from typing import Callable, Iterable, overload
-from urllib.parse import urlparse, urlunparse
+from urllib.parse import parse_qs, urlencode, urlparse, urlunparse
 
-from opentelemetry.semconv.trace import SpanAttributes
+from opentelemetry.semconv._incubating.attributes.http_attributes import (
+    HTTP_FLAVOR,
+    HTTP_HOST,
+    HTTP_METHOD,
+    HTTP_SCHEME,
+    HTTP_SERVER_NAME,
+    HTTP_STATUS_CODE,
+)
+from opentelemetry.semconv._incubating.attributes.net_attributes import (
+    NET_HOST_NAME,
+    NET_HOST_PORT,
+)
 
 OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS = (
     "OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS"
@@ -40,24 +51,26 @@
 
 # List of recommended metrics attributes
 _duration_attrs = {
-    SpanAttributes.HTTP_METHOD,
-    SpanAttributes.HTTP_HOST,
-    SpanAttributes.HTTP_SCHEME,
-    SpanAttributes.HTTP_STATUS_CODE,
-    SpanAttributes.HTTP_FLAVOR,
-    SpanAttributes.HTTP_SERVER_NAME,
-    SpanAttributes.NET_HOST_NAME,
-    SpanAttributes.NET_HOST_PORT,
+    HTTP_METHOD,
+    HTTP_HOST,
+    HTTP_SCHEME,
+    HTTP_STATUS_CODE,
+    HTTP_FLAVOR,
+    HTTP_SERVER_NAME,
+    NET_HOST_NAME,
+    NET_HOST_PORT,
 }
 
 _active_requests_count_attrs = {
-    SpanAttributes.HTTP_METHOD,
-    SpanAttributes.HTTP_HOST,
-    SpanAttributes.HTTP_SCHEME,
-    SpanAttributes.HTTP_FLAVOR,
-    SpanAttributes.HTTP_SERVER_NAME,
+    HTTP_METHOD,
+    HTTP_HOST,
+    HTTP_SCHEME,
+    HTTP_FLAVOR,
+    HTTP_SERVER_NAME,
 }
 
+PARAMS_TO_REDACT = ["AWSAccessKeyId", "Signature", "sig", "X-Goog-Signature"]
+
 
 class ExcludeList:
     """Class to exclude certain paths (given as a list of regexes) from 
tracing requests"""
@@ -159,23 +172,23 @@
 
 
 def remove_url_credentials(url: str) -> str:
-    """Given a string url, remove the username and password only if it is a 
valid url"""
-
+    """Given a string url, replace the username and password with the keyword 
`REDACTED` only if it is a valid url"""
     try:
         parsed = urlparse(url)
         if all([parsed.scheme, parsed.netloc]):  # checks for valid url
-            parsed_url = urlparse(url)
-            _, _, netloc = parsed.netloc.rpartition("@")
-            return urlunparse(
-                (
-                    parsed_url.scheme,
-                    netloc,
-                    parsed_url.path,
-                    parsed_url.params,
-                    parsed_url.query,
-                    parsed_url.fragment,
+            if "@" in parsed.netloc:
+                _, _, host = parsed.netloc.rpartition("@")
+                new_netloc = "REDACTED:REDACTED@" + host
+                return urlunparse(
+                    (
+                        parsed.scheme,
+                        new_netloc,
+                        parsed.path,
+                        parsed.params,
+                        parsed.query,
+                        parsed.fragment,
+                    )
                 )
-            )
     except ValueError:  # an unparsable url was passed
         pass
     return url
@@ -255,3 +268,36 @@
     path = parsed_url.path
     query_params = parsed_url.query
     return path, query_params
+
+
+def redact_query_parameters(url: str) -> str:
+    """Given a string url, redact sensitive query parameter values"""
+    try:
+        parsed = urlparse(url)
+        if not parsed.query:  # No query parameters to redact
+            return url
+        query_params = parse_qs(parsed.query)
+        if not any(param in query_params for param in PARAMS_TO_REDACT):
+            return url
+        for param in PARAMS_TO_REDACT:
+            if param in query_params:
+                query_params[param] = ["REDACTED"]
+        return urlunparse(
+            (
+                parsed.scheme,
+                parsed.netloc,
+                parsed.path,
+                parsed.params,
+                urlencode(query_params, doseq=True),
+                parsed.fragment,
+            )
+        )
+    except ValueError:  # an unparsable url was passed
+        return url
+
+
+def redact_url(url: str) -> str:
+    """Redact sensitive data from the URL, including credentials and query 
parameters."""
+    url = remove_url_credentials(url)
+    url = redact_query_parameters(url)
+    return url
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_util_http-0.54b1/src/opentelemetry/util/http/httplib.py 
new/opentelemetry_util_http-0.58b0/src/opentelemetry/util/http/httplib.py
--- old/opentelemetry_util_http-0.54b1/src/opentelemetry/util/http/httplib.py   
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_util_http-0.58b0/src/opentelemetry/util/http/httplib.py   
2020-02-02 01:00:00.000000000 +0100
@@ -31,7 +31,9 @@
 from opentelemetry import context
 from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
 from opentelemetry.instrumentation.utils import unwrap
-from opentelemetry.semconv.trace import SpanAttributes
+from opentelemetry.semconv._incubating.attributes.net_attributes import (
+    NET_PEER_IP,
+)
 from opentelemetry.trace.span import Span
 
 _STATE_KEY = "httpbase_instrumentation_state"
@@ -111,7 +113,7 @@
         )
     else:
         for span in spanlist:
-            span.set_attribute(SpanAttributes.NET_PEER_IP, ip)
+            span.set_attribute(NET_PEER_IP, ip)
     return True
 
 
@@ -177,7 +179,8 @@
         try:
             yield
         finally:
-            context.detach(token)
+            if token:
+                context.detach(token)
     else:
         spans = state["need_ip"]
         spans.append(span)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_util_http-0.54b1/src/opentelemetry/util/http/version.py 
new/opentelemetry_util_http-0.58b0/src/opentelemetry/util/http/version.py
--- old/opentelemetry_util_http-0.54b1/src/opentelemetry/util/http/version.py   
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_util_http-0.58b0/src/opentelemetry/util/http/version.py   
2020-02-02 01:00:00.000000000 +0100
@@ -12,4 +12,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-__version__ = "0.54b1"
+__version__ = "0.58b0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_util_http-0.54b1/tests/test_http_base.py 
new/opentelemetry_util_http-0.58b0/tests/test_http_base.py
--- old/opentelemetry_util_http-0.54b1/tests/test_http_base.py  2020-02-02 
01:00:00.000000000 +0100
+++ new/opentelemetry_util_http-0.58b0/tests/test_http_base.py  2020-02-02 
01:00:00.000000000 +0100
@@ -57,9 +57,10 @@
 
     def test_basic_with_span(self):
         tracer = trace.get_tracer(__name__)
-        with tracer.start_as_current_span(
-            "HTTP GET"
-        ) as span, set_ip_on_next_http_connection(span):
+        with (
+            tracer.start_as_current_span("HTTP GET") as span,
+            set_ip_on_next_http_connection(span),
+        ):
             resp, body = self.perform_request()
         assert resp.status == 200
         assert body == b"Hello!"
@@ -68,12 +69,14 @@
 
     def test_with_nested_span(self):
         tracer = trace.get_tracer(__name__)
-        with tracer.start_as_current_span(
-            "requests HTTP GET"
-        ) as span, set_ip_on_next_http_connection(span):
-            with tracer.start_as_current_span(
-                "urllib3 HTTP GET"
-            ) as span2, set_ip_on_next_http_connection(span2):
+        with (
+            tracer.start_as_current_span("requests HTTP GET") as span,
+            set_ip_on_next_http_connection(span),
+        ):
+            with (
+                tracer.start_as_current_span("urllib3 HTTP GET") as span2,
+                set_ip_on_next_http_connection(span2),
+            ):
                 resp, body = self.perform_request()
         assert resp.status == 200
         assert body == b"Hello!"
@@ -82,11 +85,13 @@
 
     def test_with_nested_nonrecording_span(self):
         tracer = trace.get_tracer(__name__)
-        with tracer.start_as_current_span(
-            "requests HTTP GET"
-        ) as span, set_ip_on_next_http_connection(span):
-            with trace.use_span(INVALID_SPAN), set_ip_on_next_http_connection(
-                INVALID_SPAN
+        with (
+            tracer.start_as_current_span("requests HTTP GET") as span,
+            set_ip_on_next_http_connection(span),
+        ):
+            with (
+                trace.use_span(INVALID_SPAN),
+                set_ip_on_next_http_connection(INVALID_SPAN),
             ):
                 resp, body = self.perform_request()
         assert resp.status == 200
@@ -95,8 +100,9 @@
         self.assertEqual(span.attributes, {"net.peer.ip": "127.0.0.1"})
 
     def test_with_only_nonrecording_span(self):
-        with trace.use_span(INVALID_SPAN), set_ip_on_next_http_connection(
-            INVALID_SPAN
+        with (
+            trace.use_span(INVALID_SPAN),
+            set_ip_on_next_http_connection(INVALID_SPAN),
         ):
             resp, body = self.perform_request()
         assert resp.status == 200
@@ -120,9 +126,10 @@
         HttpClientInstrumentor().uninstrument()
 
         tracer = trace.get_tracer(__name__)
-        with tracer.start_as_current_span(
-            "HTTP GET"
-        ) as span, set_ip_on_next_http_connection(span):
+        with (
+            tracer.start_as_current_span("HTTP GET") as span,
+            set_ip_on_next_http_connection(span),
+        ):
             body = self.perform_request()[1]
         self.assertEqual(b"Hello!", body)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_util_http-0.54b1/tests/test_redact_query_parameters.py 
new/opentelemetry_util_http-0.58b0/tests/test_redact_query_parameters.py
--- old/opentelemetry_util_http-0.54b1/tests/test_redact_query_parameters.py    
1970-01-01 01:00:00.000000000 +0100
+++ new/opentelemetry_util_http-0.58b0/tests/test_redact_query_parameters.py    
2020-02-02 01:00:00.000000000 +0100
@@ -0,0 +1,98 @@
+# Copyright The OpenTelemetry Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+
+from opentelemetry.util.http import redact_query_parameters
+
+
+class TestRedactSensitiveInfo(unittest.TestCase):
+    def test_redact_goog_signature(self):
+        url = "https://www.example.com/path?color=blue&X-Goog-Signature=secret";
+        self.assertEqual(
+            redact_query_parameters(url),
+            
"https://www.example.com/path?color=blue&X-Goog-Signature=REDACTED";,
+        )
+
+    def test_no_redaction_needed(self):
+        url = "https://www.example.com/path?color=blue&query=secret";
+        self.assertEqual(
+            redact_query_parameters(url),
+            "https://www.example.com/path?color=blue&query=secret";,
+        )
+
+    def test_no_query_parameters(self):
+        url = "https://www.example.com/path";
+        self.assertEqual(
+            redact_query_parameters(url), "https://www.example.com/path";
+        )
+
+    def test_empty_query_string(self):
+        url = "https://www.example.com/path?";
+        self.assertEqual(
+            redact_query_parameters(url), "https://www.example.com/path?";
+        )
+
+    def test_empty_url(self):
+        url = ""
+        self.assertEqual(redact_query_parameters(url), "")
+
+    def test_redact_aws_access_key_id(self):
+        url = "https://www.example.com/path?color=blue&AWSAccessKeyId=secrets";
+        self.assertEqual(
+            redact_query_parameters(url),
+            "https://www.example.com/path?color=blue&AWSAccessKeyId=REDACTED";,
+        )
+
+    def test_api_key_not_in_redact_list(self):
+        url = "https://www.example.com/path?api_key=secret%20key&user=john";
+        self.assertNotEqual(
+            redact_query_parameters(url),
+            "https://www.example.com/path?api_key=REDACTED&user=john";,
+        )
+
+    def test_password_key_not_in_redact_list(self):
+        url = "https://api.example.com?key=abc&password=123&user=admin";
+        self.assertNotEqual(
+            redact_query_parameters(url),
+            
"https://api.example.com?key=REDACTED&password=REDACTED&user=admin";,
+        )
+
+    def test_url_with_at_symbol_in_path_and_query(self):
+        url = "https://example.com/p@th?foo=b@r";
+        self.assertEqual(
+            redact_query_parameters(url), "https://example.com/p@th?foo=b@r";
+        )
+
+    def test_aws_access_key_with_real_format(self):
+        url = "https://mock.com?AWSAccessKeyId=AKIAIOSFODNN7";
+        self.assertEqual(
+            redact_query_parameters(url),
+            "https://mock.com?AWSAccessKeyId=REDACTED";,
+        )
+
+    def test_signature_parameter(self):
+        url = (
+            "https://service.com?sig=39Up9jzHkxhuIhFE9594DJxe7w6cIRCg0V6ICGS0";
+        )
+        self.assertEqual(
+            redact_query_parameters(url), "https://service.com?sig=REDACTED";
+        )
+
+    def test_signature_with_url_encoding(self):
+        url = 
"https://service.com?Signature=39Up9jzHkxhuIhFE9594DJxe7w6cIRCg0V6ICGS0%3A377";
+        self.assertEqual(
+            redact_query_parameters(url),
+            "https://service.com?Signature=REDACTED";,
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_util_http-0.54b1/tests/test_redact_url.py 
new/opentelemetry_util_http-0.58b0/tests/test_redact_url.py
--- old/opentelemetry_util_http-0.54b1/tests/test_redact_url.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/opentelemetry_util_http-0.58b0/tests/test_redact_url.py 2020-02-02 
01:00:00.000000000 +0100
@@ -0,0 +1,64 @@
+# Copyright The OpenTelemetry Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+
+from opentelemetry.util.http import redact_url
+
+
+class TestRedactUrl(unittest.TestCase):
+    def test_redact_both_credentials_and_query_params(self):
+        """Test URL with both credentials and sensitive query parameters."""
+        url = 
"https://user:[email protected]/data?AWSAccessKeyId=AKIAIOSFODNN7&color=blue";
+        expected = 
"https://REDACTED:[email protected]/data?AWSAccessKeyId=REDACTED&color=blue";
+        self.assertEqual(redact_url(url), expected)
+
+    def test_multiple_sensitive_query_params(self):
+        """Test URL with multiple sensitive query parameters."""
+        url = 
"https://admin:[email protected]/secure?Signature=abc123&X-Goog-Signature=xyz789&sig=def456";
+        expected = 
"https://REDACTED:[email protected]/secure?Signature=REDACTED&X-Goog-Signature=REDACTED&sig=REDACTED";
+        self.assertEqual(redact_url(url), expected)
+
+    def test_url_with_special_characters(self):
+        """Test URL with special characters in both credentials and query 
parameters."""
+        url = 
"https://user@domain:p@[email protected]/path?Signature=s%40me+special%20chars&normal=fine";
+        expected = 
"https://REDACTED:[email protected]/path?Signature=REDACTED&normal=fine";
+        self.assertEqual(redact_url(url), expected)
+
+    def test_edge_cases(self):
+        """Test unusual URL formats and corner cases."""
+        # URL with fragment
+        url1 = (
+            "https://user:[email protected]/data?Signature=secret#section";
+        )
+        self.assertEqual(
+            redact_url(url1),
+            
"https://REDACTED:[email protected]/data?Signature=REDACTED#section";,
+        )
+
+        # URL with port number
+        url2 = (
+            "https://user:[email protected]:8443/data?AWSAccessKeyId=secret";
+        )
+        self.assertEqual(
+            redact_url(url2),
+            
"https://REDACTED:[email protected]:8443/data?AWSAccessKeyId=REDACTED";,
+        )
+
+        # URL with IP address instead of domain
+        url3 = "https://user:[email protected]/path?X-Goog-Signature=xyz";
+        self.assertEqual(
+            redact_url(url3),
+            
"https://REDACTED:[email protected]/path?X-Goog-Signature=REDACTED";,
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/opentelemetry_util_http-0.54b1/tests/test_remove_credentials.py 
new/opentelemetry_util_http-0.58b0/tests/test_remove_credentials.py
--- old/opentelemetry_util_http-0.54b1/tests/test_remove_credentials.py 
2020-02-02 01:00:00.000000000 +0100
+++ new/opentelemetry_util_http-0.58b0/tests/test_remove_credentials.py 
2020-02-02 01:00:00.000000000 +0100
@@ -1,3 +1,17 @@
+# Copyright The OpenTelemetry Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 import unittest
 
 from opentelemetry.util.http import remove_url_credentials
@@ -5,27 +19,30 @@
 
 class TestRemoveUrlCredentials(unittest.TestCase):
     def test_remove_no_credentials(self):
-        url = "http://opentelemetry.io:8080/test/path?query=value";
+        url = "http://mock/status/200/test/path?query=value";
         cleaned_url = remove_url_credentials(url)
         self.assertEqual(cleaned_url, url)
 
     def test_remove_credentials(self):
-        url = 
"http://someuser:[email protected]:8080/test/path?query=value";
+        url = "http://someuser:somepass@mock/status/200/test/path?sig=value";
         cleaned_url = remove_url_credentials(url)
         self.assertEqual(
-            cleaned_url, "http://opentelemetry.io:8080/test/path?query=value";
+            cleaned_url,
+            "http://REDACTED:REDACTED@mock/status/200/test/path?sig=value";,
         )
 
     def test_remove_credentials_ipv4_literal(self):
         url = "http://someuser:[email protected]:8080/test/path?query=value";
         cleaned_url = remove_url_credentials(url)
         self.assertEqual(
-            cleaned_url, "http://127.0.0.1:8080/test/path?query=value";
+            cleaned_url,
+            "http://REDACTED:[email protected]:8080/test/path?query=value";,
         )
 
     def test_remove_credentials_ipv6_literal(self):
         url = "http://someuser:somepass@[::1]:8080/test/path?query=value";
         cleaned_url = remove_url_credentials(url)
         self.assertEqual(
-            cleaned_url, "http://[::1]:8080/test/path?query=value";
+            cleaned_url,
+            "http://REDACTED:REDACTED@[::1]:8080/test/path?query=value";,
         )

Reply via email to