Skip to content

Commit 60c84df

Browse files
committed
fixed http digest authentication, added support for opaque parameter.
(tested and fixed for getcloudapp.com)
1 parent a28aa81 commit 60c84df

File tree

3 files changed

+107
-82
lines changed

3 files changed

+107
-82
lines changed

src/main/java/com/ning/http/client/Realm.java

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616
*/
1717
package com.ning.http.client;
1818

19-
import org.slf4j.Logger;
20-
import org.slf4j.LoggerFactory;
21-
2219
import java.io.UnsupportedEncodingException;
2320
import java.security.MessageDigest;
2421
import java.security.NoSuchAlgorithmException;
2522

23+
import org.slf4j.Logger;
24+
import org.slf4j.LoggerFactory;
25+
2626
/**
2727
* This class is required when authentication is needed. The class support DIGEST and BASIC.
2828
*/
@@ -37,6 +37,7 @@ public class Realm {
3737
private final String nonce;
3838
private final String algorithm;
3939
private final String response;
40+
private final String opaque;
4041
private final String qop;
4142
private final String nc;
4243
private final String cnonce;
@@ -71,7 +72,8 @@ private Realm(AuthScheme scheme,
7172
String uri,
7273
String method,
7374
boolean usePreemptiveAuth,
74-
String domain, String enc, String host, boolean messageType2Received) {
75+
String domain, String enc, String host, boolean messageType2Received,
76+
String opaque) {
7577

7678
this.principal = principal;
7779
this.password = password;
@@ -80,6 +82,7 @@ private Realm(AuthScheme scheme,
8082
this.nonce = nonce;
8183
this.algorithm = algorithm;
8284
this.response = response;
85+
this.opaque = opaque;
8386
this.qop = qop;
8487
this.nc = nc;
8588
this.cnonce = cnonce;
@@ -124,6 +127,10 @@ public String getAlgorithm() {
124127
public String getResponse() {
125128
return response;
126129
}
130+
131+
public String getOpaque() {
132+
return opaque;
133+
}
127134

128135
public String getQop() {
129136
return qop;
@@ -261,6 +268,7 @@ public static class RealmBuilder {
261268
private String nonce = "";
262269
private String algorithm = "MD5";
263270
private String response = "";
271+
private String opaque = "";
264272
private String qop = "auth";
265273
private String nc = "00000001";
266274
private String cnonce = "";
@@ -364,16 +372,25 @@ public RealmBuilder setResponse(String response) {
364372
this.response = response;
365373
return this;
366374
}
375+
376+
public String getOpaque() {
377+
return this.opaque;
378+
}
379+
380+
public RealmBuilder setOpaque(String opaque) {
381+
this.opaque = opaque;
382+
return this;
383+
}
367384

368385
public String getQop() {
369386
return qop;
370387
}
371-
388+
372389
public RealmBuilder setQop(String qop) {
373390
this.qop = qop;
374391
return this;
375392
}
376-
393+
377394
public String getNc() {
378395
return nc;
379396
}
@@ -414,6 +431,7 @@ public RealmBuilder parseWWWAuthenticateHeader(String headerLine) {
414431
setRealmName(match(headerLine, "realm"));
415432
setNonce(match(headerLine, "nonce"));
416433
setAlgorithm(match(headerLine, "algorithm"));
434+
setOpaque(match(headerLine, "opaque"));
417435
setQop(match(headerLine, "qop"));
418436
if (getNonce() != null && !getNonce().equalsIgnoreCase("")) {
419437
setScheme(AuthScheme.DIGEST);
@@ -437,6 +455,7 @@ public RealmBuilder clone(Realm clone) {
437455
setPassword(clone.getPassword());
438456
setPrincipal(clone.getPrincipal());
439457
setEnconding(clone.getEncoding());
458+
setOpaque(clone.getOpaque());
440459
setQop(clone.getQop());
441460
setScheme(clone.getScheme());
442461
setUri(clone.getUri());
@@ -580,7 +599,8 @@ public Realm build() {
580599
domain,
581600
enc,
582601
host,
583-
messageType2Received);
602+
messageType2Received,
603+
opaque);
584604
}
585605
}
586606

src/main/java/com/ning/http/client/providers/netty/NettyAsyncHttpProvider.java

Lines changed: 75 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -15,43 +15,40 @@
1515
*/
1616
package com.ning.http.client.providers.netty;
1717

18-
import com.ning.http.client.AsyncHandler;
19-
import com.ning.http.client.AsyncHandler.STATE;
20-
import com.ning.http.client.AsyncHttpClientConfig;
21-
import com.ning.http.client.AsyncHttpProvider;
22-
import com.ning.http.client.Body;
23-
import com.ning.http.client.ConnectionsPool;
24-
import com.ning.http.client.Cookie;
25-
import com.ning.http.client.FluentCaseInsensitiveStringsMap;
26-
import com.ning.http.client.HttpResponseBodyPart;
27-
import com.ning.http.client.HttpResponseHeaders;
28-
import com.ning.http.client.HttpResponseStatus;
29-
import com.ning.http.client.ListenableFuture;
30-
import com.ning.http.client.MaxRedirectException;
31-
import com.ning.http.client.PerRequestConfig;
32-
import com.ning.http.client.ProgressAsyncHandler;
33-
import com.ning.http.client.ProxyServer;
34-
import com.ning.http.client.RandomAccessBody;
35-
import com.ning.http.client.Realm;
36-
import com.ning.http.client.Request;
37-
import com.ning.http.client.RequestBuilder;
38-
import com.ning.http.client.Response;
39-
import com.ning.http.client.filter.FilterContext;
40-
import com.ning.http.client.filter.FilterException;
41-
import com.ning.http.client.filter.IOExceptionFilter;
42-
import com.ning.http.client.filter.ResponseFilter;
43-
import com.ning.http.client.listener.TransferCompletionHandler;
44-
import com.ning.http.client.ntlm.NTLMEngine;
45-
import com.ning.http.client.ntlm.NTLMEngineException;
46-
import com.ning.http.client.providers.netty.spnego.SpnegoEngine;
47-
import com.ning.http.multipart.MultipartBody;
48-
import com.ning.http.multipart.MultipartRequestEntity;
49-
import com.ning.http.util.AsyncHttpProviderUtils;
50-
import com.ning.http.util.AuthenticatorUtils;
51-
import com.ning.http.util.CleanupChannelGroup;
52-
import com.ning.http.util.ProxyUtils;
53-
import com.ning.http.util.SslUtils;
54-
import com.ning.http.util.UTF8UrlEncoder;
18+
import static com.ning.http.util.AsyncHttpProviderUtils.DEFAULT_CHARSET;
19+
import static org.jboss.netty.channel.Channels.pipeline;
20+
21+
import java.io.File;
22+
import java.io.FileInputStream;
23+
import java.io.IOException;
24+
import java.io.RandomAccessFile;
25+
import java.net.ConnectException;
26+
import java.net.InetSocketAddress;
27+
import java.net.MalformedURLException;
28+
import java.net.URI;
29+
import java.nio.channels.ClosedChannelException;
30+
import java.nio.channels.FileChannel;
31+
import java.nio.channels.WritableByteChannel;
32+
import java.security.GeneralSecurityException;
33+
import java.security.NoSuchAlgorithmException;
34+
import java.util.ArrayList;
35+
import java.util.Collection;
36+
import java.util.Iterator;
37+
import java.util.List;
38+
import java.util.Map.Entry;
39+
import java.util.concurrent.Callable;
40+
import java.util.concurrent.ExecutionException;
41+
import java.util.concurrent.ExecutorService;
42+
import java.util.concurrent.Executors;
43+
import java.util.concurrent.Future;
44+
import java.util.concurrent.RejectedExecutionException;
45+
import java.util.concurrent.Semaphore;
46+
import java.util.concurrent.TimeUnit;
47+
import java.util.concurrent.TimeoutException;
48+
import java.util.concurrent.atomic.AtomicBoolean;
49+
50+
import javax.net.ssl.SSLEngine;
51+
5552
import org.jboss.netty.bootstrap.ClientBootstrap;
5653
import org.jboss.netty.buffer.ChannelBuffer;
5754
import org.jboss.netty.buffer.ChannelBufferOutputStream;
@@ -92,38 +89,43 @@
9289
import org.slf4j.Logger;
9390
import org.slf4j.LoggerFactory;
9491

95-
import javax.net.ssl.SSLEngine;
96-
import java.io.File;
97-
import java.io.FileInputStream;
98-
import java.io.IOException;
99-
import java.io.RandomAccessFile;
100-
import java.net.ConnectException;
101-
import java.net.InetSocketAddress;
102-
import java.net.MalformedURLException;
103-
import java.net.URI;
104-
import java.nio.channels.ClosedChannelException;
105-
import java.nio.channels.FileChannel;
106-
import java.nio.channels.WritableByteChannel;
107-
import java.security.GeneralSecurityException;
108-
import java.security.NoSuchAlgorithmException;
109-
import java.util.ArrayList;
110-
import java.util.Collection;
111-
import java.util.Iterator;
112-
import java.util.List;
113-
import java.util.Map.Entry;
114-
import java.util.concurrent.Callable;
115-
import java.util.concurrent.ExecutionException;
116-
import java.util.concurrent.ExecutorService;
117-
import java.util.concurrent.Executors;
118-
import java.util.concurrent.Future;
119-
import java.util.concurrent.RejectedExecutionException;
120-
import java.util.concurrent.Semaphore;
121-
import java.util.concurrent.TimeUnit;
122-
import java.util.concurrent.TimeoutException;
123-
import java.util.concurrent.atomic.AtomicBoolean;
124-
125-
import static com.ning.http.util.AsyncHttpProviderUtils.DEFAULT_CHARSET;
126-
import static org.jboss.netty.channel.Channels.pipeline;
92+
import com.ning.http.client.AsyncHandler;
93+
import com.ning.http.client.AsyncHandler.STATE;
94+
import com.ning.http.client.AsyncHttpClientConfig;
95+
import com.ning.http.client.AsyncHttpProvider;
96+
import com.ning.http.client.Body;
97+
import com.ning.http.client.ConnectionsPool;
98+
import com.ning.http.client.Cookie;
99+
import com.ning.http.client.FluentCaseInsensitiveStringsMap;
100+
import com.ning.http.client.HttpResponseBodyPart;
101+
import com.ning.http.client.HttpResponseHeaders;
102+
import com.ning.http.client.HttpResponseStatus;
103+
import com.ning.http.client.ListenableFuture;
104+
import com.ning.http.client.MaxRedirectException;
105+
import com.ning.http.client.PerRequestConfig;
106+
import com.ning.http.client.ProgressAsyncHandler;
107+
import com.ning.http.client.ProxyServer;
108+
import com.ning.http.client.RandomAccessBody;
109+
import com.ning.http.client.Realm;
110+
import com.ning.http.client.Request;
111+
import com.ning.http.client.RequestBuilder;
112+
import com.ning.http.client.Response;
113+
import com.ning.http.client.filter.FilterContext;
114+
import com.ning.http.client.filter.FilterException;
115+
import com.ning.http.client.filter.IOExceptionFilter;
116+
import com.ning.http.client.filter.ResponseFilter;
117+
import com.ning.http.client.listener.TransferCompletionHandler;
118+
import com.ning.http.client.ntlm.NTLMEngine;
119+
import com.ning.http.client.ntlm.NTLMEngineException;
120+
import com.ning.http.client.providers.netty.spnego.SpnegoEngine;
121+
import com.ning.http.multipart.MultipartBody;
122+
import com.ning.http.multipart.MultipartRequestEntity;
123+
import com.ning.http.util.AsyncHttpProviderUtils;
124+
import com.ning.http.util.AuthenticatorUtils;
125+
import com.ning.http.util.CleanupChannelGroup;
126+
import com.ning.http.util.ProxyUtils;
127+
import com.ning.http.util.SslUtils;
128+
import com.ning.http.util.UTF8UrlEncoder;
127129

128130
public class NettyAsyncHttpProvider extends SimpleChannelUpstreamHandler implements AsyncHttpProvider {
129131
private final static String HTTP_HANDLER = "httpHandler";
@@ -1101,8 +1103,7 @@ public void messageReceived(final ChannelHandlerContext ctx, MessageEvent e) thr
11011103
} else {
11021104
Realm.RealmBuilder realmBuilder;
11031105
if (realm != null) {
1104-
realmBuilder = new Realm.RealmBuilder().clone(realm).setScheme(realm.getAuthScheme())
1105-
;
1106+
realmBuilder = new Realm.RealmBuilder().clone(realm).setScheme(realm.getAuthScheme());
11061107
} else {
11071108
realmBuilder = new Realm.RealmBuilder();
11081109
}
@@ -1114,7 +1115,9 @@ public void messageReceived(final ChannelHandlerContext ctx, MessageEvent e) thr
11141115
.build();
11151116
}
11161117

1117-
final Realm nr = newRealm;
1118+
// final Realm nr = newRealm;
1119+
final Realm nr = new Realm.RealmBuilder().clone(newRealm)
1120+
.setUri(request.getUrl()).build();
11181121

11191122
log.debug("Sending authentication to {}", request.getUrl());
11201123
AsyncCallable ac = new AsyncCallable(future) {

src/main/java/com/ning/http/util/AuthenticatorUtils.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
*/
1313
package com.ning.http.util;
1414

15-
import com.ning.http.client.ProxyServer;
16-
import com.ning.http.client.Realm;
17-
1815
import java.io.UnsupportedEncodingException;
1916
import java.security.NoSuchAlgorithmException;
2017

18+
import com.ning.http.client.ProxyServer;
19+
import com.ning.http.client.Realm;
20+
2121
public final class AuthenticatorUtils {
2222

2323
public static String computeBasicAuthentication(Realm realm) throws UnsupportedEncodingException {
@@ -40,6 +40,8 @@ public static String computeDigestAuthentication(Realm realm) throws NoSuchAlgor
4040
builder.append("algorithm").append('=').append(realm.getAlgorithm()).append(", ");
4141

4242
construct(builder, "response", realm.getResponse());
43+
if (realm.getOpaque() != null && realm.getOpaque().isEmpty() == false)
44+
construct(builder, "opaque", realm.getOpaque());
4345
builder.append("qop").append('=').append(realm.getQop()).append(", ");
4446
builder.append("nc").append('=').append(realm.getNc()).append(", ");
4547
construct(builder, "cnonce", realm.getCnonce(), true);

0 commit comments

Comments
 (0)