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

Commit d94ca2b

Browse files
committed
OWLS-25757: Provide a way how to customize securing HttpUrlConnection instance.
Change-Id: Ibda9de73fb5bc844d617fa8248e4626878982efa
1 parent 526599a commit d94ca2b

File tree

12 files changed

+361
-25
lines changed

12 files changed

+361
-25
lines changed

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
package org.glassfish.jersey.client;
4242

4343
import java.util.Collection;
44+
import java.util.Iterator;
4445
import java.util.Map;
4546
import java.util.Set;
4647

@@ -54,6 +55,7 @@
5455
import org.glassfish.jersey.client.internal.LocalizationMessages;
5556
import org.glassfish.jersey.client.spi.Connector;
5657
import org.glassfish.jersey.client.spi.ConnectorProvider;
58+
import org.glassfish.jersey.internal.ServiceFinder;
5759
import org.glassfish.jersey.internal.inject.Injections;
5860
import org.glassfish.jersey.internal.inject.JerseyClassAnalyzer;
5961
import org.glassfish.jersey.internal.inject.ProviderBinder;
@@ -147,7 +149,12 @@ private static interface StateChangeStrategy {
147149
this.strategy = IDENTITY;
148150
this.commonConfig = new CommonConfig(RuntimeType.CLIENT, ComponentBag.EXCLUDE_EMPTY);
149151
this.client = client;
150-
this.connectorProvider = new HttpUrlConnectorProvider();
152+
final Iterator<ConnectorProvider> iterator = ServiceFinder.find(ConnectorProvider.class).iterator();
153+
if (iterator.hasNext()) {
154+
this.connectorProvider = iterator.next();
155+
} else {
156+
this.connectorProvider = new HttpUrlConnectorProvider();
157+
}
151158
}
152159

153160
/**

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import java.util.Map;
4343

4444
import org.glassfish.jersey.CommonProperties;
45+
import org.glassfish.jersey.client.internal.HttpUrlConnector;
4546
import org.glassfish.jersey.internal.util.PropertiesClass;
4647
import org.glassfish.jersey.internal.util.PropertiesHelper;
4748
import org.glassfish.jersey.internal.util.PropertyAlias;

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

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import javax.ws.rs.client.Client;
4949
import javax.ws.rs.core.Configuration;
5050

51+
import org.glassfish.jersey.client.internal.HttpUrlConnector;
5152
import org.glassfish.jersey.client.internal.LocalizationMessages;
5253
import org.glassfish.jersey.client.spi.Connector;
5354
import org.glassfish.jersey.client.spi.ConnectorProvider;
@@ -149,7 +150,6 @@ public HttpUrlConnectorProvider() {
149150
this.useSetMethodWorkaround = false;
150151
}
151152

152-
153153
/**
154154
* Set a custom {@link java.net.HttpURLConnection} factory.
155155
*
@@ -237,12 +237,33 @@ public Connector getConnector(final Client client, final Configuration config) {
237237
final boolean computedUseSetMethodWorkaround = ClientProperties.getValue(properties,
238238
SET_METHOD_WORKAROUND, useSetMethodWorkaround, Boolean.class);
239239

240+
return createHttpUrlConnector(client, connectionFactory, computedChunkSize, computedUseFixedLengthStreaming,
241+
computedUseSetMethodWorkaround);
242+
}
243+
244+
/**
245+
* Create {@link HttpUrlConnector}.
246+
*
247+
* @param client JAX-RS client instance for which the connector is being created.
248+
* @param connectionFactory {@link javax.net.ssl.HttpsURLConnection} factory to be used when creating
249+
* connections.
250+
* @param chunkSize chunk size to use when using HTTP chunked transfer coding.
251+
* @param fixLengthStreaming specify if the the {@link java.net.HttpURLConnection#setFixedLengthStreamingMode(int)
252+
* fixed-length streaming mode} on the underlying HTTP URL connection instances should
253+
* be used when sending requests.
254+
* @param setMethodWorkaround specify if the reflection workaround should be used to set HTTP URL connection method
255+
* name. See {@link HttpUrlConnectorProvider#SET_METHOD_WORKAROUND} for details.
256+
* @return created {@link HttpUrlConnector} instance.
257+
*/
258+
protected Connector createHttpUrlConnector(Client client, ConnectionFactory connectionFactory,
259+
int chunkSize, boolean fixLengthStreaming,
260+
boolean setMethodWorkaround) {
240261
return new HttpUrlConnector(
241262
client,
242263
connectionFactory,
243-
computedChunkSize,
244-
computedUseFixedLengthStreaming,
245-
computedUseSetMethodWorkaround);
264+
chunkSize,
265+
fixLengthStreaming,
266+
setMethodWorkaround);
246267
}
247268

