Uploaded image for project: 'XML-RPC'
  1. XML-RPC
  2. XMLRPC-77

Base64 encoder wraps lines (HTTP auth not possible)

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 3.0a1
    • None
    • Source
    • None
    • this bug affects all environments.

    Description

      I am using xmlrpc 3.0a1 and when I try to do http auth I always get
      Exception in thread "main" java.lang.IllegalArgumentException: Illegal character(s) in message header value: Basic ZnM6dGVzdA==
      at sun.net.www.protocol.http.HttpURLConnection.checkMessageHeader(HttpURLConnection.java:301)
      at sun.net.www.protocol.http.HttpURLConnection.setRequestProperty(HttpURLConnection.java:1936)
      at org.apache.xmlrpc.client.XmlRpcSunHttpTransport.setRequestHeader(XmlRpcSunHttpTransport.java:30)
      at org.apache.xmlrpc.client.XmlRpcHttpTransport.setCredentials(XmlRpcHttpTransport.java:37)
      at org.apache.xmlrpc.client.XmlRpcHttpTransport.initConnection(XmlRpcHttpTransport.java:68)
      at org.apache.xmlrpc.client.XmlRpcStreamTransport.sendRequest(XmlRpcStreamTransport.java:188)
      at org.apache.xmlrpc.client.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:53)
      at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:166)
      at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:136)
      at org.apache.xmlrpc.client.XmlRpcClient.execute(XmlRpcClient.java:125)
      at SnSnXmlRpcAuth.main(SnSnXmlRpcAuth.java:36)

      code snippet is like:
      server = new URL("http://localhost/RPC2");
      config.setServerURL(server);
      config.setBasicEncoding("iso-8859-1");
      config.setBasicUserName("fs");
      config.setBasicPassword("test");
      XmlRpcClient client = new XmlRpcClient();
      client.setConfig(config);
      Object[] parameters = new Object[]

      { rootElement }

      ;
      client.execute("functionname", parameters);

      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 posted a
      test case which reveals both bugs (you will have to adapt the import
      statement though) in the user mailing

      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.

      [1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4615330
      [2] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4447135

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              felix Felix Maeder
              Votes:
              1 Vote for this issue
              Watchers:
              0 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: