Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.

Commit 7863684

Browse files
committed
Introducing DefaultSslContextProvider.
Change-Id: I713ce8d6360e4619c88e0b567546fbf1260878c4
1 parent bc92311 commit 7863684

File tree

5 files changed

+334
-17
lines changed

5 files changed

+334
-17
lines changed

core-client/src/main/java/org/glassfish/jersey/client/JerseyClient.java

Lines changed: 94 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,20 +43,24 @@
4343
import java.lang.ref.ReferenceQueue;
4444
import java.lang.ref.WeakReference;
4545
import java.net.URI;
46+
import java.util.Iterator;
4647
import java.util.Map;
4748
import java.util.concurrent.LinkedBlockingDeque;
4849
import java.util.concurrent.atomic.AtomicBoolean;
4950
import java.util.logging.Level;
5051
import java.util.logging.Logger;
5152

52-
import javax.net.ssl.HostnameVerifier;
53-
import javax.net.ssl.SSLContext;
5453
import javax.ws.rs.core.Configuration;
5554
import javax.ws.rs.core.Link;
5655
import javax.ws.rs.core.UriBuilder;
5756

57+
import javax.net.ssl.HostnameVerifier;
58+
import javax.net.ssl.SSLContext;
59+
5860
import org.glassfish.jersey.SslConfigurator;
5961
import org.glassfish.jersey.client.internal.LocalizationMessages;
62+
import org.glassfish.jersey.client.spi.DefaultSslContextProvider;
63+
import org.glassfish.jersey.internal.ServiceFinder;
6064
import org.glassfish.jersey.internal.util.collection.UnsafeValue;
6165
import org.glassfish.jersey.internal.util.collection.Values;
6266

