From 07e7a0c281c439b1ece7099cc24e0e763b33f5b0 Mon Sep 17 00:00:00 2001 From: Oleg Kalnichevski Date: Thu, 5 Jun 2014 13:09:47 +0000 Subject: [PATCH] Auth scheme state cache to use object serialization git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1600641 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/http/impl/auth/BasicScheme.java | 13 +++++-- .../apache/http/impl/auth/DigestScheme.java | 2 ++ .../apache/http/impl/auth/RFC2617Scheme.java | 31 ++++++++++++++-- .../http/impl/auth/TestBasicScheme.java | 26 ++++++++++++++ .../http/impl/auth/TestDigestScheme.java | 27 ++++++++++++++ .../http/impl/auth/TestRFC2617Scheme.java | 36 +++++++++++++++++++ 6 files changed, 129 insertions(+), 6 deletions(-) diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java b/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java index 8e8c2d326..9a5f589b4 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/BasicScheme.java @@ -53,7 +53,8 @@ import org.apache.http.util.EncodingUtils; @NotThreadSafe public class BasicScheme extends RFC2617Scheme { - private final Base64 base64codec; + private static final long serialVersionUID = -1931571557597830536L; + /** Whether the basic authentication process is complete */ private boolean complete; @@ -62,7 +63,6 @@ public class BasicScheme extends RFC2617Scheme { */ public BasicScheme(final Charset credentialsCharset) { super(credentialsCharset); - this.base64codec = new Base64(0); this.complete = false; } @@ -77,7 +77,6 @@ public class BasicScheme extends RFC2617Scheme { @Deprecated public BasicScheme(final ChallengeState challengeState) { super(challengeState); - this.base64codec = new Base64(0); } public BasicScheme() { @@ -166,6 +165,7 @@ public class BasicScheme extends RFC2617Scheme { tmp.append(":"); tmp.append((credentials.getPassword() == null) ? "null" : credentials.getPassword()); + final Base64 base64codec = new Base64(0); final byte[] base64password = base64codec.encode( EncodingUtils.getBytes(tmp.toString(), getCredentialsCharset(request))); @@ -220,4 +220,11 @@ public class BasicScheme extends RFC2617Scheme { return new BufferedHeader(buffer); } + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("BASIC [complete=").append(complete) + .append("]"); + return builder.toString(); + } } diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java b/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java index c6ab233ed..74b830272 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/DigestScheme.java @@ -74,6 +74,8 @@ import org.apache.http.util.EncodingUtils; @NotThreadSafe public class DigestScheme extends RFC2617Scheme { + private static final long serialVersionUID = 3883908186234566916L; + /** * Hexa values used when creating 32 character long digest in HTTP DigestScheme * in case of authentication. diff --git a/httpclient/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java b/httpclient/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java index 126b421b4..f00cca5cf 100644 --- a/httpclient/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java +++ b/httpclient/src/main/java/org/apache/http/impl/auth/RFC2617Scheme.java @@ -26,6 +26,11 @@ */ package org.apache.http.impl.auth; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamException; +import java.io.Serializable; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Locale; @@ -42,6 +47,7 @@ import org.apache.http.message.BasicHeaderValueParser; import org.apache.http.message.HeaderValueParser; import org.apache.http.message.ParserCursor; import org.apache.http.util.CharArrayBuffer; +import org.apache.http.util.CharsetUtils; /** * Abstract authentication scheme class that lays foundation for all @@ -52,10 +58,12 @@ import org.apache.http.util.CharArrayBuffer; */ @SuppressWarnings("deprecation") @NotThreadSafe // AuthSchemeBase, params -public abstract class RFC2617Scheme extends AuthSchemeBase { +public abstract class RFC2617Scheme extends AuthSchemeBase implements Serializable { + + private static final long serialVersionUID = -2845454858205884623L; private final Map params; - private final Charset credentialsCharset; + private transient Charset credentialsCharset; /** * Creates an instance of RFC2617Scheme with the given challenge @@ -90,7 +98,7 @@ public abstract class RFC2617Scheme extends AuthSchemeBase { * @since 4.3 */ public Charset getCredentialsCharset() { - return credentialsCharset; + return credentialsCharset != null ? credentialsCharset : Consts.ASCII; } String getCredentialsCharset(final HttpRequest request) { @@ -150,4 +158,21 @@ public abstract class RFC2617Scheme extends AuthSchemeBase { return getParameter("realm"); } + private void writeObject(final ObjectOutputStream out) throws IOException { + out.defaultWriteObject(); + out.writeUTF(this.credentialsCharset.name()); + } + + @SuppressWarnings("unchecked") + private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.credentialsCharset = CharsetUtils.get(in.readUTF()); + if (this.credentialsCharset == null) { + this.credentialsCharset = Consts.ASCII; + } + } + + private void readObjectNoData() throws ObjectStreamException { + } + } diff --git a/httpclient/src/test/java/org/apache/http/impl/auth/TestBasicScheme.java b/httpclient/src/test/java/org/apache/http/impl/auth/TestBasicScheme.java index c34130d3f..d45c9a7ff 100644 --- a/httpclient/src/test/java/org/apache/http/impl/auth/TestBasicScheme.java +++ b/httpclient/src/test/java/org/apache/http/impl/auth/TestBasicScheme.java @@ -26,6 +26,11 @@ */ package org.apache.http.impl.auth; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + import org.apache.commons.codec.binary.Base64; import org.apache.http.Consts; import org.apache.http.Header; @@ -118,4 +123,25 @@ public class TestBasicScheme { Assert.assertFalse(authscheme.isConnectionBased()); } + @Test + public void testSerialization() throws Exception { + final Header challenge = new BasicHeader(AUTH.PROXY_AUTH, "Basic realm=\"test\""); + + final BasicScheme basicScheme = new BasicScheme(); + basicScheme.processChallenge(challenge); + + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + final ObjectOutputStream out = new ObjectOutputStream(buffer); + out.writeObject(basicScheme); + out.flush(); + final byte[] raw = buffer.toByteArray(); + final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(raw)); + final BasicScheme authScheme = (BasicScheme) in.readObject(); + + Assert.assertEquals(basicScheme.getSchemeName(), authScheme.getSchemeName()); + Assert.assertEquals(basicScheme.getRealm(), authScheme.getRealm()); + Assert.assertEquals(basicScheme.isComplete(), authScheme.isComplete()); + + } + } diff --git a/httpclient/src/test/java/org/apache/http/impl/auth/TestDigestScheme.java b/httpclient/src/test/java/org/apache/http/impl/auth/TestDigestScheme.java index 20e3979c8..c90c0e7ae 100644 --- a/httpclient/src/test/java/org/apache/http/impl/auth/TestDigestScheme.java +++ b/httpclient/src/test/java/org/apache/http/impl/auth/TestDigestScheme.java @@ -27,7 +27,10 @@ package org.apache.http.impl.auth; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.security.MessageDigest; import java.util.HashMap; import java.util.Map; @@ -618,4 +621,28 @@ public class TestDigestScheme { authscheme.authenticate(cred, request, context); } + @Test + public void testSerialization() throws Exception { + final String challenge = "Digest realm=\"realm1\", nonce=\"f2a3f18799759d4f1a1c068b92b573cb\", " + + "qop=\"auth,auth-int\""; + final Header authChallenge = new BasicHeader(AUTH.WWW_AUTH, challenge); + final DigestScheme digestScheme = new DigestScheme(); + digestScheme.processChallenge(authChallenge); + + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + final ObjectOutputStream out = new ObjectOutputStream(buffer); + out.writeObject(digestScheme); + out.flush(); + final byte[] raw = buffer.toByteArray(); + final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(raw)); + final DigestScheme authScheme = (DigestScheme) in.readObject(); + + Assert.assertEquals(digestScheme.getSchemeName(), authScheme.getSchemeName()); + Assert.assertEquals(digestScheme.getRealm(), authScheme.getRealm()); + Assert.assertEquals(digestScheme.isComplete(), authScheme.isComplete()); + Assert.assertEquals(digestScheme.getA1(), authScheme.getA1()); + Assert.assertEquals(digestScheme.getA2(), authScheme.getA2()); + Assert.assertEquals(digestScheme.getCnonce(), authScheme.getCnonce()); + } + } diff --git a/httpclient/src/test/java/org/apache/http/impl/auth/TestRFC2617Scheme.java b/httpclient/src/test/java/org/apache/http/impl/auth/TestRFC2617Scheme.java index e63f554d2..27fcca66c 100644 --- a/httpclient/src/test/java/org/apache/http/impl/auth/TestRFC2617Scheme.java +++ b/httpclient/src/test/java/org/apache/http/impl/auth/TestRFC2617Scheme.java @@ -27,6 +27,13 @@ package org.apache.http.impl.auth; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.nio.charset.Charset; + +import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HttpRequest; import org.apache.http.auth.AUTH; @@ -43,6 +50,14 @@ public class TestRFC2617Scheme { static class TestAuthScheme extends RFC2617Scheme { + public TestAuthScheme() { + super(); + } + + public TestAuthScheme(final Charset charset) { + super(charset); + } + @Override @Deprecated public Header authenticate( @@ -139,5 +154,26 @@ public class TestRFC2617Scheme { authscheme.processChallenge(header); } + @Test + public void testSerialization() throws Exception { + final Header challenge = new BasicHeader(AUTH.WWW_AUTH, "test realm=\"test\", blah=blah, yada=\"yada yada\""); + + final TestAuthScheme testScheme = new TestAuthScheme(Consts.ISO_8859_1); + testScheme.processChallenge(challenge); + + final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + final ObjectOutputStream out = new ObjectOutputStream(buffer); + out.writeObject(testScheme); + out.flush(); + final byte[] raw = buffer.toByteArray(); + final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(raw)); + final TestAuthScheme authScheme = (TestAuthScheme) in.readObject(); + + Assert.assertEquals(Consts.ISO_8859_1, authScheme.getCredentialsCharset()); + Assert.assertEquals("test", authScheme.getParameter("realm")); + Assert.assertEquals("blah", authScheme.getParameter("blah")); + Assert.assertEquals("yada yada", authScheme.getParameter("yada")); + } + }