Skip to content

Commit 1984af3

Browse files
authored
merge of the current 2.x into the 3.0
2 parents 2f1c88e + 83bb4b1 commit 1984af3

File tree

21 files changed

+440
-155
lines changed

21 files changed

+440
-155
lines changed

containers/jdk-http/pom.xml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<!--
33
4-
Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved.
4+
Copyright (c) 2010, 2025 Oracle and/or its affiliates. All rights reserved.
55
66
This program and the accompanying materials are made available under the
77
terms of the Eclipse Public License v. 2.0, which is available at
@@ -33,12 +33,6 @@
3333
<description>JDK Http Container</description>
3434

3535
<dependencies>
36-
<dependency>
37-
<groupId>commons-io</groupId>
38-
<artifactId>commons-io</artifactId>
39-
<scope>test</scope>
40-
<version>${commons.io.version}</version>
41-
</dependency>
4236
<dependency>
4337
<groupId>org.hamcrest</groupId>
4438
<artifactId>hamcrest</artifactId>

containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2023 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2025 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -30,9 +30,9 @@
3030
import javax.net.ssl.SSLContext;
3131
import javax.net.ssl.SSLHandshakeException;
3232

33-
import org.apache.commons.io.IOUtils;
3433
import org.glassfish.jersey.SslConfigurator;
3534
import org.glassfish.jersey.internal.util.JdkVersion;
35+
import org.glassfish.jersey.message.internal.ReaderWriter;
3636
import org.glassfish.jersey.server.ResourceConfig;
3737

