directory-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Richard Wallace <rwall...@thewallacepack.net>
Subject Re: [asn1] Stateful Decoder question.
Date Wed, 05 Jan 2005 16:16:11 GMT
Robert Newson wrote:
> Hi,
> 
> I'm developing an IMAP server in Java
> (http://wallace.sourceforge.net). I'm currently building the I/O layer
> before moving on to the higher level commands.
> 

Cool, how'd you come up with the name (just curious =P)?  I'm working on 
building a SMTP server that is utilizes the networking libraries that 
are being developed here.  Later I plan on adding POP3 and IMAP4 
servers, also utilizing the networking libraries here as well as the AAA 
framework (formerly known as Janus) that Vincent is working developing. 
  I've been in kind of a holding pattern lately tho, what with the 
holidays and all.  I've also been waiting for the protocol api to 
develop a little further and standardize a little more before developing 
too much more, that way either MINA or (my preference) sedang can be 
used for networking.  We should talk more about this stuff.

> I've been communicating with Trustin as I'm currently using the MINA
> framework (having migrated from Netty very recently).
> 
> IMAP has an interesting I/O model where most strings (and all mail
> messages) can be transferred as 'literals'. Here's an example of a
> conversation;
> 
> Client: 001 LOGIN {8}\r\n
> Server: + continue for 8 bytes.\r\n
> Client: username\r\n{8}\r\n
> Server: + continue for 8 bytes.\r\n
> Client: password\r\n
> 
> Essentially, the client has to wait for a continuation message before
> it can send the rest of the data (this is most useful for large
> numbers of bytes, of course, but can occur for any number of bytes,
> including zero).
> 
> I started building an IMAP grammar with Antlr which can handle a
> useful subset of the full IMAP grammar and I'm happy with this
> approach. The generated parser blocks for I/O if its input is
> incomplete, so I need to decode in several passes.
> 
> My question (finally) is, is the StatefulDecoder work you're doing in
> the Asn1 project applicable to my problem? I see that there's a basic
> level that is Asn1-agnostic.
> 
> I'm keen to build a high-performance, non-blocking and elegant
> solution to this problem, but I'm now thrashing backwards and forwards
> for the right tool.
> 

In some of my initial work on the SMTP server I've been using the 
StatefulDecoder.  Since the grammar for SMTP is pretty simple I just 
plan on writing a parser by hand to process the strings and generate the 
Command objects to be passed to the next stage.  I haven't looked into 
the IMAP spec yet, but is it really complicated and large enough that 
you need to use a parser generator like Antlr?

Here's what I'm doing right now (you can take a look at 
http://dropbox.compunetconsulting.com).  Basically, my SMTPDecoder the 
decode() method uses two buffers, a StringBuffer for the current command 
and byte[] for grabbing data from the ByteBuffer parameter provided to 
the decode() method.  As much data as is possible from the network is 
taken from the ByteBuffer in one get() method and put into the temporary 
byte[].  (This is the part I don't like but can't figure out a way 
around ATM)  I then have to iterate over the data in the temporary 
byte[] looking for a <CRLF> to indicate the end of the command.  If I 
don't get them I append to the command StringBuffer.  Once I do get them 
I pass the contents of the command StringBuffer and pass them to the 
command parser which returns a Command object that is passed to the next 
stage with the decodeOccurred() callback.  I then continue processing 
data in the ByteBuffer if there is any (in case a client tries to send 
multiple commands all at once).

I think this will work well, the only part I don't like is having to 
iterate over the data looking for a <CRLF>.  I just seems too 
inefficient, because then I'm basically doing two passes over the data 
the client sends me (once here and then again in the command parser). 
But, I can't always trust the only a single command will be in the 
ByteBuffer, so I don't really have a choice.

I think something similar will work for you're case.  If you (or anyone 
else) can offer a better solution, I'm more than open to it (I'd be in 
your debt ;).

Rich

Mime
View raw message