@@ -72,7 +76,15 @@
7276
public class JerseyClient implements javax.ws.rs.client.Client, Initializable<JerseyClient> {
7377
private static final Logger LOG = Logger.getLogger(JerseyClient.class.getName());
7478

79+
private static final DefaultSslContextProvider DEFAULT_SSL_CONTEXT_PROVIDER = new DefaultSslContextProvider() {
80+
@Override
81+
public SSLContext getDefaultSslContext() {
82+
return SslConfigurator.getDefaultContext();
83+
}
84+
};
85+
7586
private final AtomicBoolean closedFlag = new AtomicBoolean(false);
87+
private final boolean isDefaultSslContext;
7688
private final ClientConfig config;
7789
private final HostnameVerifier hostnameVerifier;
7890
private final UnsafeValue<SSLContext, IllegalStateException> sslContext;
@@ -83,7 +95,7 @@ public class JerseyClient implements javax.ws.rs.client.Client, Initializable<Je
8395
/**
8496
* Client instance shutdown hook.
8597
*/
86-
static interface ShutdownHook {
98+
interface ShutdownHook {
8799
/**
88100
* Invoked when the client instance is closed.
89101
*/
@@ -94,7 +106,7 @@ static interface ShutdownHook {
94106
* Create a new Jersey client instance using a default configuration.
95107
*/
96108
protected JerseyClient() {
97-
this(null, (UnsafeValue<SSLContext, IllegalStateException>) null, null);
109+
this(null, (UnsafeValue<SSLContext, IllegalStateException>) null, null, null);
98110
}
99111

100112
/**
@@ -107,7 +119,24 @@ protected JerseyClient() {
107119
protected JerseyClient(final Configuration config,
108120
final SSLContext sslContext,
109121
final HostnameVerifier verifier) {
110-
this(config, Values.<SSLContext, IllegalStateException>unsafe(sslContext), verifier);
122+
123+
this(config, sslContext, verifier, null);
124+
}
125+
126+
/**
127+
* Create a new Jersey client instance.
128+
*
129+
* @param config jersey client configuration.
130+
* @param sslContext jersey client SSL context.
131+
* @param verifier jersey client host name verifier.
132+
* @param defaultSslContextProvider default SSL context provider.
133+
*/
134+
protected JerseyClient(final Configuration config,
135+
final SSLContext sslContext,
136+
final HostnameVerifier verifier,
137+
final DefaultSslContextProvider defaultSslContextProvider) {
138+
this(config, sslContext == null ? null : Values.<SSLContext, IllegalStateException>unsafe(sslContext), verifier,
139+
defaultSslContextProvider);
111140
}
112141

113142
/**
@@ -120,18 +149,49 @@ protected JerseyClient(final Configuration config,
120149
protected JerseyClient(final Configuration config,
121150
final UnsafeValue<SSLContext, IllegalStateException> sslContextProvider,
122151
final HostnameVerifier verifier) {
123-
this.config = config == null ? new ClientConfig(this) : new ClientConfig(this, config);
124-
this.sslContext = Values.lazy(sslContextProvider != null ? sslContextProvider : createSslContextProvider());
125-
this.hostnameVerifier = verifier;
152+
this(config, sslContextProvider, verifier, null);
126153
}
127154

128-
private UnsafeValue<SSLContext, IllegalStateException> createSslContextProvider() {
129-
return new UnsafeValue<SSLContext, IllegalStateException>() {
130-
@Override
131-
public SSLContext get() {
132-
return SslConfigurator.getDefaultContext();
155+
/**
156+
* Create a new Jersey client instance.
157+
*
158+
* @param config jersey client configuration.
159+
* @param sslContextProvider jersey client SSL context provider. Non {@code null} provider is expected to
160+
* return non-default value.
161+
* @param verifier jersey client host name verifier.
162+
* @param defaultSslContextProvider default SSL context provider.
163+
*/
164+
protected JerseyClient(final Configuration config,
165+
final UnsafeValue<SSLContext, IllegalStateException> sslContextProvider,
166+
final HostnameVerifier verifier,
167+
final DefaultSslContextProvider defaultSslContextProvider) {
168+
this.config = config == null ? new ClientConfig(this) : new ClientConfig(this, config);
169+
170+
if (sslContextProvider == null) {
171+
this.isDefaultSslContext = true;
172+
173+
if (defaultSslContextProvider != null) {
174+
this.sslContext = createLazySslContext(defaultSslContextProvider);
175+
} else {
176+
final DefaultSslContextProvider lookedUpSslContextProvider;
177+
178+
final Iterator<DefaultSslContextProvider> iterator =
179+
ServiceFinder.find(DefaultSslContextProvider.class).iterator();
180+
181+
if (iterator.hasNext()) {
182+
lookedUpSslContextProvider = iterator.next();
183+
} else {
184+
lookedUpSslContextProvider = DEFAULT_SSL_CONTEXT_PROVIDER;
185+
}
186+
187+
this.sslContext = createLazySslContext(lookedUpSslContextProvider);
133188
}
134-
};
189+
} else {
190+
this.isDefaultSslContext = false;
191+
this.sslContext = Values.lazy(sslContextProvider);
192+
}
193+
194+
this.hostnameVerifier = verifier;
135195
}
136196

137197
@Override
@@ -145,7 +205,7 @@ private void release() {
145205
Reference<ShutdownHook> listenerRef;
146206
while ((listenerRef = shutdownHooks.pollFirst()) != null) {
147207
JerseyClient.ShutdownHook listener = listenerRef.get();
148-
if (listener != null){
208+
if (listener != null) {
149209
try {
150210
listener.onShutdown();
151211
} catch (Throwable t) {
@@ -155,6 +215,15 @@ private void release() {
155215
}
156216
}
157217

218+
private UnsafeValue<SSLContext, IllegalStateException> createLazySslContext(final DefaultSslContextProvider provider) {
219+
return Values.lazy(new UnsafeValue<SSLContext, IllegalStateException>() {
220+
@Override
221+
public SSLContext get() {
222+
return provider.getDefaultSslContext();
223+
}
224+
});
225+
}
226+
158227
/**
159228
* Register a new client shutdown hook.
160229
*
@@ -204,6 +273,16 @@ void checkNotClosed() {
204273
checkState(!closedFlag.get(), LocalizationMessages.CLIENT_INSTANCE_CLOSED());
205274
}
206275

276+
/**
277+
* Get information about used {@link SSLContext}.
278+
*
279+
* @return {@code true} when used {@code SSLContext} is acquired from {@link SslConfigurator#getDefaultContext()},
280+
* {@code false} otherwise.
281+
*/
282+
public boolean isDefaultSslContext() {
283+
return isDefaultSslContext;
284+
}
285+
207286
@Override
208287
public JerseyWebTarget target(final String uri) {
209288
checkNotClosed();

core-client/src/main/java/org/glassfish/jersey/client/internal/HttpUrlConnector.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import org.glassfish.jersey.client.ClientRequest;
7373
import org.glassfish.jersey.client.ClientResponse;
7474
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
75+
import org.glassfish.jersey.client.JerseyClient;
7576
import org.glassfish.jersey.client.RequestEntityProcessing;
7677
import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
7778
import org.glassfish.jersey.client.spi.Connector;
@@ -317,7 +318,7 @@ public void close() {
317318
* @param client client associated with this client runtime.
318319
* @param uc http connection to be secured.
319320
*/
320-
protected void secureConnection(final Client client, final HttpURLConnection uc) {
321+
protected void secureConnection(final JerseyClient client, final HttpURLConnection uc) {
321322
if (uc instanceof HttpsURLConnection) {
322323
HttpsURLConnection suc = (HttpsURLConnection) uc;
323324

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3+
*
4+
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
5+
*
6+
* The contents of this file are subject to the terms of either the GNU
7+
* General Public License Version 2 only ("GPL") or the Common Development
8+
* and Distribution License("CDDL") (collectively, the "License"). You
9+
* may not use this file except in compliance with the License. You can
10+
* obtain a copy of the License at
11+
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
12+
* or packager/legal/LICENSE.txt. See the License for the specific
13+
* language governing permissions and limitations under the License.
14+
*
15+
* When distributing the software, include this License Header Notice in each
16+
* file and include the License file at packager/legal/LICENSE.txt.
17+
*
18+
* GPL Classpath Exception:
19+
* Oracle designates this particular file as subject to the "Classpath"
20+
* exception as provided by Oracle in the GPL Version 2 section of the License
21+
* file that accompanied this code.
22+
*
23+
* Modifications:
24+
* If applicable, add the following below the License Header, with the fields
25+
* enclosed by brackets [] replaced by your own identifying information:
26+
* "Portions Copyright [year] [name of copyright owner]"
27+
*
28+
* Contributor(s):
29+
* If you wish your version of this file to be governed by only the CDDL or
30+
* only the GPL Version 2, indicate your decision by adding "[Contributor]
31+
* elects to include this software in this distribution under the [CDDL or GPL
32+
* Version 2] license." If you don't indicate a single choice of license, a
33+
* recipient has the option to distribute your version of this file under
34+
* either the CDDL, the GPL Version 2 or to extend the choice of license to
35+
* its licensees as provided above. However, if you add GPL Version 2 code
36+
* and therefore, elected the GPL Version 2 license, then the option applies
37+
* only if the new code is made subject to such option by the copyright
38+
* holder.
39+
*/
40+
41+
package org.glassfish.jersey.client.spi;
42+
43+
import javax.net.ssl.SSLContext;
44+
45+
import org.glassfish.jersey.SslConfigurator;
46+
47+
/**
48+
* Default {@link SSLContext} provider.
49+
* <p/>
50+
* Can be used to override {@link SslConfigurator#getDefaultContext()}.
51+
*
52+
* @author Pavel Bucek (pavel.bucek at oracle.com)
53+
*/
54+
public interface DefaultSslContextProvider {
55+
56+
/**
57+
* Get default {@code SSLContext}.
58+
* <p/>
59+
* Returned instance is expected to be configured to container default values.
60+
*
61+
* @return default SSL context.
62+
* @throws IllegalStateException when there is a problem with creating or obtaining default SSL context.
63+
*/
64+
SSLContext getDefaultSslContext();
65+
}

0 commit comments

Comments
 (0)