Skip to content

Commit 85f30e2

Browse files
authored
Merge branch 'master' into ahc-1412
2 parents 88ce96d + 00dbf54 commit 85f30e2

File tree

5 files changed

+56
-44
lines changed

5 files changed

+56
-44
lines changed

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

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
public class Realm {
3838

3939
private static final String DEFAULT_NC = "00000001";
40+
// MD5("")
4041
private static final String EMPTY_ENTITY_MD5 = "d41d8cd98f00b204e9800998ecf8427e";
4142

4243
private final String principal;
@@ -412,26 +413,35 @@ private byte[] md5FromRecycledStringBuilder(StringBuilder sb, MessageDigest md)
412413
return md.digest();
413414
}
414415

415-
private byte[] secretDigest(StringBuilder sb, MessageDigest md) {
416+
private byte[] ha1(StringBuilder sb, MessageDigest md) {
417+
// if algorithm is "MD5" or is unspecified => A1 = username ":" realm-value ":" passwd
418+
// if algorithm is "MD5-sess" => A1 = MD5( username-value ":" realm-value ":" passwd ) ":" nonce-value ":" cnonce-value
416419

417420
sb.append(principal).append(':').append(realmName).append(':').append(password);
418-
byte[] ha1 = md5FromRecycledStringBuilder(sb, md);
421+
byte[] core = md5FromRecycledStringBuilder(sb, md);
419422

420423
if (algorithm == null || algorithm.equals("MD5")) {
421-
return ha1;
424+
// A1 = username ":" realm-value ":" passwd
425+
return core;
422426
} else if ("MD5-sess".equals(algorithm)) {
423-
appendBase16(sb, ha1);
427+
// A1 = MD5(username ":" realm-value ":" passwd ) ":" nonce ":" cnonce
428+
appendBase16(sb, core);
424429
sb.append(':').append(nonce).append(':').append(cnonce);
425430
return md5FromRecycledStringBuilder(sb, md);
426431
}
427432

428433
throw new UnsupportedOperationException("Digest algorithm not supported: " + algorithm);
429434
}
430435

431-
private byte[] dataDigest(StringBuilder sb, String digestUri, MessageDigest md) {
436+
private byte[] ha2(StringBuilder sb, String digestUri, MessageDigest md) {
432437

438+
// if qop is "auth" or is unspecified => A2 = Method ":" digest-uri-value
439+
// if qop is "auth-int" => A2 = Method ":" digest-uri-value ":" H(entity-body)
433440
sb.append(methodName).append(':').append(digestUri);
434441
if ("auth-int".equals(qop)) {
442+
// when qop == "auth-int", A2 = Method ":" digest-uri-value ":" H(entity-body)
443+
// but we don't have the request body here
444+
// we would need a new API
435445
sb.append(':').append(EMPTY_ENTITY_MD5);
436446

437447
} else if (qop != null && !qop.equals("auth")) {
@@ -441,7 +451,8 @@ private byte[] dataDigest(StringBuilder sb, String digestUri, MessageDigest md)
441451
return md5FromRecycledStringBuilder(sb, md);
442452
}
443453

444-
private void appendDataBase(StringBuilder sb) {
454+
private void appendMiddlePart(StringBuilder sb) {
455+
// request-digest = MD5(H(A1) ":" nonce ":" nc ":" cnonce ":" qop ":" H(A2))
445456
sb.append(':').append(nonce).append(':');
446457
if ("auth".equals(qop) || "auth-int".equals(qop)) {
447458
sb.append(nc).append(':').append(cnonce).append(':').append(qop).append(':');
@@ -457,12 +468,12 @@ private void newResponse(MessageDigest md) {
457468
StringBuilder sb = StringBuilderPool.DEFAULT.stringBuilder();
458469

459470
// WARNING: DON'T MOVE, BUFFER IS RECYCLED!!!!
460-
byte[] secretDigest = secretDigest(sb, md);
461-
byte[] dataDigest = dataDigest(sb, digestUri, md);
471+
byte[] ha1 = ha1(sb, md);
472+
byte[] ha2 = ha2(sb, digestUri, md);
462473

463-
appendBase16(sb, secretDigest);
464-
appendDataBase(sb);
465-
appendBase16(sb, dataDigest);
474+
appendBase16(sb, ha1);
475+
appendMiddlePart(sb);
476+
appendBase16(sb, ha2);
466477

467478
byte[] responseDigest = md5FromRecycledStringBuilder(sb, md);
468479
response = toHexString(responseDigest);

client/src/main/java/org/asynchttpclient/netty/channel/ChannelManager.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,9 +322,9 @@ public void close() {
322322
if (allowReleaseEventLoopGroup) {
323323
eventLoopGroup.shutdownGracefully(config.getShutdownQuietPeriod(), config.getShutdownTimeout(), TimeUnit.MILLISECONDS)//
324324
.addListener(future -> doClose());
325-
} else
325+
} else {
326326
doClose();
327-
327+
328328
try {
329329
closeLatch.await(config.getShutdownTimeout(), TimeUnit.MILLISECONDS);
330330
}

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

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616
import static org.asynchttpclient.Dsl.*;
1717
import static org.testng.Assert.assertEquals;
1818

19-
import java.math.BigInteger;
2019
import java.nio.charset.StandardCharsets;
2120
import java.security.MessageDigest;
2221

2322
import org.asynchttpclient.uri.Uri;
23+
import org.asynchttpclient.util.StringUtils;
2424
import org.testng.annotations.Test;
2525

2626
public class RealmTest {
@@ -42,18 +42,16 @@ public void testClone() {
4242
}
4343

4444
@Test(groups = "standalone")
45-
public void testOldDigestEmptyString() {
46-
String qop = "";
47-
testOldDigest(qop);
45+
public void testOldDigestEmptyString() throws Exception {
46+
testOldDigest("");
4847
}
4948

5049
@Test(groups = "standalone")
51-
public void testOldDigestNull() {
52-
String qop = null;
53-
testOldDigest(qop);
50+
public void testOldDigestNull() throws Exception {
51+
testOldDigest(null);
5452
}
5553

56-
private void testOldDigest(String qop) {
54+
private void testOldDigest(String qop) throws Exception {
5755
String user = "user";
5856
String pass = "pass";
5957
String realm = "realm";
@@ -65,7 +63,8 @@ private void testOldDigest(String qop) {
6563
.setUri(uri)//
6664
.setMethodName(method)//
6765
.setRealmName(realm)//
68-
.setQop(qop).build();
66+
.setQop(qop)//
67+
.build();
6968

7069
String ha1 = getMd5(user + ":" + realm + ":" + pass);
7170
String ha2 = getMd5(method + ":" + uri.getPath());
@@ -75,7 +74,7 @@ private void testOldDigest(String qop) {
7574
}
7675

7776
@Test(groups = "standalone")
78-
public void testStrongDigest() {
77+
public void testStrongDigest() throws Exception {
7978
String user = "user";
8079
String pass = "pass";
8180
String realm = "realm";
@@ -88,7 +87,8 @@ public void testStrongDigest() {
8887
.setUri(uri)//
8988
.setMethodName(method)//
9089
.setRealmName(realm)//
91-
.setQop(qop).build();
90+
.setQop(qop)//
91+
.build();
9292

9393
String nc = orig.getNc();
9494
String cnonce = orig.getCnonce();
@@ -99,19 +99,10 @@ public void testStrongDigest() {
9999
assertEquals(orig.getResponse(), expectedResponse);
100100
}
101101

102-
private String getMd5(String what) {
103-
try {
104-
MessageDigest md = MessageDigest.getInstance("MD5");
105-
md.update(what.getBytes(StandardCharsets.ISO_8859_1));
106-
byte[] hash = md.digest();
107-
BigInteger bi = new BigInteger(1, hash);
108-
String result = bi.toString(16);
109-
if (result.length() % 2 != 0) {
110-
return "0" + result;
111-
}
112-
return result;
113-
} catch (Exception e) {
114-
throw new RuntimeException(e);
115-
}
102+
private String getMd5(String what) throws Exception {
103+
MessageDigest md = MessageDigest.getInstance("MD5");
104+
md.update(what.getBytes(StandardCharsets.ISO_8859_1));
105+
byte[] hash = md.digest();
106+
return StringUtils.toHexString(hash);
116107
}
117108
}

client/src/test/java/org/asynchttpclient/reactivestreams/ReactiveStreamsTest.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,24 +232,34 @@ public void testConnectionDoesNotGetClosed() throws Exception {
232232
.setHeader("X-" + CONTENT_MD5, expectedMd5);
233233

234234
Response response = requestBuilder.execute().get();
235-
assertEquals(response.getStatusCode(), 200);
235+
assertEquals(response.getStatusCode(), 200, "HTTP response was invalid on first request.");
236+
236237
byte[] responseBody = response.getResponseBodyAsBytes();
237238
responseBody = response.getResponseBodyAsBytes();
238-
assertEquals(Integer.valueOf(response.getHeader("X-" + CONTENT_LENGTH)).intValue(), LARGE_IMAGE_BYTES.length, "Server side payload length invalid");
239+
assertEquals(
240+
Integer.valueOf(response.getHeader("X-" + CONTENT_LENGTH)).intValue(),
241+
LARGE_IMAGE_BYTES.length,
242+
"Server side payload length invalid"
243+
);
239244
assertEquals(responseBody.length, LARGE_IMAGE_BYTES.length, "Client side payload length invalid");
240245
assertEquals(response.getHeader(CONTENT_MD5), expectedMd5, "Server side payload MD5 invalid");
241246
assertEquals(TestUtils.md5(responseBody), expectedMd5, "Client side payload MD5 invalid");
242-
assertEquals(responseBody, LARGE_IMAGE_BYTES);
247+
assertEquals(responseBody, LARGE_IMAGE_BYTES, "Image bytes are not equal on first attempt");
243248

244249
response = requestBuilder.execute().get();
245250
assertEquals(response.getStatusCode(), 200);
246251
responseBody = response.getResponseBodyAsBytes();
247-
assertEquals(Integer.valueOf(response.getHeader("X-" + CONTENT_LENGTH)).intValue(), LARGE_IMAGE_BYTES.length, "Server side payload length invalid");
252+
assertEquals(
253+
Integer.valueOf(response.getHeader("X-" + CONTENT_LENGTH)).intValue(),
254+
LARGE_IMAGE_BYTES.length,
255+
"Server side payload length invalid"
256+
);
248257
assertEquals(responseBody.length, LARGE_IMAGE_BYTES.length, "Client side payload length invalid");
258+
249259
try {
250260
assertEquals(response.getHeader(CONTENT_MD5), expectedMd5, "Server side payload MD5 invalid");
251261
assertEquals(TestUtils.md5(responseBody), expectedMd5, "Client side payload MD5 invalid");
252-
assertEquals(responseBody, LARGE_IMAGE_BYTES);
262+
assertEquals(responseBody, LARGE_IMAGE_BYTES, "Image bytes weren't equal on subsequent test");
253263
} catch (AssertionError e) {
254264
e.printStackTrace();
255265
for (int i = 0; i < LARGE_IMAGE_BYTES.length; i++) {

client/src/test/java/org/asynchttpclient/testserver/HttpServer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public void reset() {
119119

120120
@Override
121121
public void close() throws IOException {
122-
if (server == null) {
122+
if (server != null) {
123123
try {
124124
server.stop();
125125
} catch (Exception e) {

0 commit comments

Comments
 (0)