Skip to content

Commit b65a7a3

Browse files
author
Stephane Landelle
committed
Make all providers honor Realm.isOmitQuery and isUseAbsoluteURI, close AsyncHttpClient#607
1 parent d756d26 commit b65a7a3

File tree

7 files changed

+42
-38
lines changed

7 files changed

+42
-38
lines changed

api/src/main/java/org/asynchttpclient/Realm.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static org.asynchttpclient.util.MiscUtils.isNonEmpty;
2020

21+
import org.asynchttpclient.uri.UriComponents;
2122
import org.asynchttpclient.util.StandardCharsets;
2223

2324
import java.nio.charset.Charset;
@@ -42,7 +43,7 @@ public class Realm {
4243
private final String qop;
4344
private final String nc;
4445
private final String cnonce;
45-
private final String uri;
46+
private final UriComponents uri;
4647
private final String methodName;
4748
private final boolean usePreemptiveAuth;
4849
private final String enc;
@@ -58,7 +59,7 @@ public enum AuthScheme {
5859
}
5960

6061
private Realm(AuthScheme scheme, String principal, String password, String realmName, String nonce, String algorithm, String response,
61-
String qop, String nc, String cnonce, String uri, String method, boolean usePreemptiveAuth, String ntlmDomain, String enc,
62+
String qop, String nc, String cnonce, UriComponents uri, String method, boolean usePreemptiveAuth, String ntlmDomain, String enc,
6263
String host, boolean messageType2Received, String opaque, boolean useAbsoluteURI, boolean omitQuery) {
6364

6465
this.principal = principal;
@@ -133,7 +134,7 @@ public String getCnonce() {
133134
return cnonce;
134135
}
135136

136-
public String getUri() {
137+
public UriComponents getUri() {
137138
return uri;
138139
}
139140

@@ -268,7 +269,7 @@ public static class RealmBuilder {
268269
private String qop = "auth";
269270
private String nc = "00000001";
270271
private String cnonce = "";
271-
private String uri = "";
272+
private UriComponents uri;
272273
private String methodName = "GET";
273274
private boolean usePreemptive = false;
274275
private String domain = System.getProperty("http.auth.ntlm.domain", "");
@@ -386,11 +387,11 @@ public RealmBuilder setNc(String nc) {
386387
return this;
387388
}
388389

389-
public String getUri() {
390+
public UriComponents getUri() {
390391
return uri;
391392
}
392393

393-
public RealmBuilder setUri(String uri) {
394+
public RealmBuilder setUri(UriComponents uri) {
394395
this.uri = uri;
395396
return this;
396397
}

api/src/main/java/org/asynchttpclient/uri/UriComponents.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,15 @@ public UriComponents withNewScheme(String newScheme) {
121121
query);
122122
}
123123

124+
public UriComponents withNewPath(String newPath) {
125+
return new UriComponents(scheme,//
126+
userInfo,//
127+
host,//
128+
port,//
129+
newPath,//
130+
query);
131+
}
132+
124133
public UriComponents withNewQuery(String newQuery) {
125134
return new UriComponents(scheme,//
126135
userInfo,//

api/src/main/java/org/asynchttpclient/util/AuthenticatorUtils.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.asynchttpclient.ProxyServer;
1818
import org.asynchttpclient.Realm;
19+
import org.asynchttpclient.uri.UriComponents;
1920

2021
import java.security.NoSuchAlgorithmException;
2122

@@ -31,13 +32,24 @@ public static String computeBasicAuthentication(ProxyServer proxyServer) {
3132
return "Basic " + Base64.encode(s.getBytes(proxyServer.getCharset()));
3233
}
3334

35+
private static String computeRealmURI(Realm realm) {
36+
UriComponents uri = realm.getUri();
37+
boolean omitQuery = realm.isOmitQuery() && MiscUtils.isNonEmpty(uri.getQuery());
38+
if (realm.isUseAbsoluteURI()) {
39+
return omitQuery ? uri.withNewQuery(null).toUrl() : uri.toUrl();
40+
} else {
41+
String path = uri.getPath();
42+
return omitQuery ? path : path + "?" + uri.getQuery();
43+
}
44+
}
45+
3446
public static String computeDigestAuthentication(Realm realm) throws NoSuchAlgorithmException {
3547

3648
StringBuilder builder = new StringBuilder().append("Digest ");
3749
construct(builder, "username", realm.getPrincipal());
3850
construct(builder, "realm", realm.getRealmName());
3951
construct(builder, "nonce", realm.getNonce());
40-
construct(builder, "uri", realm.getUri());
52+
construct(builder, "uri", computeRealmURI(realm));
4153
builder.append("algorithm").append('=').append(realm.getAlgorithm()).append(", ");
4254

4355
construct(builder, "response", realm.getResponse());

api/src/test/java/org/asynchttpclient/RealmTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import org.asynchttpclient.Realm.AuthScheme;
1818
import org.asynchttpclient.Realm.RealmBuilder;
19+
import org.asynchttpclient.uri.UriComponents;
1920
import org.asynchttpclient.util.StandardCharsets;
2021
import org.testng.annotations.Test;
2122

@@ -60,7 +61,7 @@ private void testOldDigest(String qop) {
6061
String realm = "realm";
6162
String nonce = "nonce";
6263
String method = "GET";
63-
String uri = "/foo";
64+
UriComponents uri = UriComponents.create("http://ahc.io/%3C/span%3Efoo");
6465
RealmBuilder builder = new RealmBuilder();
6566
builder.setPrincipal(user).setPassword(pass);
6667
builder.setNonce(nonce);
@@ -85,7 +86,7 @@ public void testStrongDigest() {
8586
String realm = "realm";
8687
String nonce = "nonce";
8788
String method = "GET";
88-
String uri = "/foo";
89+
UriComponents uri = UriComponents.create("http://ahc.io/%3C/span%3Efoo");
8990
String qop = "auth";
9091
RealmBuilder builder = new RealmBuilder();
9192
builder.setPrincipal(user).setPassword(pass);

providers/grizzly/src/main/java/org/asynchttpclient/providers/grizzly/statushandler/AuthorizationHandler.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
package org.asynchttpclient.providers.grizzly.statushandler;
1515

16-
import static org.asynchttpclient.util.AsyncHttpProviderUtils.getNonEmptyPath;
1716
import static org.asynchttpclient.providers.grizzly.statushandler.StatusHandler.InvocationStatus.STOP;
1817

1918
import org.asynchttpclient.Realm;
@@ -68,7 +67,7 @@ public boolean handleStatus(final HttpResponsePacket responsePacket, final HttpT
6867
responsePacket.setSkipRemainder(true); // ignore the remainder of the response
6968

7069
final Request req = httpTransactionContext.getRequest();
71-
realm = new Realm.RealmBuilder().clone(realm).setScheme(realm.getAuthScheme()).setUri(getNonEmptyPath(req.getURI()))
70+
realm = new Realm.RealmBuilder().clone(realm).setScheme(realm.getAuthScheme()).setUri(req.getURI())
7271
.setMethodName(req.getMethod()).setUsePreemptiveAuth(true).parseWWWAuthenticateHeader(auth).build();
7372
String lowerCaseAuth = auth.toLowerCase(Locale.ENGLISH);
7473
if (lowerCaseAuth.startsWith("basic")) {

providers/grizzly/src/main/java/org/asynchttpclient/providers/grizzly/statushandler/ProxyAuthorizationHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public boolean handleStatus(final HttpResponsePacket responsePacket, final HttpT
6060
.select(req.getURI());
6161
String principal = proxyServer.getPrincipal();
6262
String password = proxyServer.getPassword();
63-
Realm realm = new Realm.RealmBuilder().setPrincipal(principal).setPassword(password).setUri("/")
63+
Realm realm = new Realm.RealmBuilder().setPrincipal(principal).setPassword(password).setUri(req.getURI().withNewPath("/").withNewQuery(null))
6464
.setMethodName(Method.CONNECT.getMethodString()).setUsePreemptiveAuth(true).parseProxyAuthenticateHeader(proxyAuth).build();
6565
String proxyAuthLowerCase = proxyAuth.toLowerCase(Locale.ENGLISH);
6666
if (proxyAuthLowerCase.startsWith("basic")) {

providers/netty/src/main/java/org/asynchttpclient/providers/netty/handler/HttpProtocol.java

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ private Realm kerberosChallenge(List<String> proxyAuth, Request request, ProxySe
8888
headers.add(HttpHeaders.Names.AUTHORIZATION, "Negotiate " + challengeHeader);
8989

9090
return newRealmBuilder(realm)//
91-
.setUri(getNonEmptyPath(uri))//
91+
.setUri(uri)//
9292
.setMethodName(request.getMethod())//
9393
.setScheme(Realm.AuthScheme.KERBEROS)//
9494
.build();
@@ -119,16 +119,16 @@ private Realm ntlmChallenge(List<String> wwwAuth, Request request, ProxyServer p
119119
String ntlmHost = useRealm ? realm.getNtlmHost() : proxyServer.getHost();
120120
String principal = useRealm ? realm.getPrincipal() : proxyServer.getPrincipal();
121121
String password = useRealm ? realm.getPassword() : proxyServer.getPassword();
122+
UriComponents uri = request.getURI();
122123

123124
if (realm != null && !realm.isNtlmMessageType2Received()) {
124125
String challengeHeader = NTLMEngine.INSTANCE.generateType1Msg(ntlmDomain, ntlmHost);
125126

126-
UriComponents uri = request.getURI();
127127
addNTLMAuthorizationHeader(headers, challengeHeader, proxyInd);
128128
future.getAndSetAuth(false);
129129
return newRealmBuilder(realm)//
130130
.setScheme(realm.getAuthScheme())//
131-
.setUri(getNonEmptyPath(uri))//
131+
.setUri(uri)//
132132
.setMethodName(request.getMethod())//
133133
.setNtlmMessageType2Received(true)//
134134
.build();
@@ -138,7 +138,7 @@ private Realm ntlmChallenge(List<String> wwwAuth, Request request, ProxyServer p
138138
Realm.AuthScheme authScheme = realm != null ? realm.getAuthScheme() : Realm.AuthScheme.NTLM;
139139
return newRealmBuilder(realm)//
140140
.setScheme(authScheme)//
141-
.setUri(getNonEmptyPath(request.getURI()))//
141+
.setUri(uri)//
142142
.setMethodName(request.getMethod())//
143143
.build();
144144
}
@@ -154,7 +154,7 @@ private Realm ntlmProxyChallenge(List<String> wwwAuth, Request request, ProxySer
154154

155155
return newRealmBuilder(realm)//
156156
// .setScheme(realm.getAuthScheme())
157-
.setUri(getNonEmptyPath(request.getURI()))//
157+
.setUri(request.getURI())//
158158
.setMethodName(request.getMethod()).build();
159159
}
160160

@@ -206,23 +206,6 @@ private void markAsDone(NettyResponseFuture<?> future, final Channel channel) {
206206
}
207207
}
208208

209-
private final String computeRealmURI(Realm realm, UriComponents requestURI) {
210-
if (realm.isUseAbsoluteURI()) {
211-
if (realm.isOmitQuery() && isNonEmpty(requestURI.getQuery())) {
212-
return requestURI.withNewQuery(null).toUrl();
213-
} else {
214-
return requestURI.toUrl();
215-
}
216-
} else {
217-
String path = getNonEmptyPath(requestURI);
218-
if (realm.isOmitQuery() || !isNonEmpty(requestURI.getQuery())) {
219-
return path;
220-
} else {
221-
return path + "?" + requestURI.getQuery();
222-
}
223-
}
224-
}
225-
226209
private boolean handleUnauthorizedAndExit(int statusCode, Realm realm, final Request request, HttpResponse response,
227210
final NettyResponseFuture<?> future, ProxyServer proxyServer, final Channel channel) throws Exception {
228211
if (statusCode == UNAUTHORIZED.code() && realm != null) {
@@ -246,15 +229,14 @@ private boolean handleUnauthorizedAndExit(int statusCode, Realm realm, final Req
246229
newRealm = new Realm.RealmBuilder()//
247230
.clone(realm)//
248231
.setScheme(realm.getAuthScheme())//
249-
.setUri(getNonEmptyPath(request.getURI()))//
232+
.setUri(request.getURI())//
250233
.setMethodName(request.getMethod())//
251234
.setUsePreemptiveAuth(true)//
252235
.parseWWWAuthenticateHeader(authenticateHeaders.get(0))//
253236
.build();
254237
}
255238

256-
String realmURI = computeRealmURI(newRealm, request.getURI());
257-
Realm nr = new Realm.RealmBuilder().clone(newRealm).setUri(realmURI).build();
239+
Realm nr = newRealm;
258240
final Request nextRequest = new RequestBuilder(future.getRequest()).setHeaders(request.getHeaders()).setRealm(nr).build();
259241

260242
LOGGER.debug("Sending authentication to {}", request.getURI());
@@ -318,7 +300,7 @@ private boolean handleProxyAuthenticationRequiredAndExit(int statusCode,//
318300
} else {
319301
newRealm = new Realm.RealmBuilder().clone(realm)//
320302
.setScheme(realm.getAuthScheme())//
321-
.setUri("/")//
303+
.setUri(request.getURI().withNewPath("/").withNewQuery(null))//
322304
.setMethodName(HttpMethod.CONNECT.name())//
323305
.setUsePreemptiveAuth(true)//
324306
.parseProxyAuthenticateHeader(proxyAuthenticateHeaders.get(0))//

0 commit comments

Comments
 (0)