[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xmlrpc-user
Subject:    Re: HTTP Authentication again
From:       Felix Schwarz <Felix.Schwarz () web ! de>
Date:       2006-03-07 14:58:46
Message-ID: 5110374323.20060307155846 () schwarz-online ! org
[Download RAW message or body]


Hi Marek,

(cc'ing the dev list as this mail contains a bug fix.)

Marek 'MMx' Ludha wrote:
> I am trying to authenticate to HTTP server using basic authentication
> with xmlrpc3.0. (...)

> I got an exception with this stacktrace:
> Exception in thread "main" java.lang.IllegalArgumentException: Illegal
> character(s) in message header value: Basic YWRtaW46YWRtaW4x

I hit the same bug. After some examination I found that the problem is
related to encodeBasicAuthentication (org.apache.xmlrpc.util.httpUtil).

"return new String(Base64.encode(s.getBytes(pEncoding)))" appends a
"\n" to the string which is not allowed by the Sun libraries (see bug
4615330 [1] for a bug report to Sun which has some more details in the
evaluation). Unfortunately bug 4447135 [2] is not publicly accessible.

I noticed that xmlrpc 3 uses the Base64 class from common-utils
instead of codec.binary. The later does not add a newline to the end
of the encoded string which is the correct behavior.

Further investigation revealed that the problem is in the call to:
/** Converts the given byte array into a base64 encoded character
  * array with the line size {@link #LINE_SIZE} and the separator
  * {@link #LINE_SEPARATOR}.
  * @param pBuffer The buffer being encoded.
  * @return Character array of encoded bytes.
  */
public static String encode(byte[] pBuffer) {
        return encode(pBuffer, 0, pBuffer.length);
}

As stated in the javadoc the message will perform a line wrap after
LINE_SIZE - which is defined as
/** Default size for line wrapping.
 */
public static final int LINE_SIZE = 76;

As your encoded string is shorter than 76 characters, why does a line
wrap occur?
     Obviously the first problem is that there a line wrap at all -
     but if the wrapping would occur only after 76 characters,
     probably nobody would ever have noticed the bug...

In order to explain that, look at the following method
public void flush() throws IOException {
which contains the following statement:
if (wrapSize > 0  &&  lineChars > 0) {
   wrap();
}

At there it is: If LINE_SIZE is not set to 0 (no wrapping), the Base64
encoder will *always* add a newline at the end.


I don't know if the authors wanted to have a base64 encoder which does
wrapping by default (most encoders I know do not) but I attached a
test case which reveals both bugs (you will have to adapt the import
statement though).

If the wrapping for encode(byte[] pBuffer) is a feature, I propose the
addition of
        /** Converts the given byte array into a base64 encoded character
         * array without line wrapping.
         * @param pBuffer The buffer being encoded.
         * @return Character array of encoded bytes.
         */
        public static String encode_nowrap(byte[] pBuffer) {
                return encode(pBuffer, 0, pBuffer.length, 0, null);
        }
which does no wrapping at all.

Furthermore I consider the javadoc for encode(byte[] pBuffer) to be
broken as it does not state clearly that the call will append a
newline every time.



Thank you very much for your posting. Before I read yours I though of
just using 2.0.1 but as your message was not answered for some days I
stepped into debugging because I want to use 3.0 asap. :-)

I opened a bug report so I guess it will be fixed soon:
https://issues.apache.org/jira/browse/XMLRPC-77


Have fun and happy coding!

-- 
Felix

[1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4615330
[2] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4447135
["Base64Test.java" (application/octet-stream)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic