5656import javax .crypto .Cipher ;
5757import javax .crypto .Mac ;
5858import javax .crypto .spec .SecretKeySpec ;
59+ import javax .net .SocketFactory ;
60+ import javax .net .ssl .SSLSocketFactory ;
5961import javax .xml .parsers .DocumentBuilder ;
6062import javax .xml .parsers .DocumentBuilderFactory ;
6163import javax .xml .parsers .ParserConfigurationException ;
@@ -156,6 +158,10 @@ public Request authenticate(Route route, @NotNull Response response) {
156158 }
157159 });
158160 }
161+ if (conf .proxyType == Proxy .Type .HTTP && conf .proxySSL ) {
162+ // builder.socketFactory(SSLSocketFactory.getDefault()) throws an error on some okhttp versions
163+ builder .socketFactory (new DelegatingSocketFactory (SSLSocketFactory .getDefault ()));
164+ }
159165 }
160166
161167 builder .addInterceptor (chain -> {
@@ -1029,6 +1035,7 @@ public final static class Configuration {
10291035 // Proxy
10301036 public final boolean proxyEnabled ;
10311037 public final Proxy .Type proxyType ;
1038+ public final boolean proxySSL ;
10321039 public final String proxyAddress ;
10331040 public final int proxyPort ;
10341041 public final boolean proxyAuth ;
@@ -1054,13 +1061,15 @@ public final static class Configuration {
10541061 // Network
10551062 public final int connectionTimeout ;
10561063
1057- private Configuration (boolean proxyEnabled , Proxy .Type proxyType , String proxyAddress , int proxyPort , boolean proxyAuth , String proxyUsername , String proxyPassword ,
1064+ private Configuration (boolean proxyEnabled , Proxy .Type proxyType , boolean proxySSL , String proxyAddress ,
1065+ int proxyPort , boolean proxyAuth , String proxyUsername , String proxyPassword ,
10581066 TimeProvider .Method timeSynchronizationMethod , int timeManualCorrection ,
10591067 boolean cacheEnabled , File cacheDir , boolean doCacheCleanUp ,
10601068 boolean storeCredentials , File storedCredentialsFile ,
10611069 boolean retryOnChunkError , int connectionTimeout ) {
10621070 this .proxyEnabled = proxyEnabled ;
10631071 this .proxyType = proxyType ;
1072+ this .proxySSL = proxySSL ;
10641073 this .proxyAddress = proxyAddress ;
10651074 this .proxyPort = proxyPort ;
10661075 this .proxyAuth = proxyAuth ;
@@ -1081,6 +1090,7 @@ public static final class Builder {
10811090 // Proxy
10821091 private boolean proxyEnabled = false ;
10831092 private Proxy .Type proxyType ;
1093+ private boolean proxySSL = false ;
10841094 private String proxyAddress ;
10851095 private int proxyPort ;
10861096 private boolean proxyAuth ;
@@ -1119,6 +1129,11 @@ public Builder setProxyType(Proxy.Type proxyType) {
11191129 return this ;
11201130 }
11211131
1132+ public Builder setProxySSL (boolean proxySSL ) {
1133+ this .proxySSL = proxySSL ;
1134+ return this ;
1135+ }
1136+
11221137 public Builder setProxyAddress (String proxyAddress ) {
11231138 this .proxyAddress = proxyAddress ;
11241139 return this ;
@@ -1191,7 +1206,8 @@ public Builder setConnectionTimeout(int connectionTimeout) {
11911206
11921207 @ NotNull
11931208 public Configuration build () {
1194- return new Configuration (proxyEnabled , proxyType , proxyAddress , proxyPort , proxyAuth , proxyUsername , proxyPassword ,
1209+ return new Configuration (proxyEnabled , proxyType , proxySSL , proxyAddress , proxyPort , proxyAuth ,
1210+ proxyUsername , proxyPassword ,
11951211 timeSynchronizationMethod , timeManualCorrection ,
11961212 cacheEnabled , cacheDir , doCacheCleanUp ,
11971213 storeCredentials , storedCredentialsFile ,
@@ -1245,7 +1261,12 @@ static ConnectionHolder create(@NotNull String addr, @NotNull Configuration conf
12451261
12461262 switch (conf .proxyType ) {
12471263 case HTTP :
1248- Socket sock = new Socket (conf .proxyAddress , conf .proxyPort );
1264+ Socket sock ;
1265+ if (conf .proxySSL ) {
1266+ sock = SSLSocketFactory .getDefault ().createSocket (conf .proxyAddress , conf .proxyPort );
1267+ } else {
1268+ sock = new Socket (conf .proxyAddress , conf .proxyPort );
1269+ }
12491270 OutputStream out = sock .getOutputStream ();
12501271 DataInputStream in = new DataInputStream (sock .getInputStream ());
12511272
@@ -1264,7 +1285,7 @@ static ConnectionHolder create(@NotNull String addr, @NotNull Configuration conf
12641285 // Read all headers
12651286 }
12661287
1267- LOGGER .info ("Successfully connected to the HTTP proxy." );
1288+ LOGGER .info (String . format ( "Successfully connected to the %s proxy." , conf . proxySSL ? "HTTPS" : "HTTP" ) );
12681289 return new ConnectionHolder (sock );
12691290 case SOCKS :
12701291 if (conf .proxyAuth ) {
@@ -1399,4 +1420,50 @@ public void run() {
13991420 LOGGER .trace ("Session.Receiver stopped" );
14001421 }
14011422 }
1423+
1424+ /**
1425+ * A {@link SocketFactory} that delegates calls. Sockets can be configured after creation by
1426+ * overriding {@link #configureSocket(java.net.Socket)}.
1427+ *
1428+ * Copy/pasted from okhttp3 tests sources for HTTPS proxy support
1429+ */
1430+ public static class DelegatingSocketFactory extends SocketFactory {
1431+ private final SocketFactory delegate ;
1432+
1433+ public DelegatingSocketFactory (SocketFactory delegate ) {
1434+ this .delegate = delegate ;
1435+ }
1436+
1437+ @ Override public Socket createSocket () throws IOException {
1438+ Socket socket = delegate .createSocket ();
1439+ return configureSocket (socket );
1440+ }
1441+
1442+ @ Override public Socket createSocket (String host , int port ) throws IOException {
1443+ Socket socket = delegate .createSocket (host , port );
1444+ return configureSocket (socket );
1445+ }
1446+
1447+ @ Override public Socket createSocket (String host , int port , InetAddress localAddress ,
1448+ int localPort ) throws IOException {
1449+ Socket socket = delegate .createSocket (host , port , localAddress , localPort );
1450+ return configureSocket (socket );
1451+ }
1452+
1453+ @ Override public Socket createSocket (InetAddress host , int port ) throws IOException {
1454+ Socket socket = delegate .createSocket (host , port );
1455+ return configureSocket (socket );
1456+ }
1457+
1458+ @ Override public Socket createSocket (InetAddress host , int port , InetAddress localAddress ,
1459+ int localPort ) throws IOException {
1460+ Socket socket = delegate .createSocket (host , port , localAddress , localPort );
1461+ return configureSocket (socket );
1462+ }
1463+
1464+ protected Socket configureSocket (Socket socket ) throws IOException {
1465+ // No-op by default.
1466+ return socket ;
1467+ }
1468+ }
14021469}
0 commit comments