133
133
* <li>{@code maxIdleTimeMS=ms}: Maximum idle time of a pooled connection. A connection that exceeds this limit will be closed</li>
134
134
* <li>{@code maxLifeTimeMS=ms}: Maximum life time of a pooled connection. A connection that exceeds this limit will be closed</li>
135
135
* </ul>
136
+ * <p>Proxy Configuration:</p>
137
+ * <ul>
138
+ * <li>{@code proxyHost=string}: The SOCKS5 proxy host to establish a connection through.
139
+ * It can be provided as a valid IPv4 address, IPv6 address, or a domain name. Required if either proxyPassword, proxyUsername or
140
+ * proxyPort are specified</li>
141
+ * <li>{@code proxyPort=n}: The port number for the SOCKS5 proxy server. Must be a non-negative integer.</li>
142
+ * <li>{@code proxyUsername=string}: Username for authenticating with the proxy server. Required if proxyPassword is specified.</li>
143
+ * <li>{@code proxyPassword=string}: Password for authenticating with the proxy server. Required if proxyUsername is specified.</li>
144
+ * </ul>
136
145
* <p>Connection pool configuration:</p>
137
146
* <ul>
138
147
* <li>{@code maxPoolSize=n}: The maximum number of connections in the connection pool.</li>
@@ -290,6 +299,10 @@ public class ConnectionString {
290
299
private Integer socketTimeout ;
291
300
private Boolean sslEnabled ;
292
301
private Boolean sslInvalidHostnameAllowed ;
302
+ private String proxyHost ;
303
+ private Integer proxyPort ;
304
+ private String proxyUsername ;
305
+ private String proxyPassword ;
293
306
private String requiredReplicaSetName ;
294
307
private Integer serverSelectionTimeout ;
295
308
private Integer localThreshold ;
@@ -468,6 +481,8 @@ public ConnectionString(final String connectionString, @Nullable final DnsClient
468
481
throw new IllegalArgumentException ("srvMaxHosts can not be specified with replica set name" );
469
482
}
470
483
484
+ validateProxyParameters ();
485
+
471
486
credential = createCredentials (combinedOptionsMaps , userName , password );
472
487
warnOnUnsupportedOptions (combinedOptionsMaps );
473
488
}
@@ -502,6 +517,12 @@ public ConnectionString(final String connectionString, @Nullable final DnsClient
502
517
GENERAL_OPTIONS_KEYS .add ("sslinvalidhostnameallowed" );
503
518
GENERAL_OPTIONS_KEYS .add ("tlsallowinvalidhostnames" );
504
519
520
+ //Socks5 proxy settings
521
+ GENERAL_OPTIONS_KEYS .add ("proxyhost" );
522
+ GENERAL_OPTIONS_KEYS .add ("proxyport" );
523
+ GENERAL_OPTIONS_KEYS .add ("proxyusername" );
524
+ GENERAL_OPTIONS_KEYS .add ("proxypassword" );
525
+
505
526
GENERAL_OPTIONS_KEYS .add ("replicaset" );
506
527
GENERAL_OPTIONS_KEYS .add ("readconcernlevel" );
507
528
@@ -599,6 +620,18 @@ private void translateOptions(final Map<String, List<String>> optionsMap) {
599
620
case "sockettimeoutms" :
600
621
socketTimeout = parseInteger (value , "sockettimeoutms" );
601
622
break ;
623
+ case "proxyhost" :
624
+ proxyHost = value ;
625
+ break ;
626
+ case "proxyport" :
627
+ proxyPort = parseInteger (value , "proxyPort" );
628
+ break ;
629
+ case "proxyusername" :
630
+ proxyUsername = value ;
631
+ break ;
632
+ case "proxypassword" :
633
+ proxyPassword = value ;
634
+ break ;
602
635
case "tlsallowinvalidhostnames" :
603
636
sslInvalidHostnameAllowed = parseBoolean (value , "tlsAllowInvalidHostnames" );
604
637
tlsAllowInvalidHostnamesSet = true ;
@@ -1158,6 +1191,41 @@ private void validatePort(final String host, final String port) {
1158
1191
}
1159
1192
}
1160
1193
1194
+ private void validateProxyParameters () {
1195
+ if (proxyHost == null ) {
1196
+ if (proxyPort != null ) {
1197
+ throw new IllegalArgumentException ("proxyPort can only be specified with proxyHost" );
1198
+ } else if (proxyUsername != null ) {
1199
+ throw new IllegalArgumentException ("proxyUsername can only be specified with proxyHost" );
1200
+ } else if (proxyPassword != null ) {
1201
+ throw new IllegalArgumentException ("proxyPassword can only be specified with proxyHost" );
1202
+ }
1203
+ }
1204
+ if (proxyPort != null && (proxyPort < 0 || proxyPort > 65535 )) {
1205
+ throw new IllegalArgumentException ("proxyPort should be within the valid range (0 to 65535)" );
1206
+ }
1207
+ if (proxyUsername != null ) {
1208
+ if (proxyUsername .isEmpty ()) {
1209
+ throw new IllegalArgumentException ("proxyUsername cannot be empty" );
1210
+ }
1211
+ if (proxyUsername .getBytes (StandardCharsets .UTF_8 ).length >= 255 ) {
1212
+ throw new IllegalArgumentException ("username's length in bytes cannot be greater than 255" );
1213
+ }
1214
+ }
1215
+ if (proxyPassword != null ) {
1216
+ if (proxyPassword .isEmpty ()) {
1217
+ throw new IllegalArgumentException ("proxyPassword cannot be empty" );
1218
+ }
1219
+ if (proxyPassword .getBytes (StandardCharsets .UTF_8 ).length >= 255 ) {
1220
+ throw new IllegalArgumentException ("password's length in bytes cannot be greater than 255" );
1221
+ }
1222
+ }
1223
+ if (proxyUsername == null ^ proxyPassword == null ) {
1224
+ throw new IllegalArgumentException (
1225
+ "Both proxyUsername and proxyPassword must be set together. They cannot be set individually" );
1226
+ }
1227
+ }
1228
+
1161
1229
private int countOccurrences (final String haystack , final String needle ) {
1162
1230
return haystack .length () - haystack .replace (needle , "" ).length ();
1163
1231
}
@@ -1473,6 +1541,49 @@ public Boolean getSslEnabled() {
1473
1541
return sslEnabled ;
1474
1542
}
1475
1543
1544
+ /**
1545
+ * Gets the SOCKS5 proxy host specified in the connection string.
1546
+ *
1547
+ * @return the proxy host value.
1548
+ * @since 4.11
1549
+ */
1550
+ @ Nullable
1551
+ public String getProxyHost () {
1552
+ return proxyHost ;
1553
+ }
1554
+
1555
+ /**
1556
+ * Gets the SOCKS5 proxy port specified in the connection string.
1557
+ *
1558
+ * @return the proxy port value.
1559
+ * @since 4.11
1560
+ */
1561
+ @ Nullable
1562
+ public Integer getProxyPort () {
1563
+ return proxyPort ;
1564
+ }
1565
+
1566
+ /**
1567
+ * Gets the SOCKS5 proxy username specified in the connection string.
1568
+ *
1569
+ * @return the proxy username value.
1570
+ * @since 4.11
1571
+ */
1572
+ @ Nullable
1573
+ public String getProxyUsername () {
1574
+ return proxyUsername ;
1575
+ }
1576
+
1577
+ /**
1578
+ * Gets the SOCKS5 proxy password specified in the connection string.
1579
+ *
1580
+ * @return the proxy password value.
1581
+ * @since 4.11
1582
+ */
1583
+ @ Nullable
1584
+ public String getProxyPassword () {
1585
+ return proxyPassword ;
1586
+ }
1476
1587
/**
1477
1588
* Gets the SSL invalidHostnameAllowed value specified in the connection string.
1478
1589
*
@@ -1594,6 +1705,10 @@ public boolean equals(final Object o) {
1594
1705
&& Objects .equals (maxConnecting , that .maxConnecting )
1595
1706
&& Objects .equals (connectTimeout , that .connectTimeout )
1596
1707
&& Objects .equals (socketTimeout , that .socketTimeout )
1708
+ && Objects .equals (proxyHost , that .proxyHost )
1709
+ && Objects .equals (proxyPort , that .proxyPort )
1710
+ && Objects .equals (proxyUsername , that .proxyUsername )
1711
+ && Objects .equals (proxyPassword , that .proxyPassword )
1597
1712
&& Objects .equals (sslEnabled , that .sslEnabled )
1598
1713
&& Objects .equals (sslInvalidHostnameAllowed , that .sslInvalidHostnameAllowed )
1599
1714
&& Objects .equals (requiredReplicaSetName , that .requiredReplicaSetName )
@@ -1613,6 +1728,7 @@ public int hashCode() {
1613
1728
writeConcern , retryWrites , retryReads , readConcern , minConnectionPoolSize , maxConnectionPoolSize , maxWaitTime ,
1614
1729
maxConnectionIdleTime , maxConnectionLifeTime , maxConnecting , connectTimeout , socketTimeout , sslEnabled ,
1615
1730
sslInvalidHostnameAllowed , requiredReplicaSetName , serverSelectionTimeout , localThreshold , heartbeatFrequency ,
1616
- applicationName , compressorList , uuidRepresentation , srvServiceName , srvMaxHosts );
1731
+ applicationName , compressorList , uuidRepresentation , srvServiceName , srvMaxHosts , proxyHost , proxyPort ,
1732
+ proxyUsername , proxyPassword );
1617
1733
}
1618
1734
}
0 commit comments