248269
/**

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

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* only if the new code is made subject to such option by the copyright
3838
* holder.
3939
*/
40-
package org.glassfish.jersey.client;
40+
package org.glassfish.jersey.client.internal;
4141

4242
import java.io.ByteArrayInputStream;
4343
import java.io.IOException;
@@ -68,7 +68,11 @@
6868
import javax.net.ssl.HttpsURLConnection;
6969
import javax.net.ssl.SSLSocketFactory;
7070

71-
import org.glassfish.jersey.client.internal.LocalizationMessages;
71+
import org.glassfish.jersey.client.ClientProperties;
72+
import org.glassfish.jersey.client.ClientRequest;
73+
import org.glassfish.jersey.client.ClientResponse;
74+
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
75+
import org.glassfish.jersey.client.RequestEntityProcessing;
7276
import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
7377
import org.glassfish.jersey.client.spi.Connector;
7478
import org.glassfish.jersey.internal.util.PropertiesHelper;
@@ -88,7 +92,7 @@
8892
*
8993
* @author Marek Potociar (marek.potociar at oracle.com)
9094
*/
91-
class HttpUrlConnector implements Connector {
95+
public class HttpUrlConnector implements Connector {
9296

9397
private static final Logger LOGGER = Logger.getLogger(HttpUrlConnector.class.getName());
9498
private static final String ALLOW_RESTRICTED_HEADERS_SYSTEM_PROPERTY = "sun.net.http.allowRestrictedHeaders";
@@ -135,7 +139,7 @@ class HttpUrlConnector implements Connector {
135139
* @param setMethodWorkaround specify if the reflection workaround should be used to set HTTP URL connection method
136140
* name. See {@link HttpUrlConnectorProvider#SET_METHOD_WORKAROUND} for details.
137141
*/
138-
HttpUrlConnector(
142+
public HttpUrlConnector(
139143
final Client client,
140144
final HttpUrlConnectorProvider.ConnectionFactory connectionFactory,
141145
final int chunkSize,
@@ -266,6 +270,27 @@ public void close() {
266270
// do nothing
267271
}
268272

273+
/**
274+
* Secure connection if necessary.
275+
* <p/>
276+
* Provided implementation sets {@link HostnameVerifier} and {@link SSLSocketFactory} to give connection, if that
277+
* is an instance of {@link HttpsURLConnection}.
278+
*
279+
* @param client client associated with this client runtime.
280+
* @param uc http connection to be secured.
281+
*/
282+
protected void secureConnection(final Client client, final HttpURLConnection uc) {
283+
if (uc instanceof HttpsURLConnection) {
284+
HttpsURLConnection suc = (HttpsURLConnection) uc;
285+
286+
final HostnameVerifier verifier = client.getHostnameVerifier();
287+
if (verifier != null) {
288+
suc.setHostnameVerifier(verifier);
289+
}
290+
suc.setSSLSocketFactory(sslSocketFactory.get());
291+
}
292+
}
293+
269294
private ClientResponse _apply(final ClientRequest request) throws IOException {
270295
final HttpURLConnection uc;
271296

@@ -285,16 +310,7 @@ private ClientResponse _apply(final ClientRequest request) throws IOException {
285310

286311
uc.setReadTimeout(request.resolveProperty(ClientProperties.READ_TIMEOUT, uc.getReadTimeout()));
287312

288-
if (uc instanceof HttpsURLConnection) {
289-
HttpsURLConnection suc = (HttpsURLConnection) uc;
290-
291-
final JerseyClient client = request.getClient();
292-
final HostnameVerifier verifier = client.getHostnameVerifier();
293-
if (verifier != null) {
294-
suc.setHostnameVerifier(verifier);
295-
}
296-
suc.setSSLSocketFactory(sslSocketFactory.get());
297-
}
313+
secureConnection(request.getClient(), uc);
298314

299315
final Object entity = request.getEntity();
300316
if (entity != null) {
@@ -397,10 +413,11 @@ private boolean isHeaderRestricted(String name, String value) {
397413
* The implementation of Sun/Oracle is throwing a {@code ProtocolException}
398414
* when the method is not in the list of the HTTP/1.1 default methods.
399415
* This means that to use e.g. {@code PROPFIND} and others, we must apply this workaround.
400-
*
416+
* <p/>
401417
* See issue http://java.net/jira/browse/JERSEY-639
402418
*/
403-
private static void setRequestMethodViaJreBugWorkaround(final HttpURLConnection httpURLConnection, final String method) {
419+
private static void setRequestMethodViaJreBugWorkaround(final HttpURLConnection httpURLConnection,
420+
final String method) {
404421
try {
405422
httpURLConnection.setRequestMethod(method); // Check whether we are running on a buggy JRE
406423
} catch (final ProtocolException pe) {
@@ -443,8 +460,7 @@ public Object run() throws NoSuchFieldException,
443460
continue;
444461
}
445462
methodField.setAccessible(true);
446-
methodField.set(httpURLConnection,
447-
method);
463+
methodField.set(httpURLConnection, method);
448464
break;
449465
}
450466
} catch (final Exception e) {

core-client/src/test/java/org/glassfish/jersey/client/HttpUrlConnectorTest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33
*
4-
* Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2013-2015 Oracle and/or its affiliates. All rights reserved.
55
*
66
* The contents of this file are subject to the terms of either the GNU
77
* General Public License Version 2 only ("GPL") or the Common Development
@@ -67,6 +67,8 @@
6767
import javax.net.ssl.SSLPeerUnverifiedException;
6868
import javax.net.ssl.SSLSocketFactory;
6969

70+
import org.glassfish.jersey.client.internal.HttpUrlConnector;
71+
7072
import org.junit.Assert;
7173
import org.junit.Ignore;
7274
import org.junit.Test;

tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/server/ContentNegotiationTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import javax.xml.bind.annotation.XmlRootElement;
5151

5252
import org.glassfish.jersey.client.ClientConfig;
53+
import org.glassfish.jersey.client.internal.HttpUrlConnector;
5354
import org.glassfish.jersey.filter.LoggingFilter;
5455
import org.glassfish.jersey.server.ResourceConfig;
5556
import org.glassfish.jersey.test.JerseyTest;
@@ -176,7 +177,7 @@ protected Application configure() {
176177
}
177178

178179
/**
179-
* {@link org.glassfish.jersey.client.HttpUrlConnector} by default adds some media types
180+
* {@link HttpUrlConnector} by default adds some media types
180181
* to the Accept header if we don't specify them.
181182
*/
182183
@Test
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
5+
6+
Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
7+
8+
The contents of this file are subject to the terms of either the GNU
9+
General Public License Version 2 only ("GPL") or the Common Development
10+
and Distribution License("CDDL") (collectively, the "License"). You
11+
may not use this file except in compliance with the License. You can
12+
obtain a copy of the License at
13+
http://glassfish.java.net/public/CDDL+GPL_1_1.html
14+
or packager/legal/LICENSE.txt. See the License for the specific
15+
language governing permissions and limitations under the License.
16+
17+
When distributing the software, include this License Header Notice in each
18+
file and include the License file at packager/legal/LICENSE.txt.
19+
20+
GPL Classpath Exception:
21+
Oracle designates this particular file as subject to the "Classpath"
22+
exception as provided by Oracle in the GPL Version 2 section of the License
23+
file that accompanied this code.
24+
25+
Modifications:
26+
If applicable, add the following below the License Header, with the fields
27+
enclosed by brackets [] replaced by your own identifying information:
28+
"Portions Copyright [year] [name of copyright owner]"
29+
30+
Contributor(s):
31+
If you wish your version of this file to be governed by only the CDDL or
32+
only the GPL Version 2, indicate your decision by adding "[Contributor]
33+
elects to include this software in this distribution under the [CDDL or GPL
34+
Version 2] license." If you don't indicate a single choice of license, a
35+
recipient has the option to distribute your version of this file under
36+
either the CDDL, the GPL Version 2 or to extend the choice of license to
37+
its licensees as provided above. However, if you add GPL Version 2 code
38+
and therefore, elected the GPL Version 2 license, then the option applies
39+
only if the new code is made subject to such option by the copyright
40+
holder.
41+
42+
-->
43+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
44+
<modelVersion>4.0.0</modelVersion>
45+
<parent>
46+
<groupId>org.glassfish.jersey.tests.integration</groupId>
47+
<artifactId>project</artifactId>
48+
<version>2.20-SNAPSHOT</version>
49+
</parent>
50+
51+
<artifactId>client-connector-provider</artifactId>
52+
<packaging>jar</packaging>
53+
<name>client-connector-provider</name>
54+
55+
<description>Client Connector provider test</description>
56+
57+
<dependencies>
58+
<dependency>
59+
<groupId>javax.ws.rs</groupId>
60+
<artifactId>javax.ws.rs-api</artifactId>
61+
<scope>provided</scope>
62+
</dependency>
63+
<dependency>
64+
<groupId>javax.annotation</groupId>
65+
<artifactId>javax.annotation-api</artifactId>
66+
<scope>provided</scope>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.glassfish.jersey.core</groupId>
70+
<artifactId>jersey-client</artifactId>
71+
<scope>provided</scope>
72+
</dependency>
73+
<dependency>
74+
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
75+
<artifactId>jersey-test-framework-provider-bundle</artifactId>
76+
<type>pom</type>
77+
<scope>test</scope>
78+
</dependency>
79+
</dependencies>
80+
<build>
81+
<finalName>${project.artifactId}</finalName>
82+
</build>
83+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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.tests.integration.client.connector.provider;
42+
43+
import java.net.HttpURLConnection;
44+
45+
import javax.ws.rs.client.Client;
46+
47+
import org.glassfish.jersey.client.HttpUrlConnectorProvider;
48+
import org.glassfish.jersey.client.internal.HttpUrlConnector;
49+
import org.glassfish.jersey.client.spi.Connector;
50+
51+
/**
52+
* @author Pavel Bucek (pavel.bucek at oracle.com)
53+
*/
54+
public final class CustomConnectorProvider extends HttpUrlConnectorProvider {
55+
56+
public static volatile boolean invoked = false;
57+
58+
@Override
59+
protected Connector createHttpUrlConnector(Client client, ConnectionFactory connectionFactory, int chunkSize,
60+
boolean fixLengthStreaming, boolean setMethodWorkaround) {
61+
62+
return new HttpUrlConnector(
63+
client,
64+
connectionFactory,
65+
chunkSize,
66+
fixLengthStreaming,
67+
setMethodWorkaround) {
68+
69+
@Override
70+
protected void secureConnection(Client client, HttpURLConnection uc) {
71+
invoked = true;
72+
}
73+
};
74+
}
75+
}

0 commit comments

Comments
 (0)