hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1181082 - in /httpcomponents/httpclient/trunk/httpclient/src: main/java/org/apache/http/client/protocol/ main/java/org/apache/http/impl/client/ test/java/org/apache/http/impl/client/
Date Mon, 10 Oct 2011 17:22:32 GMT
Author: olegk
Date: Mon Oct 10 17:22:32 2011
New Revision: 1181082

URL: http://svn.apache.org/viewvc?rev=1181082&view=rev
Log:
HTTPCLIENT-1129: Better handling of unexpected authentication failures in the SUCCESS auth
state

Added:
    httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestClientReauthentication.java
  (with props)
Modified:
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/protocol/RequestAuthCache.java
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
    httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpAuthenticator.java

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/protocol/RequestAuthCache.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/protocol/RequestAuthCache.java?rev=1181082&r1=1181081&r2=1181082&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/protocol/RequestAuthCache.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/client/protocol/RequestAuthCache.java
Mon Oct 10 17:22:32 2011
@@ -36,6 +36,7 @@ import org.apache.http.HttpHost;
 import org.apache.http.HttpRequest;
 import org.apache.http.HttpRequestInterceptor;
 import org.apache.http.annotation.Immutable;
+import org.apache.http.auth.AuthProtocolState;
 import org.apache.http.auth.AuthScheme;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.AuthState;
@@ -95,7 +96,7 @@ public class RequestAuthCache implements
         }
 
         AuthState targetState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
