Hi,

I have ported your code on a standalone class to test it :


import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.mina.common.ByteBuffer;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;

public class FSResponseDecoder {

private static final byte[] CONTENT_LENGTH = new String("Content-Length:").getBytes();

   private CharsetDecoder decoder = Charset.defaultCharset().newDecoder();

   public FSResponseDecoder() {
   }

synchronized public MessageDecoderResult decodable(IoSession session, ByteBuffer in) {
       try {
           return messageComplete(in) ? MessageDecoderResult.OK
                   : MessageDecoderResult.NEED_DATA;
       } catch (Exception ex) {
           ex.printStackTrace();
       }

       return MessageDecoderResult.NOT_OK;
   }

public MessageDecoderResult decode(IoSession session, ByteBuffer in) throws Exception {
       // Try to decode body

       System.out.println("[[[[[ Decode function on session "+session);

       decodeBody(in);

System.out.println("]]]]] Finish decode function on session "+session);

       return MessageDecoderResult.OK;
   }

   private String getBufferString(ByteBuffer in) {
       int size = in.remaining();

       if (size == 0) {
           return "empty";
       }

       StringBuffer out = new StringBuffer(size);

       while(in.hasRemaining()) {
           out.append((char) in.get());
       }

       in.flip();

       return out.toString();
   }

   private int getEndOfHeader(ByteBuffer in,int last) {
       int eoh = -1;
       for (int i = 0; i < last; i++) {
           if (in.get(i) == (byte) 0x0A && in.get(i + 1) == (byte) 0x0A) {
               eoh = i + 1;
               break;
           }
       }
       return eoh;
   }

   private boolean messageComplete(ByteBuffer in) throws Exception {
       int sizeToRead = 0;
       int last = in.remaining() - 1;

       System.out.println("***** New Buffer to analyze *****");

       String str = getBufferString(in);               // in.getHexDump();

       System.out.println("Buffer Dump\n"+str);

       int eoh = getEndOfHeader(in, last);

       if (eoh == -1)
           return false;


       if (in.get(0)  == (byte) 'C' && in.get(1)  == (byte) 'o' &&
in.get(2)  == (byte) 'n' &&
             in.get(3)  == (byte) 't' && in.get(4)  == (byte) 'e' &&
in.get(5)  == (byte) 'n' &&
              in.get(6)  == (byte) 't' && in.get(7)  == (byte) '-' &&
in.get(8)  == (byte) 'L' &&
              in.get(9)  == (byte) 'e' && in.get(10) == (byte) 'n' &&
in.get(11) == (byte) 'g' &&
              in.get(12)  == (byte) 't' && in.get(13) == (byte) 'h')
       {

           int contentLength = getContentLength(in, last);

           boolean result;

           if (contentLength>0) {
               result = contentLength + eoh <= in.remaining();
               sizeToRead = contentLength + (eoh+1);
System.out.println("content_length["+contentLength+"] eoh["+eoh+"] == in.remaining["+in.remaining()+"] ==> "+result);
               if (result)
                   System.out.println("sizeToRead is >>>> "+sizeToRead);
           }
           else
               result = false;

           return (result);

       }

       sizeToRead = eoh+1;
       System.out.println("sizeToRead is >>>> "+sizeToRead);

       return true;
   }


   private int getContentLength(ByteBuffer in, int last) {

       String str = getBufferString(in);               // in.getHexDump();
       System.out.println("last = "+last);
System.out.println("***** Buffer in getContentLength 1 *****\n"+str);

       for (int i = 0; i < last; i++) {
           boolean found = false;
           for (int j = 0; j < CONTENT_LENGTH.length; j++) {
               if (in.get(i + j) != CONTENT_LENGTH[j]) {
                   found = false;
                   break;
               }
               found = true;
           }
           if (found) {
               // retrieve value from this position till next 0x0D 0x0A
               System.out.println("Found content-length index at "+i);

               StringBuilder contentLength = new StringBuilder();
               for (int j = i + CONTENT_LENGTH.length; j < last; j++) {
                   if (in.get(j) == 0x0A)
                       break;
                   contentLength.append(new String( new byte[] { in.get(j)
}));
                   System.out.println("["+new String( new byte[]
{in.get(j)})+"]");
               }
// if content-length worth of data has been received then the message is complete

               str = getBufferString(in);               // in.getHexDump();
System.out.println("***** Buffer in getContentLength 2*****\n"+str);

               System.out.println("ContentLength = "+contentLength);
               System.out.println("total buffer length = "+in.remaining());
               return Integer.parseInt(contentLength.toString().trim());
           }
       }
       return -1;
   }

