From 04ea13f8a105219e35739282ede285a617a817d7 Mon Sep 17 00:00:00 2001 From: Guna Date: Fri, 4 Apr 2025 19:17:15 -0700 Subject: [PATCH 1/7] Adding low level proxies support --- splunklib/binding.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/splunklib/binding.py b/splunklib/binding.py index 25a09948..8ac1d0f3 100644 --- a/splunklib/binding.py +++ b/splunklib/binding.py @@ -39,8 +39,8 @@ from http import client from http.cookies import SimpleCookie from xml.etree.ElementTree import XML, ParseError -from splunklib.data import record -from splunklib import __version__ +from .data import record +from . import __version__ logger = logging.getLogger(__name__) @@ -1208,9 +1208,9 @@ class HttpLib: """ def __init__(self, custom_handler=None, verify=False, key_file=None, cert_file=None, context=None, retries=0, - retryDelay=10): + retryDelay=10, proxies=None): if custom_handler is None: - self.handler = handler(verify=verify, key_file=key_file, cert_file=cert_file, context=context) + self.handler = handler(verify=verify, key_file=key_file, cert_file=cert_file, context=context, proxies=proxies) else: self.handler = custom_handler self._cookies = {} @@ -1434,7 +1434,7 @@ def readinto(self, byte_array): return bytes_read -def handler(key_file=None, cert_file=None, timeout=None, verify=False, context=None): +def handler(key_file=None, cert_file=None, timeout=None, verify=False, context=None, proxies=None): """This class returns an instance of the default HTTP request handler using the values you provide. @@ -1447,7 +1447,9 @@ def handler(key_file=None, cert_file=None, timeout=None, verify=False, context=N :param `verify`: Set to False to disable SSL verification on https connections. :type verify: ``Boolean`` :param `context`: The SSLContext that can is used with the HTTPSConnection when verify=True is enabled and context is specified - :type context: ``SSLContext` + :type context: ``SSLContext`` + :param `proxies`: A dictionary of possible proxies the handler can leverage + :type proxies: ``dict`` """ def connect(scheme, host, port): @@ -1481,8 +1483,13 @@ def request(url, message, **kwargs): for key, value in message["headers"]: head[key] = value method = message.get("method", "GET") - - connection = connect(scheme, host, port) + + # have a proxy entry for the current scheme + if proxies.get(scheme): + connection = connect(scheme, *(proxies.get(scheme).split(":"))) + connection.set_tunnel("www.python.org") + else: + connection = connect(scheme, host, port) is_keepalive = False try: connection.request(method, path, body, head) From 77b68cfef82313fb1a9a54c57839871d32313bfb Mon Sep 17 00:00:00 2001 From: Guna Date: Fri, 4 Apr 2025 19:18:12 -0700 Subject: [PATCH 2/7] Adding proxies at high level classes --- splunklib/client.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/splunklib/client.py b/splunklib/client.py index ee390c9e..78ffabbc 100644 --- a/splunklib/client.py +++ b/splunklib/client.py @@ -68,9 +68,9 @@ from time import sleep from urllib import parse -from splunklib import data -from splunklib.data import record -from splunklib.binding import (AuthenticationError, Context, HTTPError, UrlEncoded, +from . import data +from .data import record +from .binding import (AuthenticationError, Context, HTTPError, UrlEncoded, _encode, _make_cookie_header, _NoAuthenticationToken, namespace) @@ -326,7 +326,11 @@ def connect(**kwargs): :type retryDelay: ``int`` (in seconds) :param `context`: The SSLContext that can be used when setting verify=True (optional) :type context: ``SSLContext`` + :param proxies: Optional proxies, formatted { "" : ":" } + :type proxies: ``dict`` + :return: An initialized :class:`Service` connection. + **Example**:: @@ -398,6 +402,8 @@ class Service(_BaseService): :param retryDelay: How long to wait between connection attempts if `retries` > 0 (optional, defaults to 10s). :type retryDelay: ``int`` (in seconds) :return: A :class:`Service` instance. + :param proxies: Optional proxies, formatted { "" : ":" } + :type proxies: ``dict`` **Example**:: @@ -3999,4 +4005,4 @@ def batch_save(self, *documents): data = json.dumps(documents) return json.loads( - self._post('batch_save', headers=KVStoreCollectionData.JSON_HEADER, body=data).body.read().decode('utf-8')) \ No newline at end of file + self._post('batch_save', headers=KVStoreCollectionData.JSON_HEADER, body=data).body.read().decode('utf-8')) From 5966279a9e208fb6592a520e8e9127dc0f11ea7d Mon Sep 17 00:00:00 2001 From: Guna Date: Fri, 4 Apr 2025 19:21:11 -0700 Subject: [PATCH 3/7] Reverting to og head --- splunklib/binding.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/splunklib/binding.py b/splunklib/binding.py index 8ac1d0f3..a24ca329 100644 --- a/splunklib/binding.py +++ b/splunklib/binding.py @@ -39,8 +39,8 @@ from http import client from http.cookies import SimpleCookie from xml.etree.ElementTree import XML, ParseError -from .data import record -from . import __version__ +from splunklib.data import record +from splunklib import __version__ logger = logging.getLogger(__name__) From 9a728e3f1bc4299353cae1eae82e1362b9951482 Mon Sep 17 00:00:00 2001 From: Guna Date: Fri, 4 Apr 2025 19:21:49 -0700 Subject: [PATCH 4/7] Revert to og head --- splunklib/client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/splunklib/client.py b/splunklib/client.py index 78ffabbc..5e2a5d54 100644 --- a/splunklib/client.py +++ b/splunklib/client.py @@ -68,9 +68,9 @@ from time import sleep from urllib import parse -from . import data -from .data import record -from .binding import (AuthenticationError, Context, HTTPError, UrlEncoded, +from splunklib import data +from splunklib.data import record +from splunklib.binding import (AuthenticationError, Context, HTTPError, UrlEncoded, _encode, _make_cookie_header, _NoAuthenticationToken, namespace) From 5fef5a66cd9c8f60586db367a95a0a32e8ff34d4 Mon Sep 17 00:00:00 2001 From: Guna Date: Fri, 4 Apr 2025 19:30:18 -0700 Subject: [PATCH 5/7] Format string for the dest host --- splunklib/binding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splunklib/binding.py b/splunklib/binding.py index a24ca329..21d6e71d 100644 --- a/splunklib/binding.py +++ b/splunklib/binding.py @@ -1487,7 +1487,7 @@ def request(url, message, **kwargs): # have a proxy entry for the current scheme if proxies.get(scheme): connection = connect(scheme, *(proxies.get(scheme).split(":"))) - connection.set_tunnel("www.python.org") + connection.set_tunnel("%s:%s" % (host,port)) else: connection = connect(scheme, host, port) is_keepalive = False From ded3fd7e70922d9158793379178da2e30f1af0d9 Mon Sep 17 00:00:00 2001 From: Guna Kondapaneni Date: Fri, 4 Apr 2025 20:17:49 -0700 Subject: [PATCH 6/7] Working version. Testing with module -> proxy -> echo server --- splunklib/binding.py | 9 +++++---- splunklib/client.py | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/splunklib/binding.py b/splunklib/binding.py index 21d6e71d..657722a0 100644 --- a/splunklib/binding.py +++ b/splunklib/binding.py @@ -513,7 +513,8 @@ def __init__(self, handler=None, **kwargs): self.http = HttpLib(handler, kwargs.get("verify", False), key_file=kwargs.get("key_file"), cert_file=kwargs.get("cert_file"), context=kwargs.get("context"), # Default to False for backward compat - retries=kwargs.get("retries", 0), retryDelay=kwargs.get("retryDelay", 10)) + retries=kwargs.get("retries", 0), retryDelay=kwargs.get("retryDelay", 10), + proxies=kwargs.get("proxies")) self.token = kwargs.get("token", _NoAuthenticationToken) if self.token is None: # In case someone explicitly passes token=None self.token = _NoAuthenticationToken @@ -1207,8 +1208,7 @@ class HttpLib: If using the default handler, SSL verification can be disabled by passing verify=False. """ - def __init__(self, custom_handler=None, verify=False, key_file=None, cert_file=None, context=None, retries=0, - retryDelay=10, proxies=None): + def __init__(self, custom_handler=None, verify=False, key_file=None, cert_file=None, context=None, retries=0,retryDelay=10, proxies={}): if custom_handler is None: self.handler = handler(verify=verify, key_file=key_file, cert_file=cert_file, context=context, proxies=proxies) else: @@ -1434,7 +1434,7 @@ def readinto(self, byte_array): return bytes_read -def handler(key_file=None, cert_file=None, timeout=None, verify=False, context=None, proxies=None): +def handler(key_file=None, cert_file=None, timeout=None, verify=False, context=None, proxies={}): """This class returns an instance of the default HTTP request handler using the values you provide. @@ -1488,6 +1488,7 @@ def request(url, message, **kwargs): if proxies.get(scheme): connection = connect(scheme, *(proxies.get(scheme).split(":"))) connection.set_tunnel("%s:%s" % (host,port)) + path = "%s://%s:%s%s" % (scheme, host, port, path) else: connection = connect(scheme, host, port) is_keepalive = False diff --git a/splunklib/client.py b/splunklib/client.py index 5e2a5d54..9f841cf5 100644 --- a/splunklib/client.py +++ b/splunklib/client.py @@ -418,7 +418,7 @@ class Service(_BaseService): s = client.Service(cookie="splunkd_8089=...") """ - def __init__(self, **kwargs): + def __init__(self, **kwargs): super().__init__(**kwargs) self._splunk_version = None self._kvstore_owner = None From f05d4e01055929eb0f7d5236a874050a0d152447 Mon Sep 17 00:00:00 2001 From: Guna Date: Fri, 4 Apr 2025 20:19:58 -0700 Subject: [PATCH 7/7] Whitespaces --- splunklib/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splunklib/client.py b/splunklib/client.py index 9f841cf5..5e2a5d54 100644 --- a/splunklib/client.py +++ b/splunklib/client.py @@ -418,7 +418,7 @@ class Service(_BaseService): s = client.Service(cookie="splunkd_8089=...") """ - def __init__(self, **kwargs): + def __init__(self, **kwargs): super().__init__(**kwargs) self._splunk_version = None self._kvstore_owner = None