View Javadoc
1   package org.metricshub.http;
2   
3   /*-
4    * ╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲
5    * HTTP Java Client
6    * ჻჻჻჻჻჻
7    * Copyright (C) 2023 MetricsHub
8    * ჻჻჻჻჻჻
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   *
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * ╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱╲╱
21   */
22  
23  import java.io.IOException;
24  import java.net.InetAddress;
25  import java.net.Socket;
26  import javax.net.ssl.SSLSocket;
27  import javax.net.ssl.SSLSocketFactory;
28  
29  /**
30   * A {@link SSLSocketFactory} which uses an existing {@link SSLSocketFactory} to delegate its operations to and overrides the
31   * {@link javax.net.ssl.SSLSocket#getEnabledProtocols() enabled protocols} to the protocols that were passed to its
32   * {@link #ProtocolOverridingSSLSocketFactory(javax.net.ssl.SSLSocketFactory, String[]) constructor}
33   *
34   */
35  public class ProtocolOverridingSSLSocketFactory extends SSLSocketFactory {
36  
37  	private final SSLSocketFactory underlyingSSLSocketFactory;
38  	private final String[] enabledProtocols;
39  
40  	/**
41  	 * Constructs a {@code ProtocolOverridingSSLSocketFactory} with the given
42  	 * delegate {@link SSLSocketFactory} and array of enabled protocols.
43  	 *
44  	 * @param delegate         The underlying {@link SSLSocketFactory} to delegate operations to.
45  	 * @param enabledProtocols The array of protocols to be set as enabled protocols.
46  	 */
47  	public ProtocolOverridingSSLSocketFactory(final SSLSocketFactory delegate, final String[] enabledProtocols) {
48  		this.underlyingSSLSocketFactory = delegate;
49  		this.enabledProtocols = enabledProtocols;
50  	}
51  
52  	@Override
53  	public String[] getDefaultCipherSuites() {
54  		return underlyingSSLSocketFactory.getDefaultCipherSuites();
55  	}
56  
57  	@Override
58  	public String[] getSupportedCipherSuites() {
59  		return underlyingSSLSocketFactory.getSupportedCipherSuites();
60  	}
61  
62  	@Override
63  	public Socket createSocket(final Socket socket, final String host, final int port, final boolean autoClose)
64  		throws IOException {
65  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(socket, host, port, autoClose);
66  		return overrideProtocol(underlyingSocket);
67  	}
68  
69  	@Override
70  	public Socket createSocket(final String host, final int port) throws IOException {
71  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(host, port);
72  		return overrideProtocol(underlyingSocket);
73  	}
74  
75  	@Override
76  	public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort)
77  		throws IOException {
78  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(host, port, localAddress, localPort);
79  		return overrideProtocol(underlyingSocket);
80  	}
81  
82  	@Override
83  	public Socket createSocket(final InetAddress host, final int port) throws IOException {
84  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(host, port);
85  		return overrideProtocol(underlyingSocket);
86  	}
87  
88  	@Override
89  	public Socket createSocket(
90  		final InetAddress host,
91  		final int port,
92  		final InetAddress localAddress,
93  		final int localPort
94  	) throws IOException {
95  		Socket underlyingSocket = underlyingSSLSocketFactory.createSocket(host, port, localAddress, localPort);
96  		return overrideProtocol(underlyingSocket);
97  	}
98  
99  	/**
100 	 * Set the {@link javax.net.ssl.SSLSocket#getEnabledProtocols() enabled protocols} to {@link #enabledProtocols} if the <code>socket</code> is a
101 	 * {@link SSLSocket}
102 	 *
103 	 * @param socket The Socket
104 	 * @return the amended socket
105 	 **/
106 	private Socket overrideProtocol(final Socket socket) {
107 		if (socket instanceof SSLSocket && enabledProtocols != null && enabledProtocols.length > 0) {
108 			((SSLSocket) socket).setEnabledProtocols(enabledProtocols);
109 		}
110 		return socket;
111 	}
112 }