You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by mb...@apache.org on 2003/12/11 02:19:33 UTC

cvs commit: jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util EncodingUtil.java

mbecke      2003/12/10 17:19:33

  Modified:    httpclient/src/java/org/apache/commons/httpclient/params
                        HttpMethodParams.java DefaultHttpParamsFactory.java
               httpclient/src/java/org/apache/commons/httpclient/auth
                        AuthScheme.java NTLMScheme.java NTLM.java
                        DigestScheme.java BasicScheme.java
                        HttpAuthenticator.java
               httpclient/src/java/org/apache/commons/httpclient
                        HttpConnection.java ConnectMethod.java
                        MultiThreadedHttpConnectionManager.java
                        HttpMethodBase.java
               httpclient/src/java/org/apache/commons/httpclient/util
                        EncodingUtil.java
  Log:
  Adds support for configuring charsets in credentials and HTTP headers.
  
  PR: 24671
  Submitted by: Michael Becke
  Reviewed by: Oleg Kalnichevski
  
  Revision  Changes    Path
  1.6       +66 -5     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/params/HttpMethodParams.java
  
  Index: HttpMethodParams.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/params/HttpMethodParams.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- HttpMethodParams.java	22 Oct 2003 19:31:00 -0000	1.5
  +++ HttpMethodParams.java	11 Dec 2003 01:19:32 -0000	1.6
  @@ -179,6 +179,24 @@
       public static final String USE_EXPECT_CONTINUE = "http.protocol.expect-continue"; 
   
       /**
  +     * Defines the charset to be used when encoding 
  +     * {@link org.apache.commons.httpclient.Credentials}. If not defined then the 
  +     * {@link #HTTP_ELEMENT_CHARSET} should be used.
  +     * <p>
  +     * This parameter expects a value of type {@link String}.
  +     * </p>
  +     */
  +    public static final String CREDENTIAL_CHARSET = "http.protocol.credential-charset"; 
  +    
  +    /**
  +     * Defines the charset to be used for encoding HTTP protocol elements.
  +     * <p>
  +     * This parameter expects a value of type {@link String}.
  +     * </p>
  +     */
  +    public static final String HTTP_ELEMENT_CHARSET = "http.protocol.element-charset"; 
  +    
  +    /**
        * Defines {@link CookiePolicy cookie policy} to be used for cookie management.
        * <p>
        * This parameter expects a value of type {@link String}.
  @@ -195,7 +213,7 @@
        * @see #getDefaultParams()
        */
       public HttpMethodParams() {
  -        super(null);
  +        super(getDefaultParams());
       }
   
       /**
  @@ -213,6 +231,49 @@
           super(defaults);
       }
   
  +    /**
  +     * Returns the charset to be used for writing HTTP headers.
  +     * @return The charset
  +     */
  +    public String getHttpElementCharset() {
  +        String charset = (String) getParameter(HTTP_ELEMENT_CHARSET);
  +        if (charset == null) {
  +            LOG.warn("HTTP element charset not configured, using US-ASCII");
  +            charset = "US-ASCII";
  +        }
  +        return charset;
  +    }
  +    
  +    /**
  +     * Sets the charset to be used for writing HTTP headers.
  +     * @param charset The charset
  +     */
  +    public void setHttpElementCharset(String charset) {
  +        setParameter(HTTP_ELEMENT_CHARSET, charset);
  +    }
  +
  +    /**
  +     * Returns the charset to be used for {@link org.apache.commons.httpclient.Credentials}. If
  +     * not configured the {@link #HTTP_ELEMENT_CHARSET HTTP element charset} is used.
  +     * @return The charset
  +     */
  +    public String getCredentialCharset() {
  +        String charset = (String) getParameter(CREDENTIAL_CHARSET);
  +        if (charset == null) {
  +            LOG.debug("Credential charset not configured, using HTTP element charset");
  +            charset = getHttpElementCharset();
  +        }
  +        return charset;
  +    }
  +    
  +    /**
  +     * Sets the charset to be used for writing HTTP headers.
  +     * @param charset The charset
  +     */
  +    public void setCredentialCharset(String charset) {
  +        setParameter(CREDENTIAL_CHARSET, charset);
  +    }
  +    
       /**
        * Returns {@link HttpVersion HTTP protocol version} to be used by the 
        * {@link org.apache.commons.httpclient.HttpMethod HTTP methods} that 
  
  
  
  1.5       +4 -3      jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/params/DefaultHttpParamsFactory.java
  
  Index: DefaultHttpParamsFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/params/DefaultHttpParamsFactory.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DefaultHttpParamsFactory.java	20 Oct 2003 22:17:12 -0000	1.4
  +++ DefaultHttpParamsFactory.java	11 Dec 2003 01:19:32 -0000	1.5
  @@ -102,6 +102,7 @@
           params.setVersion(HttpVersion.HTTP_1_1);
           params.setConnectionManagerClass(SimpleHttpConnectionManager.class);
           params.setCookiePolicy(CookiePolicy.RFC_2109);
  +        params.setHttpElementCharset("US-ASCII");
   
           ArrayList datePatterns = new ArrayList();
           datePatterns.addAll(
  
  
  
  1.6       +19 -4     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthScheme.java
  
  Index: AuthScheme.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/AuthScheme.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- AuthScheme.java	10 Dec 2003 21:04:13 -0000	1.5
  +++ AuthScheme.java	11 Dec 2003 01:19:32 -0000	1.6
  @@ -64,6 +64,7 @@
   package org.apache.commons.httpclient.auth;
   
   import org.apache.commons.httpclient.Credentials;
  +import org.apache.commons.httpclient.HttpMethod;
   
   /**
    * <p>
  @@ -164,6 +165,8 @@
       boolean isConnectionBased();    
       
       /**
  +     * @deprecated Use {@link #authenticate(Credentials, String, String, HttpMethodParams)}
  +     * 
        * Produces an authorization string for the given set of {@link Credentials},
        * method name and URI using the given authentication scheme in response to 
        * the actual authorization challenge.
  @@ -185,5 +188,17 @@
        */
       String authenticate(Credentials credentials, String method, String uri) 
         throws AuthenticationException;
  -       
  +
  +    /**
  +     * Produces an authorization string for the given set of {@link Credentials}.
  +     * 
  +     * @param credentials The set of credentials to be used for athentication
  +     * @param method The method being authenticated
  +     * @throws AuthenticationException if authorization string cannot 
  +     *   be generated due to an authentication failure
  +     * 
  +     * @return the authorization string
  +     */
  +    String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException;
  +    
   }
  
  
  
  1.13      +72 -3     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/NTLMScheme.java
  
  Index: NTLMScheme.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/NTLMScheme.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- NTLMScheme.java	10 Dec 2003 21:04:13 -0000	1.12
  +++ NTLMScheme.java	11 Dec 2003 01:19:32 -0000	1.13
  @@ -64,6 +64,7 @@
   package org.apache.commons.httpclient.auth;
   
   import org.apache.commons.httpclient.Credentials;
  +import org.apache.commons.httpclient.HttpMethod;
   import org.apache.commons.httpclient.NTCredentials;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -224,6 +225,40 @@
           credentials.getHost(), credentials.getDomain());
           return "NTLM " + s;
       }
  +
  +    /**
  +     * Create a NTLM authorization string for the given
  +     * challenge and NT credentials.
  +     *
  +     * @param challenge The challenge.
  +     * @param credentials {@link NTCredentials}
  +     * @param charset The charset to use for encoding the credentials
  +     *
  +     * @return a ntlm authorization string
  +     * @throws AuthenticationException is thrown if authentication fails
  +     */
  +    public static String authenticate(
  +        final NTCredentials credentials, 
  +		final String challenge,
  +		String charset
  +    ) throws AuthenticationException {
  +
  +        LOG.trace("enter NTLMScheme.authenticate(NTCredentials, String)");
  +
  +        if (credentials == null) {
  +            throw new IllegalArgumentException("Credentials may not be null");
  +        }
  +        
  +        NTLM ntlm = new NTLM();
  +        ntlm.setCredentialCharset(charset);
  +        String s = ntlm.getResponseFor(
  +            challenge,
  +            credentials.getUserName(), 
  +			credentials.getPassword(),
  +			credentials.getHost(), 
  +			credentials.getDomain());
  +        return "NTLM " + s;
  +    }
       
       /**
        * Produces NTLM authorization string for the given set of 
  @@ -252,5 +287,39 @@
                 + credentials.getClass().getName());
           }
           return NTLMScheme.authenticate(ntcredentials, this.ntlmchallenge);
  +    }
  +    
  +    /**
  +     * Produces NTLM authorization string for the given set of 
  +     * {@link Credentials}.
  +     * 
  +     * @param credentials The set of credentials to be used for athentication
  +     * @param method The method being authenticated
  +     * 
  +     * @throws InvalidCredentialsException if authentication credentials
  +     *         are not valid or not applicable for this authentication scheme
  +     * @throws AuthenticationException if authorization string cannot 
  +     *   be generated due to an authentication failure
  +     * 
  +     * @return an NTLM authorization string
  +     */
  +    public String authenticate(
  +        Credentials credentials, 
  +        HttpMethod method
  +    ) throws AuthenticationException {
  +        LOG.trace("enter NTLMScheme.authenticate(Credentials, HttpMethod)");
  +
  +        NTCredentials ntcredentials = null;
  +        try {
  +            ntcredentials = (NTCredentials) credentials;
  +        } catch (ClassCastException e) {
  +            throw new InvalidCredentialsException(
  +                    "Credentials cannot be used for NTLM authentication: " 
  +                    + credentials.getClass().getName());
  +        }
  +        return NTLMScheme.authenticate(
  +            ntcredentials, 
  +            this.ntlmchallenge, 
  +			method.getParams().getCredentialCharset());
       }    
   }
  
  
  
  1.5       +32 -35    jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/NTLM.java
  
  Index: NTLM.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/NTLM.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- NTLM.java	16 Aug 2003 00:41:24 -0000	1.4
  +++ NTLM.java	11 Dec 2003 01:19:32 -0000	1.5
  @@ -63,7 +63,6 @@
   
   package org.apache.commons.httpclient.auth;
   
  -import java.io.UnsupportedEncodingException;
   import java.security.InvalidKeyException;
   import java.security.NoSuchAlgorithmException;
   
  @@ -75,8 +74,7 @@
   
   import org.apache.commons.httpclient.HttpConstants;
   import org.apache.commons.httpclient.util.Base64;
  -import org.apache.commons.logging.Log;
  -import org.apache.commons.logging.LogFactory;
  +import org.apache.commons.httpclient.util.EncodingUtil;
   
   /**
    * Provides an implementation of the NTLM authentication protocol.
  @@ -102,18 +100,18 @@
    */
   final class NTLM {
   
  +    /** Character encoding */
  +    public static final String DEFAULT_CHARSET = "ASCII";
  +
       /** The current response */
       private byte[] currentResponse;
   
       /** The current position */
       private int currentPosition = 0;
   
  -    /** Log object for this class. */
  -    private static final Log LOG = LogFactory.getLog(NTLM.class);
  -
  -    /** Character encoding */
  -    public static final String DEFAULT_CHARSET = "ASCII";
  -
  +    /** The character set to use for encoding the credentials */
  +    private String credentialCharset = DEFAULT_CHARSET;
  +    
       /**
        * Returns the response for the given message.
        *
  @@ -268,14 +266,14 @@
       private String getType1Message(String host, String domain) {
           host = host.toUpperCase();
           domain = domain.toUpperCase();
  -        byte[] hostBytes = getBytes(host);
  -        byte[] domainBytes = getBytes(domain);
  +        byte[] hostBytes = EncodingUtil.getBytes(host, DEFAULT_CHARSET);
  +        byte[] domainBytes = EncodingUtil.getBytes(domain, DEFAULT_CHARSET);
   
           int finalLength = 32 + hostBytes.length + domainBytes.length;
           prepareResponse(finalLength);
           
           // The initial id string.
  -        byte[] protocol = getBytes("NTLMSSP");
  +        byte[] protocol = EncodingUtil.getBytes("NTLMSSP", DEFAULT_CHARSET);
           addBytes(protocol);
           addByte((byte) 0);
   
  @@ -342,7 +340,7 @@
        */
       private byte[] parseType2Message(String message) {
           // Decode the message first.
  -        byte[] msg = Base64.decode(getBytes(message));
  +        byte[] msg = Base64.decode(EncodingUtil.getBytes(message, DEFAULT_CHARSET));
           byte[] nonce = new byte[8];
           // The nonce is the 8 bytes starting from the byte in position 24.
           for (int i = 0; i < 8; i++) {
  @@ -373,16 +371,16 @@
           domain = domain.toUpperCase();
           host = host.toUpperCase();
           user = user.toUpperCase();
  -        byte[] domainBytes = getBytes(domain);
  -        byte[] hostBytes = getBytes(host);
  -        byte[] userBytes = getBytes(user);
  +        byte[] domainBytes = EncodingUtil.getBytes(domain, DEFAULT_CHARSET);
  +        byte[] hostBytes = EncodingUtil.getBytes(host, DEFAULT_CHARSET);
  +        byte[] userBytes = EncodingUtil.getBytes(user, credentialCharset);
           int domainLen = domainBytes.length;
           int hostLen = hostBytes.length;
           int userLen = userBytes.length;
           int finalLength = 64 + ntRespLen + lmRespLen + domainLen 
               + userLen + hostLen;
           prepareResponse(finalLength);
  -        byte[] ntlmssp = getBytes("NTLMSSP");
  +        byte[] ntlmssp = EncodingUtil.getBytes("NTLMSSP", DEFAULT_CHARSET);
           addBytes(ntlmssp);
           addByte((byte) 0);
           addByte((byte) 3);
  @@ -465,7 +463,7 @@
        */
       private byte[] hashPassword(String password, byte[] nonce)
           throws AuthenticationException {
  -        byte[] passw = getBytes(password.toUpperCase());
  +        byte[] passw = EncodingUtil.getBytes(password.toUpperCase(), credentialCharset);
           byte[] lmPw1 = new byte[7];
           byte[] lmPw2 = new byte[7];
   
  @@ -585,18 +583,17 @@
       }
       
       /**
  -     * Convert a string to a byte array.
  -     * @param s The string
  -     * @return byte[] The resulting byte array.
  -     */
  -    private static byte[] getBytes(final String s) {
  -        if (s == null) {
  -            throw new IllegalArgumentException("Parameter may not be null"); 
  -        }
  -        try {
  -            return s.getBytes(DEFAULT_CHARSET); 
  -        } catch (UnsupportedEncodingException unexpectedEncodingException) {
  -            throw new RuntimeException("NTLM requires ASCII support"); 
  -        }
  +     * @return Returns the credentialCharset.
  +     */
  +    public String getCredentialCharset() {
  +        return credentialCharset;
  +    }
  +
  +    /**
  +     * @param credentialCharset The credentialCharset to set.
  +     */
  +    public void setCredentialCharset(String credentialCharset) {
  +        this.credentialCharset = credentialCharset;
       }
  +
   }
  
  
  
  1.13      +62 -18    jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/DigestScheme.java
  
  Index: DigestScheme.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/DigestScheme.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- DigestScheme.java	10 Dec 2003 21:04:13 -0000	1.12
  +++ DigestScheme.java	11 Dec 2003 01:19:32 -0000	1.13
  @@ -63,14 +63,16 @@
   
   package org.apache.commons.httpclient.auth;
   
  -import java.util.StringTokenizer;
   import java.security.MessageDigest;
   import java.security.NoSuchAlgorithmException;
  +import java.util.StringTokenizer;
   
  +import org.apache.commons.httpclient.Credentials;
   import org.apache.commons.httpclient.HttpClientError;
   import org.apache.commons.httpclient.HttpConstants;
  -import org.apache.commons.httpclient.Credentials;
  +import org.apache.commons.httpclient.HttpMethod;
   import org.apache.commons.httpclient.UsernamePasswordCredentials;
  +import org.apache.commons.httpclient.util.EncodingUtil;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  @@ -82,6 +84,14 @@
    * is unsupported. If auth and auth-int are provided, auth is
    * used.
    * </p>
  + * <p>
  + * Credential charset is configured via the 
  + * {@link org.apache.commons.httpclient.params.HttpMethodParams#CREDENTIAL_CHARSET credential
  + * charset} parameter.  Since the digest username is included as clear text in the generated 
  + * Authentication header, the charset of the username must be compatible with the 
  + * {@link org.apache.commons.httpclient.params.HttpMethodParams#HTTP_ELEMENT_CHARSET http element 
  + * charset}.
  + * </p>
    * TODO: make class more stateful regarding repeated authentication requests
    * 
    * @author <a href="mailto:remm@apache.org">Remy Maucherat</a>
  @@ -282,28 +292,64 @@
           }
           this.getParameters().put("methodname", method);
           this.getParameters().put("uri", uri);
  -        String digest = createDigest(usernamepassword.getUserName(),
  -                usernamepassword.getPassword());
  +        String digest = createDigest(
  +            usernamepassword.getUserName(),
  +            usernamepassword.getPassword(),
  +            HttpConstants.DEFAULT_CONTENT_CHARSET);
   
  -        return "Digest " + createDigestHeader(usernamepassword.getUserName(),
  -                             digest);
  +        return "Digest " + createDigestHeader(usernamepassword.getUserName(), digest);
       }
   
       /**
  +     * Produces a digest authorization string for the given set of 
  +     * {@link Credentials}, method name and URI.
  +     * 
  +     * @param credentials A set of credentials to be used for athentication
  +     * @param method The method being authenticated
  +     * 
  +     * @throws InvalidCredentialsException if authentication credentials
  +     *         are not valid or not applicable for this authentication scheme
  +     * @throws AuthenticationException if authorization string cannot 
  +     *   be generated due to an authentication failure
  +     * 
  +     * @return a digest authorization string
  +     */
  +    public String authenticate(Credentials credentials, HttpMethod method)
  +    throws AuthenticationException {
  +
  +        LOG.trace("enter DigestScheme.authenticate(Credentials, HttpMethod)");
  +
  +        UsernamePasswordCredentials usernamepassword = null;
  +        try {
  +            usernamepassword = (UsernamePasswordCredentials) credentials;
  +        } catch (ClassCastException e) {
  +            throw new InvalidCredentialsException(
  +                    "Credentials cannot be used for digest authentication: " 
  +                    + credentials.getClass().getName());
  +        }
  +        this.getParameters().put("methodname", method.getName());
  +        this.getParameters().put("uri", method.getPath());
  +        String digest = createDigest(
  +            usernamepassword.getUserName(),
  +            usernamepassword.getPassword(), 
  +            method.getParams().getCredentialCharset());
  +
  +        return "Digest " + createDigestHeader(usernamepassword.getUserName(),
  +                digest);
  +    }
  +    
  +    /**
        * Creates an MD5 response digest.
        * 
        * @param uname Username
        * @param pwd Password
  -     * @param params The parameters necessary to construct the digest. 
  -     *  The following parameters are expected: <code>uri</code>, 
  -     *  <code>realm</code>, <code>nonce</code>, <code>nc</code>, 
  -     *  <code>cnonce</code>, <code>qop</code>, <code>methodname</code>.
  +     * @param charset The credential charset
        * 
        * @return The created digest as string. This will be the response tag's
        *         value in the Authentication HTTP header.
        * @throws AuthenticationException when MD5 is an unsupported algorithm
        */
  -    private String createDigest(String uname, String pwd) throws AuthenticationException {
  +    private String createDigest(String uname, String pwd, String charset) throws AuthenticationException {
   
           LOG.trace("enter DigestScheme.createDigest(String, String, Map)");
   
  @@ -322,7 +368,6 @@
               algorithm="MD5";
           }
   
  -
           if (qopVariant == QOP_AUTH_INT) {
               LOG.warn("qop=auth-int is not supported");
               throw new AuthenticationException(
  @@ -354,8 +399,7 @@
               //      ":" unq(nonce-value)
               //      ":" unq(cnonce-value)
   
  -            String tmp2=encode(md5Helper.digest(HttpConstants.getBytes(
  -                a1)));
  +            String tmp2=encode(md5Helper.digest(EncodingUtil.getBytes(a1, charset)));
               StringBuffer tmp3 = new StringBuffer(tmp2.length() + nonce.length() + cnonce.length() + 2);
               tmp3.append(tmp2);
               tmp3.append(':');
  @@ -366,7 +410,7 @@
           } else if(!algorithm.equals("MD5")) {
               LOG.warn("Unhandled algorithm " + algorithm + " requested");
           }
  -        String md5a1 = encode(md5Helper.digest(HttpConstants.getBytes(a1)));
  +        String md5a1 = encode(md5Helper.digest(EncodingUtil.getBytes(a1, charset)));
   
           String a2 = null;
           if (qopVariant == QOP_AUTH_INT) {
  
  
  
  1.9       +59 -8     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/BasicScheme.java
  
  Index: BasicScheme.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/BasicScheme.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- BasicScheme.java	10 Dec 2003 21:04:13 -0000	1.8
  +++ BasicScheme.java	11 Dec 2003 01:19:32 -0000	1.9
  @@ -63,10 +63,12 @@
   
   package org.apache.commons.httpclient.auth;
   
  -import org.apache.commons.httpclient.HttpConstants; 
   import org.apache.commons.httpclient.Credentials;
  +import org.apache.commons.httpclient.HttpConstants;
  +import org.apache.commons.httpclient.HttpMethod;
   import org.apache.commons.httpclient.UsernamePasswordCredentials;
  -import org.apache.commons.httpclient.util.Base64; 
  +import org.apache.commons.httpclient.util.Base64;
  +import org.apache.commons.httpclient.util.EncodingUtil;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   
  @@ -163,7 +165,39 @@
       }
   
       /**
  -     * Return a basic <tt>Authorization</tt> header value for the given 
  +     * Produces basic authorization string for the given set of {@link Credentials}.
  +     * 
  +     * @param credentials The set of credentials to be used for athentication
  +     * @param method The method being authenticated
  +     * @throws InvalidCredentialsException if authentication credentials
  +     *         are not valid or not applicable for this authentication scheme
  +     * @throws AuthenticationException if authorization string cannot 
  +     *   be generated due to an authentication failure
  +     * 
  +     * @return a basic authorization string
  +     */
  +    public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException {
  +
  +        LOG.trace("enter BasicScheme.authenticate(Credentials, HttpMethod)");
  +
  +        UsernamePasswordCredentials usernamepassword = null;
  +        try {
  +            usernamepassword = (UsernamePasswordCredentials) credentials;
  +        } catch (ClassCastException e) {
  +            throw new InvalidCredentialsException(
  +                    "Credentials cannot be used for basic authentication: " 
  +                    + credentials.getClass().getName());
  +        }
  +        
  +        return BasicScheme.authenticate(
  +            usernamepassword, 
  +            method.getParams().getCredentialCharset());
  +    }
  +    
  +    /**
  +     * @deprecated Use {@link #authenticate(UsernamePasswordCredentials, String)}
  +     * 
  +     * Returns a basic <tt>Authorization</tt> header value for the given 
        * {@link UsernamePasswordCredentials}.
        * 
        * @param credentials The credentials to encode.
  @@ -171,18 +205,35 @@
        * @return a basic authorization string
        */
       public static String authenticate(UsernamePasswordCredentials credentials) {
  +        return authenticate(credentials, HttpConstants.DEFAULT_CONTENT_CHARSET);
  +    }
  +
  +    /**
  +     * Returns a basic <tt>Authorization</tt> header value for the given 
  +     * {@link UsernamePasswordCredentials} and charset.
  +     * 
  +     * @param credentials The credentials to encode.
  +     * @param charset The charset to use for encoding the credentials
  +     * 
  +     * @return a basic authorization string
  +     */
  +    public static String authenticate(UsernamePasswordCredentials credentials, String charset) {
   
  -        LOG.trace("enter BasicScheme.authenticate(UsernamePasswordCredentials)");
  +        LOG.trace("enter BasicScheme.authenticate(UsernamePasswordCredentials, String)");
   
           if (credentials == null) {
               throw new IllegalArgumentException("Credentials may not be null"); 
           }
  +        if (charset == null || charset.length() == 0) {
  +            throw new IllegalArgumentException("charset may not be null or empty");
  +        }
           StringBuffer buffer = new StringBuffer();
           buffer.append(credentials.getUserName());
           buffer.append(":");
           buffer.append(credentials.getPassword());
           
           return "Basic " + HttpConstants.getAsciiString(
  -            Base64.encode(HttpConstants.getContentBytes(buffer.toString())));
  +                Base64.encode(EncodingUtil.getBytes(buffer.toString(), charset)));
       }
  +    
   }
  
  
  
  1.15      +7 -6      jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/HttpAuthenticator.java
  
  Index: HttpAuthenticator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/auth/HttpAuthenticator.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- HttpAuthenticator.java	10 Dec 2003 21:04:13 -0000	1.14
  +++ HttpAuthenticator.java	11 Dec 2003 01:19:32 -0000	1.15
  @@ -179,7 +179,6 @@
             "Authentication scheme(s) not supported: " + challengemap.toString()); 
       }
       
  -
       private static boolean doAuthenticateDefault(
           HttpMethod method, 
           HttpConnection conn,
  @@ -206,7 +205,9 @@
                "Credentials cannot be used for basic authentication: " 
                 + credentials.toString());
           }
  -        String auth = BasicScheme.authenticate((UsernamePasswordCredentials) credentials);
  +        String auth = BasicScheme.authenticate(
  +            (UsernamePasswordCredentials) credentials,
  +            method.getParams().getCredentialCharset());
           if (auth != null) {
               String s = proxy ? PROXY_AUTH_RESP : WWW_AUTH_RESP;
               Header header = new Header(s, auth, true);
  @@ -329,7 +330,7 @@
                   "No credentials available for the '" + realm 
                   + "' authentication realm at " + host);
           }
  -        String auth = authscheme.authenticate(credentials, method.getName(), method.getPath());
  +        String auth = authscheme.authenticate(credentials, method);
           if (auth != null) {
               String s = proxy ? PROXY_AUTH_RESP : WWW_AUTH_RESP;
               Header header = new Header(s, auth, true);
  
  
  
  1.82      +38 -4     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java
  
  Index: HttpConnection.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/HttpConnection.java,v
  retrieving revision 1.81
  retrieving revision 1.82
  diff -u -r1.81 -r1.82
  --- HttpConnection.java	11 Nov 2003 17:35:07 -0000	1.81
  +++ HttpConnection.java	11 Dec 2003 01:19:32 -0000	1.82
  @@ -79,6 +79,7 @@
   import org.apache.commons.httpclient.protocol.Protocol;
   import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
   import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
  +import org.apache.commons.httpclient.util.EncodingUtil;
   import org.apache.commons.httpclient.util.TimeoutController;
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
  @@ -983,6 +984,8 @@
       }
   
       /**
  +     * @deprecated Use {@link #print(String, String)}
  +     * 
        * Writes the specified String (as bytes) to the output stream.
        *
        * @param data the string to be written
  @@ -996,6 +999,22 @@
       }
   
       /**
  +     * Writes the specified String (as bytes) to the output stream.
  +     *
  +     * @param data the string to be written
  +     * @params charset the charset to use for writing the data
  +     * @throws IllegalStateException if the connection is not open
  +     * @throws IOException if an I/O problem occurs
  +     */
  +    public void print(String data, String charset)
  +    	throws IOException, IllegalStateException {
  +        LOG.trace("enter HttpConnection.print(String)");
  +        write(EncodingUtil.getBytes(data, charset));
  +    }
  +    
  +    /**
  +     * @deprecated Use {@link #println(String, String)}
  +     * 
        * Writes the specified String (as bytes), followed by
        * <tt>"\r\n".getBytes()</tt> to the output stream.
        *
  @@ -1009,6 +1028,21 @@
           writeLine(HttpConstants.getBytes(data));
       }
   
  +    /**
  +     * Writes the specified String (as bytes), followed by
  +     * <tt>"\r\n".getBytes()</tt> to the output stream.
  +     *
  +     * @param data the data to be written
  +     * @params charset the charset to use for writing the data
  +     * @throws IllegalStateException if the connection is not open
  +     * @throws IOException if an I/O problem occurs
  +     */
  +    public void printLine(String data, String charset)
  +    	throws IOException, IllegalStateException {
  +        LOG.trace("enter HttpConnection.printLine(String)");
  +        writeLine(EncodingUtil.getBytes(data, charset));
  +    }    
  +    
       /**
        * Writes <tt>"\r\n".getBytes()</tt> to the output stream.
        *
  
  
  
  1.24      +5 -5      jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ConnectMethod.java
  
  Index: ConnectMethod.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/ConnectMethod.java,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -r1.23 -r1.24
  --- ConnectMethod.java	10 Dec 2003 21:04:13 -0000	1.23
  +++ ConnectMethod.java	11 Dec 2003 01:19:32 -0000	1.24
  @@ -222,7 +222,7 @@
           }
           buffer.append(" HTTP/1.1"); 
           String line = buffer.toString();
  -        conn.printLine(line);
  +        conn.printLine(line, getParams().getHttpElementCharset());
           if (Wire.enabled()) {
               Wire.output(line);
           }
  
  
  
  1.29      +38 -3     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java
  
  Index: MultiThreadedHttpConnectionManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/MultiThreadedHttpConnectionManager.java,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- MultiThreadedHttpConnectionManager.java	19 Nov 2003 00:43:12 -0000	1.28
  +++ MultiThreadedHttpConnectionManager.java	11 Dec 2003 01:19:32 -0000	1.29
  @@ -1360,6 +1360,41 @@
               }
           }
   
  +        /* (non-Javadoc)
  +         * @see org.apache.commons.httpclient.HttpConnection#print(java.lang.String, java.lang.String)
  +         */
  +        public void print(String data, String charset) throws IOException, IllegalStateException {
  +            if (hasConnection()) {
  +                wrappedConnection.print(data, charset);
  +            } else {
  +                throw new IllegalStateException("Connection has been released");
  +            }
  +        }
  +
  +        /* (non-Javadoc)
  +         * @see org.apache.commons.httpclient.HttpConnection#printLine(java.lang.String, java.lang.String)
  +         */
  +        public void printLine(String data, String charset)
  +            throws IOException, IllegalStateException {
  +            if (hasConnection()) {
  +                wrappedConnection.printLine(data, charset);
  +            } else {
  +                throw new IllegalStateException("Connection has been released");
  +            }
  +        }
  +
  +        /* (non-Javadoc)
  +         * @see org.apache.commons.httpclient.HttpConnection#setSocketTimeout(int)
  +         */
  +        public void setSocketTimeout(int timeout) throws SocketException, IllegalStateException {
  +            // TODO Auto-generated method stub
  +            if (hasConnection()) {
  +                wrappedConnection.setSocketTimeout(timeout);
  +            } else {
  +                throw new IllegalStateException("Connection has been released");
  +            }
  +        }
  +
       }
   
   }
  
  
  
  1.193     +8 -6      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.192
  retrieving revision 1.193
  diff -u -r1.192 -r1.193
  --- HttpMethodBase.java	10 Dec 2003 21:37:41 -0000	1.192
  +++ HttpMethodBase.java	11 Dec 2003 01:19:32 -0000	1.193
  @@ -1949,13 +1949,15 @@
               + "HttpConnection)");
           addRequestHeaders(state, conn);
   
  +        String charset = getParams().getHttpElementCharset();
  +        
           Header[] headers = getRequestHeaders();
           for (int i = 0; i < headers.length; i++) {
               String s = headers[i].toExternalForm();
               if (Wire.enabled()) {
                   Wire.output(s);
               }
  -            conn.print(s);
  +            conn.print(s, charset);
           }
       }
   
  @@ -1986,7 +1988,7 @@
           if (Wire.enabled()) {
               Wire.output(requestLine);
           }
  -        conn.print(requestLine);
  +        conn.print(requestLine, getParams().getHttpElementCharset());
       }
   
       /**
  
  
  
  1.2       +34 -3     jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/EncodingUtil.java
  
  Index: EncodingUtil.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons/httpclient/src/java/org/apache/commons/httpclient/util/EncodingUtil.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- EncodingUtil.java	15 Jul 2003 12:46:33 -0000	1.1
  +++ EncodingUtil.java	11 Dec 2003 01:19:33 -0000	1.2
  @@ -62,6 +62,7 @@
    */
   package org.apache.commons.httpclient.util;
   
  +import java.io.UnsupportedEncodingException;
   import java.util.BitSet;
   
   import org.apache.commons.httpclient.NameValuePair;
  @@ -159,6 +160,36 @@
           }
           return buf.toString();
       }
  +    
  +    /**
  +     * Converts the specified string to a byte array.  If the charset is not supported the
  +     * default system charset is used.
  +     *
  +     * @param data the string to be encoded
  +     * @param charset the desired character encoding
  +     * @return The resulting byte array.
  +     */
  +    public static byte[] getBytes(final String data, String charset) {
  +
  +        if (data == null) {
  +            throw new IllegalArgumentException("data may not be null");
  +        }
  +
  +        if (charset == null || charset.length() == 0) {
  +            throw new IllegalArgumentException("charset may not be null or empty");
  +        }
  +
  +        try {
  +            return data.getBytes(charset);
  +        } catch (UnsupportedEncodingException e) {
  +
  +            if (LOG.isWarnEnabled()) {
  +                LOG.warn("Unsupported encoding: " + charset + ". System encoding used.");
  +            }
  +            
  +            return data.getBytes();
  +        }
  +    }    
       
       /**
        * This class should not be instantiated.
  
  
  

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