Skip to content

Allow HTTPS requests to use tls_ciphers #20179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 100 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
100 commits
Select commit Hold shift + click to select a range
e4e789a
Add core TLS context changes
dkirov-dd May 27, 2025
09bf9cc
Fix base package tests
dkirov-dd May 27, 2025
cc99a03
Run formatter
dkirov-dd May 27, 2025
e65809d
Turn requests.X mocks into requests.Session.X
dkirov-dd Jul 1, 2025
5eecd4d
Fix airflow unit tests
dkirov-dd Jul 1, 2025
c8891d5
Run formatter
dkirov-dd May 27, 2025
9c7a16a
Add tls_ciphers to TLS Remote fetch_intermediate_certs
dkirov-dd May 28, 2025
b70def0
Rework Adapter class
dkirov-dd Jun 4, 2025
370a5d6
Revert TLS protocol change
dkirov-dd Jun 4, 2025
ebd64ed
Fix error in TlsContextAdapter
dkirov-dd Jun 5, 2025
a0f8401
Stop using TlsContextWrapper in RequestsWrapper
dkirov-dd Jun 6, 2025
c8fe5e0
Run formatter
dkirov-dd Jun 6, 2025
f07f716
Add test for ciphers, switch naming to SSL and fix hole in persistent…
dkirov-dd Jun 6, 2025
2d535fc
Run formatter
dkirov-dd Jun 6, 2025
680ac8e
Naming
dkirov-dd Jun 6, 2025
5356e42
Naming and test fixes
dkirov-dd Jun 6, 2025
5942ed6
Add unit test for debugging
dkirov-dd Jun 6, 2025
faccf4b
Fix consul test
dkirov-dd Jun 6, 2025
9e6a65e
Fix consul config assertion
dkirov-dd Jun 6, 2025
796fbbd
Fail SSLContext certificate loading with WARNING instead of ERROR
dkirov-dd Jun 6, 2025
cba0c7d
Lint
dkirov-dd Jun 6, 2025
549578b
Change mocks from requests.method to requests.Session.method
dkirov-dd Jun 6, 2025
b96d1ec
Lint
dkirov-dd Jun 6, 2025
15e2ea5
Fix couchbase tests
dkirov-dd Jun 12, 2025
31b7728
Fix amazon_msk tests - mocking requests.get because the boto3 lib use…
dkirov-dd Jun 12, 2025
97cb44e
Fix apache tests by reworking mock with requests.Session
dkirov-dd Jun 12, 2025
182b4b4
Fix arangodb tests by updating mock side effect
dkirov-dd Jun 12, 2025
62378f1
Fix couch tests by updating mock with requests.Session
dkirov-dd Jun 12, 2025
bca9b9d
Fix remaining occurrences of mock.patch("datadog_checks.base.utils.ht…
dkirov-dd Jun 12, 2025
001a3e4
Fix gitlab tests
dkirov-dd Jun 12, 2025
4855a92
Fix harbor tests
dkirov-dd Jun 12, 2025
65e9769
Fix hdfs_namenode tests
dkirov-dd Jun 13, 2025
cc6c14a
Fix http_check test
dkirov-dd Jun 13, 2025
d9ff6ba
Fix mapreduce tests
dkirov-dd Jun 13, 2025
ba6b51a
Fix proxysql test
dkirov-dd Jun 13, 2025
99b3c1b
Fix spark tests
dkirov-dd Jun 13, 2025
d7028de
Fix spark ssl test by fixing REMAPPER
dkirov-dd Jun 13, 2025
4777e6c
Fix twistlock tests
dkirov-dd Jun 13, 2025
8dd1d36
Fix vault tests
dkirov-dd Jun 13, 2025
442f885
Fix vertica tests
dkirov-dd Jun 13, 2025
ca26210
Fix yarn tests
dkirov-dd Jun 13, 2025
291708e
Fix avi_vantage test
dkirov-dd Jun 16, 2025
785bf0a
Fix http warning test
dkirov-dd Jun 16, 2025
78fbd1e
Extract options to tls_config logic in separate function
dkirov-dd Jun 16, 2025
dff0f88
Add test for ssl_context initialization
dkirov-dd Jun 16, 2025
d67b169
Run linter
dkirov-dd Jun 16, 2025
cf9572c
Fix falco test
dkirov-dd Jun 16, 2025
7138a48
Fix `tls_verify` parsing in SSL context creation logic
dkirov-dd Jun 17, 2025
b9a4c3d
Add tests with custom server
dkirov-dd Jun 17, 2025
bdab774
Fix request method use
dkirov-dd Jun 17, 2025
1b34f33
Fixing vsphere tests WIP
dkirov-dd Jun 17, 2025
98ee50b
Fix vsphere tests
dkirov-dd Jun 17, 2025
f2bd9b7
Run formatter
dkirov-dd Jun 17, 2025
08d06ef
Fix vault tests again
dkirov-dd Jun 17, 2025
8b0e39b
Try fixing amazon_msk tests as they do not fail locally
dkirov-dd Jun 17, 2025
4b5dc36
Try fixing amazon_msk tests as they do not fail locally 2
dkirov-dd Jun 17, 2025
ecb0c43
Run formatter
dkirov-dd Jun 17, 2025
81f76c3
Try fixing amazon_msk tests as they do not fail locally 3
dkirov-dd Jun 17, 2025
23520a6
Try fixing amazon_msk tests as they do not fail locally 4
dkirov-dd Jun 18, 2025
d06d37b
Try fixing amazon_msk tests as they do not fail locally 5
dkirov-dd Jun 18, 2025
e8b97aa
Try fixing amazon_msk tests as they do not fail locally 6
dkirov-dd Jun 18, 2025
1df2a4f
Try fixing http_check test
dkirov-dd Jun 18, 2025
c288330
Fix datadog_checks_dev test
dkirov-dd Jun 18, 2025
5099503
Fix datadog_checks_base test
dkirov-dd Jun 18, 2025
5d3d0df
Try fixing tls_cipher test
dkirov-dd Jun 18, 2025
405350d
Run formatter
dkirov-dd Jun 18, 2025
060840f
Fix datadog_checks_base test 2
dkirov-dd Jun 18, 2025
4aba58b
Fix datadog_checks_base test 3
dkirov-dd Jun 18, 2025
717b6e3
Run formatter
dkirov-dd Jun 18, 2025
141157b
Fix datadog_checks_base test final
dkirov-dd Jun 18, 2025
9244708
Add changelog
dkirov-dd Jun 18, 2025
f5c5df6
Update base.py
dkirov-dd Jun 18, 2025
90b1832
Use create_ssl_context in tls_remote
dkirov-dd Jun 18, 2025
97abe09
Apply suggestions from code review
dkirov-dd Jun 20, 2025
ebcdf0c
Add _mount_new_ssl_adapter method
dkirov-dd Jun 20, 2025
c073243
Implement suggestions from code review
dkirov-dd Jun 20, 2025
15a5873
Use ChainMaps
dkirov-dd Jun 24, 2025
bcb39a2
Implement caching for HTTPS adapters
dkirov-dd Jun 25, 2025
9915fc5
Use pydantic for TlsConfig class
dkirov-dd Jun 25, 2025
7a9059e
Minor improvements and fixes
dkirov-dd Jun 25, 2025
b31c03b
Add tests
dkirov-dd Jun 25, 2025
374ac1f
Run formatter
dkirov-dd Jun 25, 2025
ca8febd
Allow tls_ca_cert to be bool for legacy compatibility
dkirov-dd Jun 25, 2025
ccc3c1f
Fix datadog_checks_base tests
dkirov-dd Jun 25, 2025
5abfee9
Fix default tls_verify value in go_expvar
dkirov-dd Jun 25, 2025
2277456
Fix proxysql and vertica tests
dkirov-dd Jun 26, 2025
596385f
Run formatter and fix linting
dkirov-dd Jun 26, 2025
8c9d556
Add go_expvar changelog
dkirov-dd Jun 26, 2025
1007e0a
Fix base tests
dkirov-dd Jun 26, 2025
f01d58f
Fix intermediate_certs_tests for windows
dkirov-dd Jun 26, 2025
1c5991d
Fix intermediate_certs_tests for windows in a better way
dkirov-dd Jun 26, 2025
7b27443
tweak how we create session and mount adapter
iliakur Jun 28, 2025
986ea24
Remove unused func and mounting https adapters when creating session
iliakur Jun 28, 2025
b4abb44
Mount default https adapter in property
iliakur Jun 28, 2025
ac1f6d4
Apply suggestions from code review
dkirov-dd Jul 1, 2025
146acb2
Update datadog_checks_base/datadog_checks/base/utils/http.py
dkirov-dd Jul 1, 2025
7e713a1
Add TypeError for wrong TLS option types
dkirov-dd Jul 1, 2025
c9473af
Run formatter
dkirov-dd Jul 2, 2025
3c9e876
Fix kubelet typo in test
dkirov-dd Jul 2, 2025
f14f981
Run the ACTUAL formatter
dkirov-dd Jul 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions airflow/tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ def test_service_checks_healthy_exp(aggregator, json_resp, expected_healthy_stat
check = AirflowCheck('airflow', common.FULL_CONFIG, [instance])

with mock.patch('datadog_checks.airflow.airflow.AirflowCheck._get_version', return_value=None):
with mock.patch('datadog_checks.base.utils.http.requests') as req:
mock_session = mock.MagicMock()
with mock.patch('datadog_checks.base.utils.http.requests.Session', return_value=mock_session):
mock_resp = mock.MagicMock(status_code=200)
mock_resp.json.side_effect = [json_resp]
req.get.return_value = mock_resp
mock_session.get.return_value = mock_resp

check.check(None)

Expand All @@ -59,13 +60,14 @@ def test_service_checks_healthy_stable(
check = AirflowCheck('airflow', common.FULL_CONFIG, [instance])

with mock.patch('datadog_checks.airflow.airflow.AirflowCheck._get_version', return_value='2.6.2'):
with mock.patch('datadog_checks.base.utils.http.requests') as req:
mock_session = mock.MagicMock()
with mock.patch('datadog_checks.base.utils.http.requests.Session', return_value=mock_session):
mock_resp = mock.MagicMock(status_code=200)
mock_resp.json.side_effect = [
{'metadatabase': {'status': metadb_status}, 'scheduler': {'status': scheduler_status}},
{'status': 'OK'},
]
req.get.return_value = mock_resp
mock_session.get.return_value = mock_resp

check.check(None)

Expand All @@ -80,7 +82,8 @@ def test_dag_total_tasks(aggregator, task_instance):
check = AirflowCheck('airflow', common.FULL_CONFIG, [instance])

with mock.patch('datadog_checks.airflow.airflow.AirflowCheck._get_version', return_value='2.6.2'):
with mock.patch('datadog_checks.base.utils.http.requests') as req:
req = mock.MagicMock()
with mock.patch('datadog_checks.base.utils.http.requests.Session', return_value=req):
mock_resp = mock.MagicMock(status_code=200)
mock_resp.json.side_effect = [
{'metadatabase': {'status': 'healthy'}, 'scheduler': {'status': 'healthy'}},
Expand All @@ -98,7 +101,8 @@ def test_dag_task_ongoing_duration(aggregator, task_instance):
check = AirflowCheck('airflow', common.FULL_CONFIG, [instance])

with mock.patch('datadog_checks.airflow.airflow.AirflowCheck._get_version', return_value='2.6.2'):
with mock.patch('datadog_checks.base.utils.http.requests') as req:
req = mock.MagicMock()
with mock.patch('datadog_checks.base.utils.http.requests.Session', return_value=req):
mock_resp = mock.MagicMock(status_code=200)
mock_resp.json.side_effect = [
{'metadatabase': {'status': 'healthy'}, 'scheduler': {'status': 'healthy'}},
Expand Down Expand Up @@ -142,7 +146,8 @@ def test_config_collect_ongoing_duration(collect_ongoing_duration, should_call_m
check = AirflowCheck('airflow', common.FULL_CONFIG, [instance])

with mock.patch('datadog_checks.airflow.airflow.AirflowCheck._get_version', return_value='2.6.2'):
with mock.patch('datadog_checks.base.utils.http.requests') as req:
req = mock.MagicMock()
with mock.patch('datadog_checks.base.utils.http.requests.Session', return_value=req):
mock_resp = mock.MagicMock(status_code=200)
mock_resp.json.side_effect = [
{'metadatabase': {'status': 'healthy'}, 'scheduler': {'status': 'healthy'}},
Expand Down
6 changes: 5 additions & 1 deletion amazon_msk/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ def mock_requests_get(url, *args, **kwargs):

@pytest.fixture
def mock_data():
with mock.patch('requests.get', side_effect=mock_requests_get, autospec=True):
# Mock requests.get because it is used internally within boto3
with (
mock.patch('requests.get', side_effect=mock_requests_get, autospec=True),
mock.patch('requests.Session.get', side_effect=mock_requests_get),
):
yield


Expand Down
3 changes: 2 additions & 1 deletion apache/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def check_status_page_ready():

@pytest.fixture
def mock_hide_server_version():
with mock.patch('datadog_checks.base.utils.http.requests') as req:
req = mock.MagicMock()
with mock.patch('datadog_checks.base.utils.http.requests.Session', return_value=req):

def mock_requests_get_headers(*args, **kwargs):
r = requests.get(*args, **kwargs)
Expand Down
4 changes: 2 additions & 2 deletions arangodb/tests/test_arangodb.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ def test_invalid_endpoint(aggregator, instance_invalid_endpoint, dd_run_check):
def test_check(instance, dd_run_check, aggregator, tag_condition, base_tags):
check = ArangodbCheck('arangodb', {}, [instance])

def mock_requests_get(url, *args, **kwargs):
def mock_requests_get(session, url, *args, **kwargs):
fixture = url.rsplit('/', 1)[-1]
return MockResponse(file_path=os.path.join(os.path.dirname(__file__), 'fixtures', tag_condition, fixture))

with mock.patch('requests.get', side_effect=mock_requests_get, autospec=True):
with mock.patch('requests.Session.get', side_effect=mock_requests_get, autospec=True):
dd_run_check(check)

aggregator.assert_service_check(
Expand Down
36 changes: 19 additions & 17 deletions avi_vantage/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,29 +58,31 @@ def _get_metrics(metrics_folder=NO_TENANT_METRICS_FOLDER, endpoint=None):

@pytest.fixture
def mock_client():
with mock.patch('datadog_checks.base.utils.http.requests') as req:
def mock_get(url: AnyStr, *__: Any, **___: Any):
parsed = urlparse(url)
resource = [part for part in parsed.path.split('/') if len(part) > 0][-1]
query_params = parsed.query

def get(url: AnyStr, *_: Any, **__: Any):
parsed = urlparse(url)
resource = [part for part in parsed.path.split('/') if len(part) > 0][-1]
query_params = parsed.query
path = {}

path = {}

path['tenant=admin'] = ADMIN_TENANT_METRICS_FOLDER
path['tenant=admin%2Ctenant_a%2Ctenant_b'] = MULTIPLE_TENANTS_METRICS_FOLDER

if query_params:
return MockResponse(
file_path=os.path.join(HERE, 'compose', 'fixtures', path[query_params], f'{resource}_metrics')
)
path['tenant=admin'] = ADMIN_TENANT_METRICS_FOLDER
path['tenant=admin%2Ctenant_a%2Ctenant_b'] = MULTIPLE_TENANTS_METRICS_FOLDER

if query_params:
return MockResponse(
file_path=os.path.join(HERE, 'compose', 'fixtures', NO_TENANT_METRICS_FOLDER, f'{resource}_metrics')
file_path=os.path.join(HERE, 'compose', 'fixtures', path[query_params], f'{resource}_metrics')
)

req.Session = mock.MagicMock(return_value=mock.MagicMock(get=get))
yield
return MockResponse(
file_path=os.path.join(HERE, 'compose', 'fixtures', NO_TENANT_METRICS_FOLDER, f'{resource}_metrics')
)

def mock_post(url: AnyStr, *__: Any, **___: Any):
return mock.MagicMock(status_code=200, content=b'{"results": []}')

with mock.patch('datadog_checks.base.utils.http.RequestsWrapper.get', side_effect=mock_get):
with mock.patch('datadog_checks.base.utils.http.RequestsWrapper.post', new=mock_post):
yield


@pytest.fixture(scope='session')
Expand Down
4 changes: 2 additions & 2 deletions cert_manager/tests/test_cert_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
@pytest.fixture()
def error_metrics():
with mock.patch(
'requests.get',
'requests.Session.get',
return_value=mock.MagicMock(status_code=502, headers={'Content-Type': "text/plain"}),
):
yield
Expand All @@ -34,7 +34,7 @@ def test_check(aggregator, dd_run_check):
def mock_requests_get(url, *args, **kwargs):
return MockResponse(file_path=os.path.join(os.path.dirname(__file__), 'fixtures', 'cert_manager.txt'))

with mock.patch('requests.get', side_effect=mock_requests_get, autospec=True):
with mock.patch('requests.Session.get', side_effect=mock_requests_get, autospec=True):
dd_run_check(check)

expected_metrics = dict(CERT_METRICS)
Expand Down
4 changes: 2 additions & 2 deletions cilium/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ def mock_agent_data():
with open(f_name, "r") as f:
text_data = f.read()
with mock.patch(
"requests.get",
'requests.Session.get',
return_value=mock.MagicMock(
status_code=200, iter_lines=lambda **kwargs: text_data.split("\n"), headers={"Content-Type": "text/plain"}
),
Expand All @@ -217,7 +217,7 @@ def mock_operator_data():
with open(f_name, "r") as f:
text_data = f.read()
with mock.patch(
"requests.get",
'requests.Session.get',
return_value=mock.MagicMock(
status_code=200, iter_lines=lambda **kwargs: text_data.split("\n"), headers={"Content-Type": "text/plain"}
),
Expand Down
2 changes: 1 addition & 1 deletion citrix_hypervisor/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ def mock_requests_get(url, *args, **kwargs):

@pytest.fixture
def mock_responses():
with mock.patch('requests.get', side_effect=mock_requests_get):
with mock.patch('requests.Session.get', side_effect=mock_requests_get):
yield
10 changes: 6 additions & 4 deletions consul/tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ def test_get_nodes_with_service_critical(aggregator):
def test_consul_request(aggregator, instance, mocker):
consul_check = ConsulCheck(common.CHECK_NAME, {}, [consul_mocks.MOCK_CONFIG])
mocker.patch("datadog_checks.base.utils.serialization.json.loads")
with mock.patch("datadog_checks.consul.consul.requests.get") as mock_requests_get:
with mock.patch("datadog_checks.consul.consul.requests.Session.get") as mock_requests_get:
consul_check.consul_request("foo")
url = "{}/{}".format(instance["url"], "foo")
aggregator.assert_service_check("consul.can_connect", ConsulCheck.OK, tags=["url:{}".format(url)], count=1)
Expand Down Expand Up @@ -549,8 +549,10 @@ def test_config(test_case, extra_config, expected_http_kwargs, mocker):
check = ConsulCheck(common.CHECK_NAME, {}, instances=[instance])
mocker.patch("datadog_checks.base.utils.serialization.json.loads")

with mock.patch('datadog_checks.base.utils.http.requests') as r:
r.get.return_value = mock.MagicMock(status_code=200)
with mock.patch('datadog_checks.base.utils.http.requests.Session') as session:
mock_session = mock.MagicMock()
session.return_value = mock_session
mock_session.get.return_value = mock.MagicMock(status_code=200)

check.check(None)

Expand All @@ -564,4 +566,4 @@ def test_config(test_case, extra_config, expected_http_kwargs, mocker):
'allow_redirects': mock.ANY,
}
http_wargs.update(expected_http_kwargs)
r.get.assert_called_with('/v1/status/leader', **http_wargs)
mock_session.get.assert_called_with('/v1/status/leader', **http_wargs)
3 changes: 2 additions & 1 deletion couch/tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ def test_config(test_case, extra_config, expected_http_kwargs):
instance.update(extra_config)
check = CouchDb(common.CHECK_NAME, {}, instances=[instance])

with mock.patch('datadog_checks.base.utils.http.requests') as r:
r = mock.MagicMock()
with mock.patch('datadog_checks.base.utils.http.requests.Session', return_value=r):
r.get.return_value = mock.MagicMock(status_code=200, content='{}')

check.check(instance)
Expand Down
37 changes: 18 additions & 19 deletions couchbase/tests/test_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,26 +72,25 @@ def test__get_query_monitoring_data(instance_query):
("legacy config", {'user': 'new_foo', 'ssl_verify': False}, {'auth': ('new_foo', 'password'), 'verify': False}),
],
)
def test_config(test_case, dd_run_check, extra_config, expected_http_kwargs, instance):
def test_config(test_case, extra_config, expected_http_kwargs, instance):
"""
Test that the legacy and new auth configurations are both supported.
"""
instance.update(extra_config)
check = Couchbase('couchbase', {}, [instance])

with mock.patch('datadog_checks.base.utils.http.requests') as r:
r.get.return_value = mock.MagicMock(status_code=200)

dd_run_check(check)
check = Couchbase('couchbase', {}, [instance])

http_wargs = {
'auth': mock.ANY,
'cert': mock.ANY,
'headers': mock.ANY,
'proxies': mock.ANY,
'timeout': mock.ANY,
'verify': mock.ANY,
'allow_redirects': mock.ANY,
}
http_wargs.update(expected_http_kwargs)
r.get.assert_called_with('http://localhost:8091/pools/default/tasks', **http_wargs)
http_wargs = {
'auth': mock.ANY,
'cert': mock.ANY,
'headers': mock.ANY,
'proxies': mock.ANY,
'timeout': mock.ANY,
'verify': mock.ANY,
'allow_redirects': mock.ANY,
}
http_wargs.update(expected_http_kwargs)
assert check.http.options == http_wargs


@pytest.mark.parametrize(
Expand Down Expand Up @@ -126,7 +125,7 @@ def test_extract_index_tags(instance, test_input, expected_tags):


def test_unit(dd_run_check, check, instance, mocker, aggregator):
mocker.patch("requests.get", wraps=mock_http_responses)
mocker.patch("requests.Session.get", wraps=mock_http_responses)

dd_run_check(check(instance))

Expand All @@ -142,7 +141,7 @@ def test_unit(dd_run_check, check, instance, mocker, aggregator):


def test_unit_query_metrics(dd_run_check, check, instance_query, mocker, aggregator):
mocker.patch("requests.get", wraps=mock_http_responses)
mocker.patch("requests.Session.get", wraps=mock_http_responses)

dd_run_check(check(instance_query))

Expand Down
2 changes: 1 addition & 1 deletion crio/tests/test_crio.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def mock_data():
with open(f_name, 'r') as f:
text_data = f.read()
with mock.patch(
'requests.get',
'requests.Session.get',
return_value=mock.MagicMock(
status_code=200, iter_lines=lambda **kwargs: text_data.split("\n"), headers={'Content-Type': "text/plain"}
),
Expand Down
1 change: 1 addition & 0 deletions datadog_checks_base/changelog.d/20179.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow HTTPS requests to use `tls_ciphers` parameter
Loading
Loading