Skip to content

Commit dc35123

Browse files
committed
HTTP/2 for JNH connector
Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
1 parent 050f93b commit dc35123

File tree

5 files changed

+126
-2
lines changed

5 files changed

+126
-2
lines changed

connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpClientProperties.java

+11
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,17 @@ public class JavaNetHttpClientProperties {
8585
public static final String DISABLE_COOKIES =
8686
"jersey.config.jnh.client.disableCookies";
8787

88+
/**
89+
* HTTP version - if null or instance of HttpClient.Version.HTTP_1_1 the version will be set to HTTP_1_1
90+
* if version is HttpClient.Version.HTTP_2 the client will attempt to perform each request using HTTP_2 protocol
91+
* but if not supported by server, the protocol will be still HTTP_1_1
92+
*
93+
* @since 3.1.4
94+
*/
95+
public static final String HTTP_VERSION =
96+
"jersey.config.jnh.client.httpVersion";
97+
98+
8899
/**
89100
* Prevent this class from instantiation.
90101
*/

connectors/jnh-connector/src/main/java/org/glassfish/jersey/jnh/connector/JavaNetHttpConnector.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,10 @@ public class JavaNetHttpConnector implements Connector {
8383
* @param configuration the configuration properties for this connector
8484
*/
8585
public JavaNetHttpConnector(final Client client, final Configuration configuration) {
86-
HttpClient.Builder httpClientBuilder = HttpClient.newBuilder();
87-
httpClientBuilder.version(HttpClient.Version.HTTP_1_1);
86+
final HttpClient.Builder httpClientBuilder = HttpClient.newBuilder();
87+
final HttpClient.Version version =
88+
getPropertyOrNull(configuration, JavaNetHttpClientProperties.HTTP_VERSION, HttpClient.Version.class);
89+
httpClientBuilder.version(version == null ? HttpClient.Version.HTTP_1_1 : version);
8890
SSLContext sslContext = client.getSslContext();
8991
if (sslContext != null) {
9092
httpClientBuilder.sslContext(sslContext);
@@ -230,6 +232,9 @@ private <T> T getPropertyOrNull(final Configuration configuration, final String
230232
if (propertyObject == null) {
231233
return null;
232234
}
235+
if (resultClass.isEnum() && propertyObject instanceof String) {
236+
return (T) Enum.valueOf(resultClass.asSubclass(Enum.class), (String) propertyObject);
237+
}
233238
if (!resultClass.isInstance(propertyObject)) {
234239
LOGGER.warning(LocalizationMessages.ERROR_INVALID_CLASS(propertyKey, resultClass.getName()));
235240
return null;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.jnh.connector;
18+
19+
import jakarta.ws.rs.GET;
20+
import jakarta.ws.rs.Path;
21+
import jakarta.ws.rs.core.Application;
22+
import jakarta.ws.rs.core.Context;
23+
import jakarta.ws.rs.core.HttpHeaders;
24+
import org.glassfish.jersey.client.ClientConfig;
25+
import org.glassfish.jersey.client.spi.ConnectorProvider;
26+
import org.glassfish.jersey.logging.LoggingFeature;
27+
import org.glassfish.jersey.server.ResourceConfig;
28+
import org.glassfish.jersey.test.JerseyTest;
29+
import org.junit.jupiter.api.Test;
30+
31+
import java.net.http.HttpClient;
32+
import java.util.List;
33+
import java.util.logging.Logger;
34+
35+
import static java.net.http.HttpClient.Version.HTTP_2;
36+
import static org.junit.jupiter.api.Assertions.assertEquals;
37+
import static org.junit.jupiter.api.Assertions.assertTrue;
38+
39+
/**
40+
* Tests the HTTP2 presence.
41+
*
42+
*/
43+
public class Http2PresenceTest extends JerseyTest {
44+
45+
private static final Logger LOGGER = Logger.getLogger(Http2PresenceTest.class.getName());
46+
47+
@Path("/test")
48+
public static class HttpMethodResource {
49+
50+
@GET
51+
public String testUserAgent(@Context HttpHeaders httpHeaders) {
52+
final List<String> requestHeader = httpHeaders.getRequestHeader(HttpHeaders.USER_AGENT);
53+
if (requestHeader.size() != 1) {
54+
return "FAIL";
55+
}
56+
return requestHeader.get(0);
57+
}
58+
}
59+
60+
@Override
61+
protected Application configure() {
62+
ResourceConfig config = new ResourceConfig(HttpMethodResource.class);
63+
config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
64+
return config;
65+
}
66+
67+
@Override
68+
protected void configureClient(ClientConfig config) {
69+
config.property(JavaNetHttpClientProperties.HTTP_VERSION, HTTP_2).connectorProvider(new JavaNetHttpConnectorProvider());
70+
}
71+
72+
@Test
73+
public void testHttp2Presence() {
74+
final ConnectorProvider provider = ((ClientConfig) target().getConfiguration()).getConnectorProvider();
75+
assertTrue(provider instanceof JavaNetHttpConnectorProvider);
76+
77+
final HttpClient client = ((JavaNetHttpConnectorProvider) provider).getHttpClient(target());
78+
assertEquals(HTTP_2, client.version());
79+
}
80+
81+
/**
82+
* Test, that {@code User-agent} header is as set by Jersey, not by underlying Jetty client.
83+
*/
84+
@Test
85+
public void testUserAgent() {
86+
String response = target().path("test").request().get(String.class);
87+
assertTrue(response.startsWith("Jersey"), "User-agent header should start with 'Jersey', but was " + response);
88+
}
89+
}

docs/src/main/docbook/appendix-properties.xml

+18
Original file line numberDiff line numberDiff line change
@@ -2119,6 +2119,24 @@
21192119
</para>
21202120
</entry>
21212121
</row>
2122+
<row>
2123+
<entry>&jersey.jnh.JavaNetHttpClientProperties.HTTP_VERSION;</entry>
2124+
<entry><literal>jersey.config.jnh.client.httpVersion</literal></entry>
2125+
<entry>
2126+
<para>
2127+
HTTP version - if null or instance of HttpClient.Version.HTTP_1_1
2128+
the version will be set to HTTP_1_1. If version is HttpClient.Version.HTTP_2
2129+
the client will attempt to perform each request using HTTP_2 protocol
2130+
but if not supported by server, the protocol will be still HTTP_1_1
2131+
</para>
2132+
<para>
2133+
The value MUST be an instance of <literal>java.net.http.HttpClient.Version</literal>.
2134+
</para>
2135+
<para>
2136+
The default value is &lit.null;.
2137+
</para>
2138+
</entry>
2139+
</row>
21222140
</tbody>
21232141
</tgroup>
21242142
</table>

docs/src/main/docbook/jersey.ent

+1
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@
493493
<!ENTITY jersey.jnh.JavaNetHttpClientProperties.SSL_PARAMETERS "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#SSL_PARAMETERS'>JavaNetHttpClientProperties.SSL_PARAMETERS</link>">
494494
<!ENTITY jersey.jnh.JavaNetHttpClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#PREEMPTIVE_BASIC_AUTHENTICATION'>JavaNetHttpClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION</link>">
495495
<!ENTITY jersey.jnh.JavaNetHttpClientProperties.DISABLE_COOKIES "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#DISABLE_COOKIES'>JavaNetHttpClientProperties.DISABLE_COOKIES</link>">
496+
<!ENTITY jersey.jnh.JavaNetHttpClientProperties.HTTP_VERSION "<link xlink:href='&jersey.javadoc.uri.prefix;/jnh/connector/JavaNetHttpClientProperties.html#HTTP_VERSION'>JavaNetHttpClientProperties.HTTP_VERSION</link>">
496497
<!ENTITY jersey.linking.DeclarativeLinkingFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/linking/DeclarativeLinkingFeature.html'>DeclarativeLinkingFeature</link>">
497498
<!ENTITY jersey.logging.LoggingFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html'>LoggingFeature</link>">
498499
<!ENTITY jersey.logging.LoggingFeature.DEFAULT_LOGGER_NAME "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#DEFAULT_LOGGER_NAME'>LoggingFeature.DEFAULT_LOGGER_NAME</link>">

0 commit comments

Comments
 (0)