Skip to content

Commit 8078b7d

Browse files
agherardialessandro.gherardi
authored andcommitted
Merge remote-tracking branch 'origin/master' into properlyClose
Signed-off-by: agherardi <[email protected]>
2 parents 52a0dcc + 63b51ba commit 8078b7d

File tree

38 files changed

+549
-351
lines changed

38 files changed

+549
-351
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ cache:
1313
- .autoconf
1414
env:
1515
matrix:
16-
- TEST_SET="-Ptravis_e2e_skip"
17-
- TEST_SET="-Ptravis_e2e"
16+
- TEST_SET="-Ptravis_main"
17+
- TEST_SET="-fn -Dtest=BroadcasterTest,ClientCloseTest,ResponseWriterOutputStreamTest -DfailIfNoTests=false"
1818

1919
install: true
2020

connectors/apache-connector/src/test/java/org/glassfish/jersey/apache/connector/AuthTest.java

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import javax.ws.rs.core.Context;
3030
import javax.ws.rs.core.HttpHeaders;
3131
import javax.ws.rs.core.Response;
32+
import javax.ws.rs.core.UriInfo;
3233

3334
import javax.inject.Singleton;
3435

@@ -40,6 +41,7 @@
4041
import org.apache.http.auth.AuthScope;
4142
import org.apache.http.auth.UsernamePasswordCredentials;
4243
import org.apache.http.client.CredentialsProvider;
44+
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
4345
import org.junit.Ignore;
4446
import org.junit.Test;
4547
import static org.junit.Assert.assertEquals;
@@ -116,6 +118,8 @@ public void testPreemptiveAuthPost() {
116118
public static class AuthResource {
117119

118120
int requestCount = 0;
121+
int queryParamsBasicRequestCount = 0;
122+
int queryParamsDigestRequestCount = 0;
119123

120124
@GET
121125
public String get(@Context HttpHeaders h) {
@@ -144,6 +148,25 @@ public String getFilter(@Context HttpHeaders h) {
144148
return "GET";
145149
}
146150

151+
@GET
152+
@Path("noauth")
153+
public String get() {
154+
return "GET";
155+
}
156+
157+
@GET
158+
@Path("digest")
159+
public String getDigest(@Context HttpHeaders h) {
160+
String value = h.getRequestHeaders().getFirst("Authorization");
161+
if (value == null) {
162+
throw new WebApplicationException(
163+
Response.status(401).header("WWW-Authenticate", "Digest realm=\"WallyWorld\"")
164+
.entity("Forbidden").build());
165+
}
166+
167+
return "GET";
168+
}
169+
147170
@POST
148171
public String post(@Context HttpHeaders h, String e) {
149172
requestCount++;
@@ -205,6 +228,30 @@ public String deleteFilterWithEntity(@Context HttpHeaders h, String e) {
205228

206229
return e;
207230
}
231+
232+
@GET
233+
@Path("queryParamsBasic")
234+
public String getQueryParamsBasic(@Context HttpHeaders h, @Context UriInfo uriDetails) {
235+
queryParamsBasicRequestCount++;
236+
String value = h.getRequestHeaders().getFirst("Authorization");
237+
if (value == null) {
238+
throw new WebApplicationException(
239+
Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
240+
}
241+
return "GET " + queryParamsBasicRequestCount;
242+
}
243+
244+
@GET
245+
@Path("queryParamsDigest")
246+
public String getQueryParamsDigest(@Context HttpHeaders h, @Context UriInfo uriDetails) {
247+
queryParamsDigestRequestCount++;
248+
String value = h.getRequestHeaders().getFirst("Authorization");
249+
if (value == null) {
250+
throw new WebApplicationException(
251+
Response.status(401).header("WWW-Authenticate", "Digest realm=\"WallyWorld\"").build());
252+
}
253+
return "GET " + queryParamsDigestRequestCount;
254+
}
208255
}
209256

210257
@Test
@@ -254,6 +301,35 @@ public void testAuthGetWithClientFilter() {
254301
assertEquals("GET", r.request().get(String.class));
255302
}
256303

304+
@Test
305+
public void testAuthGetBasicNoChallenge() {
306+
ClientConfig cc = new ClientConfig();
307+
cc.connectorProvider(new ApacheConnectorProvider());
308+
Client client = ClientBuilder.newClient(cc);
309+
client.register(HttpAuthenticationFeature.basicBuilder().build());
310+
WebTarget r = client.target(getBaseUri()).path("test/noauth");
311+
312+
assertEquals("GET", r.request().get(String.class));
313+
}
314+
315+
@Test
316+
public void testAuthGetWithDigestFilter() {
317+
ClientConfig cc = new ClientConfig();
318+
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
319+
cc.connectorProvider(new ApacheConnectorProvider());
320+
cc.property(ApacheClientProperties.CONNECTION_MANAGER, cm);
321+
Client client = ClientBuilder.newClient(cc);
322+
client.register(HttpAuthenticationFeature.universal("name", "password"));
323+
WebTarget r = client.target(getBaseUri()).path("test/digest");
324+
325+
assertEquals("GET", r.request().get(String.class));
326+
327+
// Verify the connection that was used for the request is available for reuse
328+
// and no connections are leased
329+
assertEquals(cm.getTotalStats().getAvailable(), 1);
330+
assertEquals(cm.getTotalStats().getLeased(), 0);
331+
}
332+
257333
@Test
258334
@Ignore("JERSEY-1750: Cannot retry request with a non-repeatable request entity. How to buffer the entity?"
259335
+ " Allow repeatable write in jersey?")
@@ -348,4 +424,40 @@ public void testAuthInteractivePost() {
348424

349425
assertEquals("POST", r.request().post(Entity.text("POST"), String.class));
350426
}
427+
428+
@Test
429+
public void testAuthGetQueryParamsBasic() {
430+
ClientConfig cc = new ClientConfig();
431+
cc.connectorProvider(new ApacheConnectorProvider());
432+
Client client = ClientBuilder.newClient(cc);
433+
client.register(HttpAuthenticationFeature.universal("name", "password"));
434+
435+
WebTarget r = client.target(getBaseUri()).path("test/queryParamsBasic");
436+
assertEquals("GET 2", r.request().get(String.class));
437+
438+
r = client.target(getBaseUri())
439+
.path("test/queryParamsBasic")
440+
.queryParam("param1", "value1")
441+
.queryParam("param2", "value2");
442+
assertEquals("GET 3", r.request().get(String.class));
443+
444+
}
445+
446+
@Test
447+
public void testAuthGetQueryParamsDigest() {
448+
ClientConfig cc = new ClientConfig();
449+
cc.connectorProvider(new ApacheConnectorProvider());
450+
Client client = ClientBuilder.newClient(cc);
451+
client.register(HttpAuthenticationFeature.universal("name", "password"));
452+
453+
WebTarget r = client.target(getBaseUri()).path("test/queryParamsDigest");
454+
assertEquals("GET 2", r.request().get(String.class));
455+
456+
r = client.target(getBaseUri())
457+
.path("test/queryParamsDigest")
458+
.queryParam("param1", "value1")
459+
.queryParam("param2", "value2");
460+
assertEquals("GET 3", r.request().get(String.class));
461+
462+
}
351463
}

connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/ProxyBasicAuthenticator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
package org.glassfish.jersey.jdk.connector.internal;
1818

1919
import java.nio.charset.Charset;
20+
import java.util.Base64;
2021

21-
import org.glassfish.jersey.internal.util.Base64;
2222

2323
/**
2424
* @author Ondrej Kosatka (ondrej.kosatka at oracle.com)
@@ -46,6 +46,6 @@ static String generateAuthorizationHeader(String userName, String password) thro
4646
System.arraycopy(prefix, 0, usernamePassword, 0, prefix.length);
4747
System.arraycopy(passwordBytes, 0, usernamePassword, prefix.length, passwordBytes.length);
4848

49-
return "Basic " + Base64.encodeAsString(usernamePassword);
49+
return "Basic " + Base64.getEncoder().encodeToString(usernamePassword);
5050
}
5151
}

connectors/jdk-connector/src/test/java/org/glassfish/jersey/jdk/connector/internal/ProxyTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.IOException;
2020
import java.io.OutputStream;
2121
import java.nio.charset.Charset;
22+
import java.util.Base64;
2223
import java.util.regex.Matcher;
2324
import java.util.regex.Pattern;
2425

@@ -31,7 +32,6 @@
3132

3233
import org.glassfish.jersey.client.ClientConfig;
3334
import org.glassfish.jersey.client.ClientProperties;
34-
import org.glassfish.jersey.internal.util.Base64;
3535
import org.glassfish.jersey.jdk.connector.JdkConnectorProperties;
3636
import org.glassfish.jersey.jdk.connector.JdkConnectorProvider;
3737
import org.glassfish.jersey.server.ResourceConfig;
@@ -227,7 +227,7 @@ private boolean verifyBasicAuthorizationHeader(Response response, String authori
227227
response.setStatus(400);
228228
return false;
229229
}
230-
String decoded = new String(Base64.decode(authorizationHeader.substring(6).getBytes()),
230+
String decoded = new String(Base64.getDecoder().decode(authorizationHeader.substring(6).getBytes()),
231231
CHARACTER_SET);
232232
final String[] split = decoded.split(":");
233233
final String username = split[0];

connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/AsyncTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ public void handleTimeout(AsyncResponse asyncResponse) {
110110
}
111111
});
112112
asyncResponse.setTimeout(1, TimeUnit.SECONDS);
113+
asyncResponse.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE)
114+
.entity("Operation time out.").build());
113115

114116
new Thread(new Runnable() {
115117

connectors/jetty-connector/src/test/java/org/glassfish/jersey/jetty/connector/HelloWorldTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ protected Application configure() {
7171

7272
@Override
7373
protected void configureClient(ClientConfig config) {
74-
config.property(ClientProperties.ASYNC_THREADPOOL_SIZE, 20);
7574
config.connectorProvider(new JettyConnectorProvider());
7675
}
7776

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) 2013, 2018 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.client.authentication;
18+
19+
import java.io.IOException;
20+
import java.io.InputStream;
21+
import java.net.URI;
22+
import java.net.URISyntaxException;
23+
24+
import javax.ws.rs.client.ClientRequestContext;
25+
26+
/**
27+
* Common authentication utilities
28+
*/
29+
class AuthenticationUtil {
30+
static void discardInputAndClose(InputStream is) {
31+
byte[] buf = new byte[4096];
32+
try {
33+
while (true) {
34+
if (is.read(buf) <= 0) {
35+
break;
36+
}
37+
}
38+
} catch (IOException ex) {
39+
// ignore
40+
} finally {
41+
try {
42+
is.close();
43+
} catch (IOException ex) {
44+
// ignore
45+
}
46+
}
47+
}
48+
49+
static URI getCacheKey(ClientRequestContext request) {
50+
URI requestUri = request.getUri();
51+
if (requestUri.getRawQuery() != null) {
52+
// Return a URI without the query part of the request URI
53+
try {
54+
return new URI(
55+
requestUri.getScheme(),
56+
requestUri.getAuthority(),
57+
requestUri.getPath(),
58+
null,
59+
requestUri.getFragment());
60+
} catch (URISyntaxException e) {
61+
// Ignore and fall through
62+
}
63+
}
64+
return requestUri;
65+
}
66+
}

core-client/src/main/java/org/glassfish/jersey/client/authentication/BasicAuthenticator.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,15 @@
1616

1717
package org.glassfish.jersey.client.authentication;
1818

19+
import java.util.Base64;
20+
import java.util.logging.Level;
21+
import java.util.logging.Logger;
22+
1923
import javax.ws.rs.client.ClientRequestContext;
2024
import javax.ws.rs.client.ClientResponseContext;
2125
import javax.ws.rs.core.HttpHeaders;
2226

2327
import org.glassfish.jersey.client.internal.LocalizationMessages;
24-
import org.glassfish.jersey.internal.util.Base64;
2528

2629
/**
2730
* Implementation of Basic Http Authentication method (RFC 2617).
@@ -32,6 +35,8 @@
3235
*/
3336
final class BasicAuthenticator {
3437

38+
private static final Logger LOGGER = Logger.getLogger(BasicAuthenticator.class.getName());
39+
3540
private final HttpAuthenticationFilter.Credentials defaultCredentials;
3641

3742
/**
@@ -61,22 +66,22 @@ private String calculateAuthentication(HttpAuthenticationFilter.Credentials cred
6166
System.arraycopy(prefix, 0, usernamePassword, 0, prefix.length);
6267
System.arraycopy(password, 0, usernamePassword, prefix.length, password.length);
6368

64-
return "Basic " + Base64.encodeAsString(usernamePassword);
69+
return "Basic " + Base64.getEncoder().encodeToString(usernamePassword);
6570
}
6671

6772
/**
6873
* Adds authentication information to the request.
6974
*
7075
* @param request Request context.
71-
* @throws RequestAuthenticationException in case that basic credentials missing or are in invalid format
7276
*/
73-
public void filterRequest(ClientRequestContext request) throws RequestAuthenticationException {
77+
public void filterRequest(ClientRequestContext request) {
7478
HttpAuthenticationFilter.Credentials credentials = HttpAuthenticationFilter.getCredentials(request,
7579
defaultCredentials, HttpAuthenticationFilter.Type.BASIC);
7680
if (credentials == null) {
77-
throw new RequestAuthenticationException(LocalizationMessages.AUTHENTICATION_CREDENTIALS_MISSING_BASIC());
81+
LOGGER.fine(LocalizationMessages.AUTHENTICATION_CREDENTIALS_NOT_PROVIDED_BASIC());
82+
} else {
83+
request.getHeaders().add(HttpHeaders.AUTHORIZATION, calculateAuthentication(credentials));
7884
}
79-
request.getHeaders().add(HttpHeaders.AUTHORIZATION, calculateAuthentication(credentials));
8085
}
8186

8287
/**

core-client/src/main/java/org/glassfish/jersey/client/authentication/DigestAuthenticator.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ protected boolean removeEldestEntry(final Map.Entry eldest) {
9090
* @throws IOException When error with encryption occurs.
9191
*/
9292
boolean filterRequest(final ClientRequestContext request) throws IOException {
93-
final DigestScheme digestScheme = digestCache.get(request.getUri());
93+
final DigestScheme digestScheme = digestCache.get(AuthenticationUtil.getCacheKey(request));
9494
if (digestScheme != null) {
9595
final HttpAuthenticationFilter.Credentials cred = HttpAuthenticationFilter.getCredentials(request,
9696
this.credentials, HttpAuthenticationFilter.Type.DIGEST);
@@ -131,10 +131,11 @@ public boolean filterResponse(final ClientRequestContext request, final ClientRe
131131

132132
final boolean success = HttpAuthenticationFilter.repeatRequest(request, response, createNextAuthToken(digestScheme,
133133
request, cred));
134+
URI cacheKey = AuthenticationUtil.getCacheKey(request);
134135
if (success) {
135-
digestCache.put(request.getUri(), digestScheme);
136+
digestCache.put(cacheKey, digestScheme);
136137
} else {
137-
digestCache.remove(request.getUri());
138+
digestCache.remove(cacheKey);
138139
}
139140
return success;
140141
}

0 commit comments

Comments
 (0)