   private void decodeBody(ByteBuffer in) {
       try {

           int sizeToRead = 0;
           int last = in.remaining() - 1;
           int eoh = getEndOfHeader(in, last);

           if (in.get(0)  == (byte) 'C' && in.get(1)  == (byte) 'o' &&
in.get(2)  == (byte) 'n' &&
                     in.get(3)  == (byte) 't' && in.get(4)  == (byte) 'e'
&& in.get(5)  == (byte) 'n' &&
                      in.get(6)  == (byte) 't' && in.get(7)  == (byte) '-'
&& in.get(8)  == (byte) 'L' &&
                      in.get(9)  == (byte) 'e' && in.get(10) == (byte) 'n'
&& in.get(11) == (byte) 'g' &&
                      in.get(12)  == (byte) 't' && in.get(13) == (byte)
'h')
           {
               int contentLength = getContentLength(in, last);
               sizeToRead = contentLength + (eoh+1);
           }
           else
               sizeToRead = eoh+1;

System.out.println("Parsing request with sizeToRead = "+sizeToRead);
           parseRequest(new StringReader(in.getString(sizeToRead,
decoder)));
       } catch (CharacterCodingException ex) {
           ex.printStackTrace();
       } catch (Exception e) {
           // TODO Auto-generated catch block
           e.printStackTrace();
       }
   }

   private void parseRequest(Reader is) {

       BufferedReader rdr = new BufferedReader(is);
       Map<String, String> response = new HashMap<String,String>();

       try {
           // Get request URL.
           String line;

           // Read header
           System.out.println("Reading parameters:");
           while ((line = rdr.readLine()) != null && line.length() > 0) {
               String[] tokens = line.split(": ");
               response.put(tokens[0], tokens[1] );
               System.out.println(tokens[0]+": "+tokens[1]);
           }

           // determine content-type of this response
           String contentType = response.get("Content-Type");

           // If method 'POST' then read Content-Length worth of data
if (contentType.equalsIgnoreCase("text/event-xml") || contentType.equalsIgnoreCase("text/event-plain")) {
               int len = Integer.parseInt(response.get("Content-Length"));
               char[] buf = new char[len];
               if (rdr.read(buf) == len) {
                   line = String.copyValueOf(buf);
               }
               String str = line;
               response.put("Event-Data", str);
           }

       } catch (IOException ex) {
           ex.printStackTrace();
       }

   }

   public static void main(String[] args) throws Exception
   {
       FSResponseDecoder decoder = new FSResponseDecoder();
       String str =
           "Content-Length: 1619\n"+
           "Content-Type: text/event-plain\n"+
           "\n"+
           "Channel-State: CS_NEW\n"+
           "Channel-State-Number: 0\n"+
           "Channel-Name: sofia/external/nobody%40192.168.3.12\n"+
           "Unique-ID: fd2229c0-2d6c-11dd-9acd-0b28d09a52aa\n"+
           "Call-Direction: inbound\n"+
           "Answer-State: ringing\n"+
           "variable_sip_from_user: nobody\n"+
           "variable_sip_from_uri: nobody%40192.168.3.12\n"+
           "variable_sip_from_host: 192.168.3.12\n"+
           "variable_sip_from_tag: 02H917ryecvgp\n"+
           "variable_sofia_profile_name: external\n"+
           "variable_sofia_profile_domain_name: external\n"+
           "variable_sip_req_user: 6001\n"+
           "variable_sip_req_port: 5080\n"+
           "variable_sip_req_uri: 6001%40192.168.3.11%3A5080\n"+
           "variable_sip_req_host: 192.168.3.11\n"+
           "variable_sip_to_user: 6001\n"+
           "variable_sip_to_port: 5080\n"+
           "variable_sip_to_uri: 6001%40192.168.3.11%3A5080\n"+
           "variable_sip_to_host: 192.168.3.11\n"+
           "variable_sip_contact_user: mod_sofia\n"+
           "variable_sip_contact_port: 5060\n"+
           "variable_sip_contact_uri: mod_sofia%40192.168.3.12%3A5060\n"+
           "variable_sip_contact_host: 192.168.3.12\n"+
           "variable_channel_name: sofia/external/nobody%40192.168.3.12\n"+
           "variable_endpoint_disposition: INBOUND%20CALL\n"+
           "variable_sip_call_id: 824f7531-a82e-122b-8485-000f1f644b48\n"+
           "variable_sip_user_agent: FreeSWITCH-mod_sofia/1.0.pre4-8539\n"+
           "variable_sip_via_host: 192.168.3.12\n"+
           "variable_sip_via_rport: 5060\n"+
           "variable_max_forwards: 70\n"+
           "Event-Name: CHANNEL_CREATE\n"+
           "Core-UUID: ed9888ba-2c94-11dd-";
       int capacity = str.getBytes().length;
       ByteBuffer bb = ByteBuffer.allocate( capacity );
       bb.put( str.getBytes() );
       decoder.decode( null, bb );
   }
}


Here are the logs :

[[[[[ Decode function on session null
last = 752
***** Buffer in getContentLength 1 *****


seems correct. Can you test it ?

--
--
cordialement, regards,
Emmanuel Lécharny
www.iktek.com
directory.apache.org


Reply via email to