The complete connect string is now sent to the server instead of just

the actual components being used. This is important for some
configurations.
This commit is contained in:
Anthony Tuininga 2022-11-07 10:34:53 -07:00
parent 62d7800f7a
commit 25d5468439
7 changed files with 20 additions and 18 deletions

View File

@ -31,6 +31,8 @@ Thin Mode Changes
:data:`~oracledb.DB_TYPE_UROWID` that exceed 3950 bytes in length.
#) Fixed bug preventing correct parsing of connect descriptors with both
ADDRESS and ADDRESS_LIST components at the same level.
#) The complete connect string is now sent to the server instead of just the
actual components being used. This is important for some configurations.
Thick Mode Changes
++++++++++++++++++

View File

@ -136,7 +136,7 @@ cdef class Description:
public str wallet_location
cdef str _build_duration_str(self, double value)
cdef str build_connect_string(self)
cdef str build_connect_string(self, str cid=*)
cdef class DescriptionList:

View File

@ -707,7 +707,7 @@ cdef class Description:
return f"{value_minutes}min"
return f"{value_int}"
cdef str build_connect_string(self):
cdef str build_connect_string(self, str cid=None):
"""
Build a connect string from the components.
"""
@ -728,10 +728,14 @@ cdef class Description:
parts.append(f"(POOL_CONNECTION_CLASS={self.cclass})")
if self.purity != 0:
parts.append(f"(POOL_PURITY={self.purity})")
if cid is not None:
parts.append(f"(CID={cid})")
connect_data = f'(CONNECT_DATA={"".join(parts)})'
# build security segment, if applicable
parts = [f"(SSL_SERVER_DN_MATCH={self.ssl_server_dn_match})"]
parts = []
if self.ssl_server_dn_match:
parts.append("(SSL_SERVER_DN_MATCH=ON)")
if self.ssl_server_cert_dn is not None:
parts.append(f"(SSL_SERVER_CERT_DN={self.ssl_server_cert_dn})")
if self.wallet_location is not None:

View File

@ -91,6 +91,7 @@ cdef class ThinConnImpl(BaseConnImpl):
cdef int _connect_with_address(self, Address address,
Description description,
ConnectParamsImpl params,
str connect_string,
bint raise_exception) except -1:
"""
Internal method used for connecting with the given description and
@ -98,7 +99,7 @@ cdef class ThinConnImpl(BaseConnImpl):
"""
try:
self._protocol._connect_phase_one(self, params, description,
address)
address, connect_string)
except exceptions.DatabaseError:
if raise_exception:
raise
@ -130,10 +131,12 @@ cdef class ThinConnImpl(BaseConnImpl):
uint32_t num_attempts = description.retry_count + 1
uint32_t num_lists = len(address_lists)
AddressList address_list
str connect_string
Address address
# Retry connecting to the socket if an attempt fails and retry_count
# is specified in the connect string. If an attempt succeeds, return
# the socket and the valid address object.
connect_string = _get_connect_data(description)
for i in range(num_attempts):
# Iterate through each address_list in the description. If the
# description level load_balance is on, keep track of the least
@ -161,7 +164,7 @@ cdef class ThinConnImpl(BaseConnImpl):
and j == num_lists - 1 \
and k == num_addresses - 1
self._connect_with_address(address, description, params,
raise_exc)
connect_string, raise_exc)
if self._protocol._in_connect:
continue
address_list.lru_index = (idx1 + 1) % num_addresses

View File

@ -120,17 +120,18 @@ cdef class Protocol:
ThinConnImpl conn_impl,
ConnectParamsImpl params,
Description description,
Address address) except -1:
Address address,
str connect_string) except -1:
"""
Method for performing the required steps for establishing a connection
within the scope of a retry. If the listener refuses the connection, a
retry will be performed, if retry_count is set.
"""
cdef:
str connect_string, host, redirect_data
ConnectMessage connect_message = None
object ssl_context, connect_info
ConnectParamsImpl temp_params
str host, redirect_data
Address temp_address
uint8_t packet_type
int port, pos
@ -143,7 +144,6 @@ cdef class Protocol:
host = address.host
port = address.port
self._connect_tcp(params, description, address, host, port)
connect_string = _get_connect_data(address, description)
# send connect message and process response; this may request the
# message to be resent multiple times; if a redirect packet is

View File

@ -88,22 +88,15 @@ cdef object _encode_rowid(Rowid *rowid):
return buf[:TNS_MAX_ROWID_LENGTH].decode()
def _get_connect_data(address, description):
cdef str _get_connect_data(Description description):
"""
Return the connect data required by the listener in order to connect.
"""
constants = _connect_constants
server_type = f"(SERVER={description.server_type})" \
if description.server_type is not None else ""
identity = f"(SERVICE_NAME={description.service_name})" \
if description.service_name is not None or \
description.sid is None else f"(SID={description.sid})"
cid = f"(PROGRAM={constants.sanitized_program_name})" + \
f"(HOST={constants.sanitized_machine_name})" + \
f"(USER={constants.sanitized_user_name})"
return f"(DESCRIPTION=(ADDRESS=(PROTOCOL={address.protocol.upper()})" + \
f"(HOST={address.host})(PORT={address.port}))" + \
f"(CONNECT_DATA={identity}{server_type}(CID={cid})))"
return description.build_connect_string(cid)
def _print_packet(operation, socket_fileno, data):

View File

@ -481,7 +481,7 @@ class TestCase(test_env.BaseTestCase):
f"(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)" + \
f"(HOST={host})(PORT=1521)))(CONNECT_DATA=" + \
f"(SERVICE_NAME={service_name}))" + \
f"(SECURITY=(SSL_SERVER_DN_MATCH=True)))"
f"(SECURITY=(SSL_SERVER_DN_MATCH=ON)))"
self.assertEqual(params.get_connect_string(), connect_string)
def test_4532_multiple_alias_entry_tnsnames(self):