Skip to content

Commit

Permalink
Don't loop forever when credentials are invalid, close #994
Browse files Browse the repository at this point in the history
  • Loading branch information
slandelle committed Oct 13, 2015
1 parent 6c3e229 commit fe2a1bc
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 25 deletions.
Expand Up @@ -69,6 +69,7 @@ public enum STATE {
private final AtomicBoolean isCancelled = new AtomicBoolean(false);
private final AtomicInteger redirectCount = new AtomicInteger();
private final AtomicBoolean inAuth = new AtomicBoolean(false);
private final AtomicBoolean inProxyAuth = new AtomicBoolean(false);
private final AtomicBoolean statusReceived = new AtomicBoolean(false);
private final AtomicLong touch = new AtomicLong(millisTime());
private final AtomicReference<STATE> state = new AtomicReference<>(STATE.NEW);
Expand Down Expand Up @@ -339,12 +340,12 @@ public void setTimeoutsHolder(TimeoutsHolder timeoutsHolder) {
this.timeoutsHolder = timeoutsHolder;
}

public boolean isInAuth() {
return inAuth.get();
public AtomicBoolean getInAuth() {
return inAuth;
}

public boolean getAndSetAuth(boolean inDigestAuth) {
return inAuth.getAndSet(inDigestAuth);
public AtomicBoolean getInProxyAuth() {
return inProxyAuth;
}

public STATE getState() {
Expand Down Expand Up @@ -442,7 +443,7 @@ public void setCurrentRequest(Request currentRequest) {
*/
public boolean canBeReplayed() {
return !isDone() && canRetry()
&& !(Channels.isChannelValid(channel) && !getUri().getScheme().equalsIgnoreCase("https")) && !isInAuth();
&& !(Channels.isChannelValid(channel) && !getUri().getScheme().equalsIgnoreCase("https")) && !inAuth.get() && !inProxyAuth.get();
}

public long getStart() {
Expand Down
Expand Up @@ -100,7 +100,7 @@ private void ntlmChallenge(String authenticateHeader,//
// FIXME we might want to filter current NTLM and add (leave other
// Authorization headers untouched)
headers.set(HttpHeaders.Names.AUTHORIZATION, "NTLM " + challengeHeader);
future.getAndSetAuth(false);
future.getInAuth().set(false);

} else {
String serverChallenge = authenticateHeader.substring("NTLM ".length()).trim();
Expand All @@ -117,16 +117,13 @@ private void ntlmProxyChallenge(String authenticateHeader,//
HttpHeaders headers,//
NettyResponseFuture<?> future) {

// FIXME what's this?????
future.getAndSetAuth(false);

if (authenticateHeader.equals("NTLM")) {
// server replied bare NTLM => we didn't preemptively sent Type1Msg
String challengeHeader = NtlmEngine.INSTANCE.generateType1Msg();
// FIXME we might want to filter current NTLM and add (leave other
// Authorization headers untouched)
headers.set(HttpHeaders.Names.PROXY_AUTHORIZATION, "NTLM " + challengeHeader);
future.getAndSetAuth(false);
future.getInProxyAuth().set(false);

} else {
String serverChallenge = authenticateHeader.substring("NTLM ".length()).trim();
Expand Down Expand Up @@ -198,7 +195,7 @@ private boolean exitAfterHandling401(//
return false;
}

if (future.getAndSetAuth(true)) {
if (future.getInAuth().getAndSet(true)) {
logger.info("Can't handle 401 as auth was already performed");
return false;
}
Expand Down Expand Up @@ -322,23 +319,22 @@ private boolean exitAfterHandling407(//
if (statusCode != PROXY_AUTHENTICATION_REQUIRED.code())
return false;

if (future.getInProxyAuth().getAndSet(true)) {
logger.info("Can't handle 407 as auth was already performed");
return false;
}

Realm proxyRealm = future.getProxyRealm();

if (proxyRealm == null) {
logger.info("Can't handle 407 as there's no proxyRealm");
return false;
}

// FIXME no good: mess direct and proxy auth
if (future.getAndSetAuth(true)) {
logger.info("Can't handle 407 as auth was already performed");
return false;
}

List<String> proxyAuthHeaders = response.headers().getAll(HttpHeaders.Names.PROXY_AUTHENTICATE);

if (proxyAuthHeaders.isEmpty()) {
logger.info("Can't handle 401 as response doesn't contain Proxy-Authenticate headers");
logger.info("Can't handle 407 as response doesn't contain Proxy-Authenticate headers");
return false;
}

Expand Down
Expand Up @@ -112,8 +112,9 @@ protected boolean exitAfterHandlingRedirect(//
throw maxRedirectException;

} else {
// We must allow 401 handling again.
future.getAndSetAuth(false);
// We must allow auth handling again.
future.getInAuth().set(false);
future.getInProxyAuth().set(false);

String originalMethod = request.getMethod();
boolean switchToGet = !originalMethod.equals(HttpMethod.GET.name()) && (statusCode == 301 || statusCode == 303 || (statusCode == 302 && !config.isStrict302Handling()));
Expand Down
Expand Up @@ -35,6 +35,7 @@
import org.asynchttpclient.ListenableFuture;
import org.asynchttpclient.Realm;
import org.asynchttpclient.Request;
import org.asynchttpclient.Realm.AuthScheme;
import org.asynchttpclient.filter.FilterContext;
import org.asynchttpclient.filter.FilterException;
import org.asynchttpclient.filter.IOExceptionFilter;
Expand Down Expand Up @@ -236,6 +237,9 @@ private <T> ListenableFuture<T> sendRequestWithNewChannel(//
Realm proxyRealm = future.getProxyRealm();
requestFactory.addAuthorizationHeader(headers, perConnectionAuthorizationHeader(request, proxy, realm));
requestFactory.setProxyAuthorizationHeader(headers, perConnectionProxyAuthorizationHeader(request, proxyRealm));

future.getInAuth().set(realm != null && realm.isUsePreemptiveAuth() && realm.getScheme() != AuthScheme.NTLM);
future.getInProxyAuth().set(proxyRealm != null && proxyRealm.isUsePreemptiveAuth() && proxyRealm.getScheme() != AuthScheme.NTLM);

// Do not throw an exception when we need an extra connection for a redirect
// FIXME why? This violate the max connection per host handling, right?
Expand Down
Expand Up @@ -20,7 +20,6 @@
import java.nio.channels.ClosedChannelException;

import org.asynchttpclient.AsyncHandler;
import org.asynchttpclient.Realm;
import org.asynchttpclient.handler.ProgressAsyncHandler;
import org.asynchttpclient.netty.NettyResponseFuture;
import org.asynchttpclient.netty.channel.Channels;
Expand Down Expand Up @@ -78,10 +77,9 @@ public void operationComplete(ChannelProgressiveFuture cf) {
* same event after the authorization, causing unpredictable
* behavior.
*/
// FIXME what about proxy auth?
Realm realm = future.getRealm();
boolean startPublishing = future.isInAuth() || realm == null || realm.isUsePreemptiveAuth();

// FIXME Don't get it?!
boolean startPublishing = future.getInAuth().get() || future.getInProxyAuth().get();

if (startPublishing && asyncHandler instanceof ProgressAsyncHandler) {
ProgressAsyncHandler<?> progressAsyncHandler = (ProgressAsyncHandler<?>) asyncHandler;
if (notifyHeaders) {
Expand Down

0 comments on commit fe2a1bc

Please sign in to comment.