11package com .bencodez .simpleapi .sql .mysql ;
22
3+ import java .net .URLDecoder ;
4+ import java .nio .charset .StandardCharsets ;
35import java .sql .Connection ;
46import java .sql .SQLException ;
7+ import java .util .Locale ;
8+ import java .util .Objects ;
59
610import com .zaxxer .hikari .HikariConfig ;
711import com .zaxxer .hikari .HikariDataSource ;
@@ -81,6 +85,13 @@ public class ConnectionManager {
8185 @ Setter
8286 private boolean useSSL = false ;
8387
88+ @ Getter
89+ private PostgreSqlTlsMode postgreSqlTlsMode = PostgreSqlTlsMode .LEGACY ;
90+
91+ public void setPostgreSqlTlsMode (PostgreSqlTlsMode mode ) {
92+ postgreSqlTlsMode = Objects .requireNonNull (mode , "mode" );
93+ }
94+
8495 /**
8596 * Legacy flag still supported; only used if dbType isn't explicitly set.
8697 */
@@ -207,7 +218,7 @@ private String resolveMariaDbWithFallback() throws ClassNotFoundException {
207218 }
208219 }
209220
210- private String buildJdbcUrl (String driverClassName ) {
221+ String buildJdbcUrl (String driverClassName ) {
211222 String extra = (str == null ? "" : str );
212223
213224 // Postgres
@@ -216,10 +227,17 @@ private String buildJdbcUrl(String driverClassName) {
216227
217228 // Defaults:
218229 // - reWriteBatchedInserts improves batch perf
219- // - sslmode if useSSL
230+ // - absent explicit mode preserves the legacy UseSSL behavior
220231 String defaults = "reWriteBatchedInserts=true" ;
221- if (useSSL ) {
232+ if (postgreSqlTlsMode == PostgreSqlTlsMode . LEGACY && useSSL ) {
222233 defaults += "&sslmode=require" ;
234+ } else if (postgreSqlTlsMode != PostgreSqlTlsMode .LEGACY ) {
235+ rejectConflictingPostgreSqlTlsOptions (extra );
236+ defaults += "&sslmode=" + postgreSqlTlsMode .getJdbcValue ();
237+ if (postgreSqlTlsMode == PostgreSqlTlsMode .REQUIRE
238+ || postgreSqlTlsMode == PostgreSqlTlsMode .VERIFY_FULL ) {
239+ defaults += "&gssEncMode=disable" ;
240+ }
223241 }
224242
225243 if (extra .isEmpty ()) {
@@ -240,6 +258,9 @@ private String buildJdbcUrl(String driverClassName) {
240258 }
241259
242260 // MySQL / MariaDB
261+ if (postgreSqlTlsMode != PostgreSqlTlsMode .LEGACY ) {
262+ throw new IllegalArgumentException ("PostgreSqlTlsMode applies only to PostgreSQL connections" );
263+ }
243264 boolean maria = (dbType == DbType .MARIADB ) || "org.mariadb.jdbc.Driver" .equals (driverClassName );
244265 String base = maria ? String .format ("jdbc:mariadb://%s:%s/%s" , host , port , database )
245266 : String .format ("jdbc:mysql://%s:%s/%s" , host , port , database );
@@ -250,6 +271,24 @@ private String buildJdbcUrl(String driverClassName) {
250271 + extra ;
251272 }
252273
274+ private void rejectConflictingPostgreSqlTlsOptions (String extra ) {
275+ String options = extra .startsWith ("?" ) || extra .startsWith ("&" ) ? extra .substring (1 ) : extra ;
276+ for (String parameter : options .split ("&" , -1 )) {
277+ String rawKey = parameter .split ("=" , 2 )[0 ];
278+ String key ;
279+ try {
280+ key = URLDecoder .decode (rawKey , StandardCharsets .UTF_8 ).trim ().toLowerCase (Locale .ROOT );
281+ } catch (IllegalArgumentException ex ) {
282+ throw new IllegalArgumentException ("Invalid encoded parameter name in PostgreSQL Line" , ex );
283+ }
284+ if (key .equals ("sslmode" ) || key .equals ("ssl" ) || key .equals ("sslfactory" )
285+ || key .equals ("sslhostnameverifier" )
286+ || (postgreSqlTlsMode != PostgreSqlTlsMode .DISABLE && key .equals ("gssencmode" ))) {
287+ throw new IllegalArgumentException ("PostgreSqlTlsMode conflicts with a TLS parameter in Line" );
288+ }
289+ }
290+ }
291+
253292 // --- Pool Configuration ---
254293
255294 public boolean open () {
0 commit comments