commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject cvs commit: jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth TestChallengeParser.java TestChallengeProcessor.java TestBasicAuth.java
Date Thu, 25 Mar 2004 20:37:20 GMT
olegk       2004/03/25 12:37:20

  Modified:    httpclient/src/java/org/apache/commons/httpclient
                        HttpMethod.java HttpMethodBase.java
                        HttpMethodDirector.java
               httpclient/src/test/org/apache/commons/httpclient
                        TestExceptions.java TestNoHost.java
               httpclient/src/test/org/apache/commons/httpclient/auth
                        TestBasicAuth.java
  Added:       httpclient/src/java/org/apache/commons/httpclient/auth
                        AuthChallengeException.java
                        AuthChallengeProcessor.java AuthState.java
               httpclient/src/test/org/apache/commons/httpclient/auth
                        TestChallengeParser.java
                        TestChallengeProcessor.java
  Removed:     httpclient/src/test/org/apache/commons/httpclient
                        TestChallengeParser.java
  Log:
  PR #25529 (Redesign of HTTP authentication framework)
  
  Changelog:
  
  * Factored out the authentication challenge processing logic from the
  HttpMethodDirector to a class of its own. Thanks to that authentication
  challenge processing can now be tested separately. Test cases provided.
  
  * HttpMethodDirector no longer intervenes if Authorization &
  Proxy-Authorization are set manually by the user. Custom authorization
  headers are never overwritten
  
  * Introduced a new class called AuthState that represents the
  authentication process state that contains all the authentication
  details. Basically it is just a convenience wrapper around the
  authentication scheme interface.
  
  * Proxy and host authentication state objects moved to the HTTP method
  level, so that they can be queried by the user to find out the details
  about authentication that has been performed by the HttpMethodDirector.
  With the current implementation all the details of proxy and host
  authentication are contained within the HttpMethodDirector instance,
  which exists only within the lifetime of HttpClient#executeMethod()
  execution. As soon as the method returns, the respective
  HttpMethodDirector instance gets GCed along with the authentication
  details
  
  * More test cases
  
  Contributed by Oleg Kalnichevski
  Reviewed by Michael Becke
  
  Revision  Changes    Path
  1.35      +30 -4     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethod.java
  
  Index: HttpMethod.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethod.java,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -r1.34 -r1.35
  --- HttpMethod.java	22 Feb 2004 18:08:45 -0000	1.34
  +++ HttpMethod.java	25 Mar 2004 20:37:19 -0000	1.35
  @@ -34,6 +34,7 @@
   import java.io.IOException;
   import java.io.InputStream;
   
  +import org.apache.commons.httpclient.auth.AuthState;
   import org.apache.commons.httpclient.params.*;
   
   
  @@ -211,6 +212,13 @@
       void removeRequestHeader(String headerName);
   
       /**
  +     * Removes the given request header.
  +     * 
  +     * @param header the header
  +     */
  +    void removeRequestHeader(Header header);
  +
  +    /**
        * Returns <tt>true</tt> if the HTTP method should automatically follow HTTP redirects 
        * (status code 302, etc.), <tt>false</tt> otherwise.
        * 
  @@ -531,5 +539,23 @@
        * @param handler the methodRetryHandler to use when this method executed
        */
       public void setMethodRetryHandler(MethodRetryHandler handler);
  +
  +    /**
  +     * Returns the target host {@link AuthState authentication state}
  +     * 
  +     * @return host authentication state
  +     * 
  +     * @since 3.0
  +     */
  +    public AuthState getHostAuthState();
  +
  +    /**
  +     * Returns the proxy {@link AuthState authentication state}
  +     * 
  +     * @return host authentication state
  +     * 
  +     * @since 3.0
  +     */
  +    public AuthState getProxyAuthState();
   
   }
  
  
  
  1.202     +52 -10    jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java
  
  Index: HttpMethodBase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodBase.java,v
  retrieving revision 1.201
  retrieving revision 1.202
  diff -u -r1.201 -r1.202
  --- HttpMethodBase.java	9 Mar 2004 14:01:02 -0000	1.201
  +++ HttpMethodBase.java	25 Mar 2004 20:37:19 -0000	1.202
  @@ -36,6 +36,7 @@
   import java.io.IOException;
   import java.io.InputStream;
   
  +import org.apache.commons.httpclient.auth.AuthState;
   import org.apache.commons.httpclient.cookie.CookiePolicy;
   import org.apache.commons.httpclient.cookie.CookieSpec;
   import org.apache.commons.httpclient.cookie.MalformedCookieException;
  @@ -139,6 +140,12 @@
       /** HTTP protocol parameters. */
       private HttpMethodParams params = new HttpMethodParams();
   
  +    /** Host authentication state */
  +    private AuthState hostAuthState = new AuthState();
  +
  +    /** Proxy authentication state */
  +    private AuthState proxyAuthState = new AuthState();
  +
       /** True if this method has already been executed. */
       private boolean used = false;
   
  @@ -998,6 +1005,8 @@
           responseBody = null;
           recoverableExceptionCount = 0;
           connectionCloseForced = false;
  +        hostAuthState.invalidate();
  +        proxyAuthState.invalidate();
       }
   
       /**
  @@ -1040,6 +1049,18 @@
           }
           
       }
  +    
  +    /**
  +     * Removes the given request header.
  +     * 
  +     * @param header the header
  +     */
  +    public void removeRequestHeader(final Header header) {
  +        if (header == null) {
  +            return;
  +        }
  +        getRequestHeaderGroup().removeHeader(header);
  +    }
   
       // ---------------------------------------------------------------- Queries
   
  @@ -2039,27 +2060,27 @@
       }
   
       /**
  -     * @deprecated no longer used
  -     * 
        * Returns proxy authentication realm, if it has been used during authentication process. 
        * Otherwise returns <tt>null</tt>.
        * 
        * @return proxy authentication realm
  +     * 
  +     * @deprecated use #getProxyAuthState()
        */
       public String getProxyAuthenticationRealm() {
  -        return null;
  +        return this.proxyAuthState.getRealm();
       }
   
       /**
  -     * @deprecated no longer used
  -     * 
        * Returns authentication realm, if it has been used during authentication process. 
        * Otherwise returns <tt>null</tt>.
        * 
        * @return authentication realm
  +     * 
  +     * @deprecated use #getHostAuthState()
        */
       public String getAuthenticationRealm() {
  -        return null;
  +        return this.hostAuthState.getRealm();
       }
   
       /**
  @@ -2241,4 +2262,25 @@
           this.responseStream = responseStream;
       }
       
  +    /**
  +     * Returns the target host {@link AuthState authentication state}
  +     * 
  +     * @return host authentication state
  +     * 
  +     * @since 3.0
  +     */
  +    public AuthState getHostAuthState() {
  +        return this.hostAuthState;
  +    }
  +
  +    /**
  +     * Returns the proxy {@link AuthState authentication state}
  +     * 
  +     * @return host authentication state
  +     * 
  +     * @since 3.0
  +     */
  +    public AuthState getProxyAuthState() {
  +        return this.proxyAuthState;
  +    }
   }
  
  
  
  1.19      +101 -170  jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java
  
  Index: HttpMethodDirector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpMethodDirector.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- HttpMethodDirector.java	22 Feb 2004 18:08:46 -0000	1.18
  +++ HttpMethodDirector.java	25 Mar 2004 20:37:19 -0000	1.19
  @@ -32,13 +32,13 @@
   package org.apache.commons.httpclient;
   
   import java.io.IOException;
  -import java.util.Collection;
  -import java.util.Iterator;
   import java.util.Map;
   
  +import org.apache.commons.httpclient.auth.AuthChallengeException;
   import org.apache.commons.httpclient.auth.AuthChallengeParser;
  -import org.apache.commons.httpclient.auth.AuthPolicy;
  +import org.apache.commons.httpclient.auth.AuthChallengeProcessor;
   import org.apache.commons.httpclient.auth.AuthScheme;
  +import org.apache.commons.httpclient.auth.AuthState;
   import org.apache.commons.httpclient.auth.AuthenticationException;
   import org.apache.commons.httpclient.auth.CredentialsProvider;
   import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
  @@ -93,20 +93,11 @@
       private static final int AUTH_NOT_REQUIRED = Integer.MAX_VALUE;
   
       /** Actual state of authentication process */
  -    private int authState = AUTH_UNINITIATED;
  +    private int authProcess = AUTH_UNINITIATED;
       
  -    /** Actual authentication scheme */
  -    private AuthScheme authScheme = null;
  +    /** Authentication processor */
  +    private AuthChallengeProcessor authProcessor = null;
   
  -    /** Whether preemtive authentication is attempted */
  -    private boolean authPreemptive  = false; 
  -      
  -    /** Actual proxy authentication scheme */
  -    private AuthScheme proxyAuthScheme = null;
  -
  -    /** Whether preemtive proxy authentication is attempted */
  -    private boolean proxyAuthPreemptive  = false; 
  -      
       public HttpMethodDirector(
           final HttpConnectionManager connectionManager,
           final HostConfiguration hostConfiguration,
  @@ -118,6 +109,7 @@
           this.hostConfiguration = hostConfiguration;
           this.params = params;
           this.state = state;
  +        this.authProcessor = new AuthChallengeProcessor(this.params);
       }
       
   	
  @@ -128,9 +120,7 @@
        * @throws HttpException
        */
       public void executeMethod(final HttpMethod method) throws IOException, HttpException {
  -        
  -        if (method == null)
  -        {
  +        if (method == null) {
               throw new IllegalArgumentException("Method may not be null");
           }
           method.getParams().setDefaults(this.params);
  @@ -161,12 +151,10 @@
                        || this.state.isAuthenticationPreemptive()) 
                       {
                           LOG.debug("Preemptively sending default basic credentials");
  -                        this.authState = AUTH_PREEMPTIVE;
  -                        this.authScheme = AuthPolicy.getAuthScheme("basic");
  -                        this.authPreemptive = true;
  +                        this.authProcess = AUTH_PREEMPTIVE;
  +                        method.getHostAuthState().setPreemptive();
                           if (this.conn.isProxied()) {
  -                            this.proxyAuthPreemptive = true;
  -                            this.proxyAuthScheme = AuthPolicy.getAuthScheme("basic");
  +                            method.getProxyAuthState().setPreemptive();
                           }
                       }
                   }
  @@ -188,7 +176,7 @@
                           retry = true;
                       }
                   } else {
  -                    this.authState = AUTH_NOT_REQUIRED;
  +                    this.authProcess = AUTH_NOT_REQUIRED;
                   }
                   if (!retry) {
                       break;
  @@ -237,14 +225,33 @@
           }
       }
   
  +
  +    private boolean cleanAuthHeaders(final HttpMethod method, final String name) {
  +        Header[] authheaders = method.getRequestHeaders(name);
  +        boolean clean = true;
  +        for (int i = 0; i < authheaders.length; i++) {
  +            Header authheader = authheaders[i];
  +            if (authheader.isAutogenerated()) {
  +                method.removeRequestHeader(authheader);
  +            } else {
  +                clean = false;
  +            }
  +        }
  +        return clean;
  +    }
       
  +
       private void authenticateHost(final HttpMethod method) throws AuthenticationException {
           // Clean up existing authentication headers
  -        method.removeRequestHeader(WWW_AUTH_RESP);
  -        if ((this.authScheme != null) 
  -         && ((this.authState == AUTH_WWW_REQUIRED) 
  -          || (!this.authScheme.isConnectionBased())))
  -        {
  +        if (!cleanAuthHeaders(method, WWW_AUTH_RESP)) {
  +            // User defined authentication header(s) present
  +            return;
  +        }
  +        AuthScheme authscheme = method.getHostAuthState().getAuthScheme();
  +        if (authscheme == null) {
  +            return;
  +        }
  +        if ((this.authProcess == AUTH_WWW_REQUIRED) || (!authscheme.isConnectionBased())) {
               String host = conn.getVirtualHost();
               if (host == null) {
                   host = conn.getHost();
  @@ -252,14 +259,14 @@
               int port = conn.getPort();
               HttpAuthRealm realm = new HttpAuthRealm(
                   host, port, 
  -                this.authScheme.getRealm(), 
  -                this.authScheme.getSchemeName());  
  +                authscheme.getRealm(), 
  +                authscheme.getSchemeName());  
               if (LOG.isDebugEnabled()) {
                   LOG.debug("Authenticating with " + realm);
               }
               Credentials credentials = this.state.getCredentials(realm);
               if (credentials != null) {
  -                String authstring = this.authScheme.authenticate(credentials, method);
  +                String authstring = authscheme.authenticate(credentials, method);
                   if (authstring != null) {
                       method.addRequestHeader(new Header(WWW_AUTH_RESP, authstring, true));
                   }
  @@ -272,21 +279,26 @@
   
       private void authenticateProxy(final HttpMethod method) throws AuthenticationException {
           // Clean up existing authentication headers
  -        method.removeRequestHeader(PROXY_AUTH_RESP);
  -        if ((this.proxyAuthScheme != null) 
  -         && ((this.authState == AUTH_PROXY_REQUIRED) 
  -          || (!this.proxyAuthScheme.isConnectionBased())))
  -        {
  +        // Clean up existing authentication headers
  +        if (!cleanAuthHeaders(method, PROXY_AUTH_RESP)) {
  +            // User defined authentication header(s) present
  +            return;
  +        }
  +        AuthScheme authscheme = method.getProxyAuthState().getAuthScheme();
  +        if (authscheme == null) {
  +            return;
  +        }
  +        if ((this.authProcess == AUTH_PROXY_REQUIRED) || (!authscheme.isConnectionBased())) {
               HttpAuthRealm realm = new HttpAuthRealm(
                   conn.getProxyHost(), conn.getProxyPort(), 
  -                this.proxyAuthScheme.getRealm(), 
  -                this.proxyAuthScheme.getSchemeName());  
  +                authscheme.getRealm(), 
  +                authscheme.getSchemeName());  
               if (LOG.isDebugEnabled()) {
                   LOG.debug("Authenticating with " + realm);
               }
               Credentials credentials = this.state.getProxyCredentials(realm);
               if (credentials != null) {
  -                String authstring = this.proxyAuthScheme.authenticate(credentials, method);
  +                String authstring = authscheme.authenticate(credentials, method);
                   if (authstring != null) {
                       method.addRequestHeader(new Header(PROXY_AUTH_RESP, authstring, true));
                   }
  @@ -416,7 +428,7 @@
                       retry = true;
                   }
               } else {
  -                this.authState = AUTH_NOT_REQUIRED;
  +                this.authProcess = AUTH_NOT_REQUIRED;
               }
               if (!retry) {
                   break;
  @@ -467,6 +479,8 @@
                   this.connectMethod.getResponseHeaderGroup(),
                   this.connectMethod.getResponseBodyAsStream()
               );
  +            method.getProxyAuthState().setAuthScheme(
  +                this.connectMethod.getProxyAuthState().getAuthScheme());
               this.connectMethod = null;
           } else {
               releaseConnection = true;
  @@ -537,7 +551,7 @@
   		}
   
           //And finally invalidate the actual authentication scheme
  -        this.authScheme = null; 
  +        method.getHostAuthState().invalidate(); 
   		return true;
   	}
   
  @@ -574,21 +588,24 @@
       private boolean processWWWAuthChallenge(final HttpMethod method)
           throws MalformedChallengeException, AuthenticationException  
       {
  -        if (this.authPreemptive) {
  -            this.authScheme = null;
  -            this.authPreemptive = false;
  +        AuthState authstate = method.getHostAuthState();
  +        if (authstate.isPreemptive()) {
  +            authstate.invalidate();
           }
           Map challenges = AuthChallengeParser.parseChallenges(
               method.getResponseHeaders(WWW_AUTH_CHALLENGE));
           if (challenges.isEmpty()) {
               return false; 
           }
  -        if (this.authScheme != null) {
  -            processChallenge(this.authScheme, challenges);
  -        } else {
  -            this.authScheme = processChallenge(challenges);
  +        AuthScheme authscheme = null;
  +        try {
  +            authscheme = this.authProcessor.processChallenge(authstate, challenges);
  +        } catch (AuthChallengeException e) {
  +            if (LOG.isWarnEnabled()) {
  +                LOG.warn(e.getMessage());
  +            }
           }
  -        if (this.authScheme == null) {
  +        if (authscheme == null) {
               return false;
           }
           String host = conn.getVirtualHost();
  @@ -598,13 +615,13 @@
           int port = conn.getPort();
           HttpAuthRealm realm = new HttpAuthRealm(
               host, port, 
  -            this.authScheme.getRealm(), 
  -            this.authScheme.getSchemeName());  
  +            authscheme.getRealm(), 
  +            authscheme.getSchemeName());  
   
  -        if ((this.authState == AUTH_WWW_REQUIRED) 
  -         && (this.authScheme.isComplete())) {
  +        if ((this.authProcess == AUTH_WWW_REQUIRED) && (authscheme.isComplete())) {
               // Already tried and failed
  -            Credentials credentials = promptForCredentials(method.getParams(), realm);
  +            Credentials credentials = promptForCredentials(
  +                authscheme, method.getParams(), realm);
               if (credentials == null) {
                   if (LOG.isInfoEnabled()) {
                       LOG.info("Failure authenticating with " + realm);
  @@ -614,11 +631,12 @@
                   return true;
               }
           } else {
  -            this.authState = AUTH_WWW_REQUIRED;
  +            this.authProcess = AUTH_WWW_REQUIRED;
                           
               Credentials credentials = this.state.getCredentials(realm);
               if (credentials == null) {
  -                credentials = promptForCredentials(method.getParams(), realm);
  +                credentials = promptForCredentials(
  +                    authscheme, method.getParams(), realm);
               }
               if (credentials == null) {
                   if (LOG.isInfoEnabled()) {
  @@ -634,32 +652,35 @@
       private boolean processProxyAuthChallenge(final HttpMethod method)
           throws MalformedChallengeException, AuthenticationException
       {  
  -        if (this.proxyAuthPreemptive) {
  -            this.proxyAuthScheme = null;
  -            this.proxyAuthPreemptive = false;
  +        AuthState authstate = method.getProxyAuthState();
  +        if (authstate.isPreemptive()) {
  +            authstate.invalidate();
           }
           Map proxyChallenges = AuthChallengeParser.parseChallenges(
               method.getResponseHeaders(PROXY_AUTH_CHALLENGE));
           if (proxyChallenges.isEmpty()) {
               return false; 
           }
  -        if (this.proxyAuthScheme != null) {
  -            processChallenge(this.proxyAuthScheme, proxyChallenges);
  -        } else {
  -            this.proxyAuthScheme = processChallenge(proxyChallenges);
  +        AuthScheme authscheme = null;
  +        try {
  +            authscheme = this.authProcessor.processChallenge(authstate, proxyChallenges);
  +        } catch (AuthChallengeException e) {
  +            if (LOG.isWarnEnabled()) {
  +                LOG.warn(e.getMessage());
  +            }
           }
  -        if (this.proxyAuthScheme == null) {
  +        if (authscheme == null) {
               return false;
           }
           HttpAuthRealm realm = new HttpAuthRealm(
               conn.getProxyHost(), conn.getProxyPort(), 
  -            this.proxyAuthScheme.getRealm(), 
  -            this.proxyAuthScheme.getSchemeName());  
  +            authscheme.getRealm(), 
  +            authscheme.getSchemeName());  
   
  -        if ((this.authState == AUTH_PROXY_REQUIRED) 
  -         && (this.proxyAuthScheme.isComplete())) {
  +        if ((this.authProcess == AUTH_PROXY_REQUIRED) && (authscheme.isComplete())) {
               // Already tried and failed
  -            Credentials credentials = promptForProxyCredentials(method.getParams(), realm);
  +            Credentials credentials = promptForProxyCredentials(
  +                authscheme, method.getParams(), realm);
               if (credentials == null) {
                   if (LOG.isInfoEnabled()) {
                       LOG.info("Failure authenticating with " + realm);
  @@ -669,11 +690,12 @@
                   return true;
               }
           } else {
  -            this.authState = AUTH_PROXY_REQUIRED;
  +            this.authProcess = AUTH_PROXY_REQUIRED;
   
               Credentials credentials = this.state.getProxyCredentials(realm);
               if (credentials == null) {
  -                credentials = promptForProxyCredentials(method.getParams(), realm);
  +                credentials = promptForProxyCredentials(
  +                    authscheme, method.getParams(), realm);
               }
               if (credentials == null) {
                   if (LOG.isInfoEnabled()) {
  @@ -686,71 +708,6 @@
           }
       }
   
  -    private void processChallenge(final AuthScheme authscheme, final Map challenges)
  -        throws MalformedChallengeException, AuthenticationException
  -    {    
  -        String id = authscheme.getSchemeName();
  -        if (LOG.isDebugEnabled()) {
  -            LOG.debug("Using present authentication scheme: " + id);
  -        }
  -        String challenge = (String) challenges.get(id.toLowerCase());
  -        if (challenge == null) {
  -            throw new AuthenticationException(id + 
  -                " authorization challenge expected, but not found");
  -        }
  -        authscheme.processChallenge(challenge);
  -    }
  -    
  -    private AuthScheme processChallenge(final Map challenges)
  -        throws MalformedChallengeException, AuthenticationException {    
  -
  -        Collection authPrefs = (Collection) this.params.getParameter(
  -                                                                AuthPolicy.AUTH_SCHEME_PRIORITY);
  -        if (authPrefs == null || authPrefs.isEmpty()) {
  -            authPrefs = AuthPolicy.getDefaultAuthPrefs();    
  -        }
  -                                                                   
  -        AuthScheme authscheme = null;
  -        String challenge = null;
  -        if (LOG.isDebugEnabled()) {
  -            LOG.debug("Supported authentication schemes in the order of preference: " 
  -                + authPrefs);
  -        }
  -        Iterator item = authPrefs.iterator();
  -        while (item.hasNext()) {
  -            String id = (String) item.next();
  -            challenge = (String) challenges.get(id.toLowerCase()); 
  -            if (challenge != null) {
  -                if (LOG.isInfoEnabled()) {
  -                    LOG.info(id + " authentication scheme selected");
  -                }
  -                authscheme = AuthPolicy.getAuthScheme(id);
  -                if (authscheme == null) {    
  -                    throw new AuthenticationException("Requested authorization scheme " +
  -                        id + " is not supported");
  -                }
  -                // Looks like we got something
  -                break;
  -            } else {
  -                if (LOG.isDebugEnabled()) {
  -                    LOG.debug("Challenge for " + id + " authentication scheme not available");
  -                    // Try again
  -                }
  -            }
  -        }
  -        if (authscheme == null) {
  -            // If none selected, something is wrong, warn and leave
  -            if (LOG.isWarnEnabled()) {
  -                LOG.warn("None of the following challenges can be responsed to: "
  -                    + challenges);
  -            }
  -        } else {
  -            // Process the challenge
  -            authscheme.processChallenge(challenge);
  -        }
  -        return authscheme;
  -    }
  -
       /**
        * Tests if the {@link HttpMethod method} requires a redirect to another location.
        * 
  @@ -802,6 +759,7 @@
       }
   
       private Credentials promptForCredentials(
  +        final AuthScheme authScheme,
           final HttpParams params, 
           final HttpAuthRealm realm)
       {
  @@ -811,7 +769,7 @@
           if (credProvider != null) {
               try {
                   creds = credProvider.getCredentials(
  -                    this.authScheme, realm.getHost(), realm.getPort(), false);
  +                    authScheme, realm.getHost(), realm.getPort(), false);
               } catch (CredentialsNotAvailableException e) {
                   LOG.warn(e.getMessage());
               }
  @@ -826,6 +784,7 @@
       }
   
       private Credentials promptForProxyCredentials(
  +        final AuthScheme authScheme,
           final HttpParams params,
           final HttpAuthRealm realm) 
       {
  @@ -835,7 +794,7 @@
           if (credProvider != null) {
               try {
                   creds = credProvider.getCredentials(
  -                    this.proxyAuthScheme, realm.getHost(), realm.getPort(), true);
  +                    authScheme, realm.getHost(), realm.getPort(), true);
               } catch (CredentialsNotAvailableException e) {
                   LOG.warn(e.getMessage());
               }
  @@ -875,33 +834,5 @@
        */
       public HttpParams getParams() {
           return this.params;
  -    }
  -
  -    /**
  -     * Returns the authentication scheme used to authenticate with the 
  -     * target host.
  -     * 
  -     * @return the authentication scheme used to authenticate with the 
  -     * target host. Null is returned if target host authentication
  -     * was not required.
  -     * 
  -     * @since 2.1
  -     */
  -    public AuthScheme getAuthScheme() {
  -        return authScheme;
  -    }
  -
  -    /**
  -     * Returns the authentication scheme used to authenticate with the 
  -     * proxy host.
  -     * 
  -     * @return the authentication scheme used to authenticate with the 
  -     * proxy host. Null is returned if proxy authentication was not 
  -     * required.
  -     * 
  -     * @since 2.1
  -     */
  -    public AuthScheme getProxyAuthScheme() {
  -        return proxyAuthScheme;
       }
   }
  
  
  
  1.1                  jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthChallengeException.java
  
  Index: AuthChallengeException.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthChallengeException.java,v 1.1 2004/03/25 20:37:20 olegk Exp $
   * $Revision: 1.1 $
   * $Date: 2004/03/25 20:37:20 $
   *
   * ====================================================================
   *
   *  Copyright 2002-2004 The Apache Software Foundation
   *
   *  Licensed 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/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.commons.httpclient.auth;
  
  /**
   * Signals a failure processing authentication challenge
   *
   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
   * 
   * @since 3.0
   */
  public class AuthChallengeException extends AuthenticationException {
  
      /**
       * Creates a new AuthChallengeException with a <tt>null</tt> detail message. 
       */
      public AuthChallengeException() {
          super();
      }
  
      /**
       * Creates a new AuthChallengeException with the specified message.
       * 
       * @param message the exception detail message
       */
      public AuthChallengeException(String message) {
          super(message);
      }
  
      /**
       * Creates a new AuthChallengeException with the specified detail message and cause.
       * 
       * @param message the exception detail message
       * @param cause the <tt>Throwable</tt> that caused this exception, or <tt>null</tt>
       * if the cause is unavailable, unknown, or not a <tt>Throwable</tt>
       */
      public AuthChallengeException(String message, Throwable cause) {
          super(message, cause);
      }
  
  }
  
  
  
  1.1                  jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthChallengeProcessor.java
  
  Index: AuthChallengeProcessor.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthChallengeProcessor.java,v 1.1 2004/03/25 20:37:20 olegk Exp $
   * $Revision: 1.1 $
   * $Date: 2004/03/25 20:37:20 $
   *
   * ====================================================================
   *
   *  Copyright 2002-2004 The Apache Software Foundation
   *
   *  Licensed 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/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.commons.httpclient.auth;
  
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.Map;
  
  import org.apache.commons.httpclient.params.HttpParams;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  /**
   * This class provides utility methods for processing HTTP www and proxy authentication 
   * challenges.
   * 
   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
   * 
   * @since 3.0
   */
  public final class AuthChallengeProcessor {
  
      private static final Log LOG = LogFactory.getLog(AuthChallengeProcessor.class);
  
      private HttpParams params = null;
      
      /**
       * Creates an authentication challenge processor with the given {@link HttpParams HTTP 
       * parameters}
       * 
       * @param params the {@link HttpParams HTTP parameters} used by this processor
       */
      public AuthChallengeProcessor(final HttpParams params) {
          super();
          if (params == null) {
              throw new IllegalArgumentException("Parameter collection may not be null");
          }
          this.params = params;
      }
  
      /**
       * Determines the preferred {@link AuthScheme authentication scheme} that can be used 
       * to respond to the given collection of challenges.
       * 
       * @param challenges the collection of authentication challenges
       * 
       * @return the preferred {@link AuthScheme authentication scheme}
       * 
       * @throws AuthChallengeException if the preferred authentication scheme 
       * cannot be determined or is not supported
       */
      public AuthScheme selectAuthScheme(final Map challenges) throws AuthChallengeException {
          if (challenges == null) {
              throw new IllegalArgumentException("Challenge map may not be null"); 
          }
          Collection authPrefs = (Collection) this.params.getParameter(
              AuthPolicy.AUTH_SCHEME_PRIORITY);
          if (authPrefs == null || authPrefs.isEmpty()) {
              authPrefs = AuthPolicy.getDefaultAuthPrefs();    
          }
          if (LOG.isDebugEnabled()) {
              LOG.debug("Supported authentication schemes in the order of preference: " 
                  + authPrefs);
          }
          AuthScheme authscheme = null;
          String challenge = null;
          Iterator item = authPrefs.iterator();
          while (item.hasNext()) {
              String id = (String) item.next();
              challenge = (String) challenges.get(id.toLowerCase()); 
              if (challenge != null) {
                  if (LOG.isInfoEnabled()) {
                      LOG.info(id + " authentication scheme selected");
                  }
                  try {
                      authscheme = AuthPolicy.getAuthScheme(id);
                  } catch (IllegalStateException e) {
                      throw new AuthChallengeException(e.getMessage());
                  }
                  break;
              } else {
                  if (LOG.isDebugEnabled()) {
                      LOG.debug("Challenge for " + id + " authentication scheme not available");
                      // Try again
                  }
              }
          }
          if (authscheme == null) {
              // If none selected, something is wrong
              throw new AuthChallengeException(
                  "Unable to respond to any of these challenges: "
                      + challenges);
          }
          return authscheme;
      }
  
      /**
       * Processes the given collection of challenges and updates the 
       * {@link AuthState state} of the authentication process.
       * 
       * @param challenges the collection of authentication challenges
       * 
       * @return the {@link AuthScheme authentication scheme} used to 
       * process the challenge
       * 
       * @throws AuthChallengeException if authentication challenges cannot be 
       * successfully processed or the preferred authentication scheme cannot
       * be determined
       */
      public AuthScheme processChallenge(final AuthState state, final Map challenges)
          throws MalformedChallengeException, AuthenticationException
      {    
          if (state == null) {
              throw new IllegalArgumentException("Authentication state may not be null"); 
          }
          if (challenges == null) {
              throw new IllegalArgumentException("Challenge map may not be null"); 
          }
          if (state.getAuthScheme() == null) {
              // Authentication not attempted before
              state.setAuthScheme(selectAuthScheme(challenges));
          }
          AuthScheme authscheme = state.getAuthScheme();
          String id = authscheme.getSchemeName();
          if (LOG.isDebugEnabled()) {
              LOG.debug("Using authentication scheme: " + id);
          }
          String challenge = (String) challenges.get(id.toLowerCase());
          if (challenge == null) {
              throw new AuthenticationException(id + 
                  " authorization challenge expected, but not found");
          }
          authscheme.processChallenge(challenge);
          return authscheme;
      }
  }
  
  
  
  1.1                  jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthState.java
  
  Index: AuthState.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthState.java,v 1.1 2004/03/25 20:37:20 olegk Exp $
   * $Revision: 1.1 $
   * $Date: 2004/03/25 20:37:20 $
   *
   * ====================================================================
   *
   *  Copyright 1999-2004 The Apache Software Foundation
   *
   *  Licensed 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/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.commons.httpclient.auth;
  
  /**
   * This class provides detailed information about the state of the
   * authentication process.
   * 
   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
   * @since 3.0
   */
  public class AuthState {
  
      /** Actual authentication scheme */
      private AuthScheme authScheme = null;
  
      /** Whether preemtive authentication is attempted */
      private boolean preemptive  = false; 
        
      /**
       * Default constructor.
       * 
       */
      public AuthState() {
          super();
      }
  
      /**
       * Preemptively assigns Basic authentication scheme.
       */
      public void setPreemptive() {
          if (this.authScheme != null) {
              throw new IllegalStateException("Authentication state already initialized");
          }
          this.authScheme = AuthPolicy.getAuthScheme("basic");
          this.preemptive = true;
      }
  
      /**
       * Invalidates the authentication state by resetting its parameters.
       */
      public void invalidate() {
          this.authScheme = null;
          this.preemptive = false;
      }
      
      /**
       * Tests if preemptive authentication is used.
       * 
       * @return <tt>true</tt> if using the default Basic {@link AuthScheme 
       * authentication scheme}, <tt>false</tt> otherwise.
       */
      public boolean isPreemptive() {
          return this.preemptive;
      }
      
      /**
       * Assigns the given {@link AuthScheme authentication scheme}.
       * 
       * @param authScheme the {@link AuthScheme authentication scheme}
       */
      public void setAuthScheme(final AuthScheme authScheme) {
          this.authScheme = authScheme;
          this.preemptive = false;
      }
  
      /**
       * Returns the {@link AuthScheme authentication scheme}.
       * 
       * @return {@link AuthScheme authentication scheme}
       */
      public AuthScheme getAuthScheme() {
          return authScheme;
      }
      
      /**
       * Returns the authentication realm.
       * 
       * @return the name of the authentication realm
       */
      public String getRealm() {
          if (this.authScheme != null) {
              return this.authScheme.getRealm();
          } else {
              return null;
          }
      }
  }
  
  
  
  1.4       +5 -3      jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestExceptions.java
  
  Index: TestExceptions.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestExceptions.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TestExceptions.java	22 Feb 2004 18:08:49 -0000	1.3
  +++ TestExceptions.java	25 Mar 2004 20:37:20 -0000	1.4
  @@ -34,6 +34,8 @@
   import java.io.PrintWriter;
   import java.io.StringWriter;
   
  +import org.apache.commons.httpclient.auth.*;
  +
   import junit.framework.Test;
   import junit.framework.TestCase;
   import junit.framework.TestSuite;
  
  
  
  1.33      +7 -4      jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java
  
  Index: TestNoHost.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/TestNoHost.java,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- TestNoHost.java	27 Feb 2004 19:01:33 -0000	1.32
  +++ TestNoHost.java	25 Mar 2004 20:37:20 -0000	1.33
  @@ -35,6 +35,8 @@
   import junit.framework.TestSuite;
   
   import org.apache.commons.httpclient.auth.TestBasicAuth;
  +import org.apache.commons.httpclient.auth.TestChallengeParser;
  +import org.apache.commons.httpclient.auth.TestChallengeProcessor;
   
   /**
    * Tests that don't require any external host.
  @@ -61,6 +63,7 @@
           suite.addTest(TestParameterParser.suite());
           suite.addTest(TestHeaderElement.suite());
           suite.addTest(TestChallengeParser.suite());
  +        suite.addTest(TestChallengeProcessor.suite());
           suite.addTest(TestAuthenticator.suite());
           suite.addTest(TestBasicAuth.suite());
           suite.addTest(TestHttpUrlMethod.suite());
  
  
  
  1.2       +49 -4     jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth/TestBasicAuth.java
  
  Index: TestBasicAuth.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth/TestBasicAuth.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TestBasicAuth.java	27 Feb 2004 19:04:32 -0000	1.1
  +++ TestBasicAuth.java	25 Mar 2004 20:37:20 -0000	1.2
  @@ -216,6 +216,10 @@
               this.client.executeMethod(httpget);
               assertNotNull(httpget.getStatusLine());
               assertEquals(HttpStatus.SC_UNAUTHORIZED, httpget.getStatusLine().getStatusCode());
  +            AuthState authstate = httpget.getHostAuthState();
  +            assertNotNull(authstate.getAuthScheme());
  +            assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
  +            assertEquals("test", authstate.getRealm());
           } finally {
               httpget.releaseConnection();
           }
  @@ -262,6 +266,10 @@
           String expected = "Basic " + EncodingUtil.getAsciiString(
               Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
           assertEquals(expected, auth.getValue());
  +        AuthState authstate = httpget.getHostAuthState();
  +        assertNotNull(authstate.getAuthScheme());
  +        assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
  +        assertEquals("test", authstate.getRealm());
       }
   
       public void testBasicAuthentication() throws Exception {
  @@ -286,6 +294,10 @@
           String expected = "Basic " + EncodingUtil.getAsciiString(
               Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
           assertEquals(expected, auth.getValue());
  +        AuthState authstate = httpget.getHostAuthState();
  +        assertNotNull(authstate.getAuthScheme());
  +        assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
  +        assertEquals("test", authstate.getRealm());
       }
   
       public void testBasicAuthenticationWithInvalidCredentials() throws Exception {
  @@ -305,6 +317,10 @@
           }
           assertNotNull(httpget.getStatusLine());
           assertEquals(HttpStatus.SC_FORBIDDEN, httpget.getStatusLine().getStatusCode());
  +        AuthState authstate = httpget.getHostAuthState();
  +        assertNotNull(authstate.getAuthScheme());
  +        assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
  +        assertEquals("test", authstate.getRealm());
       }
   
       public void testBasicAuthenticationWithMutlipleRealms() throws Exception {
  @@ -335,6 +351,10 @@
               String expected = "Basic " + EncodingUtil.getAsciiString(
                   Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
               assertEquals(expected, auth.getValue());
  +            AuthState authstate = httpget.getHostAuthState();
  +            assertNotNull(authstate.getAuthScheme());
  +            assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
  +            assertEquals("test", authstate.getRealm());
           }
           {
               this.server.setHttpService(new BasicAuthService2());
  @@ -351,6 +371,10 @@
               String expected = "Basic " + EncodingUtil.getAsciiString(
                   Base64.encodeBase64(EncodingUtil.getAsciiBytes("test2:test2")));
               assertEquals(expected, auth.getValue());
  +            AuthState authstate = httpget.getHostAuthState();
  +            assertNotNull(authstate.getAuthScheme());
  +            assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
  +            assertEquals("test2", authstate.getRealm());
           }
       }
   
  @@ -373,6 +397,11 @@
           String expected = "Basic " + EncodingUtil.getAsciiString(
               Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
           assertEquals(expected, auth.getValue());
  +        AuthState authstate = httpget.getHostAuthState();
  +        assertNotNull(authstate.getAuthScheme());
  +        assertTrue(authstate.getAuthScheme() instanceof BasicScheme);
  +        assertNull(authstate.getRealm());
  +        assertTrue(authstate.isPreemptive());
       }
   
       public void testBasicAuthenticationCaseInsensitivity() throws Exception {
  @@ -397,5 +426,21 @@
           String expected = "Basic " + EncodingUtil.getAsciiString(
               Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
           assertEquals(expected, auth.getValue());
  +    }
  +
  +
  +    public void testCustomAuthorizationHeader() throws Exception {
  +        String authResponse = "Basic " + EncodingUtil.getAsciiString(
  +            Base64.encodeBase64(EncodingUtil.getAsciiBytes("test:test")));
  +        this.server.setHttpService(new BasicAuthService());
  +        GetMethod httpget = new GetMethod("/test/");
  +        httpget.addRequestHeader(new Header("Authorization", authResponse));
  +        try {
  +            this.client.executeMethod(httpget);
  +        } finally {
  +            httpget.releaseConnection();
  +        }
  +        assertNotNull(httpget.getStatusLine());
  +        assertEquals(HttpStatus.SC_OK, httpget.getStatusLine().getStatusCode());
       }
   }
  
  
  
  1.1                  jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth/TestChallengeParser.java
  
  Index: TestChallengeParser.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth/TestChallengeParser.java,v 1.1 2004/03/25 20:37:20 olegk Exp $
   * $Revision: 1.1 $
   * $Date: 2004/03/25 20:37:20 $
   * ====================================================================
   *
   *  Copyright 1999-2004 The Apache Software Foundation
   *
   *  Licensed 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/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.commons.httpclient.auth;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  import java.util.Map;
  import org.apache.commons.httpclient.auth.AuthChallengeParser;
  import org.apache.commons.httpclient.auth.MalformedChallengeException; 
  
  /**
   * Unit tests for {@link AuthChallengeParser}.
   *
   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
   */
  public class TestChallengeParser extends TestCase {
  
      // ------------------------------------------------------------ Constructor
      public TestChallengeParser(String testName) {
          super(testName);
      }
  
      // ------------------------------------------------------------------- Main
      public static void main(String args[]) {
          String[] testCaseName = { TestChallengeParser.class.getName() };
          junit.textui.TestRunner.main(testCaseName);
      }
  
      // ------------------------------------------------------- TestCase Methods
  
      public static Test suite() {
          return new TestSuite(TestChallengeParser.class);
      }
  
  
      public void testParsingChallenge() {
          String challenge = 
            "Basic realm=\"realm1\", test, test1 =  stuff, test2 =  \"stuff, stuff\", test3=\"crap";
          String scheme = null;
          Map elements = null;
          try {
              scheme = AuthChallengeParser.extractScheme(challenge);
              elements = AuthChallengeParser.extractParams(challenge);
          } catch (MalformedChallengeException e) {
              fail("Unexpected exception: " + e.toString());
          }
          assertEquals("basic", scheme);
          assertEquals("realm1", elements.get("realm"));
          assertEquals(null, elements.get("test"));
          assertEquals("stuff", elements.get("test1"));
          assertEquals("stuff, stuff", elements.get("test2"));
          assertEquals("\"crap", elements.get("test3"));
      }
  }
  
  
  
  1.1                  jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth/TestChallengeProcessor.java
  
  Index: TestChallengeProcessor.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-commons/httpclient/src/test/org/apache/commons/httpclient/auth/TestChallengeProcessor.java,v 1.1 2004/03/25 20:37:20 olegk Exp $
   * $Revision: 1.1 $
   * $Date: 2004/03/25 20:37:20 $
   * ====================================================================
   *
   *  Copyright 1999-2004 The Apache Software Foundation
   *
   *  Licensed 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/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */
  
  package org.apache.commons.httpclient.auth;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import junit.framework.Test;
  import junit.framework.TestCase;
  import junit.framework.TestSuite;
  
  import org.apache.commons.httpclient.params.DefaultHttpParams;
  import org.apache.commons.httpclient.params.HttpParams;
  
  /**
   * Unit tests for {@link testParsingChallenge}.
   *
   * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a>
   */
  public class TestChallengeProcessor extends TestCase {
  
      // ------------------------------------------------------------ Constructor
      public TestChallengeProcessor(String testName) {
          super(testName);
      }
  
      // ------------------------------------------------------------------- Main
      public static void main(String args[]) {
          String[] testCaseName = { TestChallengeProcessor.class.getName() };
          junit.textui.TestRunner.main(testCaseName);
      }
  
      // ------------------------------------------------------- TestCase Methods
  
      public static Test suite() {
          return new TestSuite(TestChallengeProcessor.class);
      }
  
  
      public void testChallengeSelection() throws Exception {
          List authPrefs = new ArrayList(3);
          authPrefs.add(AuthPolicy.NTLM);
          authPrefs.add(AuthPolicy.DIGEST);
          authPrefs.add(AuthPolicy.BASIC);
          HttpParams httpparams = new DefaultHttpParams(); 
          httpparams.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
          
          AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
  
          Map map = new HashMap(); 
          map.put("unknown", "unknown realm=\"whatever\"");
          map.put("basic", "basic realm=\"whatever\"");
          
          AuthScheme authscheme = processor.selectAuthScheme(map);
          assertTrue(authscheme instanceof BasicScheme);
      }
  
  
      public void testInvalidChallenge() throws Exception {
          List authPrefs = new ArrayList(3);
          authPrefs.add("unsupported1");
          authPrefs.add("unsupported2");
          HttpParams httpparams = new DefaultHttpParams(); 
          httpparams.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
          
          AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
  
          Map map = new HashMap(); 
          map.put("unsupported1", "unsupported1 realm=\"whatever\"");
          map.put("unsupported2", "unsupported2 realm=\"whatever\"");
          try {
              AuthScheme authscheme = processor.selectAuthScheme(map);
              fail("AuthChallengeException should have been thrown");
          } catch (AuthChallengeException e) {
              //ignore
          }
      }
  
  
      public void testUnsupportedChallenge() throws Exception {
          List authPrefs = new ArrayList(3);
          authPrefs.add(AuthPolicy.NTLM);
          authPrefs.add(AuthPolicy.BASIC);
          authPrefs.add(AuthPolicy.DIGEST);
          HttpParams httpparams = new DefaultHttpParams(); 
          httpparams.setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
          
          AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
  
          Map map = new HashMap(); 
          map.put("unsupported1", "unsupported1 realm=\"whatever\"");
          map.put("unsupported2", "unsupported2 realm=\"whatever\"");
          
          try {
              AuthScheme authscheme = processor.selectAuthScheme(map);
              fail("AuthChallengeException should have been thrown");
          } catch (AuthChallengeException e) {
              //expected
          }
      }
  
      public void testChallengeProcessing() throws Exception {
          HttpParams httpparams = new DefaultHttpParams(); 
          AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
  
          Map map = new HashMap(); 
          map.put("basic", "basic realm=\"whatever\", param=\"value\"");
          
          AuthState authstate = new AuthState();
          
          AuthScheme authscheme = processor.processChallenge(authstate, map);
          assertTrue(authscheme instanceof BasicScheme);
          assertEquals("whatever", authscheme.getRealm());
          assertEquals(authscheme, authstate.getAuthScheme());
          assertEquals("value", authscheme.getParameter("param"));
      }
  
      public void testInvalidChallengeProcessing() throws Exception {
          HttpParams httpparams = new DefaultHttpParams(); 
          AuthChallengeProcessor processor = new AuthChallengeProcessor(httpparams);
  
          Map map = new HashMap(); 
          map.put("basic", "basic realm=\"whatever\", param=\"value\"");
          
          AuthState authstate = new AuthState();
          
          AuthScheme authscheme = processor.processChallenge(authstate, map);
          assertTrue(authscheme instanceof BasicScheme);
          assertEquals("whatever", authscheme.getRealm());
          assertEquals(authscheme, authstate.getAuthScheme());
          assertEquals("value", authscheme.getParameter("param"));
  
          Map map2 = new HashMap(); 
          map2.put("ntlm", "NTLM");
          try {
              // Basic authentication scheme expected
              authscheme = processor.processChallenge(authstate, map2);
              fail("AuthenticationException should have been thrown");
          } catch (AuthenticationException e) {
              //expected
          }
      }
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message