3838
import org.junit.jupiter.api.AfterEach;
@@ -195,9 +195,9 @@ private SSLContext getClientSslContext() throws IOException {
195195

196196

197197
final SslConfigurator sslConfigClient = SslConfigurator.newInstance()
198-
.trustStoreBytes(IOUtils.toByteArray(trustStore))
198+
.trustStoreBytes(ReaderWriter.readFromAsBytes(trustStore))
199199
.trustStorePassword(TRUSTSTORE_CLIENT_PWD)
200-
.keyStoreBytes(IOUtils.toByteArray(keyStore))
200+
.keyStoreBytes(ReaderWriter.readFromAsBytes(keyStore))
201201
.keyPassword(KEYSTORE_CLIENT_PWD);
202202

203203
return sslConfigClient.createSSLContext();
@@ -208,9 +208,9 @@ private SSLContext getServerSslContext() throws IOException {
208208
final InputStream keyStore = JdkHttpsServerTest.class.getResourceAsStream(KEYSTORE_SERVER_FILE);
209209

210210
final SslConfigurator sslConfigServer = SslConfigurator.newInstance()
211-
.keyStoreBytes(IOUtils.toByteArray(keyStore))
211+
.keyStoreBytes(ReaderWriter.readFromAsBytes(keyStore))
212212
.keyPassword(KEYSTORE_SERVER_PWD)
213-
.trustStoreBytes(IOUtils.toByteArray(trustStore))
213+
.trustStoreBytes(ReaderWriter.readFromAsBytes(trustStore))
214214
.trustStorePassword(TRUSTSTORE_SERVER_PWD);
215215

216216
return sslConfigServer.createSSLContext();

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@ public class ClientResponse extends InboundMessageContext implements ClientRespo
6363
* @param response JAX-RS response to be used to initialize the response context.
6464
*/
6565
public ClientResponse(final ClientRequest requestContext, final Response response) {
66-
this(response.getStatusInfo(), requestContext);
67-
this.headers(OutboundJaxrsResponse.from(response, requestContext.getConfiguration()).getContext().getStringHeaders());
66+
super(requestContext.getConfiguration(),
67+
OutboundJaxrsResponse.from(response, requestContext.getConfiguration()).getContext().getStringHeaders(),
68+
false
69+
);
70+
this.requestContext = requestContext;
71+
init(response.getStatusInfo(), requestContext, requestContext.getUri());
6872

6973
final Object entity = response.getEntity();
7074
if (entity != null) {
@@ -122,10 +126,13 @@ public ClientResponse(Response.StatusType status, ClientRequest requestContext)
122126
*/
123127
public ClientResponse(Response.StatusType status, ClientRequest requestContext, URI resolvedRequestUri) {
124128
super(requestContext.getConfiguration());
125-
this.status = status;
126-
this.resolvedUri = resolvedRequestUri;
127129
this.requestContext = requestContext;
130+
init(status, requestContext, resolvedRequestUri);
131+
}
128132

133+
private void init(Response.StatusType status, ClientRequest requestContext, URI resolvedRequestUri) {
134+
this.status = status;
135+
this.resolvedUri = resolvedRequestUri;
129136
setWorkers(requestContext.getWorkers());
130137
}
131138

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

Lines changed: 187 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,30 @@
1616

1717
package org.glassfish.jersey.client;
1818

19+
import org.junit.jupiter.api.Assertions;
1920
import org.junit.jupiter.api.Test;
2021

22+
import jakarta.ws.rs.Priorities;
2123
import jakarta.ws.rs.Produces;
2224
import jakarta.ws.rs.WebApplicationException;
2325
import jakarta.ws.rs.client.Client;
2426
import jakarta.ws.rs.client.ClientBuilder;
2527
import jakarta.ws.rs.client.ClientRequestContext;
2628
import jakarta.ws.rs.client.ClientRequestFilter;
29+
import jakarta.ws.rs.client.ClientResponseContext;
30+
import jakarta.ws.rs.client.ClientResponseFilter;
31+
import jakarta.ws.rs.core.Application;
2732
import jakarta.ws.rs.core.GenericEntity;
33+
import jakarta.ws.rs.core.Link;
2834
import jakarta.ws.rs.core.MediaType;
2935
import jakarta.ws.rs.core.MultivaluedMap;
3036
import jakarta.ws.rs.core.Response;
37+
import jakarta.ws.rs.core.UriBuilder;
38+
import jakarta.ws.rs.core.Variant;
3139
import jakarta.ws.rs.ext.MessageBodyWriter;
40+
import jakarta.ws.rs.ext.ReaderInterceptor;
41+
import jakarta.ws.rs.ext.ReaderInterceptorContext;
42+
import jakarta.ws.rs.ext.RuntimeDelegate;
3243
import java.io.IOException;
3344
import java.io.OutputStream;
3445
import java.lang.annotation.Annotation;
@@ -37,18 +48,25 @@
3748
import java.nio.charset.StandardCharsets;
3849
import java.util.ArrayList;
3950
import java.util.Arrays;
51+
import java.util.Collections;
52+
import java.util.Iterator;
4053
import java.util.List;
54+
import java.util.Map;
55+
import java.util.concurrent.atomic.AtomicReference;
4156

42-
//import static java.nio.charset.StandardCharsets;
4357
import static org.junit.jupiter.api.Assertions.assertEquals;
4458

4559
public class AbortTest {
4660
private static final String TEXT_CSV = "text/csv";
61+
private static final String TEXT_HEADER = "text/header";
4762
private static final String EXPECTED_CSV = "hello;goodbye\nsalutations;farewell";
4863
private static final List<List<String>> CSV_LIST = Arrays.asList(
4964
Arrays.asList("hello", "goodbye"),
5065
Arrays.asList("salutations", "farewell")
5166
);
67+
private final String entity = "HI";
68+
private final String header = "CUSTOM_HEADER";
69+
5270

5371
@Test
5472
void testAbortWithGenericEntity() {
@@ -77,7 +95,6 @@ public static class CsvWriter implements MessageBodyWriter<List<List<String>>> {
7795

7896
@Override
7997
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
80-
System.out.println(genericType.getTypeName());
8198
return List.class.isAssignableFrom(type) && genericType instanceof ParameterizedType
8299
&& ((ParameterizedType) genericType).getActualTypeArguments()[0] instanceof ParameterizedType
83100
&& String.class.equals(((ParameterizedType) ((ParameterizedType) genericType).getActualTypeArguments()[0])
@@ -99,4 +116,172 @@ public void writeTo(List<List<String>> csvList, Class<?> type, Type genericType,
99116
}
100117
}
101118

119+
@Test
120+
void testAbortWithMBWWritingHeaders() {
121+
try (Response response = ClientBuilder.newClient().register(new ClientRequestFilter() {
122+
@Override
123+
public void filter(ClientRequestContext requestContext) throws IOException {
124+
requestContext.abortWith(Response.ok(entity, TEXT_HEADER).build());
125+
}
126+
}).register(new MessageBodyWriter<String>() {
127+
128+
@Override
129+
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
130+
return mediaType.toString().equals(TEXT_HEADER);
131+
}
132+
133+
@Override
134+
public void writeTo(String s, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
135+
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException,
136+
WebApplicationException {
137+
httpHeaders.add(header, entity);
138+
entityStream.write(s.getBytes());
139+
}
140+
}, Priorities.USER - 1).target("http://localhost:8080").request().get()) {
141+
Assertions.assertEquals(entity, response.readEntity(String.class));
142+
Assertions.assertEquals(entity, response.getHeaderString(header));
143+
}
144+
}
145+
146+
@Test
147+
void testInterceptorHeaderAdd() {
148+
final String header2 = "CUSTOM_HEADER_2";
149+
150+
try (Response response = ClientBuilder.newClient().register(new ClientRequestFilter() {
151+
@Override
152+
public void filter(ClientRequestContext requestContext) throws IOException {
153+
requestContext.abortWith(Response.ok().entity(entity).build());
154+
}
155+
}).register(new ReaderInterceptor() {
156+
@Override
157+
public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
158+
MultivaluedMap<String, String> headers = context.getHeaders();
159+
headers.put(header, Collections.singletonList(entity));
160+
headers.add(header2, entity);
161+
return context.proceed();
162+
}
163+
})
164+
.target("http://localhost:8080").request().get()) {
165+
Assertions.assertEquals(entity, response.readEntity(String.class));
166+
Assertions.assertEquals(entity, response.getHeaderString(header));
167+
Assertions.assertEquals(entity, response.getHeaderString(header2));
168+
}
169+
}
170+
171+
@Test
172+
void testInterceptorHeaderIterate() {
173+
final AtomicReference<String> originalHeader = new AtomicReference<>();
174+
175+
try (Response response = ClientBuilder.newClient().register(new ClientRequestFilter() {
176+
@Override
177+
public void filter(ClientRequestContext requestContext) throws IOException {
178+
requestContext.abortWith(Response.ok().header(header, header).entity(entity).build());
179+
}
180+
}).register(new ReaderInterceptor() {
181+
@Override
182+
public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
183+
MultivaluedMap<String, String> headers = context.getHeaders();
184+
Iterator<Map.Entry<String, List<String>>> it = headers.entrySet().iterator();
185+
while (it.hasNext()) {
186+
Map.Entry<String, List<String>> next = it.next();
187+
if (header.equals(next.getKey())) {
188+
originalHeader.set(next.setValue(Collections.singletonList(entity)).get(0));
189+
}
190+
}
191+
return context.proceed();
192+
}
193+
})
194+
.target("http://localhost:8080").request().get()) {
195+
Assertions.assertEquals(entity, response.readEntity(String.class));
196+
Assertions.assertEquals(entity, response.getHeaderString(header));
197+
Assertions.assertEquals(header, originalHeader.get());
198+
}
199+
}
200+
201+
@Test
202+
void testNullHeader() {
203+
final AtomicReference<String> originalHeader = new AtomicReference<>();
204+
RuntimeDelegate.setInstance(new StringHeaderRuntimeDelegate(RuntimeDelegate.getInstance()));
205+
try (Response response = ClientBuilder.newClient().register(new ClientRequestFilter() {
206+
@Override
207+
public void filter(ClientRequestContext requestContext) throws IOException {
208+
requestContext.abortWith(Response.ok()
209+
.header(header, new StringHeader())
210+
.entity(entity).build());
211+
}
212+
}).register(new ClientResponseFilter() {
213+
@Override
214+
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext)
215+
throws IOException {
216+
originalHeader.set(responseContext.getHeaderString(header));
217+
}
218+
})
219+
.target("http://localhost:8080").request().get()) {
220+
Assertions.assertEquals(entity, response.readEntity(String.class));
221+
Assertions.assertEquals("", originalHeader.get());
222+
}
223+
}
224+
225+
private static class StringHeader extends AtomicReference<String> {
226+
227+
}
228+
229+
private static class StringHeaderDelegate implements RuntimeDelegate.HeaderDelegate<StringHeader> {
230+
@Override
231+
public StringHeader fromString(String value) {
232+
StringHeader stringHeader = new StringHeader();
233+
stringHeader.set(value);
234+
return stringHeader;
235+
}
236+
237+
@Override
238+
public String toString(StringHeader value) {
239+
//on purpose
240+
return null;
241+
}
242+
}
243+
244+
private static class StringHeaderRuntimeDelegate extends RuntimeDelegate {
245+
private final RuntimeDelegate original;
246+
247+
private StringHeaderRuntimeDelegate(RuntimeDelegate original) {
248+
this.original = original;
249+
}
250+
251+
@Override
252+
public UriBuilder createUriBuilder() {
253+
return original.createUriBuilder();
254+
}
255+
256+
@Override
257+
public Response.ResponseBuilder createResponseBuilder() {
258+
return original.createResponseBuilder();
259+
}
260+
261+
@Override
262+
public Variant.VariantListBuilder createVariantListBuilder() {
263+
return original.createVariantListBuilder();
264+
}
265+
266+
@Override
267+
public <T> T createEndpoint(Application application, Class<T> endpointType)
268+
throws IllegalArgumentException, UnsupportedOperationException {
269+
return original.createEndpoint(application, endpointType);
270+
}
271+
272+
@Override
273+
@SuppressWarnings("unchecked")
274+
public <T> HeaderDelegate<T> createHeaderDelegate(Class<T> type) throws IllegalArgumentException {
275+
if (StringHeader.class.equals(type)) {
276+
return (HeaderDelegate<T>) new StringHeaderDelegate();
277+
}
278+
return original.createHeaderDelegate(type);
279+
}
280+
281+
@Override
282+
public Link.Builder createLinkBuilder() {
283+
return original.createLinkBuilder();
284+
}
285+
}
286+
102287
}

0 commit comments

Comments
 (0)