-        if (target != null && targetState != null && targetState.getAuthScheme()
== null) {
+        if (target != null && targetState != null && targetState.getState()
== AuthProtocolState.UNCHALLENGED) {
             AuthScheme authScheme = authCache.get(target);
             if (authScheme != null) {
                 doPreemptiveAuth(target, authScheme, targetState, credsProvider);
@@ -104,7 +105,7 @@ public class RequestAuthCache implements
 
         HttpHost proxy = (HttpHost) context.getAttribute(ExecutionContext.HTTP_PROXY_HOST);
         AuthState proxyState = (AuthState) context.getAttribute(ClientContext.PROXY_AUTH_STATE);
-        if (proxy != null && proxyState != null && proxyState.getAuthScheme()
== null) {
+        if (proxy != null && proxyState != null && proxyState.getState()
== AuthProtocolState.UNCHALLENGED) {
             AuthScheme authScheme = authCache.get(proxy);
             if (authScheme != null) {
                 doPreemptiveAuth(proxy, authScheme, proxyState, credsProvider);

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java?rev=1181082&r1=1181081&r2=1181082&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/DefaultRequestDirector.java
Mon Oct 10 17:22:32 2011
@@ -184,9 +184,9 @@ public class DefaultRequestDirector impl
     /** The currently allocated connection. */
     protected ManagedClientConnection managedConn;
 
-    protected final AuthState targetAuthState;
+    protected AuthState targetAuthState;
 
-    protected final AuthState proxyAuthState;
+    protected AuthState proxyAuthState;
 
     private final HttpAuthenticator authenticator;
 
@@ -352,8 +352,6 @@ public class DefaultRequestDirector impl
         this.execCount = 0;
         this.redirectCount = 0;
         this.maxRedirects = this.params.getIntParameter(ClientPNames.MAX_REDIRECTS, 100);
-        this.targetAuthState = new AuthState();
-        this.proxyAuthState = new AuthState();
     }
 
 
@@ -402,6 +400,17 @@ public class DefaultRequestDirector impl
                                 HttpContext context)
         throws HttpException, IOException {
 
+        targetAuthState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE);
+        if (targetAuthState == null) {
+            targetAuthState = new AuthState();
+            context.setAttribute(ClientContext.TARGET_AUTH_STATE, targetAuthState);
+        }
+        proxyAuthState = (AuthState) context.getAttribute(ClientContext.PROXY_AUTH_STATE);
+        if (proxyAuthState == null) {
+            proxyAuthState = new AuthState();
+            context.setAttribute(ClientContext.PROXY_AUTH_STATE, proxyAuthState);
+        }
+
         HttpRequest orig = request;
         RequestWrapper origWrapper = wrapRequest(orig);
         origWrapper.setParams(params);
@@ -502,16 +511,9 @@ public class DefaultRequestDirector impl
                 HttpHost proxy = route.getProxyHost();
 
                 // Populate the execution context
-                context.setAttribute(ExecutionContext.HTTP_TARGET_HOST,
-                        target);
-                context.setAttribute(ExecutionContext.HTTP_PROXY_HOST,
-                        proxy);
-                context.setAttribute(ExecutionContext.HTTP_CONNECTION,
-                        managedConn);
-                context.setAttribute(ClientContext.TARGET_AUTH_STATE,
-                        targetAuthState);
-                context.setAttribute(ClientContext.PROXY_AUTH_STATE,
-                        proxyAuthState);
+                context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
+                context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy);
+                context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn);
 
                 // Run request protocol interceptors
                 requestExec.preProcess(wrapper, httpProcessor, context);
@@ -619,10 +621,10 @@ public class DefaultRequestDirector impl
             final RoutedRequest req, final HttpContext context) throws HttpException, IOException
{
         HttpRoute route = req.getRoute();
         HttpRequest wrapper = req.getRequest();
-        context.setAttribute(ExecutionContext.HTTP_REQUEST, wrapper);
 
         int connectCount = 0;
         for (;;) {
+            context.setAttribute(ExecutionContext.HTTP_REQUEST, wrapper);
             // Increment connect count
             connectCount++;
             try {
@@ -879,18 +881,10 @@ public class DefaultRequestDirector impl
             connect.setParams(this.params);
 
             // Populate the execution context
-            context.setAttribute(ExecutionContext.HTTP_TARGET_HOST,
-                    target);
-            context.setAttribute(ExecutionContext.HTTP_PROXY_HOST,
-                    proxy);
-            context.setAttribute(ExecutionContext.HTTP_CONNECTION,
-                    managedConn);
-            context.setAttribute(ClientContext.TARGET_AUTH_STATE,
-                    targetAuthState);
-            context.setAttribute(ClientContext.PROXY_AUTH_STATE,
-                    proxyAuthState);
-            context.setAttribute(ExecutionContext.HTTP_REQUEST,
-                    connect);
+            context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, target);
+            context.setAttribute(ExecutionContext.HTTP_PROXY_HOST, proxy);
+            context.setAttribute(ExecutionContext.HTTP_CONNECTION, managedConn);
+            context.setAttribute(ExecutionContext.HTTP_REQUEST, connect);
 
             this.requestExec.preProcess(connect, this.httpProcessor, context);
 

Modified: httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpAuthenticator.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpAuthenticator.java?rev=1181082&r1=1181081&r2=1181082&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpAuthenticator.java
(original)
+++ httpcomponents/httpclient/trunk/httpclient/src/main/java/org/apache/http/impl/client/HttpAuthenticator.java
Mon Oct 10 17:22:32 2011
@@ -70,6 +70,8 @@ public class HttpAuthenticator {
             case HANDSHAKE:
                 authState.setState(AuthProtocolState.SUCCESS);
                 break;
+            case SUCCESS:
+                break;
             default:
                 authState.setState(AuthProtocolState.UNCHALLENGED);
             }
@@ -98,6 +100,8 @@ public class HttpAuthenticator {
             case FAILURE:
                 return false;
             case SUCCESS:
+                authState.invalidate();
+                break;
             case CHALLENGED:
                 if (authScheme == null) {
                     this.log.debug("Auth scheme is null");

Added: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestClientReauthentication.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestClientReauthentication.java?rev=1181082&view=auto
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestClientReauthentication.java
(added)
+++ httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestClientReauthentication.java
Mon Oct 10 17:22:32 2011
@@ -0,0 +1,163 @@
+/*
+ * ====================================================================
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.http.impl.client;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpResponseInterceptor;
+import org.apache.http.HttpStatus;
+import org.apache.http.auth.AUTH;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.localserver.BasicServerTestBase;
+import org.apache.http.localserver.LocalTestServer;
+import org.apache.http.localserver.RequestBasicAuth;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.BasicHttpProcessor;
+import org.apache.http.protocol.HTTP;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.protocol.ResponseConnControl;
+import org.apache.http.protocol.ResponseContent;
+import org.apache.http.protocol.ResponseDate;
+import org.apache.http.protocol.ResponseServer;
+import org.apache.http.util.EntityUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class TestClientReauthentication extends BasicServerTestBase {
+
+    public class ResponseBasicUnauthorized implements HttpResponseInterceptor {
+
+        public void process(
+                final HttpResponse response,
+                final HttpContext context) throws HttpException, IOException {
+            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
+                response.addHeader(AUTH.WWW_AUTH, "Basic realm=\"test realm\"");
+            }
+        }
+
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        BasicHttpProcessor httpproc = new BasicHttpProcessor();
+        httpproc.addInterceptor(new ResponseDate());
+        httpproc.addInterceptor(new ResponseServer());
+        httpproc.addInterceptor(new ResponseContent());
+        httpproc.addInterceptor(new ResponseConnControl());
+        httpproc.addInterceptor(new RequestBasicAuth());
+        httpproc.addInterceptor(new ResponseBasicUnauthorized());
+
+        this.localServer = new LocalTestServer(httpproc, null);
+        this.httpclient = new DefaultHttpClient();
+    }
+
+    static class AuthHandler implements HttpRequestHandler {
+
+        private AtomicLong count = new AtomicLong(0);
+
+        public void handle(
+                final HttpRequest request,
+                final HttpResponse response,
+                final HttpContext context) throws HttpException, IOException {
+            String creds = (String) context.getAttribute("creds");
+            if (creds == null || !creds.equals("test:test")) {
+                response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
+            } else {
+                // Make client re-authenticate on each fourth request
+                if (this.count.incrementAndGet() % 4 == 0) {
+                    response.setStatusCode(HttpStatus.SC_UNAUTHORIZED);
+                } else {
+                    response.setStatusCode(HttpStatus.SC_OK);
+                    StringEntity entity = new StringEntity("success", HTTP.ASCII);
+                    response.setEntity(entity);
+                }
+            }
+        }
+
+    }
+
+    static class TestCredentialsProvider implements CredentialsProvider {
+
+        private final Credentials creds;
+        private AuthScope authscope;
+
+        TestCredentialsProvider(final Credentials creds) {
+            super();
+            this.creds = creds;
+        }
+
+        public void clear() {
+        }
+
+        public Credentials getCredentials(AuthScope authscope) {
+            this.authscope = authscope;
+            return this.creds;
+        }
+
+        public void setCredentials(AuthScope authscope, Credentials credentials) {
+        }
+
+        public AuthScope getAuthScope() {
+            return this.authscope;
+        }
+
+    }
+
+    @Test
+    public void testBasicAuthenticationSuccess() throws Exception {
+        this.localServer.register("*", new AuthHandler());
+        this.localServer.start();
+
+        TestCredentialsProvider credsProvider = new TestCredentialsProvider(
+                new UsernamePasswordCredentials("test", "test"));
+
+        this.httpclient.setCredentialsProvider(credsProvider);
+
+        HttpContext context = new BasicHttpContext();
+        for (int i = 0; i < 10; i++) {
+            HttpGet httpget = new HttpGet("/");
+            System.out.println("count " + i);
+            HttpResponse response = this.httpclient.execute(getServerHttp(), httpget, context);
+            HttpEntity entity = response.getEntity();
+            Assert.assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
+            Assert.assertNotNull(entity);
+            EntityUtils.consume(entity);
+        }
+    }
+
+}

Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestClientReauthentication.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestClientReauthentication.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: httpcomponents/httpclient/trunk/httpclient/src/test/java/org/apache/http/impl/client/TestClientReauthentication.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain



Mime
View raw message